title: Recover from Hard Fault on Cortex M0+
body: <p>Until now I had a Hard fault handler in C that I defined in the vector table:</p>
  
  <pre><code>.sect ".intvecs"
  
  .word _top_of_main_stack
  .word _c_int00
  .word NMI  
  .word Hard_Fault
  .word Reserved
  .word Reserved  
  .word Reserved
  .word Reserved
  .word Reserved
  .word Reserved
  .word Reserved
  .word Reserved
  .word Reserved
  .word Reserved
  .word Reserved
  .word Reserved
  ....
  ....
  ....
  </code></pre>
  
  <p>One of our tests triggers a hard fault (on purpose) by writing to a non existing address. Once the test is done, the handler returns to the calling function and the cortex recovers from the fault. Worth mentioning that the handler does not have any arguments.</p>
  
  <p>Now I'm in the phase of writing a real handler.
  I created a struct for the stack frame so we can print PC, LR, and xPSR in case of a fault:</p>
  
  <pre><code>typedef struct
  {
      int     R0              ;  
      int     R1              ;  
      int     R2              ;  
      int     R3              ;  
      int     R12             ;
      int     LR              ; 
      int     ReturnAddress   ; 
      int     xPSR            ;
  
  }   InterruptStackFrame_t  ;
  </code></pre>
  
  <p>My hard fault handler in C is defined:</p>
  
  <pre><code>void Hard_Fault(InterruptStackFrame_t* p_stack_frame)
  {
      // Write to external memory that I can read from outside
      /* prints a message containing information about stack frame:
       * p_stack_frame-&gt;LR, p_stack_frame-&gt;PC, p_stack_frame-&gt;xPSR,
       * (uint32_t)p_stack_frame (SP)
       */
  }
  </code></pre>
  
  <p>I created an assembly function:</p>
  
  <pre><code>        .thumbfunc  _hard_fault_wrapper
  _hard_fault_wrapper: .asmfunc
      MRS    R0, MSP    ; store pointer to stack frame
      BL     Hard_Fault ; go to C function handler
      POP    {R0-R7}    ; pop out all stack frame
      MOV    PC, R5     ; jump to LR that was in the stack frame (the calling function before the fault)
  
  .endasmfunc
  </code></pre>
  
  <p>This is the right time to say that I don't have an OS, so I do not have to check bit[2] of LR because I definitely know that I use MSP and not PSP.</p>
  
  <p>The program compiles and runs properly and I used JTAG to ensure that all registers restore to the wanted values.
  When executing the last command (<code>MOV    PC, R5</code>) the PC returns to the correct address, but at some point, the debugger indicates that the M0 is locked in a hard fault and cannot recover.</p>
  
  <p>I do not understand the difference between using a C function as a handler or an assembly function that calls a C function.</p>
  
  <p>Does anyone know what is the problem?</p>
  
  <p>Eventually, I will use an assert function that will stuck the processor, but I want it to be optional and up to my decision.</p>