I have an STM32 Cortex M3 that is experiencing an intermittent invalid PC (INVPC) fault. Unfortunately it takes a day or more to manifest and I don't know the cause.
I have the device paused in the debugger after the fault happened. The INVPC flag is set. The stacked registers are as follows:
0x08003555 xPSR
0x08006824 PC
0x08006824 LR
0x00000000 R12
0x08003341 R3
0x08006824 R2
0xFFFFFFFD R2
0x0000FFFF R0
Unfortunately the return address 0x08006824 is just past the end of the firmware image. The decompilation of that region is as follows:
Region$$Table$$Base
0x08006804: 08006824 $h.. DCD 134244388
0x08006808: 20000000 ... DCD 536870912
0x0800680c: 000000bc .... DCD 188
0x08006810: 08005b30 0[.. DCD 134241072
0x08006814: 080068e0 .h.. DCD 134244576
0x08006818: 200000bc ... DCD 536871100
0x0800681c: 00001a34 4... DCD 6708
0x08006820: 08005b40 @[.. DCD 134241088
Region$$Table$$Limit
** Section #2 'RW_IRAM1' (SHT_PROGBITS) [SHF_ALLOC + SHF_WRITE]
Size : 188 bytes (alignment 4)
Address: 0x20000000
I'm not sure this address is valid. The disassembly of that address in the debugger looks like nonsense, maybe data interpreted as code or something.
Is there any way I can trace this back to see where the exception happened? If necessary I can add some additional code to capture more information.
Don't sure how it works on Cortex M3, but on some other ARMs PSR register holds processor mode bits that could help you find out when it happens (in user mode, IRQ, FIQ etc). Each mode generally have it's own stack.
For user mode, if you use some RTOS with multi-tasking, you probably have many stacks for each task, but you could try to find out which task is current one (was running before crash).
When you find crashed task (or IRQ) you could try to look at it's stack for addresses of all routines and find out what was called before accident. Of course if stack was not unrecoverably corrupted.
This is what I'd start investigation from. If you find crashed task or even function but still have no idea what happens, you could make something like small circular history buffer where you write some codes on every step of your program, so you could find what it does last even if stack was destroyed.
User contributions licensed under CC BY-SA 3.0