FreeRTOS硬件中断发生时的现场
在FreeRTOS中,当硬件中断发生时,当前正在运行的任务会立即被挂起,处理器会跳转到中断相关的中断服务程序中,在中断服务程序执行期间,遵循以下规则:
1、中断独占CPU,ISR拥有最高的执行优先级,在它执行完毕并显示退出之前,没有任何任务能够得到CPU时间片来运行,处理器完全用于执行ISR代码,也就是说,任务和裸奔时的while循环一样,内部怎么调度,那是他们自己的事儿,中断一旦来临,他们都靠边站;
2、中断嵌套,如果系统允许中断嵌套,并且发生了更高级的中断,那么当前ISR会被新的中断抢占,这和裸奔没啥区别;
3、ISR中触发调度,中断服务程序执行完毕以后,会发生哪些事情呢?主要取决于以下几个方面:
(1)、中断是否触发了任务切换,也就是说,在中断中,是否调用了portYIELD_FROM_ISR()接口;
(2)、FreeRTOS调度模式的配置,也就是
configUSE_PREEMPTION的配置,如果配置为1,则为抢占式,如果配置为0,则为协作式,一班情况下,都是抢占式;
(3)、是否有更高优先级的任务就绪;
以下是中断退出后系统调度的详细流程和规则:
(1)、中断退出时的核心决策点
中断退出代码(通常是portYIELD_FROM_ISR(xHigherPriorityTaskWoken或者是portEND_SWITCHING_ISR(xHigherPriorityTaskWoken)),是调度的触发点;
该宏的参数xHigherPriorityTaskWoken的值是关键的输入;
(2)、调度逻辑
当xHigherPriorityTaskWoken的值为true时,退出中断后,处理器不会返回到被中断的任务,调度器会检查就绪的任务列表,选择优先级最高的就绪任务运行;
当xHigherPriorityTaskWoken的值为false时,退出中断后,处理器会返回到被中断的任务继续执行,但是同时调度器会检查就绪的任务列表,在下一个调度点,切换到更高优先级的任务上;
简单的来说:这有点儿类似于篮球场上的换人,中断退出的那一刻(类似于罚球时刻),系统会看中断服务程序有没有要求主动“换人”,如果portYIELD_FROM_ISR(pdTRUE),则表示主动要求“换人”,马上就会换上优先级最高的就绪任务,否则,只能在下一个调度点(类似于暂停等停球点)换上优先级最高的就绪任务;