Because the error is imprecise, it is not possible to see the address of the offending data access. In this specific case, it is very difficult to find the actual reason for the problem, because it has to do with a CPU running at an incorrect frequency. See the screenshot below:

Example 2: Division by Zero

This example shows how to catch division by zero errors, by enabling the DIV_0_TRP bit in the CCR register. In the Call Stack window, you can see the source code line where the invalid division occurred. Looking at the Register window, you can see that the NVIC:CFSR flag DIVBYZERO is set. See the screenshot below:

Example 3: Accessing an invalid address

In this example, invalid memory is accessed. In the Call Stack window, you can see where the illegal access was made. In the Register window, the NVIC:CFSR flags show a PRECISERR. A precise data access error has occurred, and the processor has written the erroneous address to the BFAR register. See the screenshots below:

Example 4: Branch to an address where no code is located

In this example, an invalid function pointer is called. In the Register window, the NVIC:CFSR flags show: UNDEFINSTR = 1. The processor has attempted to execute an undefined instruction.

In the Call Stack window, you can see from where the illegal instruction was called.There are several ways to continue:

1. Set a breakpoint on the illegal instruction, and run your application again. When you get to the breakpoint, use the Call Stack window to find the calling function.

2. In the Register window, look at the CPU:LR register to find where the previous call was made. Use the address from the LR register in the Disassembly window, and "Go to" that address. This is where the previous call was made. See the screenshots below:

Debugging tools

To make it easier to identify exactly which type of HardFault your application has encountered, there is a debugger macro available in recent versions of IAR Embedded Workbench for ARM. The macro file is located in the installation directory:

arm\config\debugger\ARM\vector_catch.mac

Choose View > Macros > Macro Registrationto load the macro. When a HardFault is triggered, the macro will produce useful output in the Debug Log window. See the screenshot below:

Notes

Note 1

The information in the Register window might look different from the screenshots above, depending on what type of Cortex-M device you are using. Cortex-M0 devices also do not have all the fault status registers available on larger Cortex-M devices.

Note 2

If you have complex code in the fault handlers, it might be a good idea to set a breakpoint early in the handler, so that registers and buffers do not lose any vital information when the execution continues. By setting a breakpoint early, execution will stop immediately when the fault handler is called.

Note 3

The above information does not cover how to use Trace to debug the problem. See our articles on Trace in the Resources section on www.iar.com.

Conclusion

You can debug a HardFault using several methods and windows in IAR Embedded Workbench for ARM. To make it easier to find the reason for a HardFault, there is also a debugger macro file available. For more information about faults, see the chapter "Fault types" in the"Cortex-M3 Devices Generic User Guide".

All product names are trademarks or registered trademarks of their respective owners.