This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSPM0G3107: How to supplement the cause of Default_handler

Part Number: MSPM0G3107

Hello.

When I'm working on an implementation, I sometimes come across a mysterious Default_handler.
I'm having trouble reproducing it and dealing with potential bugs.

In which function it happened when I entered Default_handler. Can you figure out in which line it happened?

thank you.

  • Can you figure out in which line it happened?

    Are you talking about a hard fault exception (vector 0xC)?

    If so, maybe this will help: Debugging a Cortex-M0 Hard Fault - Embedded forum - Support forums - Arm Community

  • Hi Kei,

    Insert the following into your code, comment out any that you already have or that throw errors on your first build.

    /*
    * These are traps for debugging when you find that your code
    * ends up in the default handler for some unknown reason.
    * To keep the compiler from complaining, comment out the ones
    * below if you already have a working handler for that vector.
    *
    */
    void NMI_Handler(void){ __BKPT(0);}
    void HardFault_Handler(void){ __BKPT(0);}
    void SVC_Handler(void){ __BKPT(0);}
    void PendSV_Handler(void){ __BKPT(0);}
    void SysTick_Handler(void){ __BKPT(0);}
    void GROUP0_IRQHandler(void){ __BKPT(0);}
    void GROUP1_IRQHandler(void){ __BKPT(0);}
    void TIMG8_IRQHandler(void){ __BKPT(0);}
    void UART3_IRQHandler(void){ __BKPT(0);}
    void ADC0_IRQHandler(void){ __BKPT(0);}
    void ADC1_IRQHandler(void){ __BKPT(0);}
    void CANFD0_IRQHandler(void){ __BKPT(0);}
    void DAC0_IRQHandler(void){ __BKPT(0);}
    void SPI0_IRQHandler(void){ __BKPT(0);}
    void SPI1_IRQHandler(void){ __BKPT(0);}
    void UART1_IRQHandler(void){ __BKPT(0);}
    void UART2_IRQHandler(void){ __BKPT(0);}
    void UART0_IRQHandler(void){ __BKPT(0);}
    void TIMG0_IRQHandler(void){ __BKPT(0);}
    void TIMG6_IRQHandler(void){ __BKPT(0);}
    void TIMA0_IRQHandler(void){ __BKPT(0);}
    void TIMA1_IRQHandler(void){ __BKPT(0);}
    void TIMG7_IRQHandler(void){ __BKPT(0);}
    void TIMG12_IRQHandler(void){ __BKPT(0);}
    void I2C0_IRQHandler(void){ __BKPT(0);}
    void I2C1_IRQHandler(void){ __BKPT(0);}
    void AES_IRQHandler(void){ __BKPT(0);}
    void RTC_IRQHandler(void){ __BKPT(0);}
    void DMA_IRQHandler(void){ __BKPT(0);}

    When your code runs you should hit one of these instead of the default handler. 

    Best Regards,
    Brandon Fisher

  • Thank you, Kier and Brandon.

    By referring to the advice, it is now possible to check the EXCEPTION Number that caused the exception.

    However, ideally I would like to obtain the code position that was executed immediately before.
    Unfortunately, the LR (Link register) at the time of the problem became 0xFFFFFFF9, and the problematic program part could not be retrieved.

  • Hi Kei,

    There are two good ways on the M0 architecture I know of to try and do this.

    The first is to just add some inline assembly to the handler being triggered during your code failure to grab the last PC value right before it (shown below in the hard fault handler). I didn't write this inline assembly statement, it was developed by someone else for a different ARM Device, but unfortunately I can't seem to find the original blog post to give proper credit. If I do manage to I'll update this post with a link. 

    void HardFault_Handler(void){
        __asm volatile (
            "movs R0,#4\n"
            "mov r1, r14\n"
            "TST R0, R1       \n"
            "BEQ _MSP         \n"
            "MRS R0, psp      \n"
            "B _HALT          \n"
          "_MSP:               \n"
            "MRS R0, msp      \n"
          "_HALT:              \n"
            "LDR R1,[R0,#20]  \n"
            "BKPT #0          \n"
          );
        __BKPT(0);
    }
    

    The second is to use the Micro Trace Buffer (MTB), which is available on MSPM0G. 

    The instructions for doing that in CCS are here: https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_debug-main.html#mtb-trace

    If you run the MTB in circular buffer mode and hit the breakpoint in your ISR handler, it will display the latest trace info as described in that guide. This will give you more trace info than that inline assembly method will. 

    There is also always the third option of trying to step through your code until you find the problematic section, but that is pretty tedious, ad sometimes the halting/resuming of the debugger will interfere with the occurrence of timing related failures. 

    Best Regards,
    Brandon Fisher