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
  • I seems that the boot code calls the "Application" while still in Handler Mode.  The setting of the the PendSV bit in the application will not actually cause it to happen until interrupts are enabled and you leave Handler Mode. You never leave handler mode. A fix would be to call the "Application" in Thread Mode instead of Handler Mode.

Reply
  • I seems that the boot code calls the "Application" while still in Handler Mode.  The setting of the the PendSV bit in the application will not actually cause it to happen until interrupts are enabled and you leave Handler Mode. You never leave handler mode. A fix would be to call the "Application" in Thread Mode instead of Handler Mode.

Children