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

Can't write on the control register during handler mode

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