Search code examples
exceptionarduinointerrupt-handlingatmelatsam3x

Atmel Studio Dummy_Handler


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?


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.