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();
		}
	}
相关推荐
清风6666667 小时前
基于单片机与DAC0832的双路波形信号发生系统设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
azwsm8 小时前
电路元器件和GPIO控制器
单片机·嵌入式硬件
kebidaixu11 小时前
FreeRTOS 移植到 STM32F407VETX 记录(一)
stm32·单片机·嵌入式硬件
半条-咸鱼12 小时前
【INACCESSIBLE_BOOT_DEVICE】安装 Config Tool 后 Windows 蓝屏,最终通过 VMware 虚拟机解决
windows·stm32·vmware·芯片
点灯小铭12 小时前
基于单片机的数码管定时插座设计与定时开关功能实现
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
数智工坊14 小时前
机器人四大主控板系统分层选型指南:树莓派、ESP32、STM32与Arduino的能力边界与实战定位
stm32·嵌入式硬件·机器人
某林21215 小时前
跨越底层与AI的鸿沟:ROS2+多模态大模型(Qwen-VL)机器人全链路排障实录
人工智能·stm32·机器人·人机交互·ros2·技术复盘
点灯小铭15 小时前
基于单片机的多模式智能洗衣机设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
项目題供诗15 小时前
STM32-AD单通道&AD多通道(十九)
stm32·单片机·嵌入式硬件
南岸的水16 小时前
BMS国标充电解析
单片机·嵌入式硬件·mcu