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

Tasks can't switch to others, always run at OSStartHang. but whitout boot code ,the app can run ok. the core of the chip is cortex-M0

The app is ucos II. 

OSStartHighRdy
    LDR     R0, =NVIC_SYSPRI14                                  ; Set the PendSV exception priority
    LDR     R1, =NVIC_PENDSV_PRI
    STR     R1, [R0]                                            ; Not storing entire byte with STRB to avoid error

    MOVS    R0, #0                                              ; Set the PSP to 0 for initial context switch call
    MSR     PSP, R0

    LDR     R0, =OS_CPU_ExceptStkBase                           ; Initialize the MSP to the OS_CPU_ExceptStkBase
    LDR     R1, [R0]
    MSR     MSP, R1   

    LDR     R0, =OSRunning                                      ; OSRunning = TRUE
    MOVS    R1, #1
    STRB    R1, [R0]

    LDR     R0, =NVIC_INT_CTRL                                  ; Trigger the PendSV exception (causes context switch)
    LDR     R1, =NVIC_PENDSVSET
    STR     R1, [R0]

    CPSIE   I                                                   ; Enable interrupts at processor level

OSStartHang
    B       OSStartHang                                         ; Should never get here

PendSV_Handler
    CPSID   I                                                   ; Prevent interruption during context switch
    MRS     R0, PSP                                             ; PSP is process stack pointer

    CMP     R0, #0
    BEQ     OS_CPU_PendSVHandler_nosave       ; equivalent code to CBZ from M3 arch to M0 arch
                ; Except that it does not change the condition code flags

    SUBS    R0, R0, #0x10                                       ; Adjust stack pointer to where memory needs to be stored to avoid overwriting
    STM     R0!, {R4-R7}                                        ; Stores 4 4-byte registers, default increments SP after each storing
    SUBS    R0, R0, #0x10                                       ; STM does not automatically call back the SP to initial location so we must do this manually

    LDR     R1, =OSTCBCur                                       ; OSTCBCur->OSTCBStkPtr = SP;
    LDR     R1, [R1]
    STR     R0, [R1]                                            ; R0 is SP of process being switched out

                                                                ; At this point, entire context of process has been saved
OS_CPU_PendSVHandler_nosave
    PUSH   {R14}                                                ; Save LR exc_return value
    LDR     R0, =OSTaskSwHook                                   ; OSTaskSwHook();
    BLX     R0
    POP    {R0}
    MOV     R14, R0

    LDR     R0, =OSPrioCur                                      ; OSPrioCur = OSPrioHighRdy;
    LDR     R1, =OSPrioHighRdy
    LDRB    R2, [R1]
    STRB    R2, [R0]

    LDR     R0, =OSTCBCur                                       ; OSTCBCur  = OSTCBHighRdy;
    LDR     R1, =OSTCBHighRdy
    LDR     R2, [R1]
    STR     R2, [R0]

    LDR     R0, [R2]                                            ; R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr;

    LDM     R0!, {R4-R7}                                        ; Restore R4-R7 from new process stack

    MSR     PSP, R0                                             ; Load PSP with new process SP

    MOV     R0,  R14
    MOVS    R1,  #0x04                                          ; Immediate move to register
    ORRS    R0,  R1                                             ; Ensure exception return uses process stack
    MOV     R14, R0
    CPSIE   I
    BX      LR                                                  ; Exception return will restore remaining context

    ;ALIGN                                                       ; Ensures that ARM instructions start on four-byte boundary

    END

the boot  code

void PendSV_Handler()
{
//    void (*pFunction)(void);

    uint32_t address;

 //   HT_Flash_WordRead(&address, FLASH_OFFSET+4*16,1); 
  
// pFunction = (void (*)(void))address; 
// pFunction();//Jump t
   address=FLASH_OFFSET+4*14;
   (*(void(*)(void))(*(uint32_t*) address))();
}

void SVC_Handler()
{
//    void (*pFunction)(void);

    uint32_t address;

 //   HT_Flash_WordRead(&address, FLASH_OFFSET+4*16,1); 
  
// pFunction = (void (*)(void))address; 
// pFunction();//Jump t
   address=FLASH_OFFSET+4*11;
   (*(void(*)(void))(*(uint32_t*) address))();
}

Parents Reply Children