【问题标题】:How to analyse the invalid PC fault on Cortex-M3?如何分析 Cortex-M3 上的无效 PC 故障?
【发布时间】:2020-08-14 14:50:32
【问题描述】:

SoC:SmartFusion2

处理器:Cortex-M3

操作系统:FreeRTOS v9.0.0

IDE:SoftConsole v4.0

软件运行过程中出现异常,进入HardFault with invalid PC,不知道原因,如何追查。

/*==============================================================================
 * HardFault_Handler
 */
    .weak   HardFault_Handler
    .type   HardFault_Handler, %function
HardFault_Handler:
    TST LR, #4
    ITE EQ
    MRSEQ R0, MSP
    MRSNE R0, PSP
    B HardFault_Handler_c
/*==============================================================================
 * END
 */

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

从表中可以看出,每个异常压栈的IPSR中存储的Exception Number为0x34,对应中断向量表中的FabricIrq2_IRQHandler。在这个中断中,我们处理 CAN 数据接收。

void FabricIrq2_IRQHandler( void )
{
    IP_can_isr();
}

程序的每个循环都会触发CAN中断,但问题不经常出现,一次出现时间较长。

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

我不认为异常发生在IP_can_isr()函数中,因为当它发生在IP_can_isr()函数中时,lr寄存器不能为0xFFFFFFFD。

【问题讨论】:

    标签: arm cortex-m3


    【解决方案1】:

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

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

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

    【讨论】:

    • 非常感谢,我会尝试检查一下。它与浮点运算有关吗?因为当异常发生时,大多数情况下,被中断的上下文是在进行浮点运算的过程中。
    猜你喜欢
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    • 2011-04-15
    • 2017-04-28
    • 1970-01-01
    • 2021-12-18
    • 2016-12-18
    • 1970-01-01
    相关资源
    最近更新 更多