AnsweredAssumed Answered

KL25 Freedom Board HardFaults, un-used interrupts and finding out

Question asked by Jim Donelson on Feb 8, 2013
Latest reply on Feb 8, 2013 by Erich Styger

I have seen a number of questions concerning these matters and have had these issues myself, so I came up with some handy code for bare board projects.

This code replaces the Default_Handler in kinetis_sysinit.c. There is probably a slicker way to do this,  but this is how I did it. All improvements welcome.

It also illustrates how to suppress a warning in GCC.

 

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
/*
 *  Default_Handler_Helper
 * Stack contains:
 * R0, R1, R2, R3, R12, R14, the pc and xPSR
 *  
 *  vIPSR is the interrupt number.
 */ 
void Default_Handler_Helper(uint32_t * svc_args,uint32_t vIPSR)
{
     // The pc might trace back to the instruction on a hardfault.
     // If you jumped to data, it might not.
      volatile uint32_t pc = ((uint32_t)svc_args[6]);
        
      __asm("bkpt");

}
#pragma GCC diagnostic pop
/*
 * Default_Handler() Replacement.
 * naked means no "C" prologue or epilogue.
 * Set up the SP and IPSR registers as function parameters.
 */
void __attribute__ ((naked)) Default_Handler()
{
        asm volatile (
         "MRS R0, MSP\n"        // Pass the SP in as the first "C" argument.
         "MRS R1, IPSR\n"        // Pass in IPSR as the second "C" argument.
         "B Default_Handler_Helper\n"
         );
}

 

To test it:

              *((char *) main) = 0;  // Cause a hard fault by writing to Flash.

 

When you get to the break point in the Default_Handler_Helper function, take the value of the PC, go to the Debugger Shell, type "bp <the value of pc>" and then click on the break point in the break point window to see the line of code causing the hard fault. (there is probably a better way to do this, but this how I did it).

 

Next, to test un-handled interrupts:

 

   SCB_ICSR |= SCB_ICSR_PENDSVSET_MASK;  // Cause a PendSV interrupt.

 

When you get to the break point in the help function, vIPSR will be 14, the interrupt number of the PendSV interrupt.

 

Or cause an NMI:

     SCB_ICSR |= SCB_ICSR_NMIPENDSET_MASK;

 

 

Once you get into the Default_Handler_Helper you are done. The program will not continue, but at least now you know....

Outcomes