Topic : Returning from assembly function (task switch)

Forum : ARM

Original Post
Post Information Post
November 26, 2010 - 3:27pm
Guest

Hello
I am trying to return from an assembly function (context switch) by using mov pc,lr .
LR has 200009D7 so I should return to 200009D6 but I return to 20000004 when I am debugging in hardware.
But the same code when I run in Simulator SIM-ARM the return is perfectly fine.
I have tried push and pop also but they work in the Simulator SIM-ARM not in hardware.

Target : STM32F107VCT6 (Cortex M3)
Toolset: RIDE7

Here is the code snippet

thread_switch_context:

save:
stmia r0!, {r0-r12} /*Save upto PC*/
mov r3,r13
stmia r0!, {r3,r14}
ldr r2,=task_restore_pc
str r2, [r0], #4 /*Save PC*/
restore:
ldr SP,[r1,#52] /*Loading sp value since it cannot be in load multiple list */
ldr LR,[r1,#56] /*Loading lr as lr and pc cannot be loaded simultaneously*/
ldr r3,[r1,#60] /*Loading pc as lr and pc cannot be loaded simultaneously*/
stmfd sp!,{r3};
ldmia r1, {r0-r12}
ldmfd sp!,{r15};
task_restore_pc:
mov pc,lr

Thanks In Advance

Replies
Post Information Post
+1
0
-1
November 28, 2010 - 7:39am
Guest

Reason: UsageFault at ldmfd sp!,{r15};
No problem with bx lr .
Cause:
The PC can be specified as the destination register of an LDR instruction.
The loaded value is treated as an address, and the effect of execution is a branch to that address. bit [0] of the loaded value selects the execution state after the branch and must have the value 1.
So whenever you do LDR PC,[]; the loaded value must be (destination_address + 1).

In the debugging environment you will see the last nibble of APSR will change to 3.
but it will change one instruction after ldmfd sp!,{r15};.Thus since bx lr is in pipe its shown as if its
getting excecuted actually the core is jumping to ISR.

____________________________________________________________________________________

I still have some doubts:
1. Why does it work in the simulator.
2. Why does it show APSR changing and not EPSR and xPSR in the debugging mode.