13.4.5 高优先级查找

更新于 2026年10月10日 版权声明
13.4.5 高优先级查找

1.函数vTaskSwitchContext()

PendSV中断服务程序调用函数vTaskSwitchContext()来获取下一个要运行的任务,也就是查找已经就绪的优先级最高的任务,函数主要源码如下。

图示

主要语句功能如下。

①如果调度器挂起,那么就不能进行任务切换。

②查找高优先级函数,从就绪列表中查找优先级最高的优先级数值。

2.高优先级查找算法

在FreeRTOS中,查找下一个要运行的任务有两种方法:一种是软件实现法,另一种是硬件实现法。选择哪种方法是通过宏configUSE_PORT_OPTIMISED_TASK_SELECTION来决定的,当这个宏为1的时候,就使用硬件实现法,否则就使用软件实现法。

(1)软件实现法。

每一个任务均按优先级数值对应一个自己所属的任务列表,列表中的列表项代表任务,如果有列表项存在,表示任务就绪(运行态也存在),每一次任务就绪后都会进行比较,把最大的优先级数值存放在变量uxTopReadyPriori ty中,因此该变量中始终存放的是优先级最高的数值。

软件实现法的定义如下。

图示

主要语句功能如下。

①pxReadyTasksLists[]为就绪任务列表数组,一个优先级对应一个列表,同优先级的就绪任务都挂到相应的列表中。uxTopReadyPriori ty代表处于就绪态的最高优先级数值,每次创建任务的时候,都会判断新任务的优先级数值是否大于uxTopReadyPriori ty,如果大于,就将这个新任务的优先级赋值给变量uxTopReadyPriori ty。函数prvAddTaskToReadyList()也会修改这个值,将某个任务添加到就绪列表中的时候都会用uxTopReadyPriori ty来记录就绪列表中的最高优先级。这里就从这个最高优先级开始判断,看看哪个列表不为空就说明哪个优先级有就绪的任务。函数listLIST_IS_EMPTY()用于判断某个列表是否为空,变量uxTopPriori ty用来记录这个有就绪任务的优先级。(https://www.daowen.com)

②找到了高优先级数值uxTopPriori ty,接下来就用函数listGET_OWNER_OF_NEXT_ENTRY()来获取pxReadyTasksLists[uxTopPriori ty]列表中的下一个列表项,列表项中的pvOwner就指向该任务的任务控制块。把任务控制块赋值给pxCurrentTCB,至此就确定了要运行的任务,开始任务调度。

(2)硬件实现法。

硬件实现法是利用某些CPU中的一些高级指令来加速查找高优先级任务的一种方法,如ARM Cortex-M3的指令集中,指令CLZ可实现高优先级数值查找,该指令功能是计算源操作数(二进制)前导零的个数。

硬件实现法的定义如下。

图示

主要语句功能如下。

①portGET_HIGHEST_PRIORITY()函数获取处于就绪态的最高优先级。该宏定义如下。

图示

例如,13.2.1小节应用案例中的3个任务的优先级分别为1、2和2,调用xTaskCreate()函数后,3个任务均就绪,就绪列表的全局变量uxTopReadyPriority=0x00000006。高优先级数据的查找方法如下。

第一步:CLZ(0x00000006)=29。0x00000006转换成32位二进制,最高位1前导0的个数为29个。

第二步:31-29=2,因此找到了高优先级数值2。

用这种方法查找高优先级数值是最快的,建议用户使用此方法。

②根据优先级数值找到列表,把任务控制块传给当前任务控制块pxCurrentTCB。

↑上一章 ↓下一章
关注公众号获取验证码
复制内容需要验证码(7.99元/天)