根据STM32F103上uCOS-II代码中OS_CPU_PendSVHandler的函数代码整理。
uCOS-II是非剥夺式的操作系统,任务切换只发生在以下几种情况:
1> 外部中断引起变化,导致高优先级任务就绪。
例如串口中断收到数据,在中断例程中接收数据后调用OSSemPost(),互斥量的Post使uCOS-II知道相应的串口接收任务转变到就绪状态。
2> SysTick的定时中断,导致之前处于OSTimeDly挂起的高优先级任务就绪。
3> 当前任务执行如OSSemPend、OSTimeDly等操作导致当前任务挂起,需要切换到其他次优先级的任务。
前两种都是在中断退出后引起任务切换。
外部中断退出时调用OSIntExit函数激活PendSV中断,真正的task切换在PendSV中断例程中实现。
SysTick中断优先级较高,也不直接做任务切换,其同样在中断退出时调用OSIntExit函数激活PendSV中断,真正的task切换在PendSV中断例程中实现。
第3种是在需要任务切换时调用OS_Sched,后者会调用OSCtxSw,而OSCtxSw也是激活PendSV中断,再由PendSV中断例程完成真正的任务切换。
所以所有的任务切换最终都是由PendSV中断例程完成的。
PendSV的中断优先级必须是系统所有中断中最低的。
PendSV中断由OS_CPU_PendSVHandler函数处理。
OS_CPU_PendSVHandler函数的代码:
OS_CPU_PendSVHandler
CPSID I ; Prevent interruption during context switch
MRS R0, PSP ; PSP is process stack pointer
CBZ R0, OS_CPU_PendSVHandler_nosave ; Skip register save the first time
SUBS R0, R0, #0x20 ; Save remaining regs r4