Cortex-M HardFault decoder
Paste a CFSR value, or a fault dump from your HardFault handler, Zephyr, the Pico SDK, STM32Cube or FreeRTOS, and see which fault it was, what each bit means and what usually causes it. Add the ELF to turn PC and LR into lines.
Getting the values
In a debugger, read them at the HardFault breakpoint: x/x 0xE000ED28 (CFSR), 0xE000ED2C (HFSR), 0xE000ED34 (MMFAR), 0xE000ED38 (BFAR). In a handler of your own, print SCB->CFSR and SCB->HFSR and the stacked PC and LR. Paste them in any form, such as CFSR = 0x00008200.
The fault status bits
| Bit | Fault | Usually means |
|---|---|---|
DACCVIOL | MemManage | A read or write the MPU forbids: a NULL pointer (MMFAR near 0) or a stack overflow into the guard. |
IACCVIOL | MemManage | Code run from a region that may not execute: a jump through a bad function pointer. |
MSTKERR, STKERR | MemManage, BusFault | The registers could not be saved on exception entry: a stack overflow. |
PRECISERR | BusFault | The instruction at PC touched an address with nothing behind it; BFAR says which. |
IMPRECISERR | BusFault | A buffered write failed; the culprit is a few instructions before PC. Often a peripheral with its clock off. |
UNDEFINSTR | UsageFault | Bytes that are not an instruction: a corrupt pointer or return address, or __builtin_trap(). |
INVSTATE | UsageFault | A branch to an even address: a call through a NULL or uninitialised function pointer. |
NOCP | UsageFault | A floating-point instruction with the FPU off. |
UNALIGNED, DIVBYZERO | UsageFault | An unaligned access or an integer division by zero, when trapping is on. |
FORCED (HFSR) | HardFault | One of the above escalated to HardFault; read the CFSR bits. |
VECTTBL (HFSR) | HardFault | The vector table could not be read: an image linked for the wrong address, often behind a bootloader. |
For devices in the field
A HardFault on a device you cannot reach is a reboot and nothing else. Pinscope keeps the PC, LR and stack addresses across the reset on the Pico and Zephyr, and decodes them with your ELF.
Try it
Three devices are free, and no card is needed. Create an account, or read the guide for your platform: ESP32, Zephyr, Raspberry Pi Pico, Linux, ESP8266.
More
- Remote access to an ESP32 without TLS: what it measured and what it costs
- Serial monitor in the browser for ESP32 and Zephyr, with crash decoding
- Pinscope now runs on Zephyr, Raspberry Pi Pico, Linux and ESP8266
- Zephyr devices in the field: logs, crashes and OTA over the internet
- Reading a Zephyr fatal error: fault, reason, CFSR and call trace
- MCUboot: are your images signed with the public development key?
- Raspberry Pi Pico 2 W: remote access, logs and OTA over the internet
- Zephyr fatal error decoder
- MCUboot image inspector
- UF2 converter and inspector
- Zephyr flash partition checker
- Memfault vs Pinscope: which one fits
- Golioth vs Pinscope: which one fits
- nRF Cloud vs Pinscope: which one fits