void backtrace(int pcAddr, int spAddr, unsigned *line) { UnwResult r; lcd_putsf(0, (*line)++, "pc:%08x sp:%08x", pcAddr, spAddr); lcd_update(); r = UnwindStart(pcAddr, spAddr, &cliCallbacks, (void *)line); lcd_puts(0, (*line)++, "bt end"); lcd_update(); }
void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause) { static const char* causestr[] = { "NMI","Hard","Mem","Bus","Usage","Debug","WDT","RSTC" }; UnwindFrame btf; // Dump report to the Programming port (interrupts are DISABLED) TXBegin(); TX("\n\n## Software Fault detected ##\n"); TX("Cause: "); TX(causestr[cause]); TX('\n'); TX("R0 : "); TXHex(((unsigned long)sp[0])); TX('\n'); TX("R1 : "); TXHex(((unsigned long)sp[1])); TX('\n'); TX("R2 : "); TXHex(((unsigned long)sp[2])); TX('\n'); TX("R3 : "); TXHex(((unsigned long)sp[3])); TX('\n'); TX("R12 : "); TXHex(((unsigned long)sp[4])); TX('\n'); TX("LR : "); TXHex(((unsigned long)sp[5])); TX('\n'); TX("PC : "); TXHex(((unsigned long)sp[6])); TX('\n'); TX("PSR : "); TXHex(((unsigned long)sp[7])); TX('\n'); // Configurable Fault Status Register // Consists of MMSR, BFSR and UFSR TX("CFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED28)))); TX('\n'); // Hard Fault Status Register TX("HFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED2C)))); TX('\n'); // Debug Fault Status Register TX("DFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED30)))); TX('\n'); // Auxiliary Fault Status Register TX("AFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED3C)))); TX('\n'); // Read the Fault Address Registers. These may not contain valid values. // Check BFARVALID/MMARVALID to see if they are valid values // MemManage Fault Address Register TX("MMAR : "); TXHex((*((volatile unsigned long *)(0xE000ED34)))); TX('\n'); // Bus Fault Address Register TX("BFAR : "); TXHex((*((volatile unsigned long *)(0xE000ED38)))); TX('\n'); TX("ExcLR: "); TXHex(lr); TX('\n'); TX("ExcSP: "); TXHex((unsigned long)sp); TX('\n'); btf.sp = ((unsigned long)sp) + 8*4; // The original stack pointer btf.fp = btf.sp; btf.lr = ((unsigned long)sp[5]); btf.pc = ((unsigned long)sp[6]) | 1; // Force Thumb, as CORTEX only support it // Perform a backtrace TX("\nBacktrace:\n\n"); int ctr = 0; UnwindStart(&btf, &UnwCallbacks, &ctr); // Disable all NVIC interrupts NVIC->ICER[0] = 0xFFFFFFFF; NVIC->ICER[1] = 0xFFFFFFFF; // Relocate VTOR table to default position SCB->VTOR = 0; // Disable USB otg_disable(); // Restart watchdog WDT_Restart(WDT); // Reset controller NVIC_SystemReset(); while(1) { WDT_Restart(WDT); } }