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 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
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);
// 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))();}
It seems like the PendSV exception is not triggered as you expected. Please note setting the PendSV bit in the code should allow the PendSV operation to be pended to the current operation or to execute at the next opportunity when priority allows.Without knowing detail of the code and what is occurring around the setting of the PendSV bit I cannot comment on why this is failing, there are 2 reasons that may stop the PendSV exception from running.
Firstly, is the priority of the executing code correct, if the current execution level is too high then the PendSV code will not execute as it will not have sufficient priority.Secondly, has there been any change to the System Handler and State Register which can remove the active bit of the PendSVC, this will ensure that a PendSV exception is not taken.
It seems like you meet the first one. You set the PendSV in the main code (thread mode) instead of interrupt handler (handler mode). The PendSV will wait for the complete of current thread mode code's execution, but it will not. So no PendSV will be taken.