PendSV是可悬起异常。
如果我们把它配置最低优先级,那么如果同时有多个异常被触发,它会在其他异常执行完毕后再执行,而且任何异常都可以中断它。
OS可以利用它“缓期执行”一个异常——直到其它重要的任务完成后才执行动作。悬起PendSV的方法是:手工往NVIC的PendSV悬起寄存器中写1。悬起后,如果优先级不够高,则将缓期等待执行。PendSV的典型使用场合是在上下文切换时(在不同任务之间切换)。
当某中断源的频率和SysTick异常的频率比较接近时,会发生“共振”,使上下文切换迟迟不能进行。现在好了,PendSV来完美解决这个问题了。
PendSV异常会自动延迟上下文切换的请求,直到其它的ISR都完成了处理后才放行。为实现这个机制,需要把PendSV编程为最低优先级的异常。如果OS检测到某IRQ正在活动并且被SysTick抢占,它将悬起一个PendSV异常,以便缓期执行上下文切换。
使用PendSV控制上下文切换个中事件的流水账记录如下:
1、任务A呼叫SVC来请求任务切换(例如,等待某些工作完成)
2、OS接收到请求,做好上下文切换的准备,并且悬起一个PendSV异常。
3、当CPU退出SVC后,它立即进入PendSV,从而执行上下文切换。
4、当PendSV执行完毕后,将返回到任务B,同时进入线程模式。
5、发生了一个中断,并且中断服务程序开始执行
6、在ISR执行过程中,发生SysTick异常,并且抢占了该ISR。
7、OS执行必要的操作,然后悬起PendSV异常以作好上下文切换的准备。
8、当SysTick退出后,回到先前被抢占的ISR中,ISR继续执行
9、ISR执行完毕并退出后,PendSV服务例程开始执行,并且在里面执行上下文切换
10、当PendSV执行完毕后,回到任务A,同时系统再次进入线程模式。