Hard faults can be a pain to track down, especially if they are intermittent and don't happen consistently in the same location. A Hard Fault is an ARM Cortex exception, and the ARM M0 Generic User Guide lists the following sources for a hard fault:
Faults are a subset of exceptions, see Exception model on page 2-19. All faults result in
the HardFault exception being taken or cause lockup if they occur in the NMI or
HardFault handler. The faults are:
execution of an SVC instruction at a priority equal or higher than SVCall
execution of a BKPT instruction without a debugger attached
a system-generated bus error on a load or store
execution of an instruction from an XN memory address
execution of an instruction from a location for which the system generates a bus
a system-generated bus error on a vector fetch
execution of an Undefined instruction
execution of an instruction when not in Thumb-State as a result of the T-bit being
previously cleared to 0
an attempted load or store to an unaligned address.
But I find usually a hard fault is caused by a bus error or unaligned address. Bus errors in Kinetis are usually accessing an invalid address (usually from a bad pointer), or accessing a peripheral register before the clock gate is enabled. In either case, the bus stalls out with no response, triggering a hard fault.
Debugging hard faults is a common issue in ARM cores, and if you Google the issue, you will find several guides and tips available for help finding the root cause of the hard fault, including this appnote below from Keil, although it is targeted at M3 and M4 cores:
IAR also has a macro to help with their debugger. Here's more details, with some tips for diagnosing hard faults:
From NXP, our software expert Erich has a blog site, where he has posted some good information on tracking down hard faults. This link describes a hard fault handler he implemented to find the PC location of where the hard fault occurred:
He also has a post on automating the GDB debugger to run a script with the hard fault details, which can be used within the Kinetis Design Studio (KDS) IDE:
And then he discusses how to use the Micro Trace Buffer in the M0+ core to get more visibility in the execution history leading up to the hard fault
For legacy users using Processor Expert, he even wrapped his handler in a Processor Expert component
I am attempting to recreate the solution from the Debugging Hard Faults on ARM Cortex-M | MCU on Eclipse link. I get "illegal operand" errors for the assembly code. What do I need to do to be able to compile this for a Kinetis K60 using Codewarrior 10.5?
I also attempted to use the PE component from the next link and get a "Freescale ARM/Kinetis compiler is NOT supported! Only ARM gcc is supported." error. How can this error be corrected.
I would greatly appreciate any help that you can provide.
As you found, the example code provided from Erich on his blog is for the GCC compiler. But I used the code below and was able to build it fine with the Freescale compiler in CodeWarrior v10.5:
" movs r0,#4 \n"
" movs r1, lr \n"
" tst r0, r1 \n"
" beq _MSP \n"
" mrs r0, psp \n"
" b _HALT \n"
" mrs r0, msp \n"
" ldr r1,[r0,#20] \n"
" bkpt #0 \n"