【ESP32】arduino中的ESP32实时系统FreeRTOS使用教程(一)

2023-05-16

ESP32 FreeRTOS

    • 任务的状态
    • 任务的优先级
  • 创建任务
  • 传递给任务函数的参数
  • 结构体多参数传递
  • 互斥量Mutex
  • ESP32的双核心
  • 固定频率运行任务
  • 软件定时器

简单的本节略过,详细的可以看视频:单片机ESP32上的FREERTOS这个作者讲的挺好的,通俗易懂

任务的状态

FreeRTOS中的任务有运行态、就绪态、阻塞态、挂起态四种状态,在任何时候都只处于其中一种状态。任务状态之间的转换如下图所示:
在这里插入图片描述

任务的优先级

每一个任务都会有一个任务优先级,其范围为 0 (configMAX_PRIORITIES - 1),0优先级最低,(configMAX_PRIORITIES - 1)优先级最大,通常空闲任务的优先级最低,为0。

创建任务

使用动态的方法创建一个任务:


void setup() {
	xTaskCreate(task1, 		//任务函数
	            "task1",    //任务名字
	            4096,       //任务堆栈大小
		        NULL,		//传递给任务函数的参数
	            5,          //任务优先级
	            NULL);      //任务句柄
}

void task1(void *pvParameters)
{
//任务初始化程序
   while(1)
   {
   //任务的循环任务
    vTaskDelay(1);    //任务延时调度
   }
   vTaskDelete(NULL);  //删除自身函数
}

更多的任务创建和FreeRTOS函数说明看这里:
ESP32之FreeRTOS–任务的创建和运行

传递给任务函数的参数

/*
  程序: FREERTOS - 单个参数传递
        大家在看本程序的时候,需要对指针非常的了解
        知道 * -> &的作用
  作业: 添加LED3_PIN 15
  公众号:孤独的二进制
*/
byte LED1_PIN = 23;
byte LED2_PIN = 21;

void task1(void *pt) {
  byte * pbLEDPIN;
  pbLEDPIN = (byte *)pt;

  byte LEDPIN;
  LEDPIN = *pbLEDPIN;
  pinMode(LEDPIN, OUTPUT);
  while (1) {
    digitalWrite(LEDPIN, !digitalRead(LEDPIN));
    vTaskDelay(1000);
  }
}

void task2(void *pt) {
  byte LEDPIN = *(byte *)pt;
  pinMode(LEDPIN, OUTPUT);
  while (1) {
    digitalWrite(LEDPIN, !digitalRead(LEDPIN));
    vTaskDelay(3000);
  }
}

void setup() {
  Serial.begin(9600);

  byte * pbLED1PIN;
  pbLED1PIN = &LED1_PIN;

  void * pvLED1PIN;
  pvLED1PIN = (void *)pbLED1PIN;

  if (xTaskCreate(task1,
                  "Blink 23",
                  1024,
                  pvLED1PIN,
                  1,
                  NULL) == pdPASS)
    Serial.println("Task1 Created.");

  if (xTaskCreate(task2,
                  "Blink 21",
                  1024,
                  (void *)&LED2_PIN,
                  1,
                  NULL) == pdPASS)
    Serial.println("Task2 Created.");

}

void loop() {
}

程序出处
该程序task1创建一个字节指针 byte * pbLED1PIN,通过 pbLED1PIN =&LED1_PIN来指向LED1_PIN的地址,再创建pvLED1PIN这个void类型的指针来存储pbLED1PIN转换成void的值。

函数传递的是void类型的指针,所以参数需要转换成void类型的指针才能在任务函数传递。

task2则简单粗暴一点,(void *)&LED2_PIN,直接取地址,然后用空指针去指向,也一样完成传递。

结构体多参数传递

程序出处


typedef struct {
  byte pin;
  int delayTime;
} LEDFLASH;

LEDFLASH led1, led2;

if (xTaskCreate(ledFlash,
                  "FLASH LED",
                  1024,
                  (void *)&led1,
                  1,
                  NULL) == pdPASS)
    Serial.println("led1 flash task Created.");
    
void ledFlash(void *pt) {
  LEDFLASH * ptLedFlash = (LEDFLASH *)pt;
  byte pin = ptLedFlash->pin;
  int delayTime = ptLedFlash->delayTime;

  pinMode(pin,OUTPUT);
  while (1) {
    digitalWrite(pin, !digitalRead(pin));
    vTaskDelay(delayTime);
  }
}

实例化结构体led1,然后传入结构体的指针地址,再创建结构体指针(类型为LEDFLASH )使其等于pt(类型转换为LEDFLASH *),这样子就可以获取到结构体led1的地址了。

互斥量Mutex

程序
多个任务一起用同一个变量就会出问题了,所以就要引入互斥量的概念,简单来说,就是互斥锁锁住一个变量之后,只有等这个锁解了,其他任务才能使用这个变量。

/*
  程序: Tasks之间数据传递
        有多任务同时写入,或者数据大小超过cpu内存通道时,或者对共享资源的访问时候,需要有防范机制
        使用MUTEX对数据对Cirtical Section的内容进行保护
        可以想象成MUTEX就是一把锁

  公众号:孤独的二进制

  语法:
  SemaphoreHandle_t xHandler; 创建Handler
  xHandler = xSemaphoreCreateMutex(); 创建一个MUTEX 返回NULL,或者handler
  xSemaphoreGive(xHandler); 释放
  xSemaphoreTake(xHanlder, timeout); 指定时间内获取信号量 返回pdPASS, 或者pdFAIL

  理解方法:
  MUTEX的工作原理可以想象成
  共享的资源被锁在了一个箱子里,只有一把钥匙,有钥匙的任务才能对改资源进行访问
*/
SemaphoreHandle_t xMutexInventory = NULL; //创建信号量Handler

void retailTask(void *pvParam) {
  while (1) {

    // 在timeout的时间内如果能够获取就继续
    // 通俗一些:获取钥匙
    if (xSemaphoreTake(xMutexInventory, timeOut) == pdPASS) {
      //被MUTEX保护的内容叫做 Critical Section

      for (int i; i < random(10, 100); i++) 
      vTaskDelay(pdMS_TO_TICKS(i));

        //释放钥匙
        xSemaphoreGive(xMutexInventory);
      } else {
        //无法获取钥匙
      }


    };

    vTaskDelay(100); //老板要求慢一些,客户升级后,可以再加快速度
  }
}
  if (xSemaphoreTake(xMutexInventory, timeOut) == pdPASS)
   如果没有获取到互斥量,则执行以下内容,超时时间是timeOut
        xSemaphoreGive(xMutexInventory);

ESP32的双核心

在这里插入图片描述
ESP32是具有两个核心的芯片(可以对应一下你手中的型号作对比),是一个40nm的芯片。

核心0主要负责WiFi和蓝牙,如果不是操作这两个,十分不建议将代码放在核心0中运行

/*
  程序: 多核多任务

  API:
      xPortGetCoreID() 获取当前任务运行的核心
      xTaskCreate() 有系统选择运行核心,优先选择0
      xTaskCreatePinnedToCore() 指派任何给指定核心

  公众号:孤独的二进制
*/

void taskA(void *ptParam) {
  while (1) {
    Serial.println(xPortGetCoreID());	//获取当前任务在哪个核心运行
  }
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  xTaskCreatePinnedToCore(taskA, "Task A", 1024 * 4, NULL, 1, NULL,1);
  

}

void loop() {

Serial.println(xPortGetCoreID());

}

主要是这一句,修改最后一个参数0或1即可修改核心数,使用Arduino环境对esp进行开发时建议使用Application CPU(id=1),否则可能有bug,不建议使用xTaskCreate

  xTaskCreatePinnedToCore(taskA, "Task A", 1024 * 4, NULL, 1, NULL,1);

固定频率运行任务

以固定频率运行任务,不多也不少


  TickType_t xLastWakeTime = xTaskGetTickCount();

    vTaskDelayUntil(&xLastWakeTime, xFrequency);
    vTaskDelayUntil(上一次唤醒的时间的结构体地址, 下一次运行的时间);

软件定时器

FreeRTOS中只要内存允许,想要多少个Timer 就有多少个Timer

  lockHandle = xTimerCreate("Lock Car",
                            2000,		//两秒钟唤醒一次
                            pdFALSE,
                            (void *)0,
                            lockCarCallback);

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【ESP32】arduino中的ESP32实时系统FreeRTOS使用教程(一) 的相关文章

  • 小菜鸡的第二天

    绝对路径 xff1a 以 开头 代表当前路径 xff0c 或者 代表上一级目录 xff0c 或者 插入U盘之后 xff0c 在 dev文件夹下输入 ls sd 可以看到U盘信息 xff0c 要想知道插入的U盘是哪个 xff0c 重新插拔再次
  • 小菜鸡的第三天

    压缩与解压 tar vcjf 43 文件名 tar bz2 xxx xxx是要压缩的文件名 压缩命令 tar vxjf 43 xxx tar bz2 xxx是要解压缩的文件名 解压缩命令 f xff1a 使用归档文件或ARCHIVE设备 c
  • 初级算法:判断数组是否存在重复元素

    qsort函数原型是 void qsort xff08 void base size t num size t width int cdecl compare const void const void xff09 4个参数 xff1a v
  • 初级算法:删除排序数组中的重复项

    因为数组是排序的 xff0c 只要是相同的肯定是挨着的 xff0c 我们只需要遍历所有数组 xff0c 然后前后两两比较 xff0c 如果有相同的就把后面的给删除 双指针解决 使用两个指针 xff0c 右指针始终往右移动 xff0c 如果右
  • 运算符重载

    加号运算符重载 作用 xff1a 实现两个自定义数据类型相加的运算 span class token keyword class span span class token class name Person span span class
  • .在python中的作用

    的作用 点把前后连起来 xff0c 构成一种索引机制 前面是库 后面是函数 ex xff1a pybullet setAdditionalSearchPath是指在pybullet的库中引用setAdditionalSearchPath这个
  • ROS服务通信(七)C++、Python实现

    目录 简介 理论模型 服务通信自定srv 创建srv 编辑配置文件 C 43 43 实现 vscode配置 服务端实现 客户端实现 优化 Python实现 服务端实现 客户端实现 简介 服务通信也是ROS中一种极其常用的通信模式 xff0c
  • ROS中的API:C++、Python(十)实现及理解

    目录 简介 C 43 43 初始化 话题与服务相关对象 回旋函数 ros xff1a xff1a spinOnce xff08 xff09 ros xff1a xff1a spin xff08 xff09 时间相关API 时刻 持续时间 持
  • ROS Gazebo安装入门及仿真室内环境和小车实现(十九)

    目录 安装 简介 URDF与Gazebo基本集成流程 创建功能包 编写URDF文件 启动Gazebo并显示模型 launch 文件实现 命令行启动 xff08 去掉launch中的第三行加载模型 xff09 集成到launch里启动 URD
  • Test Case Framework (TCF) tcf 参数

    root 64 embargo ww13 tcf help usage tcf h v log pid tid log time config file CONFIG FILE py p CONFIG PATH state path STA
  • 第一章操作系统引论测验错题整理(二)

    中断和特权级 计算机系统中判断是否有外部中断事件发生应该在 xff09 A 进程切换时 B 执行完一条指令后 C 执行一条指令过程中 D 由用户态转入内核态时 B 解析 xff1a 因果关系 xff0c 指令执行了才知道 从用户态到内核态的
  • 多旋翼飞行器设计与控制(三)—— 机架设计

    多旋翼飞行器设计与控制 xff08 三 xff09 机架设计 一 布局设计 1 机身基本布局 共有三种 xff1a 环型 43 字型 X字型 常用X字型 xff1a 机动性更强前视相机的视场角不容易被遮挡 环形的特点 xff1a 刚性更大避
  • 路径规划与轨迹优化 —— Dijkstra算法寻找最短路径

    一 算法思路 Dijkstra算法是一种用来寻找最短路径的算法 xff0c 其中涉及的思想有贪心 动态规划 广度优先搜索等 图中g n 代表的时代价 xff0c 在机器人路径规划中可以理解为距离 二 代码 源码来源于Github xff0c
  • VSCode远程连接免密登录

    配置了VSCode远程连接服务器 xff0c 但每次打开project都需要重新输入密码 xff0c 比较麻烦 xff0c 所以下面就介绍一下如何免密码登入 在上一篇blog里面配置好VSCode远程连接服务器之后按照如下操作 步骤如下 x
  • raspberry(树莓派)的简介及实验

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 树莓派是什么 xff1f 二 使用步骤 1 主要Pin脚的编号2 使用硬件3 连接树莓派Pin位4 使用代码实验 总结
  • 深度学习环境配置Anaconda+cuda+cudnn+PyTorch——李沐大神《动手学深度学习》环境配置(巨详细,持续迭代)

    李沐大神 动手学深度学习 安装篇 通用AI 深度学习 机器学习环境 Anaconda 43 cuda 43 cudnn 43 Pytorch 手把手教你安装深度学习环境 xff09 这里是GPU 43 PyTorch版本 文章目录 李沐大神
  • FreeRTOS-任务间共享数据的管理框架

    本文章介绍一种在FreeRTOS项目中任务间共享数据的管理框架 xff0c 思路比较简单 任务在更新和获取共享数据时利用互斥量进行上锁保护数据 xff0c 操作完之后进行解锁 xff0c 并且当共享数据使用setting 更新时调用对应的回
  • 树莓派、Jetson nao在ROS下进行darknet深度学习识别物体大致方向及流程

    目标成果 xff1a 在linux设备中启用darknet ros 0 如何获得darknet ros源码 xff1a 渠道1 xff1a github的darknet ros 渠道2 xff1a gitee的darknet ros xff
  • 如何重新设置Ubuntu20.04用户密码以及管理员密码

    当我们在Windows上安装VMwareWorkstation虚拟机上运行Linux系统发现一件尴尬的事情 那就是 忘记密码了 解决方法具体如下 一 在VMwareWorkstation虚拟机上方工具栏选中重新启动客户机 xff0c 启动后
  • STM32CubeMX 修改下载文件(固件包)的存储路径

    当我们在使用STM32CubeMX 的过程中 xff0c 会有一些文件下载像各种STM32Cube FW固件开发包 如果安装了CubeMxIDE这个图形化工具 xff0c 我们就不用去官方下载了 可极大的节省开发效率 在win10和win7

随机推荐

  • Test Case Framework (TCF) tcf 刷机/AC/KVM 基本使用(一)

    移除属于我的机器 tcf alloc rm tcf alloc ls q u self 查看机器版本 tcf ls vv targetname 串口log tcf console read spr40s01 c log flash bios
  • 多线程CompletableFuture之常用方法示例

    文章目录 前期准备1 runAsync2 supplyAsync3 thenRunAsync4 thenAcceptAsync5 runAfterBothAsync6 thenCombineAsync7 exceptionally8 han
  • 算法题解-- stl

    周末舞会 题目描述 假设在周末舞会上 xff0c X 名男士和 Y 名女士进入舞厅时 xff0c 各自排成一队 xff0c 并分别按顺序编号 跳舞开始时 xff0c 依次从男队和女队的队头上各出一人配成舞伴 规定每个舞曲只能有一对跳舞者 跳
  • 简说spring 的设计模式

    spring 的设计模式 xff08 23种 xff08 面试题 xff09 说说BeanFactory和FactoryBean的实现原理和区别 xff1f spring 中你还知道哪些设计模式 xff1f xff1f 1 简单工厂模式 实
  • 【转载】MathGL中报错:undefined reference to `mgl_create_graph‘的解决方法

    概述 xff1a 在环境 xff1a ubuntu 20 04 中 成功下载好了mathGL xff0c 但是最后编译却报错 undefined reference to 96 mgl create graph 39 如下 xff1a 各种
  • 第十三届蓝桥杯 C/C++ 大学B组 题解

    第十三届蓝桥杯 C C 43 43 大学B组 题解 A 进制计算简单模拟 span class token macro property span class token directive hash span span class tok
  • Android12系统源码目录简单分析

    在这里插入图片描述 https img blog csdnimg cn 07a0627ec4754074b5b621cb3e4dae4d png 上面这么多文件夹 xff0c 有些是一直不需要去理会的 xff0c 比如说接触较多的文件夹 x
  • 应用层与内核层的区别

    应用层 xff1a 主要操作用户空间 xff0c 主要编写逻辑 xff0c 打印信息调用标准库里面的printf函数 内核层 xff1a 主要操作内核空间 xff0c 实现五大管理 xff1a 进程管理 xff0c 内存管理 xff0c 文
  • ubuntu软件:录制视频和截图工具,压缩视频

    1 自带录制视频工具 xff1b 使用方式 xff1a 无需下载 开始录屏 结束录屏 xff1a Ctrl 43 Alt 43 Shift 43 r 当看到 Ubuntu 桌面的右上方多了一个红色的小圆点 xff0c 代表正在录制 注意 x
  • Eth-trunk :LACP模式链路聚合实战

    Eth trunk LACP模式链路聚合实战 需求描述 PC1和PC3数据vlan10 xff0c 网段为192 168 10 0 24PC2和PC4数据vlan20 xff0c 网段为192 168 20 0 24确保设备之间互联互通 x
  • Test Case Framework (TCF) tcf itp 基本使用(二)

    查看机器是否支持itp tcf ls v interfaces power itp0 instrument
  • PDF发送短信2

    SMS是由Esti 所制定的一个规范 xff08 GSM 03 40 和 GSM 03 38 xff09 有两种方式来发送和接收SMS消息 xff1a 文本模式或者PDU xff08 protocol description unit xf
  • maven 打包资源文件需要注意的问题

    初衷 我写这篇博客的目的是想让大家了解一些 maven 项目的结构以及打包后是什么样子的 xff0c 方便大家在实际项目中去排查问题 比如 xff1a 我明明在 src main java 下把 mybatis 的 xml 写上了 xff0
  • Linux服务器Ubuntu上搭建Jenkins+Pytest+Gitee+Allure自动化

    一 安装Jenkins和Java Jenkins 是一个开源自动化服务器 xff0c 它可以自动执行软件持续集成和交付中涉及的重复性技术任务 Jenkins 易于安装且基于 Java xff0c 此外 xff0c 可以使用 Web 界面轻松
  • Python Cookbook学习总结

    第一章 xff1a 数据结构和算法 任何序列 xff08 可迭代的对象 xff09 都可以通过一个简单的赋值操作来分解为单独的变量 xff0c 唯一的要求是变量的总数和结构要与序列相吻合 xff08 比如对于存储二维坐标等的二维数组 xff
  • FreeRTOS入门——STM32下完成一个基于FreeRTOS的多任务程序

    文章目录 一 什么是FreeRTOS二 裸机系统与多任务系统1 裸机系统2 多任务系统3 系统之间的对比 三 实验要求四 实验准备五 在KEIL新建 FreeRTOS 工程1 新建本地工程文件夹2 使用 KEIL 新建工程3 在 KEIL
  • natnet/vrpn_cliernt环境配置

    vrpn sdk的频率上限就是60hz xff0c 想要提高频率可以使用natnet client进行话题接收 1 basalt vrpn client src下需要的其他package vrpn catkin glog catkin ca
  • 无人机集群学习

    natnet sdk4 0 学习 中文介绍 xff1a NatNet SDK Wiki 示例工程 xff1a NatNet Sample Projects NaturalPoint Product Documentation Ver 2 2
  • Nginx证书管理

    一 下载证书到本地 Nginx服务器上传 管理SSL证书 xff0c 将SSL证书压缩包下载到本地后 xff0c 加压Nginx服务器证书的压缩包文件 cert file name pem PEM格式的证书文件 xff0c PEM格式的证书
  • 【ESP32】arduino中的ESP32实时系统FreeRTOS使用教程(一)

    ESP32 FreeRTOS 任务的状态任务的优先级 创建任务传递给任务函数的参数结构体多参数传递互斥量MutexESP32的双核心固定频率运行任务软件定时器 简单的本节略过 xff0c 详细的可以看视频 xff1a 单片机ESP32上的F