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();
		}
	}
相关推荐
somi714 分钟前
ARM-06-时钟系统配置
arm开发·单片机·嵌入式硬件·时钟配置
爱喝纯牛奶的柠檬21 分钟前
基于STM32和HAL库的大夏龙雀BT311-10C02S蓝牙模块驱动
stm32·单片机·嵌入式硬件
小谦325141 分钟前
NTC热敏电阻分压测量电路的数学特性与应用选择研究
stm32·嵌入式硬件
Xueqian E2 小时前
驱动策略和效率的整理
stm32·单片机·嵌入式硬件
电子工程师成长日记-C513 小时前
51单片机气压检测仪
单片机·嵌入式硬件·51单片机
嵌入式老菜鸟qq1252427733 小时前
nRF54H20 + Zephyr 开发环境(二):烧录与踩坑实录
stm32·单片机·嵌入式硬件
-Try hard-3 小时前
ARM | 点亮LED灯!
arm开发·单片机·嵌入式硬件
llilian_164 小时前
卫星时钟 时钟同步解决方案——基于高精度卫星时钟同步授时装置 卫星同步时钟 授时同步装置
功能测试·单片机·测试工具
日更嵌入式的打工仔4 小时前
电机三环控制
单片机·嵌入式硬件
weixin_669545204 小时前
JT8166A/B电容式六按键触摸控制芯片,JT8166B具备IIC通信接口
人工智能·单片机·嵌入式硬件·硬件工程