Ground Embedded KO Subscribe

Notes / Machine Code & Assembly

HardFault analysis: which line did it die on?

When a HardFault occurs, the PC and LR saved on the stack and the fault status registers lead you to the cause and the location.

GROUND EMBEDDED · NOTEMachine Code & Assembly 08Hard-fault analysis 1ldr r0, =0x40020014 2ldr r1, [r0] 3orr r1, r1, #0x20 4str r1, [r0] 5bl main 6b .

Common causes

  • Access through a null pointer or to freed memory
  • Access to the registers of a peripheral whose clock is off
  • Stack overflow
  • Unaligned access, division by zero (depending on configuration)
  • Calling a bad function pointer (an address with the Thumb bit at 0)

How to find it

Stop in HardFault_HandlerRead the stacked PCFind the address in the map / disassemblyThe C line
The order for finding the line that faulted.

On entering the exception the CPU saves r0 to r3, r12, lr, pc and xPSR on the stack. The saved pc is the address of the instruction that caused the problem.

void HardFault_Handler(void) {
    __asm volatile ("tst lr, #4\n ite eq\n mrseq r0, msp\n mrsne r0, psp\n b hf_c");
}
void hf_c(uint32_t *sp) {
    volatile uint32_t pc = sp[6], lr = sp[5];
    volatile uint32_t cfsr = SCB->CFSR, bfar = SCB->BFAR;
    while (1);   // inspect pc, lr and cfsr with the debugger
}

Fault registers

Register What it tells you
CFSR The kind of fault (detail bits for bus / memory / usage faults)
BFAR The data address that caused a bus fault
MMFAR The address of a memory-management fault

Convert the pc address to a source line with the map file or addr2line -e firmware.elf 0x080012AC and you have the location. In a fielded product, record these values in .noinit RAM or Flash and read them back after the reboot, and even faults that are hard to reproduce can be traced.

FREE PDFGet the 3 free ebooksIf you want to keep reading this topic as one book: BLDC motor control, serial communication and sensors at book length. PDFs are in Korean.Get them free →