当前位置: 首页 > news >正文

SOC-ESP32S3部分:11-任务创建

飞书文档https://x509p6c8to.feishu.cn/wiki/EH3owsPahisvl6kL6k3cqaQ3n0g  在我们学习单片机的时候,main函数入口中一般有一个while大循环在不停轮询,如果我们需要实现多种不同的业务,就需要用到状态机,根据不同时刻的要求执行不同的代码,虽然可以实现需求,但这种情况下代码是比较臃肿的。试想下,如果我们可以开启多个while循环,每个while循环负责不同的业务,这样实现复杂的业务是不是更容易了呢?

void main1(){while (1){//执行某些操作}
}void main2(){while (1){//执行某些操作}
}

在 FreeRTOS 中,任务(Task) 可以通俗地理解为一个独立的“小程序”或“小工人”,每个任务都有自己的工作内容和优先级,它们共同协作完成整个系统的功能。

1、任务是什么?

任务是一个独立的执行单元

每个任务就像一个小工人,负责完成特定的工作。例如:

  • 一个任务负责读取传感器数据。
  • 一个任务负责控制 LED 灯。
  • 一个任务负责处理网络通信。

任务有自己的运行空间

每个任务都有自己的栈(Stack),用于存储临时变量和函数调用信息。任务之间是相互独立的,不会互相干扰。

任务可以同时运行

虽然 ESP32 是单核或双核处理器,但 FreeRTOS 通过快速切换任务,让多个任务看起来像是同时运行的(这叫做“并发”)。

假设我们有一个智能家居系统,需要完成以下功能:

  • 读取温度传感器的数据。
  • 根据温度控制风扇的开关。
  • 将温度数据发送到云端。

我们可以创建 3 个任务:

任务 1:读取温度
每隔 1 秒读取一次温度传感器的数据,并将数据发送到队列中。
任务 2:控制风扇
从队列中读取温度数据,如果温度超过 30°C,打开风扇;否则关闭风扇。
任务 3:上传数据
从队列中读取温度数据,并通过 Wi-Fi 上传到云端。

2、如何实现多任务?

IDF默认是集成了实时操作系统FreeRTOS的,所以FreeRTOS相关接口我们都是可以用的。

但是需要注意的是,IDF的例程中,是不会单独对FreeRTOS通用的任务创建、任务通信等RTOS相关特性进行讲解,这部分我们可以参考FreeRTOS官方文档或者IDF API文档进行了解。

IDF freertos api :https://docs.espressif.com/projects/esp-idf/zh_CN/v5.4/esp32s3/api-reference/system/freertos_idf.html

freertos 官方api:https://www.freertos.org/zh-cn-cmn-s/Documentation/02-Kernel/04-API-references/01-Task-creation/01-xTaskCreate

那这节课,我们就来了解下FreeRTOS的多任务实现。

头文件
#include "freertos/task.h"BaseType_t xTaskCreate(TaskFunction_t pxTaskCode,const char *const pcName,const configSTACK_DEPTH_TYPE usStackDepth,void *const pvParameters,UBaseType_t uxPriority,TaskHandle_t *const pxCreatedTask
);
功能: xTaskCreate 函数用于创建一个新的 FreeRTOS 任务。该函数分配任务所需的内存,并初始化任务控制块(TCB),然后将任务添加到就绪列表中,等待调度器运行该任务。
参数:
pxTaskCode: 指向任务函数的指针。任务函数的原型必须为 void TaskFunction(void *pvParameters)。
pcName: 任务的名称,用于调试和日志记录。长度不能超过 configMAX_TASK_NAME_LEN 个字符。
usStackDepth: 任务堆栈的大小,以字为单位
pvParameters: 传递给任务函数的参数。
uxPriority: 任务的优先级。优先级值越高,任务的优先级越高。优先级值的范围通常是 0 到 configMAX_PRIORITIES - 1。
pxCreatedTask: 用于存储新创建任务的句柄。如果不需要任务句柄,可以传递 NULL。
返回值:
pdPASS: 任务创建成功。

如下方例程,我们在app_main中创建了两个任务task1和task2,创建成功后,我们可以看到app_main、task1、task2间隔运行的效果。

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"static const char *TAG = "MyModule";static void task1_func(void *arg)
{while (1){ESP_LOGI(TAG, "task1 run");vTaskDelay(1000 / portTICK_PERIOD_MS);}
}static void task2_func(void *arg)
{while (1){ESP_LOGI(TAG, "task2 run");vTaskDelay(1000 / portTICK_PERIOD_MS);}
}void app_main(void)
{// 创建任务,任务堆栈大小为 2048 字,优先级为 5xTaskCreate(task1_func,    // 任务函数"task1_name",  // 任务名称2048,          // 堆栈大小(字)NULL,          // 传递给任务的参数5,             // 任务优先级NULL           // 任务句柄);xTaskCreate(task2_func,    // 任务函数"task2_name",  // 任务名称2048,          // 堆栈大小(字)NULL,          // 传递给任务的参数5,             // 任务优先级NULL           // 任务句柄);int cnt = 0;while (1){ESP_LOGI(TAG, "app_main run: %d", cnt++);vTaskDelay(1000 / portTICK_PERIOD_MS);}
}

编译烧录后,运行效果如下:

相关文章:

  • 基于亚博K210开发板——lvgl 图形化实验
  • ubuntu ollama /Dify/Docker部署大模型
  • 刷题 | 牛客 - js中等题-下(更ing)30/54知识点解答
  • 多态的总结
  • 【C语言】习题练手套餐 2
  • 在WPF程序中设置背景图片
  • 深度解析NL2SQL:从语义理解到工程实践的全链路探索
  • 向量数据库Milvus03-高级功能与性能调优
  • 探索产品经理的MVP:从概念到实践
  • AVL树简介与部分实现
  • 基于pycharm,python,flask,sklearn,orm,mysql,在线深度学习sql语句检测系统
  • Microsoft.ClearScript.V8单例模式封装,方便下次使用。
  • web常见的攻击方式有哪些?如何防御?
  • JVM学习(四)--对象内存布局
  • Vue3性能优化: 大规模列表渲染解决方案
  • CUDA 性能优化 | 共享内存机制 / 向量化访存策略
  • 一个开源的 Blazor 跨平台入门级实战项目
  • Baklib内容中台的主要构成是什么?
  • vscode | Trae【实用插件】Remove empty lines 保存文件时删除空行
  • MQTT-共享订阅
  • 至高建设集团 网站/网站seo快速优化
  • 点图片跳到网站怎么做的/搜索软件
  • 华为手机开发者模式怎么关闭/文山seo公司
  • 建站之星如何建网站/自己怎么优化网站排名
  • 网站建设面对的问题/宁波seo哪家好快速推广
  • 做网站用百度百科的资料会侵权吗/苏州整站优化