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

Cortex M7 : Exception return query

Hi I am working on Cortex M7. I am generating some interrupts and according to it my ISR is being called which I have already installed. After the execution of the ISR the PC is not returning to the instruction at the time of the interrupt, due to which I am not able to proceed further.

I have tried the PUSH of lr and then the POP to pc but that does not work(Maybe I am calling it at a wrong place). Also tried the RX instruction, with an example will be the best.

Please provide some info on how to return from the exception.

Thanks in Advance

  • Hi,

    I would like to confirm that you know the lr does not contain the return address but EXC_RETURN code during processing ISR.

    When the EXC_RETURN is put into the pc, the actual return address will be extracted from the exception stack frame which had been build on the user stack.

    I guess the possible cause of the phenomenon would be that the lr had had a wrong code.

    Best regards,

    Yasuhiko Koumoto.

  • Hi,

    Thanks for your reply!!

    One more question from your reply. The EXC_RETURN is put into the PC after the ISR execution or we need to put it into the PC?

    What I am doing is :

    <Entering the ISR Execution>

    PUSH {lr}

    <C_int_haldler>

    POP {pc}

    Please let me know the what is incorrect in this as I am new to Processor's

    Regards

    Ritesh

  • Hi,

    I found out another possibility that the exception stack frame was something wrong. For example, the stack pointer value was not aligned to 8-byte or the user stack pointer was accidentally modified.

    Best regards,

    Yasuhiko Koumoto.

  • Hi,

    One more question from your reply. The EXC_RETURN is put into the PC after the ISR execution or we need to put it into the PC?

    The answer is "we need to put it into the PC".


    Ordinarily speaking, the interrupt/exception process is performed as the following.
    The numbered procedures are performed automatically by the hardware.

    1. interrupt acception

    2. make the current stack pointer (MSP or PSP) aligned to 8 byte

    3. PUSH xPSR

    4. PUSH PC (return PC)

    5. PUSH LR

    6. PUSH R12

    7. PUSH R3

    8. PUSH R2

    9. PUSH R1

    10. PUSH R0

    11. change the stack pointer to MSP

    12. make the execution mode to the Handler Mode

    13. put EXC_RETURN code to LR

    14. go to ISR

    --------------------------

    [ISR entry]

        exception handling              -- software processing

        move LR (i.e. EXC_RETURN) to PC -- software processing

    [ISR exit]

    --------------------------

    15. if LR[2]==0 then tmp_SP:=MSP else tmp_SP:=PSP.

    16. if LR[3]==0 then tmp_MOD:=Handler else tmp_MOD:=Thread

    17. make the current stack pointer to tmp_SP.

    18. make the current execution mode to tmp_MOD.

    19. POP R0

    20. POP R1

    21. POP R2

    22. POP R3

    23. POP R12

    24. POP LR

    25. POP PC to tmp_PC

    26. POP xPSR to tmp_xPSR.

    27. set tmp_xPSR to xPSR

    28. go to tmp_PC


    From these view points, your exception handling seems not to be wrong.


    How about checking the return address on the stack pointer.
    It can be carried out by executing the following instructions and the return address would be put into R1 (R0, R1, R2, R3, R12 can be freely used in the ISR because they are already stacked).

     __asm volatile ( " tst lr, #4 \n\r"
                      " ite eq \n\r" 
                      " mrseq r0, msp \n\r"
                      " mrsne r0, psp \n\r" 
                      " ldr r1, [r0, #24]\n\r" );
    

    By the way, is your "<C_int_handler>" procedure a function call?
    If it is so, neither "PUSH {lr}" nor "POP {pc}" would be needed.

    Best regards,

    Yasuhiko Koumoto.

  • Hi,

    Thanks for your prompt and detailed reply!!!

    Yes, the C_int_handler is a function call and now it works properly. The operation now performed is calling the C_int_handler function once the interrupt is generated, the PC properly returns to the previous instruction. There was one more issue that there were 2 more interrupts generated(due to some other operation and these interrupts were not enabled) along with the interrupt which I was generating and processing.

    Thanks!!!