0.开发环境
用ESP8266的FreeRTOS的开发环境做实验,打开msys2,输入cdsrc
从官方的示例文件复制一个GPIO的例子,编译一次(如何编译请看上一篇文章)
编译指令
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
3.任务的挂起和恢复
任务的挂起和恢复函数很简单,传入需要挂起或者恢复的任务句柄就可以了
//挂起
void vTaskSuspend( TaskHandle_t xTaskToSuspend )
//恢复
void vTaskResume( TaskHandle_t xTaskToResume )
第一次运行发现bug,发现无法挂起和恢复,检查发现可能是任务句柄的问题,然后找到了任务创建的地方
任务句柄应该是传出参数,应取地址,否则函数内部修改的是副本
完整代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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);
}
}