FreeRTOS-任务挂起和恢复

一、任务挂起及恢复介绍

  • 任务挂起是指将某个任务从就绪态或运行态中移除,并将其置于挂起态,让它暂时不再参与调度,不分配CPU时间片,直到它被恢复
  • 挂起任务时,它会立即停止运行,直到该任务被显式恢复。挂起任务用于节省CPU资源防止某些任务在特定条件下继续执行

  挂起任务可以恢复,而删除任务无法恢复

  • 任务恢复是指将挂起的任务从挂起态恢复到就绪态,使其可以再次参与调度,并根据其优先级来决定何时运行
  • 任务恢复通常是在外部条件发生变化、或另一个条件ISR(中断服务程序)通知当前任务可以继续工作时使用
  • 下面是任务挂起和恢复的API函数
vTaskSuspend(TaskHandle_t xTaskToSuspend);//挂起任务,参数是待挂起任务句柄
vTaskResume(TaskHandle_t xTaskToResume);//恢复被挂起的任务,参数是待恢复任务句柄
BaseType_t vTaskResumeFromISR(TaskHandle_t xTaskToResume);//在中断中恢复被挂起的任务,参数是任务句柄//FromISR表示在中断函数中专用的API函数
  • 任务挂起操作时,需要将宏INCLUDE_vTaskSuspend配置为1,当传入参数为NULL,表示挂起任务自身
  • 任务恢复操作时,需要将宏INCLUDE_vTaskSuspend配置为1,无论任务被挂起多少次,调用一次vTaskResume()即可恢复,进入就绪态
  • 中断中恢复任务操作时,需要将宏INCLUDE_vTaskSuspendINCLUDE_xTaskResumeFromISR配置为1。返回值为pdTRUE:任务恢复后需要进行任务切换(恢复的任务优先级高)和pdFALSE:任务恢复后不需要进行任务切换,专用于中断服务函数中
  • 中断服务程序中要调用FreeRTOS的API函数时,中断优先级不能高于FreeRTOS所管理的最高优先级
  • 例:设置可调用FreeRTOS API的最高优先级为为4,且系统有8个可配置中断优先级,从0-7,数字越小,中断优先级越高,那么优先级4,5,6,7的中断可以调用API函数,0,1,2,3的中断不可以调用API函数

二、实战编程

  • 创建四个任务,Start_task(用来创建其他三个任务)、task1(LED0每500ms闪烁一次)、task2(LED1每500ms闪烁一次)、task3(KEY0按下,挂起task1,按下KEY1在任务中恢复task1)
#define configSUPPORT_DYNAMIC_ALLOCATION					1//动态创建任务宏定义配置
#define INCLUDE_vTaskSuspend								1//挂起/恢复任务宏定义配置

//start_task参数宏定义
#define	START_TASK_STACK_SIZE 								128//堆栈大小
#define	START_TASK_PRIO										1//任务优先级
TaskHandle_t	start_task_handle;							//任务句柄
//task1参数宏定义
#define	TASK1_STACK_SIZE 									128//堆栈大小
#define	TASK1_PRIO											2//任务优先级
TaskHandle_t	task1_handle;								//任务句柄
//task2参数宏定义
#define	TASK2_STACK_SIZE 									128//堆栈大小
#define	TASK2_PRIO											3//任务优先级
TaskHandle_t	task2_handle;								//任务句柄
//task3参数宏定义
#define	TASK3_STACK_SIZE 									128//堆栈大小
#define	TASK3_PRIO											4//任务优先级
TaskHandle_t	task3_handle;								//任务句柄


//task1任务函数:LED0每500ms闪烁一次
void task1( void * pvParameters )
{
		while(1)
		{
			LED0_Turn();//LED0反转
			vTaskDelay(500);//自带延时函数
		}
}
//task2任务函数:LED1每500ms闪烁一次
void task2( void * pvParameters )
{
		while(1)
		{
			LED0_Turn();//LED1反转
			vTaskDelay(500);//自带延时函数
		}
}
//task3任务函数:判断按键按下,KEY0按下挂起task1,KEY1按下恢复task1
void task3( void * pvParameters )
{
		uint8_t KeyNum = 0;
		while(1)
		{
			KeyNum = Key_GetNum();//获取按键键码
			if(KeyNum == 0)//KEY0按下
			{
				vTaskSuspend(task1_handle);//挂起task1
			}
			else if(KeyNum == 1)//KEY1按下
			{
				vTaskResume(task1_handle);//恢复task1
			}
			vTaskDelay(10);//延时10ms,给了task1和task2机会
		}
}
//Start_task任务函数
void Start_task( void * pvParameters )
{
		taskENTER_CRITICAL();//进入临界区
		//创建任务1
		xTaskCreate(task1,//任务函数
					"task1",//任务名称
					TASK1_STACK_SIZE,//堆栈大小/字
					NULL,//入口参数没有
					TASK1_PRIO,//优先级
					&task1_handle//任务句柄
					);
		//创建任务2
		xTaskCreate(task2,//任务函数
					"task2",//任务名称
					TASK2_STACK_SIZE,//堆栈大小/字
					NULL,//入口参数没有
					TASK2_PRIO,//优先级
					&task2_handle//句柄
					);
		//创建任务3
		xTaskCreate(task3,//任务函数
					"task3",//任务名称
					TASK3_STACK_SIZE,//堆栈大小/字
					NULL,//入口参数没有
					TASK3_PRIO,//优先级
					&task3_handle//句柄
					);
		vTaskDelete(start_task_handle);
		//删除自身任务Start_task,start_task_handle或NULL都可以
		taskEXIT_CRITICAL();//退出临界区
}

//FreeRTOS入口函数,程序从此处开始执行
void freertos_demo()
{
		xTaskCreate(Start_task,//任务函数
					"Start_task",//任务名称
					START_TASK_STACK_SIZE,//堆栈大小/字
					NULL,//入口参数没有
					START_TASK_PRIO,//优先级
					&start_task_handle//句柄
					);//创建Start任务
		vTaskStartScheduler();//开启任务调度器,开启执行Start任务,创建task123
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值