13.6.2 时钟节拍的服务
1.节拍函数xTaskIncrementTick()
SysTick的中断服务通过调用xTaskIncrementTick()函数,来实现对所有处于阻塞态的任务节拍数xTickCount进行加1操作,并检查延时节拍是否已到。函数源码如下。



通过以上分析可知,xTaskIncrementTick()函数在每一个节拍期间完成了如下功能。
(1)首先判断调度器是否被挂起了,如果没被挂起,xTickCount表示一共发生了多少次SysTick中断,每次都加1。
(2)检查xNextTaskUnblockTime以确认有没有任务使用了延时函数而被阻塞,如果有并且延时时间已到,就把阻塞的任务从列表项中移除,并使用prvAddTaskToReadyList()函数把任务通过尾插方式添加到就绪列表pxReadyTasksLists[]中,然后设置下一个因延时而阻塞的任务的xNextTaskUnblockTime。(https://www.daowen.com)
(3)若是时间片轮转调度,还会使用listCURRENT_LIST_LENGTH来进行当前列表调整。
(4)返回xSwitchRequired的值,如果是pdTRUE,就需要进行任务切换。
2.就绪情况分析
13.2.1小节应用案例中,Task3_led任务调用vTaskDelay(500),即需要SysTick中断500次后,延时时间到。FreeRTOS通过xTaskIncrementTick()函数从延时列表pxDelayedTaskList[]中把该任务的列表项xStateListItem删除,然后通过prvAddTaskToReadyList()函数把任务列表项加到就绪列表pxReadyTasksLists[]中。如果CPU空闲,该任务优先级又是最高的,那么FreeRTOS重新调度该任务运行后面的程序,任务Task3_led的语句如下。

至此,Task3_led任务从睡眠态、就绪态、运行态、阻塞态再到就绪态,然后运行,只要没有删除任务,它将永远在就绪态、运行态、阻塞态中运行。
其他两个任务也一样,在就绪态、运行态、阻塞态中运行,这就是FreeRTOS的工作原理。