[uCOS/RTOS]freertos——任务的挂起与恢复(二)

文章介绍了FreeRTOS操作系统中如何通过vTaskSuspend和vTaskResume函数来实现任务的挂起和恢复,从而控制任务的执行和暂停,特别是在需要临时停止某任务而又不丢失其状态的情况下。文中提供了代码示例,展示了如何在C语言中使用这些函数来管理任务的运行状态。
摘要由CSDN通过智能技术生成

 # FreeRTOS操作系统学习

# 前言

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

# 一、任务挂起与恢复
API函数:

vTaskSuspend():

挂起一个任务。
此函数用于将某个任务设置为挂起态,进入挂起态的任务永远都不会进入运行态。退出挂
起态的唯一方法就是调用任务恢复函数 vTaskResume()或 xTaskResumeFromISR()。函数原型

```c
void vTaskSuspend( 任务句柄)
```

vTaskResume() 恢复一个任务的运行。

xTaskResumeFromISR() 中断服务函数中恢复一个任务的运行。
挂起后处于挂起态。

# 二、任务挂起与恢复
## 1.代码实战








代码如下,注释在图片里



```c
#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)
        {
                task2_num++;        //ÈÎÎñ2Ö´ÐдÎÊý¼Ó1 ×¢Òâtask1_num2¼Óµ½255µÄʱºò»áÇåÁ㣡£¡
    LED1=!LED1;
                printf("ÈÎÎñ2ÒѾ­Ö´ÐУº%d´Î\r\n",task2_num);
    vTaskDelay(500);                        
        }
}


```

# 总结
在FreeRTOS中任务的挂起与恢复,掌握挂起函数与恢复函数的使用。

实验报告三:(1)设计 Task0、Task1 两个任务任务 Task0 不断地挂起自己,再被任务 Task1 解挂,两个任务不断地切换执行,并输出两个任务在各个时刻的状态。Task0 的主要功能是显示 Task1 的状态,Task1 的主要功能是显示 Task0 的状态。整个应用的运行流程如图 1 所示,其描述如下:在 main 函数创建起始任务 TaskStart,其优先级为 0。TaskStart 任务主要完成创建 2 个应用任务 Task0、Task1,并挂起自己(不再被其它任务唤醒)。之后整个系统的运行流程如下:t1 时刻,Task0 开始执行,它运行到 t2 时刻挂起自己;t2 时刻,系统调度处于就绪状态的优先级最高任务 Task1 执行,它在 t3 时刻唤醒 Task0,后者由于优先级较高而抢占 CPU;Task0 执行到 t4 时刻又挂起自己,内核调度 Task1执行;Task1 运行至 t5 时刻再度唤醒 Task0; 注意:图中的栅格并不代表严格的时间刻度,而仅仅表现各任务启动和执行的相对先后关系。 (2)设计 MyTask、YouTask、KeyTask 三个任务:MyTask 任务输出 M;YouTask 任务输出 Y,并输出 MyTask 任务的状态;KeyTask 任务从键盘接收字符 Y 或 N,当接收 Y 时挂起 MyTask 任务,当接收 N 时恢复 MyTask 任务。 (3)设计 KeyTask 任务,当从键盘输入+号时动态创建任务,最多可以创建 10 个任务,这 10个任务都执行一个函数 MyTask,要求优先级是(PRIO_BASE+0,1,2,3,4,5,6,7,8,9),还要向不同的任务传递不同的参数(0,1,2,3,4,5,6,7,8,9)给 MyTask 函数,优先级为(PRIO_BASE+0,1,2,3,4,5,6,7,8,9)的任务分别输出数字(0,1,2,3,4,5,6,7,8,9)。当从键盘输入-号时动态的删除刚创建的一个任务,最多可删除 10 个任务。提示:多个任务可以执行一个函数。运行结果如下图所示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值