ARM Cortex M3 How to determine the value of the program counter before a hard error?

I have a built-in project using STM32F103 (ARM Cortex M3), it sometimes gets a hard error in release mode. As part of the recovery, I would like to get the PC value before a hard error and save it for later debugging in the area supported by the battery.

How to determine the value of the program counter at a hard fault point? Obviously, the PC is now configured for its location as part of a hard failure interrupt.

Where should I look? Is that the address for the normal mode register bank?

Thanks!

+5
source share
5 answers

Cortex-M3 uses a completely different model for handling exceptions from the "classic" ARM, for example. it does not have the โ€œinterrupt modeโ€ mentioned in another message. I suggest you read this application note . For example, for a hard failure:

The value SCB-> BFAR indicates the memory address that caused the bus error and is valid if the BFARVALID bit in the SCB-> CFSR register is set. the value SCB-> MMFAR indicates the memory address that caused the memory. The control error is valid if the MMFARVALID bit in the SCB-> CFSR register is set.

To determine the value of the PC at the time of the exception, you need to examine the stack; the processor starts R0-R3, R12, PC, and LR before executing the handler. The stack used can be either the main one (if bit 2 LR is 0), or a process (otherwise). For details, see Page 13 notes to the application.

+6
source

You should study the ARM Architecture Reference Guide in the Exceptions section. You need to register to receive it.

Typically, the corresponding reference address will be placed in the LR reference register (R14), but the exact value changes according to the exception, and there are various offsets.

Wrt access to the bank register of the user / system mode, I think you need to switch the mode to access it.

+3
source

When an exception occurs, the state of the processor goes from the current state to the interrupt state. In an interrupt state, the processor switches to using a new set of registers for sp and lr (sp_abt and sp_lr, respectively. To interrupt data, the insult command can be found in lr_abt + 8 for the prefect near lr_abt + 4 (according to the ARMv7 Architecure Reference Guide)

+1
source

I have a FAQ on this topic. The FAQ page includes an error handler code that will get the program counter from the stack for you.

+1
source

I found a common reason for these problems - these are delays "per cycle". When using -O3, they are simply optimized if you are not referencing mutable variables. Personally, I prefer the SysTick approach.

0
source

Source: https://habr.com/ru/post/953960/


All Articles