ARM Cortex M3 如何在发生硬故障之前确定程序计数器值?
我有一个使用 STM32F103 (ARM Cortex M3) 的嵌入式项目,它在发布模式下偶尔会出现硬故障。作为恢复的一部分,我想检索硬故障之前的 PC 值并将其存储起来以供以后在电池支持区域进行调试。
如何确定发生硬故障时程序计数器的值?显然,PC 现在已设置为硬故障中断内的位置。
我应该去哪里看?是否有正常模式寄存器组的地址?
谢谢!
I have an embedded project using a STM32F103 (ARM Cortex M3), it is getting a occasionally getting hard fault in release mode. As part of recovery, I would like to retrieve the PC value from before the hard fault and store it for later debugging in the battery backed region.
How would I determine the value of the program counter at the point of the hard fault? Obviously, the PC is now set to its location within the hardfault interrupt.
Where should I look? It there an address for the normal mode register bank?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Cortex-M3 使用与“经典”ARM 完全不同的异常处理模型,例如,它没有另一篇文章中提到的“中止模式”。我建议您阅读此应用说明。例如,对于硬故障:
要确定异常时的 PC 值,您需要检查堆栈;处理器在执行处理程序之前压入 R0-R3、R12、PC 和 LR。使用的堆栈可以是 Main(如果 LR 的位 2 为 0)或 Process(否则)。有关详细信息,请参阅应用说明的第 13 页。
Cortex-M3 uses a quite different model of exception handling from the "classic" ARM, e.g. it doesn't have "abort mode" mentioned in the other post. I suggest you to read this app note. For example, for the Hard Fault:
To determine the PC value at the time of exception you need to examine the stack; the processor pushes R0-R3, R12, PC and LR before executing the handler. The stack used can be either Main (if bit 2 of LR is 0) or Process (otherwise). See page 13 of the app note for details.
您应该查看 ARM 架构参考手册中的异常部分。您需要注册才能获取它。
通常,相关地址会被放入链接寄存器LR(R14)中,但具体含义根据异常情况而变化,并且存在不同的偏移量。
当访问用户/系统模式寄存器组时,我认为您需要切换模式才能访问它。
You should look into the ARM Architecture Reference Manual in the section on Exceptions. You need to register to get it.
Typically a relevant address will be put in the link register LR (R14), but the precise meaning varies according to the exception, and there are varying offsets.
W.r.t. accessing the User/System mode register bank, I think you need to switch the mode to access it.
当异常发生时,处理器状态从当前状态变为中止状态。在中止状态下,处理器转向对 sp 和 lr 使用一组新的寄存器(分别为 sp_abt 和 sp_lr)。对于数据中止,可以在 lr_abt + 8 中找到违规指令,大约在 lr_abt + 4 中(根据ARMv7 架构参考手册)
When an exception occurs, the processor state change from the current state to the abort state. In the abort state the processor shifts to use a new set of registers for sp and lr (sp_abt and sp_lr respectively. For a data abort, the offending instruction can be found in lr_abt + 8 for an prefect about in lr_abt + 4 (as per the ARMv7 Architecure reference manual)
我有一个关于这个主题的常见问题解答。常见问题解答链接到的页面包括故障处理程序代码 将为您从堆栈中获取程序计数器。
I have an FAQ on this very topic. The page linked to from the FAQ includes fault handler code that will obtain the program counter from the stack for you.
我发现这些问题的一个常见原因是“for 循环”延迟。当使用-O3时,如果您没有引用易失性变量,它们就会被优化掉。就我个人而言,我更喜欢 SysTick 方法。
I found a common cause for these issues are those 'for loop' delays. When using -O3 they simply get optimized away if you are are not referring to volatile variables. Personally, I prefer the SysTick approach.