有些操作系统在“心跳”中断(SysTick中断)里进行线程切换,如果处理器正在执行一个ISR,此时SysTick异常到来,且SysTick优先级高,抢占了正在运行的用户ISR,SysTick ISR是不能进行线程切换的,因为SysTick ISR运行完后要返回上一层用户ISR,此时仍然处于异常模式,不能进入线程模式,强行进入线程模式会导致Fault异常。如下图,延时到了第二个SysTick ISR才线程切换,实时性降低。在这种情况下,SysTick ISR中切换任务,这会导致任务切换延后。
极端的情况下,SysTick中断和用户中断步调一致,会导致任务切换严重滞后。如下图所示:
有朋友说了,既然SysTick中断抢占了用户中断不能调度线程,那么在用户ISR即将退出时进行调度就好了呀,确实比上面的情况要好一些,但这就需要在所有中断的末尾都要检查是否需要切换,增加用户中断程序复杂度。
也有朋友说了,把SysTick中断优先级调到最低是不是也可以呢,当然可以,调低了优先级,避免了嵌套,就算用户中断期间产生SysTick中断,但是SysTick中断不能运行,用户中断结束后,SysTick中断“咬尾”,这样是没问题的,可是有一点SysTick的优先级就无法提高了。
鉴于上述原因,我们想到了PendSV异常,这个异常比较特殊,可以理解为一个软中断(软异常),代码中操作寄存器就可以触发此中断,我们把它的优先级调整到最低,当SysTick ISR抢占了用户中断后,发现需要任务调度,就设置寄存器触发PendSV异常,因为它优先级最低,不能响应,等到用户中断执行完立即自动响应,进行任务切换,如下图所示。
一般情况下:
1、PendSV中断优先级设置为最低,用于线程调度。
2、SysTick中断优先级根据自己需求设置,如果想让心跳更准确就调高一些,如果想让用户中断相应更迅速就调低一些。
3、可以和PendSV一样都设置为最低。
全部0条评论
快来发表一下你的评论吧 !