Cortex M4 hard fault finding root cause on LPC4078 pc=0x0

Hi everyone,

I'm getting a hard fault at my LPC4078 on LPCXpresso and would be very glad if you could help me finding the root cause.

The µC runs with freeRtos 8.2.2 but I'm not sure if the hard fault has ever anything to do with it.

When the hard fault occurs it hangs on this position:

The register values are:

r0 volatile uint32_t 0x1 (Hex)
r1 volatile uint32_t 0x300 (Hex)
r2 volatile uint32_t 0x0 (Hex)
r3 volatile uint32_t 0x10008a90 (Hex)
r12 volatile uint32_t 0x0 (Hex)
lr volatile uint32_t 0x12f89 (Hex)
pc volatile uint32_t 0x0 (Hex)
psr volatile uint32_t 0x0 (Hex)
SCB SCB_Type * 0xe000ed00
CPUID const volatile uint32_t 0x410fc241 (Hex)
ICSR volatile uint32_t 0x429803 (Hex)
VTOR volatile uint32_t 0x8000 (Hex)
AIRCR volatile uint32_t 0xfa050000 (Hex)
SCR volatile uint32_t 0x0 (Hex)
CCR volatile uint32_t 0x200 (Hex)
SHP volatile uint8_t [12] 0xe000ed18 (Hex)
SHCSR volatile uint32_t 0x0 (Hex)
CFSR volatile uint32_t 0x20000 (Hex)
HFSR volatile uint32_t 0x40000000 (Hex)
DFSR volatile uint32_t 0x0 (Hex)
MMFAR volatile uint32_t 0xe000edf8 (Hex)
BFAR volatile uint32_t 0xe000edf8 (Hex)
AFSR volatile uint32_t 0x0 (Hex)
PFR const volatile uint32_t [2] 0xe000ed40 (Hex)
PFR[0] const volatile uint32_t 48
PFR[1] const volatile uint32_t 512
DFR const volatile uint32_t 0x100000 (Hex)
ADR const volatile uint32_t 0x0 (Hex)
MMFR const volatile uint32_t [4] 0xe000ed50 (Hex)
MMFR[0] const volatile uint32_t 1048624
MMFR[1] const volatile uint32_t 0
MMFR[2] const volatile uint32_t 16777216
MMFR[3] const volatile uint32_t 0
ISAR const volatile uint32_t [5] 0xe000ed60 (Hex)
ISAR[0] const volatile uint32_t 17830160
ISAR[1] const volatile uint32_t 34676736
ISAR[2] const volatile uint32_t 555950641
ISAR[3] const volatile uint32_t 17895729
ISAR[4] const volatile uint32_t 19988786
RESERVED0 uint32_t [5] 0xe000ed74 (Hex)
RESERVED0[0] uint32_t 0
RESERVED0[1] uint32_t 0
RESERVED0[2] uint32_t 0
RESERVED0[3] uint32_t 0
RESERVED0[4] uint32_t 0
CPACR volatile uint32_t 0xf00000 (Hex)

Unfortunately pc is 0x0. That helped me a lot at similar hard fault failures.

How would you proceed finding the cause? Are there any information missing or should I check any other values?

I already searched in Google but until now I didn't find anything useful or it seemed to be too complex.

I'm looking forward hearing from you for any hints or tips.

Best regards,

Daniel

Parents
  • Hi 

    what is the correct stack frame layout?

    In Cortex-M4 User Guide I find:

    In case 7th byte is 0 I get a UsageFault with UFSR_INVSTATE=1, e.g.:

    In case 7th byte is any other invalid address (this happens very rarely) I get a BusFault with BFSR_IBUSERR=1 (e.g. if PC is 0x14000000).

    But you wrote the byte after PC, isn't that the 8th byte "xPSR" or what is the correct layout?

    As you suggested I defined a global variable and set it to unique numbers in every interrupt: NVIC_ISER shows these enabled interrupts:

    Enum LPC40XX_IRQn_Type in cmsis_40xx.h extracts it (set bits in ISER[0] and [1]) to these interrupts:

    5: UART0_IRQn

    10: I2C0_IRQn

    22: ADC_IRQn

    25: CAN_IRQn

    26: DMA_IRQn

    38: GPIO_IRQn

    But what about these 3 FreeRTOS-Interrupts which are implemented, too?

    #define vPortSVCHandler SVC_Handler
    #define xPortPendSVHandler PendSV_Handler
    #define xPortSysTickHandler SysTick_Handler

    Everytime I get the UsageFault (or very rarely BusFault) my variable is set to 26 DMA_IRQn and PendSVHandler was used recently. I checked by a counting variable at begin and end of DMA_IRQHandler() and PendSVHandler() if there were run completely last time and yes, the counting-variables in DMA_IRQHandler() are the same. PendSVHandler() is a bit complecated because of the assembly code inside, the 2nd variable stays at 0.

    What would you suggest, what could cause setting the stacked PC to 0? How can I check if possibly DMA_IRQHandler() some time has a stack corruption?

    Is it correct that USFR=INVSTATE-Bit-Set is caused by corrupt stacked PC=0?

Reply
  • Hi 

    what is the correct stack frame layout?

    In Cortex-M4 User Guide I find:

    In case 7th byte is 0 I get a UsageFault with UFSR_INVSTATE=1, e.g.:

    In case 7th byte is any other invalid address (this happens very rarely) I get a BusFault with BFSR_IBUSERR=1 (e.g. if PC is 0x14000000).

    But you wrote the byte after PC, isn't that the 8th byte "xPSR" or what is the correct layout?

    As you suggested I defined a global variable and set it to unique numbers in every interrupt: NVIC_ISER shows these enabled interrupts:

    Enum LPC40XX_IRQn_Type in cmsis_40xx.h extracts it (set bits in ISER[0] and [1]) to these interrupts:

    5: UART0_IRQn

    10: I2C0_IRQn

    22: ADC_IRQn

    25: CAN_IRQn

    26: DMA_IRQn

    38: GPIO_IRQn

    But what about these 3 FreeRTOS-Interrupts which are implemented, too?

    #define vPortSVCHandler SVC_Handler
    #define xPortPendSVHandler PendSV_Handler
    #define xPortSysTickHandler SysTick_Handler

    Everytime I get the UsageFault (or very rarely BusFault) my variable is set to 26 DMA_IRQn and PendSVHandler was used recently. I checked by a counting variable at begin and end of DMA_IRQHandler() and PendSVHandler() if there were run completely last time and yes, the counting-variables in DMA_IRQHandler() are the same. PendSVHandler() is a bit complecated because of the assembly code inside, the 2nd variable stays at 0.

    What would you suggest, what could cause setting the stacked PC to 0? How can I check if possibly DMA_IRQHandler() some time has a stack corruption?

    Is it correct that USFR=INVSTATE-Bit-Set is caused by corrupt stacked PC=0?

Children