在ESP32 Arduino框架上实验FreeRTOS:多任务操作系统的简介与应用

news2025/2/22 20:36:40

FreeRTOS

介绍


实时操作系统(RTOS):

实时操作系统是一种专为实时应用程序设计的操作系统。实时应用程序对任务的响应时间有严格的要求,因此实时操作系统必须能够在预定的时间内完成任务的调度和执行。这与通用操作系统(如Windows、Linux)的设计目标有所不同,通用操作系统更注重用户体验和各种应用程序的同时运行。

实时操作系统通常用于嵌入式系统、航空航天、医疗设备、汽车控制系统等领域,这些领域对系统的响应时间和可靠性要求非常高。

FreeRTOS:

FreeRTOS(Real-Time Operating System)是一个开源的实时操作系统内核,它是由英国公司Real Time Engineers Ltd.创建并维护的。FreeRTOS提供了一个轻量级、可移植的内核,适用于多种嵌入式平台。

以下是FreeRTOS的一些特点和功能:

  1. 多任务管理: FreeRTOS支持多任务,允许在同一系统中运行多个任务。每个任务都有自己的堆栈和优先级,任务之间可以共享资源。

  2. 任务调度: FreeRTOS使用抢占式任务调度,任务按照优先级进行调度,高优先级任务可以打断低优先级任务的执行。

  3. 内存管理: FreeRTOS提供内存管理机制,可以灵活地配置和管理任务堆栈、消息队列等资源。

  4. 互斥锁和信号量: 用于实现任务之间的同步和互斥,防止资源冲突。

  5. 定时器和中断处理: FreeRTOS提供了软件定时器和硬件定时器的支持,以及灵活的中断处理机制。

  6. 可移植性: FreeRTOS的内核设计使其能够轻松地移植到不同的嵌入式平台上,支持多种处理器架构。

  7. 开源和社区支持: 作为开源项目,FreeRTOS得到了广泛的社区支持,用户可以方便地获取源代码、文档和社区帮助。

在使用FreeRTOS时,可以通过创建任务、使用信号量和队列等机制,以一种结构化和可维护的方式设计和实现复杂的嵌入式系统。

第一个FreeRTOS程序


创建多任务

在FreeRTOS中,创建多任务可以使用 xTaskCreate 函数。该函数的原型如下:

BaseType_t xTaskCreate(
    TaskFunction_t pvTaskCode,
    const char * const pcName,
    const uint32_t usStackDepth,
    void * const pvParameters,
    UBaseType_t uxPriority,
    TaskHandle_t * const pxCreatedTask
);

这个函数用于创建一个新的任务。下面是各个参数的解释:

  • TaskFunction_t pvTaskCode: 这是任务函数的指针,该函数将在任务被创建时运行。任务函数的原型应为 void taskFunction(void *pvParameters),其中 pvParameters 是传递给任务的参数。

  • const char * const pcName: 这是任务的名称,用于识别任务。这个参数是一个字符串。

  • const uint32_t usStackDepth: 这是任务堆栈的深度,以字为单位。堆栈的深度取决于任务的要求和系统的限制。

  • void * const pvParameters: 这是传递给任务函数的参数,可以是一个结构体、整数或其他任何类型。

  • UBaseType_t uxPriority: 这是任务的优先级。优先级越高的任务将更早得到执行。通常,0是最低优先级,数字越大优先级越高。

  • TaskHandle_t * const pxCreatedTask: 这是一个指向任务句柄的指针,用于接收任务的句柄。如果不需要任务句柄,可以将此参数设置为 NULL

下面是一个简单的例子,演示如何创建两个任务:

#include <Arduino.h>

void task1(void *pvParameters) {
  while (1) {
    Serial.println("Task 1 is running...");
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
}

void task2(void *pvParameters) {
  while (1) {
    Serial.println("Task 2 is running...");
    vTaskDelay(2000 / portTICK_PERIOD_MS);
  }
}

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

  xTaskCreate(task1, "Task1", 1024, NULL, 1, NULL);
  xTaskCreate(task2, "Task2", 1024, NULL, 1, NULL);
}

void loop() {
  // 什么都不做
}

在这个例子中,task1task2 是两个简单的任务函数,分别以不同的频率输出消息。通过 xTaskCreate 函数创建这两个任务,并在 setup 函数中启动它们。这样,两个任务将并行运行,形成多任务系统。

给任务函数传参

在FreeRTOS中,可以通过 pvParameters 参数将参数传递给任务函数。当使用 xTaskCreate 函数创建任务时,你可以将参数作为最后一个参数传递给该函数。这个参数是一个 void * 类型的指针,可以指向任何类型的数据。

以下是一个简单的例子:

#include <Arduino.h>


// 定义结构体作为参数
typedef struct {
  int ledPin;
  int delayTime;
} TaskParameters;

// 任务函数
void blinkTask(void *pvParameters) {
  TaskParameters *params = (TaskParameters *)pvParameters;

  pinMode(params->ledPin, OUTPUT);

  while (1) {
    digitalWrite(params->ledPin, !digitalRead(params->ledPin));
    vTaskDelay(params->delayTime / portTICK_PERIOD_MS);
  }
}

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

  // 设置LED1任务参数
  TaskParameters params1 = {21, 1000};
  // 创建LED1任务
  xTaskCreate(blinkTask, "BlinkTask1", 1024, (void *)&params1, 1, NULL);

  // 设置LED2任务参数
  TaskParameters params2 = {23, 2000};
  // 创建LED2任务
  xTaskCreate(blinkTask, "BlinkTask2", 1024, (void *)&params2, 1, NULL);
}

void loop() {
  // 什么都不做
}

在这个例子中,我们定义了一个结构体 TaskParameters 来存储任务的参数,其中包括LED引脚号和LED闪烁间隔时间。然后,我们分别为两个LED创建了两个任务,将不同的参数传递给它们。在任务函数 blinkTask 中,通过类型转换将 pvParameters 转换为 TaskParameters 类型,然后就可以访问传递的参数了。

FreeRTOS多任务点灯

掌握了创建多任务以及向任务传参的方法,我们就可以完成第一个FreeRTOS项目了

项目任务:
通过两个任务,分别控制两个LED的闪烁。每个LED由一个独立的任务来处理,通过在任务中控制LED的状态,实现两LED的闪烁间隔时间不同。
在这里插入图片描述

以下是这个项目的基本流程:

  1. 结构体定义:

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

    定义了一个结构体 LEDFLASH,其中包含了 LED 的引脚号和闪烁的时间间隔。

  2. 任务函数定义:

    void task(void *pt) {
      LEDFLASH *ptLedFlash = (LEDFLASH *)pt;
    
      pinMode(ptLedFlash->pin, OUTPUT);
      while (1) {
        digitalWrite(ptLedFlash->pin, !digitalRead(ptLedFlash->pin));
        vTaskDelay(ptLedFlash->DelayTime); // 通过 FreeRTOS 的延迟函数实现 LED 闪烁
      }
    }
    

    定义了一个任务函数 task,该函数通过类型转换获取 LED 结构体指针,然后在一个无限循环中控制 LED 的状态并通过 vTaskDelay 实现 LED 的闪烁效果。

  3. 任务创建:

    void setup() {
      LEDFLASH ledFlash1 = {21, 1000}; // 第一个LED,引脚21,每秒一次
      LEDFLASH ledFlash2 = {23, 3000}; // 第二个LED,引脚23,每三秒一次
    
      xTaskCreate(task, "Blink 21", 1024, (void *)&ledFlash1, 1, NULL);
      xTaskCreate(task, "Blink 23", 1024, (void *)&ledFlash2, 1, NULL);
    
      Serial.begin(115200);
      Serial.println(portTICK_PERIOD_MS); // 打印一个 tick 的时间
    }
    

    setup 函数中,创建了两个任务,分别用于控制两个 LED。每个任务都独立运行,控制不同 LED 的状态。

  4. 串口初始化:

    Serial.begin(115200);
    

    初始化串口通信,用于在串口监视器上输出信息。

  5. 主循环:

    void loop() {
      // 什么都不做
    }
    

    由于任务在 FreeRTOS 中进行管理和调度,因此 loop 函数为空。

通过 FreeRTOS 实现多任务处理,通过两个任务控制两个 LED 的独立闪烁,展示了 FreeRTOS 在 ESP32 上实时操作系统的应用。源码点击查看

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity 桥接模式(实例详解)

文章目录 示例1&#xff1a;角色与装备系统示例2&#xff1a;UI控件库示例3&#xff1a;渲染引擎模块示例4&#xff1a;AI决策树算法示例5&#xff1a;物理模拟引擎 在Unity游戏开发中&#xff0c;桥接模式&#xff08;Bridge Pattern&#xff09;是一种设计模式&#xff0c;它…

语义分割常用评价指标

在图像处理领域中&#xff0c;语义分割是很重要的一个任务。在实际项目开发中,评估模型预测效果以及各指标的含义对于优化模型极为重要。 本文将主要评价指标的计算算法进行了详细说明,并加上注释解释每个指标的含义。这对理解各指标背后的数学原理以及能否在实践中应用或许有…

【MATLAB基础绘图第20棒】云雨图

MATLAB绘制云雨图 云雨图(Raincloud plots)MATLAB绘制云雨图横向云雨图竖向云雨图 参考 云雨图(Raincloud plots) 云雨图&#xff08;Raincloud plots&#xff09;其实是可以看成核密度估计曲线图、箱形图和抖动散点图的组合图&#xff0c;清晰、完整、美观地展示了所有数据信…

数组与 Web 程序打包

5. 数组 在Java中&#xff0c;数组是一种用于存储相同类型元素的数据结构。以下是如何定义和赋值Java数组的基本方法&#xff1a; 1. 定义数组&#xff1a; 一维数组&#xff1a; // 语法&#xff1a;elementType[] arrayName; int[] intArray; // 声明一个整型数组&#…

操作系统【OS】Ch2【大题】 PV题型分类

生产者-消费者问题&#xff1a;生产资源-消费资源理发师问题&#xff1a;服务-被服务读者-写者问题&#xff1a;同类进程不互斥、异类进程互斥哲学家进餐问题&#xff1a;只有一类进程&#xff0c;每个进程需要同时拥有多种资源才能运行单纯的同步问题&#xff1a;前驱后继图 生…

​第14节-高质量简历写作求职通关-在线测试

在线测试主要包括性格测试、综合能力测试、技能测试三类 性格测试 性格测试主要用于考察个人与工岗位的匹配程度 考察内容包含性格、能力、动机、价值观等&#xff0c;考察形式一般为给出相应的工作场景&#xff0c;让你选择最喜欢或者最不喜欢的答案 技能考试 这类测试一般是针…

xxe漏洞之scms靶场漏洞

xxe-scms 代码审核 &#xff08;1&#xff09;全局搜索simplexml_load_string simplexml_load_string--将XML字符串解释为对象 &#xff08;2&#xff09;查看源代码 ID1 $GLOBALS[HTTP_RAW_POST_DATA]就相当于file_get_contents("php://input"); 因此这里就存…

AI搜索引擎Perplexity来了,谷歌等老牌搜索引擎或许会有新的威胁?

Perplexity AI 是一家 AI 搜索初创公司&#xff0c;它通过结合内容索引技术和大型语言模型的推理能力&#xff0c;提供更便捷和高效的搜索体验。另外&#xff0c;最近很火的小兔子Rabbit R1硬件AI设备中的搜索功能正是这家公司的杰作。在短短一年半的时间里&#xff0c;一个企业…

快速了解工业交换机

工业交换机是专门为工业环境设计的数据通信设备。该设备的主要作用是满足工业控制系统对数据通信的要求&#xff0c;实现不同设备之间的数据传输和网络连接。工业交换机在适应恶劣环境、抗干扰和稳定性等方面表现更出色&#xff0c;相较于传统的商用交换机。 它的基本原理是利用…

牛客网-----跳石头

题目描述&#xff1a; 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行&#xff0c;河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间&#xff0c;有N块岩石(不含起点和终点的岩石)。在比赛过程中&#xff0…

[Linux 杂货铺] —— 权限(文件权限和目录配置)

目录 &#x1f308;前言 &#x1f4c1; 文件的属性 &#x1f4c1; 权限的概念 &#x1f4c2;拥有者和所属组&#xff08;角色&#xff09;&#xff1a; &#x1f4c2;用户&#xff08;具体的人&#xff09;&#xff1a; &#x1f4c1; 权限的管理 &#x1f4c2;1. chmod…

对读取的Excel文件数据进行拆分并发请求发送到后端服务器

首先&#xff0c;我们先回顾一下文件的读取操作&#xff1a; 本地读取Excel文件并进行数据压缩传递到服务器-CSDN博客 第一步&#xff1a;根据以上博客&#xff0c;我们将原先的handleFile方法&#xff0c;改为以下内容&#xff1a; const handleFile async(e) > {conso…

gitlab.rb主要配置

根据是否docker安装,进入挂载目录或安装目录 修改此文件,我一般是在可视化窗口中修改,有时候也在命令行手敲 将下面的配置复制到该文件中 external_url http://192.168.100.50 # nginx[listen_port] = 8000 (docker安装的这一行不需要,因为端口映射导致此处修改会导致访问…

Python 自动化办公:一键批量生成 PPT

Stata and Python 数据分析 一、导读 在实际工作中&#xff0c;经常需要批量处理Office文件&#xff0c;比如需要制作一个几十页的PPT进行产品介绍时&#xff0c;一页一页地制作不仅麻烦而且格式可能不统一。那么有什么办法可以一键生成PPT呢&#xff1f;Python提供的pptx 包…

常见PCB封装

表面贴片封装 通孔封装 公众号 | FunIO 微信搜一搜 “funio”&#xff0c;发现更多精彩内容。 个人博客 | blog.boringhex.top

Web 开发 1: Flask 框架介绍和使用

在 Web 开发中&#xff0c;Flask 是一个流行且灵活的 Python Web 框架&#xff0c;用于构建 Web 应用程序。它简洁而易于上手&#xff0c;适用于小型到中型的项目。在本篇博客中&#xff0c;我将为你介绍 Flask 框架的基础知识和常用技巧&#xff0c;帮助你更好地掌握 Web 开发…

android audio framework

linux ALSA ALSA表示高级Linux声音体系结构(Advanced Linux Sound Architecture)。它由一系列内核驱动&#xff0c;应用程序编译接口(API)以及支持Linux下声音的实用程序组成。 最上层是音频应用和声卡服务&#xff1b;ALSA Library&#xff1a;alsa 提高用户空间访问声卡设备…

【就现在这个市场环境,还是别选游戏开发行业了】

就现在这个市场环境&#xff0c;还是别选游戏开发行业了 最近上网闲逛时我发现&#xff0c;一提到“怎样进入游戏开发行业&#xff1f;”&#xff0c; 大部分都是劝退。 劝退的点大致有以下几点&#xff1a; &#x1f7e5; 游戏开发经常需要加班&#xff0c;尤其是项目快要…

如何在Shopee平台上选择LED产品进行销售的步骤和策略

在如今的电商市场中&#xff0c;Shopee平台是一个非常受欢迎的在线销售平台。如果您计划在Shopee上销售LED产品&#xff0c;那么了解如何选择合适的产品是至关重要的。在本文中&#xff0c;我们将为您介绍一些在Shopee平台上选择LED产品进行销售的步骤和策略&#xff0c;以帮助…

防御保护-防火墙

1.防火墙的主要职责&#xff1a; 控制和防护--安全策略&#xff08;本质ACL&#xff09;--防火墙可以根据安全策略来抓取流量之后做出相应的动作 2-4层 2.防火墙分类&#xff1a; 吞吐量&#xff1a;防火墙同一时间处理的数据量 3.防火墙的发展历程 包过滤防火墙 应用代理防…