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

The code of app is freertos , the chip has a bootloader, The chip run on Cortex M0

When trigger the PendSV exception, the context switches with Cortex-M0 is wrong.  but the program without the bootloader, the app can run ok.

Parents
  • I  found that LR is wrong,when it run out from PendSV_handler of  the app. I try to save the LR. but I do konw how to do this.

    The code of the boot :

    void PendSV_Handler()
    {
    //  uint32_t address;
    //  __asm("PUSH   {R14}\n");
    //  address=FLASH_OFFSET+4*14;
      (*(void(*)(void))(*(uint32_t*) 0x2038))();
    //   __asm("POP  {R0}\n");
    // __asm("LDR 0x1213223\n");
    }

    the app code :

    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

Reply
  • I  found that LR is wrong,when it run out from PendSV_handler of  the app. I try to save the LR. but I do konw how to do this.

    The code of the boot :

    void PendSV_Handler()
    {
    //  uint32_t address;
    //  __asm("PUSH   {R14}\n");
    //  address=FLASH_OFFSET+4*14;
      (*(void(*)(void))(*(uint32_t*) 0x2038))();
    //   __asm("POP  {R0}\n");
    // __asm("LDR 0x1213223\n");
    }

    the app code :

    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

Children
No data