How to analyse the invalid PC fault on Cortex-M3?

0

SoC:SmartFusion2

Processor:Cortex-M3

OS: FreeRTOS v9.0.0

IDE:SoftConsole v4.0

During the running of the software, an exception occurs and enter HardFault with invalid PC.I don't know the cause and how to trace.

/*==============================================================================
 * 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
 */

In the HardFault_Handler_c function, get the value of the registers pushed onto the stack when an exception occurs.

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

It can be seen from the table that the Exception Number stored in the IPSR that is pushed on the stack for each exception is 0x34, which corresponds to the FabricIrq2_IRQHandler in the interrupt vector table. In this interrupt, we process CAN data reception.

void FabricIrq2_IRQHandler( void )
{
    IP_can_isr();
}

The CAN interrupt is triggered in each cycle of the program, but the problem does not occur frequently, and it takes a long time to occur once.

I don't know where the exception happened. If necessary I can add some additional code to capture more information.

I don't think the exception occurs in the IP_can_isr() function, because when it happened in the IP_can_isr() function, the lr register can't be 0xFFFFFFFD.

arm
cortex-m3
asked on Stack Overflow Aug 14, 2020 by gby • edited Aug 14, 2020 by gby

1 Answer

0

because when it happened in the IP_can_isr() function, the lr register can't be 0xFFFFFFFD.

Yes, it can be. Any decent compiler can optimize the tail call to a simple b IP_can_isr (branch instruction). Which keeps the "exception return" value in the LR register during execution of IP_can_isr function.

If the stacked PC is garbage, you might have a buffer overflow somewhere.

answered on Stack Overflow Sep 15, 2020 by Turbo J

User contributions licensed under CC BY-SA 3.0