This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Resume execution after hardfault on cortex m0

Hi all,

I 'm an embedded software engineer and I'm currently working on a nRF51822 target which is a ARM m0. I want to design a fault logger to track errors in our code even it a debugger is not attached to the device at the moment of the fault. 

I think the best solution is to write a custom hardfault handler to dump the stack frame and flash it in the internal flash memory. To do that, I need to exit the hardfault handler which is in Handler mode, whith privilege etc... and return to a "normal" threaded mode execution. In fact, in order to flash the device, I need severals interrupts to be fired. That's not possible in handler mode.

My first guess was to corrupt the stack frame to change the value of the PC and LR to jump to a safe zone. In the safe zone I would just had to flash the saved stack frame and reset the chip. 

Here is my pseudo code : 

->generate fault

void(*f)(void)=NULL;
f();

My hardfault handler :

 void HardFault_Handler(void)
{

     volatile void* msp;
      
     msp=(void*)(__get_MSP()+0x20); //in my example I know i'm using MSP
      
    volatile uint32_t* r0=((uint32_t*)msp);
    volatile uint32_t* r1=((uint32_t*)msp+1);
    volatile uint32_t* r2=((uint32_t*)msp+2);
    volatile uint32_t* r3=((uint32_t*)msp+3);
    volatile uint32_t* r12=((uint32_t*)msp+4);
    volatile uint32_t* lr=((uint32_t*)msp+5); /* Link register. */
    volatile uint32_t* pc=((uint32_t*)msp+6); /* Program counter. */
    volatile uint32_t* psr=((uint32_t*)msp+7);/* Program status register. */

    //Save stack frame in structure
    error_logger_stack_frame.r0=*r0;
    error_logger_stack_frame.r1=*r1;
    error_logger_stack_frame.r2=*r2;
    error_logger_stack_frame.r3=*r3;
    error_logger_stack_frame.r12=*r12;
    error_logger_stack_frame.lr=*lr;
    error_logger_stack_frame.pc=*pc;
    error_logger_stack_frame.psr=*psr;
    
    //Prepare jump to safezone
    *pc=(uint32_t)&errorLogger_handler;

}

The problem is if I go step by step in debugger the code jump as intended in the safe zone in threaded mode but if I place a breakpoint in the safe zone and run the code at once, the breakpoint is never reached.

What is happening ? Is it possible to continue execution after a Hardfault ? Did I omit some actions in order to recover ? Is the device in Lockup ?

I'm lost...

Tanks in advance,

PS: Sorry for my bad English, I'm French 

Parents Reply Children