When trigger the PendSV exception, the context switches with Cortex-M0 is wrong. but the program without the bootloader, the app can run ok.
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 savedOS_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