FreeRTOS任务优先级

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;
}

猜你喜欢

转载自blog.csdn.net/lushoumin/article/details/88062224