我有一个使用 STM32F103(ARM Cortex M3)的嵌入式项目,它在发布模式下偶尔会出现硬故障。作为恢复的一部分,我想从硬故障之前检索 PC 值并将其存储以供以后在电池供电区域进行调试。
如何确定发生硬故障时程序计数器的值?显然,PC 现在已设置为其在硬故障中断内的位置。
我应该去哪里看?它有正常模式寄存器组的地址吗?
谢谢!
我有一个使用 STM32F103(ARM Cortex M3)的嵌入式项目,它在发布模式下偶尔会出现硬故障。作为恢复的一部分,我想从硬故障之前检索 PC 值并将其存储以供以后在电池供电区域进行调试。
如何确定发生硬故障时程序计数器的值?显然,PC 现在已设置为其在硬故障中断内的位置。
我应该去哪里看?它有正常模式寄存器组的地址吗?
谢谢!
Cortex-M3 使用与“经典”ARM 完全不同的异常处理模型,例如,它没有在另一篇文章中提到的“中止模式”。我建议您阅读此应用说明。例如,对于硬故障:
SCB->BFAR 的值表示导致总线故障的内存地址,如果 SCB->CFSR 寄存器中的 BFARVALID 位被置位,则该值有效。SCB->MMFAR 的值表示导致内存管理故障的内存地址,如果 SCB->CFSR 寄存器中的 MMFARVALID 位被置位,则该内存地址有效。
要确定异常时的 PC 值,您需要检查堆栈;处理器在执行处理程序之前推送 R0-R3、R12、PC 和 LR。使用的堆栈可以是 Main(如果 LR 的第 2 位为 0)或 Process(否则)。有关详细信息,请参阅应用说明的第 13 页。
您应该查看异常部分中的ARM 体系结构参考手册。您需要注册才能获得它。
通常相关的地址会放在链接寄存器 LR (R14) 中,但具体含义会根据例外情况而有所不同,并且存在不同的偏移量。
Wrt 访问用户/系统模式寄存器库,我认为您需要切换模式才能访问它。
我有一个关于这个主题的常见问题解答。FAQ 链接到的页面包含错误处理程序代码,它将为您从堆栈中获取程序计数器。
当异常发生时,处理器状态从当前状态变为中止状态。在中止状态,处理器转换为使用一组新的寄存器用于 sp 和 lr(分别为 sp_abt 和 sp_lr。对于数据中止,违规指令可以在 lr_abt + 8 中找到 lr_abt + 4 中的 prefect (根据ARMv7 架构参考手册)
我发现这些问题的一个常见原因是那些“for loop”延迟。使用 -O3 时,如果您不是指易失性变量,它们只会被优化掉。就个人而言,我更喜欢 SysTick 方法。