如何分析Cortex-M3上的无效PC故障?

问题描述

SoC:SmartFusion2

处理器:Cortex-M3

OS:FreeRTOS v9.0.0

IDE:SoftConsole v4.0

在软件运行期间,发生异常并使用无效的PC进入HardFault。我不知道原因以及如何跟踪。

HardFault_Handler_c

void HardFault_Handler_c(unsigned int *hardfault_args) { //... stack[0] = xTime.SysSec.u32Data; stack[1] = xTime.MicroSec.u32Data; stack[2] = ((unsigned long) hardfault_args[0]); stack[3] = ((unsigned long) hardfault_args[1]); stack[4] = ((unsigned long) hardfault_args[2]); stack[5] = ((unsigned long) hardfault_args[3]); stack[6] = ((unsigned long) hardfault_args[4]); stack[7] = ((unsigned long) hardfault_args[5]); stack[8] = ((unsigned long) hardfault_args[6]); stack[9] = ((unsigned long) hardfault_args[7]); stack[10] = (*((volatile unsigned char *)(0xE000ED28))); stack[11] = (*((volatile unsigned char *)(0xE000ED29))); stack[12] = (*((volatile unsigned short int *)(0xE000ED2A))); stack[13] = (*((volatile unsigned long *)(0xE000ED2C))); stack[14] = (*((volatile unsigned long *)(0xE000ED30))); stack[15] = (*((volatile unsigned long *)(0xE000ED34))); stack[16] = (*((volatile unsigned long *)(0xE000ED38))); //... while (1); } 函数中,获取发生异常时压入堆栈的寄存器的值。

ind     r0          r1          r2          r3          r12         lr          PC          PSR      MFSR       BFSR        UFSR        HFSR        DFSR        MMAR        BFAR
1   C4000000    BE58F8E1    C4000000    BE58F8E1    FFFFFC1A    FFFFFFFD    EA820302    61000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
2   61EE71CA    001FE93E    00000000    001FE93E    DA2BF364    FFFFFFFD    EB410000    A0000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
3   79701455    00144F49    00000000    00144F49    25FD6439    FFFFFFFD    EB410000    20000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
4   CC75E094    0014C068    00000000    001B850B    66924D58    FFFFFFFD    EB410000    A0000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
5   849F9982    0019F6D7    80000000    00114A21    119DB886    FFFFFFFD    F006E502    A0000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
6   295737D9    00180C72    80000000    001A5AD2    20000000    FFFFFFFD    EB410000    A0000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
7   3E95C344    0011ECCA    00000000    00145F30    4B940BCC    FFFFFFFD    EB410000    00000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
8   00000000    00138000    00000000    00199999    00000000    FFFFFFFD    EB410000    A0000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
9   B1894BAF    0016BC15    80000000    001A4910    7E070C6B    FFFFFFFD    EB410000    80000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
10  00000000    00000000    00000000    00000000    FFFFFFFF    FFFFFFFD    EA820302    41000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
11  00000014    00080000    A5FF8640    008A6357    3E97FE19    FFFFFFFD    EA4F0342    81000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
12  70000000    001BA7B7    F8988C00    01A81E6F    08000000    FFFFFFFD    F44F0232    20000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
13  3546B3A0    00000007    00000000    0017D90D    F9892400    FFFFFFFD    EB410000    20000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
14  00000000    00000007    00000000    001921FB    00000000    FFFFFFFD    EB410000    A0000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
15  00000000    001A7C00    80000000    001179EC    00000000    FFFFFFFD    EB410000    A0000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
16  B99C0540    00152E49    00000000    001B8F39    73954D80    FFFFFFFD    EB410000    80000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
17  A7DBD1DC    001BAE2C    80000000    001AA887    4DABDB1C    FFFFFFFD    EB410000    80000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
18  7AE147AE    001FAE14    80000000    0017DE1B    BE908A20    FFFFFFFD    EB410000    20000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
19  00000001    3FF00000    00000000    00000000    7FE00000    FFFFFFFD    5C6CEA7E    21000034    00000001    00000000    00000000    40000000    00000000    E000ED34    E000ED38
FabricIrq2_IRQHandler

从表中可以看出,对于每个异常,栈中推送的IPSR中存储的异常号为0x34,它与中断向量表中的void FabricIrq2_IRQHandler( void ) { IP_can_isr(); } 相对应。在此中断中,我们处理CAN数据接收。

IP_can_isr()

在程序的每个循环中都会触发CAN中断,但是该问题并不经常发生,并且需要很长时间才能发生一次。

我不知道异常发生在哪里。如有必要,我可以添加一些其他代码来捕获更多信息。

我认为IP_can_isr()函数中不会发生该异常,因为在lr函数中发生该异常时,{{1}}寄存器不能为0xFFFFFFFD。

解决方法

由于发生在IP_can_isr()函数中,因此lr寄存器不能为0xFFFFFFFD。

是的,可以。任何体面的编译器都可以优化对简单b IP_can_isr(分支指令)的tail调用。在执行IP_can_isr函数的过程中,它将“异常返回”值保留在LR寄存器中。

如果堆叠的PC是垃圾,则可能在某处有缓冲区溢出。