I am using TM4C development board and Uvision 4 IDE. During the context switch routine i need to store PSP value. When i use PSP symbol in the assembly code i have an error "error: A1647E: Bad register name symbol, expected Integer register" but this is not the case when i use SP only (without define explicitly MSP or PSP).
I try to access the CONTROL register and write 2 to switch the stack pointer to PSP (and then i SP which i can use the assembly code will be the PSP) but the control register is not get changed. Could any one help?
Here is my code.
Switch_Context ; 1) Saves R0-R3,R12,LR,PC,PSR CPSID I ; 2) Prevent interrupt during switch PUSH {R4-R11} ; 3) Save remaining regs r4-11 LDR R0, =RunPt ; 4) R0=pointer to RunPt, old thread LDR R1, [R0] ; R1 = RunPt MOV R2, #2 ; MSR CONTROL, R2 STR SP, [R1] ; 5) Save SP into TCB MOV R2, #0 ; MSR CONTROL, R2 . . . BX LR ; 10) restore R0-R3,R12,LR,PC,PSR
You cannot write to bit 2 of the control register in Handler Mode. It is always read as 0 (It MUST always be on the MSP)
You the MRS / MSR ( Move Register to Special, Move Special to Register to specifically reference the USP / MSP. You may ONLY reference the SP (the currently active stack pointer) with the MOV(s) instruction.
MSR USP, R0 ; Move Register to Special
MRS R1, USP ; Move Special to Register
also it is best to save the reaming context on the USP and not the MSP. This allow many threads each with there own stack.
MRS R0, USP ; move USP to R0
STMDB R0!, {R4-R11} ; Save the reaming registers on the USP
; Now save R0 in the TCB as the current stack pointer
; Restore SP from TCB to R0
LDMIA R0!, {R4-R11} ; Restore R4-R11 from the correct USP
MSR PSP, R0 ; Move new thread SP to USP.
BX LR ; Return to new thread. Make sure LR is correct.
Switch Context CPSID I ; You should not need this if done "right" MRS R2,USP ; Get Current USP STMDB R2!, {R4-R11} ; Save Registers to Thread Stack not MSP LDR R0, =RunThreadTCB LDR R1, [R0] STR R2,[R1] ; Store USP to TCB LDR R0,=NewThreadTCB LDR R3,[R0] LDR R2,[R3] ; TCB of next Thread to run STR R3,[R1] ; Move New TCB to RunThreadTCB LDMIA R2!,{R4-R11} ; Restore New Threads R4-R11 BX LR ; Restore the Remaining and go