飞书文档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);}
}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/82086.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/82086.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/82086.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Git] 如何进行版本回退

版本控制系统最重要的能力之一&#xff0c;就是能够轻松地在项目的不同历史版本之间切换。有时&#xff0c;你可能发现最近的修改引入了严重问题&#xff0c;或者需要回到之前的某个节点重新开始。这时&#xff0c;“版本回退”功能就派上用场了。 版本回退&#xff1a;反方向…

易贝平台关键字搜索技术深度解析

一、核心搜索机制 关键词匹配原理 采用TF-IDF算法计算关键词权重 支持同义词扩展&#xff08;如"phone"匹配"cellphone"&#xff09; 标题权重 > 副标题 > 商品描述 搜索排序因素 # 搜索权重模拟计算 def calculate_rank(keyword, item): title…

深度剖析 MCP SDK 最新版:Streamable HTTP 模式

好记忆不如烂笔头&#xff0c;能记下点东西&#xff0c;就记下点&#xff0c;有时间拿出来看看&#xff0c;也会发觉不一样的感受. 目录 一、概述 二、快速上手&#xff1a;开启 Streamable HTTP 服务端开启 客户端连接 三、深入两个核心参数 stateless_http json_resp…

树莓派开箱上手教程(无需显示器版)

树莓派开箱上手教程&#xff08;无需显示器版&#xff09; 硬件准备 名称参数电源适配器5V电源适配器&#xff0c;至少需要3A的额定电流&#xff0c;配备USB Type-C输出接头microSD卡用来将树莓派的操作系统安装到上边&#xff0c;至少需要8GB容量&#xff0c;一般建议16GB及以…

MySQL强化关键_015_存储过程

目 录 一、概述 1.说明 2.优点 3.缺点 二、存储过程的操作 1.创建 2.调用 3.查看 4.删除 三、变量 1.系统变量 &#xff08;1&#xff09;说明 &#xff08;2&#xff09;查看系统变量 &#xff08;3&#xff09;设置系统变量 2.用户变量 &#xff08;1&…

动态规划dp

这里写目录标题 动态规划01背包完全背包多重背包混合背包二维费用的背包分组背包有依赖的背包背包问题求方案数背包问题求具体方案数位 DP状压 DP常用例题 动态规划 01背包 有 n n n 件物品和一个容量为 W W W 的背包&#xff0c;第 i i i 件物品的体积为 w [ i ] w[i] w…

arcgis js统计FeatureLayer的椭球面积、平面面积

1、导入依赖 import FeatureLayer from arcgis/core/layers/FeatureLayer import { geodesicArea, planarArea, simplify } from arcgis/core/geometry/geometryEngine; import { project, load as projectionLoad } from arcgis/core/geometry/projection2、初始化project o…

2.2.1 05年T2

引言 本文将从一预习、二自习、三学习、四复习等四个阶段来分析2005年考研英语阅读第二篇文章。为了便于后续阅读&#xff0c;我将第四部分复习放在了首位。 四、复习 方法&#xff1a;错误思路分析总结考点文章梳理 4.1 错题分析 题目&#xff1a;26&#xff08;细节题&…

Java 连接并操作 Redis 万字详解:从 Jedis 直连到 RedisTemplate 封装,5 种方式全解析

引言 在分布式系统和高并发场景中&#xff0c;Redis 作为高性能内存数据库的地位举足轻重。对于 Java 开发者而言&#xff0c;掌握 Redis 的连接与操作是进阶必备技能。然而&#xff0c;从基础的 Jedis 原生客户端到 Spring 封装的 RedisTemplate&#xff0c;不同连接方式的原…

谈谈对《加密算法》的理解

文章目录 一、什么是加密算法&#xff1f;二、常见的加密算法有哪些&#xff1f;2.1 对称加密2.2 非对称加密2.3 哈希算法 三、加密算法代码展示3.1 MD5加密3.2 秘钥加密3.3 AES加密解密 四、加密算法的使用场景 一、什么是加密算法&#xff1f; 加密算法是一种通过数学方法将…

Fuzz 模糊测试篇JS 算法口令隐藏参数盲 Payload未知文件目录

1 、 Fuzz 是一种基于黑盒的自动化软件模糊测试技术 , 简单的说一种懒惰且暴力的技术融合了常见 的以及精心构建的数据文本进行网站、软件安全性测试。 2 、 Fuzz 的核心思想 : 口令 Fuzz( 弱口令 ) 目录 Fuzz( 漏洞点 ) 参数 Fuzz( 利用参数 ) PayloadFuzz(Bypass)…

哈希表的实现(下)

目录 前言 开散列概念 开散列实现 Insert 优化 Find Erase 前言 上一章节我们用闭散列实现了一下哈希表&#xff0c;但存在一些问题&#xff0c;比如空间浪费比较严重&#xff0c;如果连续一段空间都已经存放值&#xff0c;那么在此位置插入新值的时候就会一直挪动&…

再谈Linux 进程:进程等待、进程替换与环境变量

目录 1.进程等待 为什么需要进程等待&#xff1f; 相关系统调用&#xff1a;wait()和waitpid() wait(): waitpid(): 解析子进程状态&#xff08;status&#xff09; 2.进程替换 为什么需要进程替换&#xff1f; 相关系统调用&#xff1a;exec函数家族 3.环境变量 ​…

基于深度学习的无线电调制识别系统

基于深度学习的无线电调制识别系统 本项目实现了一个基于深度学习的无线电调制识别系统&#xff0c;使用LSTM&#xff08;长短期记忆网络&#xff09;模型对不同类型的 无线电信号进行自动分类识别。该系统能够在不同信噪比(SNR)条件下&#xff0c;准确识别多种调制类型&#…

Python 爬虫之requests 模块的应用

requests 是用 python 语言编写的一个开源的HTTP库&#xff0c;可以通过 requests 库编写 python 代码发送网络请求&#xff0c;其简单易用&#xff0c;是编写爬虫程序时必知必会的一个模块。 requests 模块的作用 发送网络请求&#xff0c;获取响应数据。 中文文档&#xf…

随机森林(Random Forest)学习

随机森林是一种基于集成学习的机器学习算法&#xff0c;属于Bagging&#xff08;Bootstrap Aggregating&#xff09;方法的一种扩展。它通过组合多个决策树来提升模型的泛化能力和鲁棒性&#xff0c;广泛用于分类、回归和特征选择任务。 1.随机森林核心思想 1.1少数服从多数 在…

从 0 到 1!Java 并发编程基础全解析,零基础入门必看!

写在前面 博主在之前写了很多关于并发编程深入理解的系列文章&#xff0c;有博友反馈说对博主的文章表示非常有收获但是对作者文章的某些基础描述有些模糊&#xff0c;所以博主再根据最能接触到的基础&#xff0c;为这类博友进行扫盲&#xff01;当然&#xff0c;后续仍然会接…

el-input宽度自适应方法总结

使用 style 或 class 直接设置宽度 可以通过内联样式或 CSS 类来直接设置 el-input 的宽度为 100%&#xff0c;使其自适应父容器的宽度 <template><div style"width: 100%;"><el-input style"width: 100%;" v-model"input">…

解决 Supabase “permission denied for table XXX“ 错误

解决 Supabase “permission denied for table” 错误 问题描述 在使用 Supabase 开发应用时&#xff0c;你可能会遇到以下错误&#xff1a; [Nest] ERROR [ExceptionsHandler] Object(4) {code: 42501,details: null,hint: null,message: permission denied for table user…

java每日精进 5.20【MyBatis 联表分页查询】

1. MyBatis XML 实现分页查询 1.1 实现方式 MyBatis XML 是一种传统的 MyBatis 使用方式&#xff0c;通过在 XML 文件中编写 SQL 语句&#xff0c;并结合 Mapper 接口和 Service 层实现分页查询。分页需要手动编写两条 SQL 语句&#xff1a;一条查询分页数据列表&#xff0c;…