Cortex M4 - Returning from Interrupt

Hi,

I'm using the STM32 F407 (Cortex M4), and I am also only using assembly in uVision IDE. So far I have managed to setup a ISR for a pushbutton generated interrupt via GPIO. This all works, I get the ISR handler hit, but after I perform my ISR function how do I return back to thread mode, and set the PC back to last point of execution ?

I have tried doing a straightforward BX LR like the ARM wiki states, (LR is currently set to 0xFFFF FFF9 which is the exception return set by the CPU), I thought when the CPU saw I was trying to set PC to this it would auto handle the transition back to thread, but it goes straight to hard fault handler. Then I tried manually popping off r0,r4 and then pop PC, to set the PC directly to the 5th item on the stack (only main stack is used), this was the previous execution address, but I'm not sure how to change back to thread from handler mode.

So my question is does the CPU handle switching execution back to thread after handler, or do I have to manually unwind the stack, set the PC correctly and change mode back to thread ?

Thanks.

Parents
  • Keep in mind that if you use separate stacks (MSP and PSP), the exception is stacked up on the thread's PSP stack, NOT MSP unless it's nested.  So you'll need to access it through a register: "mrs r0, psp; ldr r1,[r0,#6*4]" for example if you need to fetch the stacked LR.

    The exception is nested if the low 9 bits of IPSR are non-zero, in which case the exception is stacked up on MSP.

    One way of getting a guaranteed hard fault on exception return on Cortex-M is if you modify the exception stacked up and forget to set the T bit in the modifed on-stack PSR before exception return.  Instant hard fault.  Also, the stacked LR needs to have bit 0 set, but the PC should not.  If LR doesn't have it set you'll get a fault when the interrupted function returns... 

    Just a few things I found out the hard way myself, that are easy to overlook when you modify the exception stackup.

    I suspect your bx lr works just fine, and there's something about the stacked state that causes the fault.

Reply
  • Keep in mind that if you use separate stacks (MSP and PSP), the exception is stacked up on the thread's PSP stack, NOT MSP unless it's nested.  So you'll need to access it through a register: "mrs r0, psp; ldr r1,[r0,#6*4]" for example if you need to fetch the stacked LR.

    The exception is nested if the low 9 bits of IPSR are non-zero, in which case the exception is stacked up on MSP.

    One way of getting a guaranteed hard fault on exception return on Cortex-M is if you modify the exception stacked up and forget to set the T bit in the modifed on-stack PSR before exception return.  Instant hard fault.  Also, the stacked LR needs to have bit 0 set, but the PC should not.  If LR doesn't have it set you'll get a fault when the interrupted function returns... 

    Just a few things I found out the hard way myself, that are easy to overlook when you modify the exception stackup.

    I suspect your bx lr works just fine, and there's something about the stacked state that causes the fault.

Children
More questions in this forum