FreeRTOS学习(三)任务的挂起和恢复(vTaskSuspend / vTaskResume)

0.开发环境

用ESP8266的FreeRTOS的开发环境做实验,打开msys2,输入cdsrc
FreeRTOS学习(三)任务的挂起和恢复(vTaskSuspend / vTaskResume)_第1张图片
从官方的示例文件复制一个GPIO的例子,编译一次(如何编译请看上一篇文章)
FreeRTOS学习(三)任务的挂起和恢复(vTaskSuspend / vTaskResume)_第2张图片
编译指令

make -j4 all flash monitor

1. 任务创建

//创建两个任务  函数            任务名         栈大小 参数 优先级   任务句柄
xTaskCreate(led_blink_task, "led_blink_task", 2048, NULL, 2, &led_blink_task_handle);
xTaskCreate(button_scan_task, "button_scan_task", 2048, NULL, 3,&button_scan_task_handle); //按键扫描优先级高于LED闪烁

2. GPIO

FreeRTOS学习(三)任务的挂起和恢复(vTaskSuspend / vTaskResume)_第3张图片
FreeRTOS学习(三)任务的挂起和恢复(vTaskSuspend / vTaskResume)_第4张图片

3.任务的挂起和恢复

任务的挂起和恢复函数很简单,传入需要挂起或者恢复的任务句柄就可以了

//挂起
void vTaskSuspend( TaskHandle_t xTaskToSuspend )
//恢复
void vTaskResume( TaskHandle_t xTaskToResume )

FreeRTOS学习(三)任务的挂起和恢复(vTaskSuspend / vTaskResume)_第5张图片
第一次运行发现bug,发现无法挂起和恢复,检查发现可能是任务句柄的问题,然后找到了任务创建的地方
FreeRTOS学习(三)任务的挂起和恢复(vTaskSuspend / vTaskResume)_第6张图片
任务句柄应该是传出参数,应取地址,否则函数内部修改的是副本
FreeRTOS学习(三)任务的挂起和恢复(vTaskSuspend / vTaskResume)_第7张图片

完整代码

#include 
#include 
#include 

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"

#include "driver/gpio.h"

#include "esp_log.h"
#include "esp_system.h"

#define LED_PIN 4
#define BUTTON_PIN 5

//任务句柄
TaskHandle_t led_blink_task_handle;
TaskHandle_t button_scan_task_handle;

//LED闪烁任务
void led_blink_task(){
    gpio_config_t io_conf;
    memset(&io_conf,0,sizeof(gpio_config_t));
    io_conf.mode = GPIO_MODE_OUTPUT;//设置为输出
    io_conf.pin_bit_mask = 1ULL<<LED_PIN;
    gpio_config(&io_conf);

    while (1)
    {
        //
        gpio_set_level(LED_PIN,1);
        vTaskDelay(300 / portTICK_RATE_MS);
        gpio_set_level(LED_PIN,0);
        vTaskDelay(300 / portTICK_RATE_MS);
    }
    
}

//按键扫描任务
void button_scan_task(){
    gpio_config_t io_conf;
    memset(&io_conf,0,sizeof(gpio_config_t));
    io_conf.mode = GPIO_MODE_INPUT;//设置为输入
    io_conf.pin_bit_mask = 1ULL<<BUTTON_PIN;
    io_conf.pull_up_en = 1;//上辣
    gpio_config(&io_conf);

    int isSuspend = 0;

    while (1)
    {
        if(gpio_get_level(BUTTON_PIN) == 0)
        {
            vTaskDelay(20 / portTICK_RATE_MS);//软件消除抖动
            if(gpio_get_level(BUTTON_PIN) == 0 )
            {
                
                if(isSuspend == 0)
                {
                        printf("vTaskSuspend\n");
                        vTaskSuspend(led_blink_task_handle);
                        isSuspend = 1;
                }
            }
        }
        else
        {
            vTaskDelay(20 / portTICK_RATE_MS);//软件消除抖动
            if(gpio_get_level(BUTTON_PIN) == 1)
            {
                //任务恢复
                if(isSuspend == 1)
                {
                        printf("vTaskResume\n");
                        vTaskResume(led_blink_task_handle);
                        isSuspend = 0;
                }
            }
        }
        vTaskDelay(20 / portTICK_RATE_MS);
    }
}



void app_main(void)
{
    printf("Helloworld\n");

    //创建两个任务  函数            任务名         栈大小 参数 优先级   任务句柄
    xTaskCreate(led_blink_task, "led_blink_task", 2048, NULL, 2, &led_blink_task_handle);
    xTaskCreate(button_scan_task, "button_scan_task", 2048, NULL, 3, &button_scan_task_handle); //按键扫描优先级高于LED闪烁

    while (1) {
        vTaskDelay(1000 / portTICK_RATE_MS);
    }
}

你可能感兴趣的:(RTOS,ESP,C语言)