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
  • You wrote:

    "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."

    Actually, this kind of goal cannot be achieved by a simple hardfault handler in software layer. As you know, once the hard fault occurs, the CPU falls into fault handlers. For some serious hardware errors, we cannot rely on that other peripheral interrupts such as flash devices can work well because the whole hardware system may hang up if the bus is locked up.

    One possible solution is to design software based on the hardware features. If the hard faults occur, the CPU triggers a silent reset and makes a special flag while keeping the DDR or SRAM content unchanged. So that after the reboot, the software can check the flag, which may be a special hardware register bit. If there is a previous hard fault detected, the software will use a separate debug stack to analyze the DDR/SRAM that all offending bug context was saved.

Reply
  • You wrote:

    "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."

    Actually, this kind of goal cannot be achieved by a simple hardfault handler in software layer. As you know, once the hard fault occurs, the CPU falls into fault handlers. For some serious hardware errors, we cannot rely on that other peripheral interrupts such as flash devices can work well because the whole hardware system may hang up if the bus is locked up.

    One possible solution is to design software based on the hardware features. If the hard faults occur, the CPU triggers a silent reset and makes a special flag while keeping the DDR or SRAM content unchanged. So that after the reboot, the software can check the flag, which may be a special hardware register bit. If there is a previous hard fault detected, the software will use a separate debug stack to analyze the DDR/SRAM that all offending bug context was saved.

Children