FreeRTOS任务挂起和恢复 API函数(二)

FreeRTOS学习


前言

有时候我们需要暂停某个任务的运行,过一段时间以后再重新运行。这个时候要是使用任
务删除和重建的方法的话那么任务中变量保存的值肯定丢失了!FreeRTOS 给我们提供了解决
这种问题的方法,那就是任务挂起和恢复,当某个任务要停止运行一段时间的话就将这个任务
挂起,当要重新运行这个任务的话就恢复这个任务的运行。

一起来看看吧!!!

一、函数

在这里插入图片描述
此函数用于将某个任务设置为挂起态,进入挂起态的任务永远都不会进入运行态。退出挂
起态的唯一方法就是调用任务恢复函数 vTaskResume()或 xTaskResumeFromISR()。,函数原型如
下:
1.函数 vTaskSuspend()

void vTaskSuspend( TaskHandle_t xTaskToSuspend)

参数:xTaskToSuspend为要挂起的任务的任务句柄
返回值:NULL
2.函数 vTaskResume()

void vTaskResume( TaskHandle_t xTaskToResume)

参数:xTaskToResume为要恢复的任务的任务句柄
返回值:NULL
3.函数 xTaskResumeFromISR()

BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume)

参数:xTaskToResume: 要恢复的任务的任务句柄。
返回值:
pdTRUE: 恢复运行的任务的任务优先级等于或者高于正在运行的任务(被中断打
断的任务),这意味着在退出中断服务函数以后必须进行一次上下文切换。
pdFALSE: 恢复运行的任务的任务优先级低于当前正在运行的任务(被中断打断的
任务),这意味着在退出中断服务函数的以后不需要进行上下文切换。

二、任务挂起和恢复实践

1.任务

在这里插入图片描述

2.主要代码

在这里插入图片描述
在这里插入图片描述

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "lcd.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);


int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//ÉèÖÃϵͳÖжÏÓÅÏȼ¶·Ö×é4	 
	delay_init();	    				//ÑÓʱº¯Êý³õʼ»¯	 
	uart_init(115200);					//³õʼ»¯´®¿Ú
	LED_Init();		  					//³õʼ»¯LED
	KEY_Init();							//³õʼ»¯°´¼ü
	EXTIX_Init();						//³õʼ»¯ÍⲿÖжÏ
//´´½¨¿ªÊ¼ÈÎÎñ
    xTaskCreate((TaskFunction_t )start_task,            //ÈÎÎñº¯Êý
                (const char*    )"start_task",          //ÈÎÎñÃû³Æ
                (uint16_t       )START_STK_SIZE,        //ÈÎÎñ¶ÑÕ»´óС
                (void*          )NULL,                  //´«µÝ¸øÈÎÎñº¯ÊýµÄ²ÎÊý
                (UBaseType_t    )START_TASK_PRIO,       //ÈÎÎñÓÅÏȼ¶
                (TaskHandle_t*  )&StartTask_Handler);   //ÈÎÎñ¾ä±ú              
    vTaskStartScheduler();          //¿ªÆôÈÎÎñµ÷¶È
}

//¿ªÊ¼ÈÎÎñÈÎÎñº¯Êý
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //½øÈëÁÙ½çÇø(²»ÄܽøÈëSysTickÖжÏ)
	//´´½¨KEYÈÎÎñ
	xTaskCreate((TaskFunction_t )key_task,             
                (const char*    )"key_task",           
                (uint16_t       )KEY_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )KEY_TASK_PRIO,        
                (TaskHandle_t*  )&KeyTask_Handler);  
    //´´½¨TASK1ÈÎÎñ
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //´´½¨TASK2ÈÎÎñ
    xTaskCreate((TaskFunction_t )task2_task,     
                (const char*    )"task2_task",   
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_TASK_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler); 
    vTaskDelete(StartTask_Handler); //ɾ³ý¿ªÊ¼ÈÎÎñ
    taskEXIT_CRITICAL();            //Í˳öÁÙ½çÇø
}

//keyÈÎÎñº¯Êý
void key_task(void *pvParameters)
{
	u8 key,statflag=0;
	while(1)
	{
		key=KEY_Scan(0);//»ñÈ¡°´¼üÖµ
		vTaskDelay(10);
		switch(key)
		{
			case WKUP_PRES:
				statflag=!statflag;
				if(statflag==1)
				{
					vTaskSuspend(Task1Task_Handler);//¹ÒÆðÈÎÎñ1,º¯Êý(¾ä±ú)
					printf("¹ÒÆðÈÎÎñ1µÄÔËÐÐ!\r\n");
				}
				else if(statflag==0)
				{
					vTaskResume(Task1Task_Handler);	//»Ö¸´ÈÎÎñ1£¬º¯Êý(¾ä±ú)
					printf("»Ö¸´ÈÎÎñ1µÄÔËÐÐ!\r\n");
				}		
				break;
			case KEY1_PRES:
				vTaskSuspend(Task2Task_Handler);//¹ÒÆðÈÎÎñ2
				printf("¹ÒÆðÈÎÎñ2µÄÔËÐÐ!\r\n");
				break;
			case KEY0_PRES:
			vTaskResume(Task2Task_Handler);//»Ö¸´ÈÎÎñ2
				printf("»Ö¸´ÈÎÎñ2µÄÔËÐÐ!\r\n");
			break;
		}
		vTaskDelay(10);			//ÑÓʱ10ms 
	}
}

//task1ÈÎÎñº¯Êý
void task1_task(void *pvParameters)
{
	u8 task1_num=0;
	while(1)
	{
		task1_num++;	//ÈÎÎñÖ´1ÐдÎÊý¼Ó1 ×¢Òâtask1_num1¼Óµ½255µÄʱºò»áÇåÁ㣡£¡
		LED0=!LED0;
		printf("ÈÎÎñ1ÒѾ­Ö´ÐУº%d´Î\r\n",task1_num);
    vTaskDelay(500);                          
	}
}

//task2ÈÎÎñº¯Êý
void task2_task(void *pvParameters)
{
	u8 task2_num=0;
	while(1)
	{
		vTaskDelayUntil();
		task2_num++;	//ÈÎÎñ2Ö´ÐдÎÊý¼Ó1 ×¢Òâtask1_num2¼Óµ½255µÄʱºò»áÇåÁ㣡£¡
    LED1=!LED1;
		printf("ÈÎÎñ2ÒѾ­Ö´ÐУº%d´Î\r\n",task2_num);
    vTaskDelay(500);                         
	}
}

总结

今天学习了FreeRTOS中任务的挂起与恢复以及其相关的函数使用方法。
继续加油!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值