Question

Occasionally I will get an unexpected interrupt, and my code will hang inside Dummy_Handler() in exceptions.c of the Atmel Studio Framework (ASF). I am using the ATSAM3X8E microcontroller of the Arduino Due.

void Dummy_Handler(void)
{
    while(1) {
    }
}

Any ideas how to determine which interrupt it was?

Of course I could replace this single handler with unique dummy handlers, one for each exception. (There are about fifty of them.) For example change each line in the same exceptions.c file:

void HardFault_Handler  ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

to this

void HardFault_Handler  ( void ) __attribute__ ((weak, alias("Dummy_HardFault_Handler")));

Etc... Or try to reason how my code could have generated which interrupt. But who has that kind of time?

Was it helpful?

Solution

This MCU has an Interrupt Program Status Register that gives some clue as to source. ASF has wrapped it in a function __get_IPSR() in core_cmFunc.h:

uint32_t phantomISR = 9999;

void Dummy_Handler(void)
{
    while(1) {
        phantomISR = __get_IPSR();
    }
}

Then this global variable can be monitored at runtime. (In my case I paused the assembly code for this loop-of-death and saw the value 3 in the R3 register.) The Atmel MCU doc explains its value:

ISR_NUMBER
This is the number of the current exception:
0 = Thread mode
1 = Reserved
2 = NMI
3 = Hard fault
4 = Memory management fault
5 = Bus fault
6 = Usage fault
7-10 = Reserved
11 = SVCall
12 = Reserved for Debug
13 = Reserved
14 = PendSV
15 = SysTick
16 = IRQ0
45 = IRQ29

Both times this happened to me it was the Hard Fault, a kind of blue-screen-of-death for the Ardunio Due. So I also installed a Hard Fault handler of my own.

ISR(HardFault_Handler)
{
    while (1) {
    }
}

Also, detectable in debug mode by pausing. Of course the sequel is, what causes a Hard Fault? I'm guessing memory wipe or infinite recursion.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top