FreeRTOS的任务挂起和恢复

1.任务的挂起

c 复制代码
void vTaskSuspend( TaskHandle_t xTaskToSuspend )
	{
	TCB_t *pxTCB;

        /* 进入临界区 */
		taskENTER_CRITICAL();
		{
			/* If null is passed in here then it is the running task that is
			being suspended. */
			 /* 获取任务控制块,若为NULL则挂起自身 */
			pxTCB = prvGetTCBFromHandle( xTaskToSuspend );

			traceTASK_SUSPEND( pxTCB );

			/* Remove task from the ready/delayed list and place in the
			suspended list. */

			/*从就绪/延迟列表中删除任务 */
			if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
			{
				taskRESET_READY_PRIORITY( pxTCB->uxPriority );
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}

			/* Is the task waiting on an event also? */
			/*任务是否也在等待事件,从事件链表中删除*/
			if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
			{
				( void ) uxListRemove( &( pxTCB->xEventListItem ) );
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}
			/* 将任务放在挂起链表中 */
			vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xGenericListItem ) );
		}
		taskEXIT_CRITICAL();  /* 退出临界区 */

		if( pxTCB == pxCurrentTCB )  /*若刚挂起的是正在运行的任务 */
		{
			if( xSchedulerRunning != pdFALSE )  /* 调度器正常运行 */
			{
				/* The current task has just been suspended. */
				configASSERT( uxSchedulerSuspended == 0 );
				portYIELD_WITHIN_API();  /* 直接发起任务切换 */
			}
			else
			{
				/* The scheduler is not running, but the task that was pointed
				to by pxCurrentTCB has just been suspended and pxCurrentTCB
				must be adjusted to point to a different task. */
				 /* 若任务调度器没有开启,则读取当前任务挂起列表的长度,判断所有任务是否都被挂起*/
				if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks )
				{
					/* No other tasks are ready, so set pxCurrentTCB back to
					NULL so when the next task is created pxCurrentTCB will
					be set to point to it no matter what its relative priority
					is. */
					/*没有其他任务准备就绪,因此将pxCurrentTCB设置回NULL*/
					pxCurrentTCB = NULL;
				}
				else
				{
					/* 若还有没被挂起的任务,则获取下一个要运行的任务 */
					vTaskSwitchContext();
				}
			}
		}
		else
		{
			if( xSchedulerRunning != pdFALSE )  /* 调度器正常运行 */
			{
				/* A task other than the currently running task was suspended,
				reset the next expected unblock time in case it referred to the
				task that is now in the Suspended state. */
				taskENTER_CRITICAL();
				{
					prvResetNextTaskUnblockTime();  /* 重置下一个预期的解锁时间 */
				}
				taskEXIT_CRITICAL();
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}
		}
	}

2.任务的恢复

c 复制代码
	void vTaskResume( TaskHandle_t xTaskToResume )
	{
	TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume;

		/* It does not make sense to resume the calling task. */
		configASSERT( xTaskToResume );

		/* The parameter cannot be NULL as it is impossible to resume the
		currently executing task. */
		if( ( pxTCB != NULL ) && ( pxTCB != pxCurrentTCB ) )    /* 任务控制块不能为NULL和当前任务	*/
		{
			taskENTER_CRITICAL();
			{
				if( prvTaskIsTaskSuspended( pxTCB ) == pdTRUE )  /* 判断任务是否被挂起 */
				{
					traceTASK_RESUME( pxTCB );

					/* As we are in a critical section we can access the ready
					lists even if the scheduler is suspended. */
					( void ) uxListRemove(  &( pxTCB->xGenericListItem ) );  /* 从挂起列表中移除 */
					prvAddTaskToReadyList( pxTCB );   /* 添加到就绪列表中 */

					/* We may have just resumed a higher priority task. */
					if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )  /* 恢复的任务优先级更高 */
					{
						/* This yield may not cause the task just resumed to run,
						but will leave the lists in the correct state for the
						next yield. */
						taskYIELD_IF_USING_PREEMPTION();  /* 发起任务调度切换 */
					}
					else
					{
						mtCOVERAGE_TEST_MARKER();
					}
				}
				else
				{
					mtCOVERAGE_TEST_MARKER();
				}
			}
			taskEXIT_CRITICAL();
		}
		else
		{
			mtCOVERAGE_TEST_MARKER();
		}
	}
相关推荐
天昊吖8 分钟前
stc8H启用DMA发送后 卡住【踩坑日志】
单片机
李永奉15 分钟前
杰理芯片SDK开发-ENC双麦降噪配置/调试教程
人工智能·单片机·嵌入式硬件·物联网·语音识别
BackCatK Chen26 分钟前
第 1 篇:软件视角扫盲|TMC2240 软件核心特性 + 学习路径(附工具清单)
c语言·stm32·单片机·学习·电机驱动·保姆级教程·tmc2240
兆龙电子单片机设计26 分钟前
【STM32项目开源】STM32单片机多功能电子秤
stm32·单片机·开源·毕业设计·智能家居
切糕师学AI1 小时前
ARM 架构中的复位(Reset)与复位流程
arm开发·单片机·嵌入式·复位
wotaifuzao1 小时前
STM32多协议网关-FreeRTOS事件驱动架构实战
stm32·嵌入式硬件·can·freertos·uart·modbus·spi
llilian_161 小时前
信号发生器 多通道多功能脉冲信号发生器应用解决方案 多功能脉冲发生器
功能测试·单片机·嵌入式硬件·测试工具
yuanmenghao2 小时前
Classic AUTOSAR深入浅出系列 - 【第十六篇】MCAL:为什么 MCU 换了,上层几乎不用动
单片机·嵌入式硬件·autosar
MickyCode3 小时前
嵌入式开发调试之Traceback
arm开发·stm32·单片机·mcu
czwxkn4 小时前
3STM32(stdl)外部中断
stm32·单片机·嵌入式硬件