aiie/teensy/teensy-crash.h

73 lines
2.1 KiB
C
Raw Normal View History

2017-02-20 18:55:16 +00:00
/*
* https://forum.pjrc.com/threads/186-Teensy-3-fault-handler-demonstration?highlight=crash+handler
*
* call this from setup():
* enableFaultHandler();
*
* On crash you see something like:
* !!!! Crashed at pc=0x490, lr=0x55B.
*
* which you can interpret thusly:
* $ arm-none-eabi-addr2line -s -f -C -e main.elf 0x490 0x55B
* Print:: println(char const*)
* Print.h:47
* main
* main_crash.cpp:86
*/
#define SCB_SHCSR_USGFAULTENA (uint32_t)1<<18
#define SCB_SHCSR_BUSFAULTENA (uint32_t)1<<17
#define SCB_SHCSR_MEMFAULTENA (uint32_t)1<<16
#define SCB_SHPR1_USGFAULTPRI *(volatile uint8_t *)0xE000ED20
#define SCB_SHPR1_BUSFAULTPRI *(volatile uint8_t *)0xE000ED19
#define SCB_SHPR1_MEMFAULTPRI *(volatile uint8_t *)0xE000ED18
// enable bus, usage, and mem fault handlers.
void enableFaultHandler()
{
SCB_SHCSR |= SCB_SHCSR_BUSFAULTENA | SCB_SHCSR_USGFAULTENA | SCB_SHCSR_MEMFAULTENA;
}
extern "C" {
void __attribute__((naked)) _fault_isr () {
uint32_t* sp=0;
// this is from "Definitive Guide to the Cortex M3" pg 423
asm volatile ( "TST LR, #0x4\n\t" // Test EXC_RETURN number in LR bit 2
"ITE EQ\n\t" // if zero (equal) then
"MRSEQ %0, MSP\n\t" // Main Stack was used, put MSP in sp
"MRSNE %0, PSP\n\t" // else Process stack was used, put PSP in sp
: "=r" (sp) : : "cc");
Serial.print("!!!! Crashed at pc=0x");
Serial.print(sp[6], 16);
Serial.print(", lr=0x");
Serial.print(sp[5], 16);
Serial.println(".");
Serial.flush();
// allow USB interrupts to preempt us:
SCB_SHPR1_BUSFAULTPRI = (uint8_t)255;
SCB_SHPR1_USGFAULTPRI = (uint8_t)255;
SCB_SHPR1_MEMFAULTPRI = (uint8_t)255;
while (1) {
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
asm volatile (
"WFI" // Wait For Interrupt.
);
}
}
}
void hard_fault_isr(void) __attribute__ ((alias("_fault_isr")));
void memmanage_fault_isr(void) __attribute__ ((alias("_fault_isr")));
void bus_fault_isr(void) __attribute__ ((alias("_fault_isr")));
void usage_fault_isr(void) __attribute__ ((alias("_fault_isr")));