我的STM32 Cortex M3遇到间歇性无效PC(INVPC)故障。不幸的是,这需要一天或更长的时间才能显现出来,我不知道原因。
故障发生后,我已将设备暂停在调试器中。 INVPC标志被设置。堆叠的寄存器如下:
0x08003555 xPSR
0x08006824 PC
0x08006824 LR
0x00000000 R12
0x08003341 R3
0x08006824 R2
0xFFFFFFFD R2
0x0000FFFF R0
不幸的是,返回地址0x08006824刚超出固件映像的末尾。该区域的反编译如下:
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
我不确定该地址是否有效。在调试器中对该地址的反汇编看起来像是胡说八道,也许数据解释为代码之类的东西。
有什么办法可以追溯到该异常发生的地方吗?如有必要,我可以添加一些其他代码来捕获更多信息。
答案 0 :(得分:0)
不确定它在Cortex M3上如何工作,但是在其他一些ARM上,PSR寄存器包含处理器模式位,可以帮助您确定何时发生(在用户模式,IRQ,FIQ等)。每种模式通常都有自己的堆栈。
对于用户模式,如果您将某些RTOS与多任务一起使用,则每个任务可能有很多堆栈,但是您可以尝试找出哪个是当前任务(崩溃前正在运行)。
当您发现崩溃的任务(或IRQ)时,您可以尝试查看其堆栈中所有例程的地址,并找出发生意外之前被调用的内容。当然,如果堆栈没有被不可恢复地损坏。
这就是我要开始调查的内容。如果您发现崩溃的任务甚至函数,但仍然不知道会发生什么,则可以创建类似小的循环历史记录缓冲区的程序,在该缓冲区中,您可以在程序的每个步骤上编写一些代码,因此即使堆栈被破坏,也可以找到它的作用