FreeRTOS任务优先级越小优先级越小,系统在运行过程中允许修改任务优先级
修改任务优先级的主要工作包括:
如果新的优先级大于当前任务优先级,则请求切换
重新设置事件列表值
将任务从原就绪列表中移除并挂接到新的就绪列表中
/* 设置任务优先级 */
void vTaskPrioritySet(TaskHandle_t xTask, UBaseType_t uxNewPriority)
{
TCB_t *pxTCB;
UBaseType_t uxCurrentBasePriority, uxPriorityUsedOnEntry;
BaseType_t xYieldRequired = pdFALSE;
configASSERT((uxNewPriority < configMAX_PRIORITIES));
/* 任务优先级不能超过最大值 */
if(uxNewPriority >= (UBaseType_t)configMAX_PRIORITIES)
{
uxNewPriority = (UBaseType_t)configMAX_PRIORITIES - (UBaseType_t)1U;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
taskENTER_CRITICAL();
{
/* 通过任务句柄获取任务TCB */
pxTCB = prvGetTCBFromHandle(xTask);
traceTASK_PRIORITY_SET(pxTCB, uxNewPriority);
#if (configUSE_MUTEXES == 1)
{
uxCurrentBasePriority = pxTCB->uxBasePriority;
}
#else
{
/* 记录原先的优先级 */
uxCurrentBasePriority = pxTCB->uxPriority;
}
#endif
/* 优先级和原先优先级不同 */
if(uxCurrentBasePriority != uxNewPriority)
{
/* 新优先级大于原优先级 */
if(uxNewPriority > uxCurrentBasePriority)
{
/* 该任务不是当前任务 */
if(pxTCB != pxCurrentTCB)
{
/* 新优先级大于当前任务优先级 */
if(uxNewPriority >= pxCurrentTCB->uxPriority)
{
/* 请求切换任务 */
xYieldRequired = pdTRUE;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
}
}
/* 该任务为当前任务 */
else if(pxTCB == pxCurrentTCB)
{
/* 请求切换任务 */
xYieldRequired = pdTRUE;
}
else
{
}
/* 记录原优先级 */
uxPriorityUsedOnEntry = pxTCB->uxPriority;
#if (configUSE_MUTEXES == 1)
{
if(pxTCB->uxBasePriority == pxTCB->uxPriority)
{
pxTCB->uxPriority = uxNewPriority;
}
else
{
mtCOVERAGE_TEST_MARKER();
}
pxTCB->uxBasePriority = uxNewPriority;
}
#else
{
/* 设置新优先级 */
pxTCB->uxPriority = uxNewPriority;
}
#endif
/* 重新设置事件列表项的值 */
if((listGET_LIST_ITEM_VALUE(&(pxTCB->xEventListItem)) & taskEVENT_LIST_ITEM_VALUE_IN_USE) == 0UL)
{
listSET_LIST_ITEM_VALUE(&(pxTCB->xEventListItem), ((TickType_t)configMAX_PRIORITIES - (TickType_t)uxNewPriority));
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* 任务在就绪列表中 */
if(listIS_CONTAINED_WITHIN(&(pxReadyTasksLists[uxPriorityUsedOnEntry]), &(pxTCB->xStateListItem)) != pdFALSE)
{
/* 从原就绪列表中移除,就绪列表已经没有任务 */
if(uxListRemove(&(pxTCB->xStateListItem)) == (UBaseType_t)0)
{
/* 清除任务优先级记录中的优先级 */
portRESET_READY_PRIORITY(uxPriorityUsedOnEntry, uxTopReadyPriority);
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* 将任务加入新的就绪列表 */
prvAddTaskToReadyList(pxTCB);
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* 需要请求切换任务 */
if(xYieldRequired != pdFALSE)
{
taskYIELD_IF_USING_PREEMPTION();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
(void)uxPriorityUsedOnEntry;
}
}
taskEXIT_CRITICAL();
}
系统也提供了获取任务优先级的接口,程序比较简单
/* 获取任务优先级 */
UBaseType_t uxTaskPriorityGet(const TaskHandle_t xTask)
{
TCB_t const *pxTCB;
UBaseType_t uxReturn;
taskENTER_CRITICAL();
{
pxTCB = prvGetTCBFromHandle(xTask);
uxReturn = pxTCB->uxPriority;
}
taskEXIT_CRITICAL();
return uxReturn;
}
/* 在中断中获取任务优先级 */
UBaseType_t uxTaskPriorityGetFromISR(const TaskHandle_t xTask)
{
TCB_t const *pxTCB;
UBaseType_t uxReturn, uxSavedInterruptState;
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
uxSavedInterruptState = portSET_INTERRUPT_MASK_FROM_ISR();
{
pxTCB = prvGetTCBFromHandle(xTask);
uxReturn = pxTCB->uxPriority;
}
portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptState);
return uxReturn;
}