Finding the source of a Hard Fault using extended HardFault_Handler

So, here's the fun part: it may be impossible to cite exactly which line is throwing the fault. The reason is that a bug in your code may be causing a fault to appear elsewhere -or- the bug might be destroying all the state information in the system, which is super cool. What would really help, though, is to see your entire code base: including the linker scripts and startup code.

In general though, if you are ending up in hard-fault territory, Here are the first things I would check:

  • Faults caused by trying to dynamically allocate memory when there is no heap defined by your linker. What happens here is that some function is calling malloc (or one of its cousins) and library is failing because there is not enough space on the heap to allocate memory, so it crashes the program. This is a real possibility for you, you are using an RTOS & most vanilla linker scripts don't have heap space allocated. See this: https://stackoverflow.com/questions/10467244/using-newlibs-malloc-in-an-arm-cortex-m3

  • Faults caused by doing something silly like writing data past the end of an array. This can be really easy to do if you are using math to generate array indices or using pointers to elements directly. What (can) happen here is if your boundary checks are buggy, when you write data to your array, you may, in fact, just be overwriting everything! If this doesn't cause an error directly (e.g. writing to a read-only or protected location), it may just break your stack. Then you jump to a garbage location, and probably execute an invalid instruction and then fault.

I'd also take a look at this document, which is related to your Code Red post. Even though the instructions are for ARM Cortex-M3 and ARM Cortex-M4 the method of interpreting the results are the same.
Debugging Hard Fault & Other Exceptions

Using the Register Values

The first register of interest is the program counter. In the code above, the variable pc contains the program counter value. When the fault is a precise fault, the pc holds the address of the instruction that was executing when the hard fault (or other fault) occurred. When the fault is an imprecise fault, then additional steps are required to find the address of the instruction that caused the fault.

To find the instruction at the address held in the pc variable, either...

  1. Open an assembly code window in the debugger, and manually enter the address to view the assembly instructions at that address, or

  2. Open the break point window in the debugger, and manually define an execution or access break point at that address. With the break point set, restart the application to see which line of code the instruction relates to.

Knowing the instruction that was being executed when the fault occurred allows you to know which other register values are also of interest. For example, if the instruction was using the value of R7 as an address, then the value of R7 needs to be know. Further, examining the assembly code, and the C code that generated the assembly code, will show what R7 actually holds (it might be the value of a variable, for example).

Those are just my top-two off-the-top reasons. If you post your entire code base, we can probably give you more direct help. Good luck!