13.4.3 SVC任务切换
更新于 2026年10月10日
版权声明
13.4.3 SVC任务切换
1.开启SVC中断
FreeRTOS中第一次启动任务切换是触发一次SVC中断来实现的,只用进行这一次,以后的任务切换就是通过PendSV来实现(其实第一次也可以采用PendSV中断)的。prvStartFirstTask()函数触发一次SVC中断的程序如下。

2.SVC软件中断的服务程序
由于第一次调度不需要保护现场,不需要压栈,直接从堆栈中将第一个任务(如13.2.1小节中应用案例的task3_led)的初始化数据弹给CPU,程序如下。
(https://www.daowen.com)
SVC任务切换示意图如图13.14所示。
首先把当前任务控制块pxCurrentTCB的地址赋给R3,然后把当前任务控制块pxCurrentTCB所指向的地址赋给R1,然后把任务控制块pxCurrentTCB地址里的值赋给R0(这个值即任务控制块的第一个成员pxTopOfStack),然后用批量出栈指令LDMIA把R0指向的堆栈地址中的连续8个地址里的值赋给CPU的R4~R11,然后调整进程堆栈指针让PSP=R0,指向A位置,最后中断返回,系统自动将剩下的自动出栈的寄存器R3~R0、R12、LR、PC、xPSR弹给对应的CPU寄存器。

图13.14 SVC任务切换示意图
在堆栈C处是之前xTaskCreate()函数创建任务时初始化的堆栈,该处保存的是指向任务代码(Task3_led),即出栈后CPU的PC=Task3_led,所以CPU就自然转向Task3_led任务执行。