50#include "cmsis_compiler.h"
54#if NRF_HARDFAULT_HANDLER_EXTENDED
56typedef struct HardFault_stack {
72#define CRASH_MAGIC 0xDEADF007UL
73#define HF_CANARY_VALUE 0xFA17FA17UL
91__attribute__((section(
".noinit"))) crash_info_t crash_info;
98hardfault_print_saved_crash(
void)
101 static const char hx[] =
"0123456789abcdef";
102 extern volatile uint32_t hf_canary;
105 if(hf_canary == HF_CANARY_VALUE) {
108 { uint32_t c = hf_canary;
109 for(
int s = 28; s >= 0; s -= 4)
dbg_putchar(hx[(c >> s) & 0xf]);
114 { uint32_t m = crash_info.magic;
115 for(
int s = 28; s >= 0; s -= 4)
dbg_putchar(hx[(m >> s) & 0xf]);
120 }
else if(crash_info.magic != CRASH_MAGIC) {
125 { uint32_t c = hf_canary;
126 for(
int s = 28; s >= 0; s -= 4)
dbg_putchar(hx[(c >> s) & 0xf]);
131 { uint32_t m = crash_info.magic;
132 for(
int s = 28; s >= 0; s -= 4)
dbg_putchar(hx[(m >> s) & 0xf]);
138 crash_info.magic = 0;
140 static const char hex[] =
"0123456789abcdef";
143#define FAULT_PUTHEX(val) do { \
144 uint32_t _v = (val); \
145 for(int _s = 28; _s >= 0; _s -= 4) \
146 dbg_putchar(hex[(_v >> _s) & 0xf]); \
148#define FAULT_PUTS(s) do { \
149 const char *_p = (s); \
150 while(*_p) dbg_putchar(*_p++); \
153 FAULT_PUTS(
"\n*** PREVIOUS CRASH ***\n");
154 FAULT_PUTS(
"PC="); FAULT_PUTHEX(crash_info.pc);
155 FAULT_PUTS(
" LR="); FAULT_PUTHEX(crash_info.lr);
156 FAULT_PUTS(
" PSR="); FAULT_PUTHEX(crash_info.psr);
158 FAULT_PUTS(
"R0="); FAULT_PUTHEX(crash_info.r0);
159 FAULT_PUTS(
" R1="); FAULT_PUTHEX(crash_info.r1);
160 FAULT_PUTS(
" R2="); FAULT_PUTHEX(crash_info.r2);
161 FAULT_PUTS(
" R3="); FAULT_PUTHEX(crash_info.r3);
163 FAULT_PUTS(
"R12="); FAULT_PUTHEX(crash_info.r12);
164 FAULT_PUTS(
" CFSR="); FAULT_PUTHEX(crash_info.cfsr);
165 FAULT_PUTS(
" HFSR="); FAULT_PUTHEX(crash_info.hfsr);
168 if(crash_info.cfsr & (1 << 7)) {
169 FAULT_PUTS(
"MMFAR="); FAULT_PUTHEX(crash_info.mmfar);
dbg_putchar(
'\n');
171 if(crash_info.cfsr & (1 << 15)) {
172 FAULT_PUTS(
"BFAR="); FAULT_PUTHEX(crash_info.bfar);
dbg_putchar(
'\n');
174 FAULT_PUTS(
"*** END CRASH ***\n");
196__attribute__((section(
".noinit"))) volatile uint32_t hf_canary;
199HardFault_c_handler(uint32_t *p_stack_address)
202 static const char hex[] =
"0123456789abcdef";
205 hf_canary = HF_CANARY_VALUE;
215 HardFault_stack_t *p_stack = (HardFault_stack_t *)p_stack_address;
217 crash_info.cfsr = SCB->CFSR;
218 crash_info.hfsr = SCB->HFSR;
219 crash_info.mmfar = SCB->MMFAR;
220 crash_info.bfar = SCB->BFAR;
222 if(p_stack != NULL) {
223 crash_info.pc = p_stack->pc;
224 crash_info.lr = p_stack->lr;
225 crash_info.psr = p_stack->psr;
226 crash_info.r0 = p_stack->r0;
227 crash_info.r1 = p_stack->r1;
228 crash_info.r2 = p_stack->r2;
229 crash_info.r3 = p_stack->r3;
230 crash_info.r12 = p_stack->r12;
234 crash_info.magic = CRASH_MAGIC;
238#define HF_PUTHEX(val) do { \
239 uint32_t _v = (val); \
240 for(int _s = 28; _s >= 0; _s -= 4) { \
241 dbg_putchar(hex[(_v >> _s) & 0xf]); \
247 HF_PUTHEX(crash_info.pc);
252 HF_PUTHEX(crash_info.lr);
257 HF_PUTHEX(crash_info.cfsr);
279 " .syntax unified \n"
281 " ldr r0, =0xFFFFFFFD \n"
283 " bne HardFault_Handler_ChooseMSP \n"
286 " b HardFault_Handler_Continue \n"
287 "HardFault_Handler_ChooseMSP: \n"
293 " ldr r1, =__StackTop \n"
294 " ldr r2, =__StackLimit \n"
298 " bhi HardFault_MoveSP \n"
300 " bhi HardFault_Handler_Continue \n"
302 "HardFault_MoveSP: \n"
306 "HardFault_Handler_Continue: \n"
311 : :
"X" (HardFault_c_handler)
346fault_print_and_reset(
char f1,
char f2)
355 for(
volatile int i = 0; i < 50000; i++) {
360void BusFault_Handler(
void) { fault_print_and_reset(
'B',
'F'); }
361void UsageFault_Handler(
void) { fault_print_and_reset(
'U',
'F'); }
362void MemoryManagement_Handler(
void) { fault_print_and_reset(
'M',
'M'); }
363#ifndef TRUSTZONE_SECURE
365void SecureFault_Handler(
void) { fault_print_and_reset(
'S',
'F'); }
int dbg_putchar(int c)
Print a character to debug output.
void HardFault_Handler(void)
Hardfault handler.