Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ARM Cortex M3 How do I determine the program counter value before a hard fault?

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!

like image 730
JeffV Avatar asked Sep 21 '10 20:09

JeffV


People also ask

What is hard fault in Cortex-M3?

Hard Fault: is caused by Bus Fault, Memory Management Fault, or Usage Fault if their handler cannot be executed. After reset, not all fault exceptions are enabled, and with every fault the Hard Fault execp- tion handler is executed. Cortex-M vector table.

What is hard fault in arm?

A hard fault is an exception that occurs because of an error during normal or exception processing. As per the Cortex-M0 Devices Generic User Guide (revision r0p0), the following sources can cause a hard fault: execution of an SVC instruction at a priority equal or higher than SVCall.

What is ARM usage fault?

Usage Fault: detects execution of undefined instructions, unaligned memory access for load/store multiple. When enabled, divide-by-zero and other unaligned memory accesses are also detected.

What is a HardFault?

HardFault refers to all classes of faults that cannot be handled by any of the other exception mechanisms. Typically, HardFault is used for unrecoverable system failures.


4 Answers

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.

like image 65
Igor Skochinsky Avatar answered Oct 06 '22 05:10

Igor Skochinsky


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.

like image 34
starblue Avatar answered Oct 06 '22 05:10

starblue


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)

like image 36
doron Avatar answered Oct 06 '22 05:10

doron


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.

like image 22
Richard Avatar answered Oct 06 '22 03:10

Richard