A hardfault handler to dump useful registers to aid debugging of program exceptions. Often knowing the ProgramCounter (PC) at fault time is enough to find a useful location in source code.

The library installs an alternate version of the HardFault_Handler to replace the system default. The replaced handler is able to emit useful registers on the system console to aid debugging. You can enhance the handler to emit more useful information.

How would one test this..

Here's how one might produce an exception to trigger a hard-fault. You would not want to do this in your project, but the snippet helps demonstrate the function of this library. The snippet comes from a shared project: PointerError.

// Example of hanging when reading a bad pointer
/* Refer to http://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html */

#include "mbed.h"

DigitalOut myled(LED1);

unsigned x[10] = {0};

int main() {
    unsigned *ok_ptr = x;
    unsigned *bad_ptr = (unsigned*)0xe600b0; // not in RAM!
    printf("ok_ptr = 0x%08X, bad_ptr = 0x%08X\n", (unsigned)ok_ptr, (unsigned)bad_ptr);

    unsigned ok_read = ok_ptr[0];
    printf("ok_read = %d\n", ok_read);

    unsigned bad_read = bad_ptr[0];
    printf("bad_read = %d\n", bad_read);

    while(1) {
        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);
    }
}
Revision:
0:68900ac9bc4b
Child:
1:c325619800b2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hardfault.s	Wed Jan 29 15:27:24 2014 +0000
@@ -0,0 +1,44 @@
+; Reference: http://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html
+
+; On the Cortex-M3, the processor core automatically saves some interesting
+; registers to the stack on initial exception entry. The following
+; HardFault_Handler is a short assembly function to determine which stack (MSP
+; or PSP) was being used when the fault occurred; once this is done, the fault
+; handler assembly code passes a pointer to the stack frame into a C function
+; called prvGetRegistersFromStack() which then aids user-debugging.
+
+    AREA asm_func, CODE, READONLY
+
+; Export HardFault_Handler function location so that linker can find it
+    EXPORT HardFault_Handler
+HardFault_Handler
+
+    TST LR, #4 ; test bit 2 of the EXC_RETURN placed in LR to determine which
+               ; stack was in use before entering the handler
+
+    ; move the appropriate stack pointer value into R0
+    ITE EQ
+    MRSEQ R0, MSP
+    MRSNE R0, PSP
+
+    LDR R1, [R0, #24] ; get stacked PC
+
+    ; call prvGetRegistersFromStack() with R0 set as the stack pointer at the
+    ; time of exception entry.
+    LDR R2, HANDLER2_ADDRESS_CONST
+    BX R2
+    IMPORT prvGetRegistersFromStack
+    ALIGN 4
+HANDLER2_ADDRESS_CONST DCD prvGetRegistersFromStack
+
+    END
+
+    ; call prvGetRegistersFromStack() with R0 set as the stack pointer at the
+    ; time of exception entry.
+    LDR R2, HANDLER2_ADDRESS_CONST
+    BX R2
+    IMPORT prvGetRegistersFromStack
+    ALIGN 4
+HANDLER2_ADDRESS_CONST DCD prvGetRegistersFromStack
+
+    END