支持多优先级
在 FreeRTOS 中,数字优先级越小,逻辑优先级也越小,这与RT-Thread 和 μC/OS 刚好相反。
1、如何支持多优先级
就绪列表 pxReadyTasksLists[ configMAX_PRIORITIES ]是一个数组,数组里面存的是就绪任务的 TCB(准确来说是 TCB 里面的 xStateListItem 节点),数组的下标对应任务的优先级,优先级越低对应的数组下标越小。空闲任务的优先级最低,对应的是下标为 0 的链表。
2、查找最高优先级的就绪任务相关代码
/* 查找最高优先级的就绪任务:通用方法 */
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 )
/* uxTopReadyPriority 存的是就绪任务的最高优先级 */
#define taskRECORD_READY_PRIORITY( uxPriority )\
{\
if( ( uxPriority ) > uxTopReadyPriority )\
{\
uxTopReadyPriority = ( uxPriority );\
}\
} /* taskRECORD_READY_PRIORITY */
/*-----------------------------------------------------------*/
#define taskSELECT_HIGHEST_PRIORITY_TASK()\
{\
UBaseType_t uxTopPriority = uxTopReadyPriority;\
/* 寻找包含就绪任务的最高优先级的队列 */\
while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) )\
{\
--uxTopPriority;\
}\
/* 获取优先级最高的就绪任务的 TCB,然后更新到 pxCurrentTCB */\
listGET_OWNER_OF_NEXT_ENTRY(pxCurrentTCB, &(pxReadyTasksLists[ uxTopPriority ])); \
/* 更新 uxTopReadyPriority */\
uxTopReadyPriority = uxTopPriority;\
} /* taskSELECT_HIGHEST_PRIORITY_TASK */
/*-----------------------------------------------------------*/
/* 这两个宏定义只有在选择优化方法时才用,这里定义为空 */
#define taskRESET_READY_PRIORITY( uxPriority )
#define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority )
/* 查找最高优先级的就绪任务:根据处理器架构优化后的方法 */
#else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
#define taskRECORD_READY_PRIORITY( uxPriority ) \
portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority )
/*-----------------------------------------------------------*/
#define taskSELECT_HIGHEST_PRIORITY_TASK()\
{\
UBaseType_t uxTopPriority;\
/* 寻找最高优先级 */\
portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority );\
/* 获取优先级最高的就绪任务的 TCB,然后更新到 pxCurrentTCB */\
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) );\
} /* taskSELECT_HIGHEST_PRIORITY_TASK() */
/*-----------------------------------------------------------*/
#if 0
#define taskRESET_READY_PRIORITY( uxPriority )\ (注意)
{\
if(listCURRENT_LIST_LENGTH(&(pxReadyTasksLists[( uxPriority)]))==(UBaseType_t)0)\
{\
portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) );\
}\
}
#else
#define taskRESET_READY_PRIORITY( uxPriority )\
{\
portRESET_READY_PRIORITY((uxPriority ), (uxTopReadyPriority));\
}
#endif
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
查 找 最 高 优 先 级 的 就 绪 任 务 有 两 种 方 法 , 具 体 由configUSE_PORT_OPTIMISED_TASK_SELECTION 这个宏控制,定义为 0 选择通用方法,定义为 1 选择根据处理器优化的方法,该宏默认在 portmacro.h 中定义为 1,即使用优化过的方法。
3、修改代码,支持多优先级
在之前的代码基础上,继续迭代修改,实现多优先级。
分别:
修改任务控制块
修改 xTaskCreateStatic()函数
修改 vTaskStartScheduler()函数
修改 vTaskDelay()函数
修改 vTaskSwitchContext()函数
修改 xTaskIncrementTick()函数