问题
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!
回答1:
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:
The value of SCB->BFAR indicates the memory address that caused a Bus Fault and is valid if the bit BFARVALID in the SCB->CFSR register is set. The value of SCB->MMFAR indicates the memory address that caused a Memory Management Fault and is valid if the bit MMFARVALID in the SCB->CFSR register is set.
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.
回答2:
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.
回答3:
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)
回答4:
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.
回答5:
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.
来源:https://stackoverflow.com/questions/3764119/arm-cortex-m3-how-do-i-determine-the-program-counter-value-before-a-hard-fault