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