FreeRTOS任务挂起和恢复

任务挂起:暂停某个任务的执行
任务恢复:让暂停的任务继续执行
通过任务挂起和恢复,可以达到让任务停止一段时间后重新运行。
相关API函数:
在这里插入图片描述

vTaskSuspend
void vTaskSuspend( TaskHandle_t xTaskToSuspend );
  • xTaskToSuspend :要挂起任务的任务句柄,如果使用函数xTaskCreate创建任务的话,xTaskCreate的参数pxCreatedTask就是此任务的任务句柄,如果使用xTaskCreateStatic创建任务,那么函数的返回值就是此任务的任务句柄。
vTaskResume
void vTaskResume( TaskHandle_t xTaskToResume ) ;
  • xTaskToResume :要恢复的任务的任务句柄

将一个任务从挂起态恢复到就绪态,只有通过vTaskSuspend设置为挂起态的任务才可以使用vTaskResume恢复

xTaskResumeFromISR
BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) ;

此函数是vTaskResume的中断版本,用于在中断服务函数中恢复一个任务
返回值:

  • pdTRUE:恢复运行的任务的任务优先级等于或者高于正在运行的任务(被中断打断的任务)
  • pdFALSE:恢复运行的任务的任务优先级低于当前运行的任务(被中断打断的任务)
实验程序设计
  • start_task:用来创建其他三个任务
  • key_task:按键服务函数,检测按键的按下结果,根据不同的按键结果执行不同的操作
  • task1_task:应用任务1
  • task2_task:应用任务2

具体代码:
start_task:

void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();		//进入临界区
	xTaskCreate(key_task,"key_task",KEY_STK_SIZE,NULL,KEY_TASK_PRIO,&KeyTask_Handler);
	xTaskCreate(task1_task,"task1_task",TASK1_STK_SIZE,NULL,TASK1_TASK_PRIO,&Task1Task_Handler);
	xTaskCreate(task2_task,"task2_task",TASK2_STK_SIZE,NULL,TASK2_TASK_PRIO,&Task2Task_Handler);
	taskEXIT_CRITICAL();		//退出临界区
	vTaskDelete(StartTask_Handler);	//删除任务
}

key_task:

void key_task(void *pvParameters)
{
	u8 key;
	while(1)
	{
		key=KEY_Scan(0);
		switch(key)
		{

			case WKUP_PRES:
				vTaskSuspend(Task1Task_Handler);	//挂起任务1
				break;
			case KEY0_PRES:
				vTaskResume(Task1Task_Handler);	//恢复任务1
				break;
			case KEY1_PRES:
				vTaskSuspend(Task2Task_Handler);
				break;
			case KEY2_PRES:
				vTaskResume(Task2Task_Handler);
				break;		
			
		}
		vTaskDelay(10);	//延迟10ms
	}
	
}

task1_task:

//task1任务函数
void task1_task(void *pvParameters)
{
	u8 task1_num=0;
	
	POINT_COLOR = BLACK;

	LCD_DrawRectangle(5,110,115,314); 	//画一个矩形	
	LCD_DrawLine(5,130,115,130);		//画线
	POINT_COLOR = BLUE;
	LCD_ShowString(6,111,110,16,16,"Task1 Run:000");
	while(1)
	{
		task1_num++;	//任务执1行次数加1 注意task1_num1加到255的时候会清零!!
		LED0=!LED0;
		LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]); //填充区域
		LCD_ShowxNum(86,111,task1_num,3,16,0x80);	//显示任务执行次数
        vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍	
	}
}

task2_task

//task2任务函数
void task2_task(void *pvParameters)
{
	u8 task2_num=0;
	
	POINT_COLOR = BLACK;

	LCD_DrawRectangle(125,110,234,314); //画一个矩形	
	LCD_DrawLine(125,130,234,130);		//画线
	POINT_COLOR = BLUE;
	LCD_ShowString(126,111,110,16,16,"Task2 Run:000");
	while(1)
	{
		task2_num++;	//任务2执行次数加1 注意task1_num2加到255的时候会清零!!
        LED1=!LED1;
		//printf("任务2已经执行:%d次\r\n",task2_num);
		LCD_ShowxNum(206,111,task2_num,3,16,0x80);  //显示任务执行次数
		LCD_Fill(126,131,233,313,lcd_discolor[13-task2_num%14]); //填充区域
        vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍	
	}
}

main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "sdram.h"
#include "key.h"
#include "exti.h"
#include "FreeRTOS.h"
#include "task.h"


//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define KEY_TASK_PRIO		2
//任务堆栈大小	
#define KEY_STK_SIZE 		128  
//任务句柄
TaskHandle_t KeyTask_Handler;
//任务函数
void key_task(void *pvParameters);

//任务优先级
#define TASK1_TASK_PRIO		3
//任务堆栈大小	
#define TASK1_STK_SIZE 		128  
//任务句柄
TaskHandle_t Task1Task_Handler;
//任务函数
void task1_task(void *pvParameters);

//任务优先级
#define TASK2_TASK_PRIO		4
//任务堆栈大小	
#define TASK2_STK_SIZE 		128  
//任务句柄
TaskHandle_t Task2Task_Handler;
//任务函数
void task2_task(void *pvParameters);

//LCD刷屏时使用的颜色
int lcd_discolor[14]={	WHITE, BLACK, BLUE,  BRED,      
						GRED,  GBLUE, RED,   MAGENTA,       	 
						GREEN, CYAN,  YELLOW,BROWN, 			
						BRRED, GRAY };

int main(void)
{
    HAL_Init();                     //初始化HAL库   
    Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz
	delay_init(180);                //初始化延时函数
	uart_init(115200);              //初始化串口
    LED_Init();                     //初始化LED 
	KEY_Init();						//初始化按键
	SDRAM_Init();					//初始化SDRAM
	LCD_Init();						//初始化LCD
	
	POINT_COLOR = RED;
	LCD_ShowString(30,10,200,16,16,"Apollo STM32F4/F7");	
	LCD_ShowString(30,30,200,16,16,"FreeRTOS Examp 6-3");
	LCD_ShowString(30,50,200,16,16,"Task Susp and Resum");
	//LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");
	LCD_ShowString(30,90,200,16,16,"2021/11/21");
	xTaskCreate(start_task,"start_task",START_STK_SIZE,NULL,START_TASK_PRIO,&StartTask_Handler);
	vTaskStartScheduler();	//开启粪污调度
	
     
}

void start_task(void *pvParameters)
{
	taskENTER_CRITICAL();		//进入临界区
	xTaskCreate(key_task,"key_task",KEY_STK_SIZE,NULL,KEY_TASK_PRIO,&KeyTask_Handler);
	xTaskCreate(task1_task,"task1_task",TASK1_STK_SIZE,NULL,TASK1_TASK_PRIO,&Task1Task_Handler);
	xTaskCreate(task2_task,"task2_task",TASK2_STK_SIZE,NULL,TASK2_TASK_PRIO,&Task2Task_Handler);
	taskEXIT_CRITICAL();		//退出临界区
	vTaskDelete(StartTask_Handler);	//删除任务
}

void key_task(void *pvParameters)
{
	u8 key;
	while(1)
	{
		key=KEY_Scan(0);
		switch(key)
		{

			case WKUP_PRES:
				vTaskSuspend(Task1Task_Handler);	//挂起任务1
				break;
			case KEY0_PRES:
				vTaskResume(Task1Task_Handler);	//恢复任务1
				break;
			case KEY1_PRES:
				vTaskSuspend(Task2Task_Handler);
				break;
			case KEY2_PRES:
				vTaskResume(Task2Task_Handler);
				break;		
			
		}
		vTaskDelay(10);	//延迟10ms
	}
	
}

//task1任务函数
void task1_task(void *pvParameters)
{
	u8 task1_num=0;
	
	POINT_COLOR = BLACK;

	LCD_DrawRectangle(5,110,115,314); 	//画一个矩形	
	LCD_DrawLine(5,130,115,130);		//画线
	POINT_COLOR = BLUE;
	LCD_ShowString(6,111,110,16,16,"Task1 Run:000");
	while(1)
	{
		task1_num++;	//任务执1行次数加1 注意task1_num1加到255的时候会清零!!
		LED0=!LED0;
		LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]); //填充区域
		LCD_ShowxNum(86,111,task1_num,3,16,0x80);	//显示任务执行次数
        vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍	
	}
}

//task2任务函数
void task2_task(void *pvParameters)
{
	u8 task2_num=0;
	
	POINT_COLOR = BLACK;

	LCD_DrawRectangle(125,110,234,314); //画一个矩形	
	LCD_DrawLine(125,130,234,130);		//画线
	POINT_COLOR = BLUE;
	LCD_ShowString(126,111,110,16,16,"Task2 Run:000");
	while(1)
	{
		task2_num++;	//任务2执行次数加1 注意task1_num2加到255的时候会清零!!
        LED1=!LED1;
		//printf("任务2已经执行:%d次\r\n",task2_num);
		LCD_ShowxNum(206,111,task2_num,3,16,0x80);  //显示任务执行次数
		LCD_Fill(126,131,233,313,lcd_discolor[13-task2_num%14]); //填充区域
        vTaskDelay(1000);                           //延时1s,也就是1000个时钟节拍	
	}
}



编译即可

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值