五分钟学会使用FreeRTOS队列

这篇具有很好参考价值的文章主要介绍了五分钟学会使用FreeRTOS队列。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

何为队列?

示例代码

函数讲解

xQueueCreate

xQueueSend

xQueueReceive


何为队列?

        在FreeRTOS中,队列是一种用于任务间通信的重要机制。队列可以用来在任务之间传递数据,实现数据的异步传输和共享。

队列的作用包括:

  1. 数据传输:任务可以通过将数据发送到队列中,供其他任务接收和处理。队列提供了一种可靠的机制,确保数据的有序传输和接收。

  2. 任务同步:队列可以用于任务之间的同步,一个任务可以等待另一个任务发送数据到队列中,从而实现任务的协调和同步。

  3. 缓冲区:队列可以作为一个缓冲区,用于存储和管理任务之间的数据。任务可以按照一定的顺序将数据放入队列中,其他任务可以按照相同的顺序从队列中取出数据进行处理。

  4. 通知机制:队列还可以用作任务之间的通知机制。一个任务可以通过向队列发送特定的数据来通知其他任务进行某种操作或者改变状态。

        总之,队列在FreeRTOS中提供了一种高效、可靠的任务间通信机制,使得任务之间可以方便地进行数据传输、同步和协调。        

示例代码

   ESP32基于FreeRTOS的多任务通信,有三个任务,第一个任务是让LED1以0.5秒为间隔闪烁,每次点亮都会进行一次计数,第二个任务根据第一个任务的计数去做处理,比如计数到10以后,LED2灯亮,第三个任务是按键任务,可以把第一个任务中的计数清空。

#include <Arduino.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>

#define LED1_PIN 2
#define LED2_PIN 4
#define BUTTON_PIN 39

TaskHandle_t Task1Handle, Task2Handle, Task3Handle;
QueueHandle_t countQueue;

int count = 0;

void Task1(void* parameter) {
  pinMode(LED1_PIN, OUTPUT);
  while (1) {
    digitalWrite(LED1_PIN, HIGH);
    vTaskDelay(500 / portTICK_PERIOD_MS);
    digitalWrite(LED1_PIN, LOW);
    vTaskDelay(500 / portTICK_PERIOD_MS);

    count++;
    Serial.print("Task1_count=");
    Serial.println(count);
    xQueueSend(countQueue, &count, portMAX_DELAY);
  }
}
void Task2(void* parameter) {
  pinMode(LED2_PIN, OUTPUT);
  while (1) {
    
    xQueueReceive(countQueue, &count, portMAX_DELAY);
    Serial.println(count);
    if (count >= 10) {
      digitalWrite(LED2_PIN, HIGH);
    } else {
      digitalWrite(LED2_PIN, LOW);
    }
  }
}
void Task3(void *pvParameters) {
  pinMode(BUTTON_PIN, INPUT);
  while (1) {
    if (digitalRead(BUTTON_PIN) == HIGH) {
      count = 0;
      xQueueSend(countQueue, &count, portMAX_DELAY);
    }
    vTaskDelay(10 / portTICK_PERIOD_MS);
  }
}

void setup() {
  Serial.begin(115200);
  countQueue = xQueueCreate(100, sizeof(int));
  xTaskCreate(Task1, "Task1", 1024, NULL, 1, &Task1Handle);
  xTaskCreate(Task2, "Task2", 1024, NULL, 2, &Task2Handle);
  xTaskCreate(Task3, "Task3", 1024, NULL, 3, &Task3Handle);
}
void loop()
{

}

函数讲解

xQueueCreate

xQueueCreate是一个FreeRTOS函数,用于创建一个队列。队列是一种用于在任务之间传递数据的数据结构,可以实现任务之间的通信和同步。

xQueueCreate函数的原型如下:

QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength, UBaseType_t uxItemSize);

参数说明:

  • uxQueueLength:队列的长度,表示队列可以容纳的数据项数量。
  • uxItemSize:每个数据项的大小,以字节为单位。

        xQueueCreate函数的返回值是一个QueueHandle_t类型的队列句柄,用于后续对队列的操作。

        下面是一个示例代码,演示如何使用xQueueCreate函数创建一个队列:

// 创建一个队列,长度为10,每个数据项的大小为4字节(32位整数)
QueueHandle_t xQueue = xQueueCreate(10, sizeof(int));

if (xQueue != NULL) {

  // 队列创建成功

  // 执行其他操作

} else {

  // 队列创建失败
  
  // 执行错误处理

}

        在上面的示例中,我们使用xQueueCreate函数创建了一个队列xQueue,它有容量为10的整型数据项。我们使用sizeof(int)来指定每个数据项的大小,这里假设整型数据占用4个字节。

        请注意,创建队列时需要确保有足够的内存可用。如果内存不足,队列创建可能会失败,返回NULL。因此,在创建队列后,建议检查队列句柄是否为NULL,以确保队列创建成功。

        创建队列后,您可以使用其他FreeRTOS队列函数(如xQueueSend、xQueueReceive等)来发送和接收数据。这些函数可以帮助实现任务之间的通信和同步。

xQueueSend

        xQueueSend是一个FreeRTOS函数,用于向队列发送数据。它用于将数据项发送到先前创建的队列中,以供其他任务读取和处理。

        xQueueSend函数的原型如下:

BaseType_t xQueueSend(QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait);

参数说明:

  • xQueue:队列句柄,表示要发送数据的队列。
  • pvItemToQueue:指向要发送的数据项的指针。
  • xTicksToWait:等待时间,如果队列已满,任务将在此处阻塞等待直到队列有空闲空间。

        xQueueSend函数的返回值是一个BaseType_t类型的值,用于指示发送操作是否成功。如果返回pdPASS,则表示数据已成功发送到队列中;如果返回errQUEUE_FULL,则表示队列已满,数据发送失败。

        下面是一个示例代码,演示如何使用xQueueSend函数向队列发送数据:

// 创建一个队列
QueueHandle_t xQueue = xQueueCreate(10, sizeof(int));

// 定义要发送的数据
int dataToSend = 42;

// 发送数据到队列
BaseType_t xStatus = xQueueSend(xQueue, &dataToSend, portMAX_DELAY);
if (xStatus == pdPASS) {
    // 数据发送成功
    // 执行其他操作
} else {
    // 数据发送失败
    // 执行错误处理
}

在上面的示例中,我们首先创建了一个队列xQueue,它有容量为10的整型数据项。然后,我们定义了一个要发送的数据dataToSend,并使用xQueueSend函数将其发送到队列中。我们使用portMAX_DELAY作为等待时间,这将导致任务在队列有空闲空间之前一直阻塞。

请注意,xQueueSend函数是阻塞函数,如果队列已满,任务将被阻塞,直到队列有空闲空间。如果您希望在队列已满时立即返回而不是阻塞任务,可以使用xQueueSendFromISR函数,它适用于从中断服务例程中发送数据。

xQueueReceive

xQueueReceive函数是FreeRTOS中用于从队列中接收数据的函数。它的原型如下:

BaseType_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait);

参数说明:

  • xQueue:队列的句柄,即通过xQueueCreate函数创建的队列。
  • pvBuffer:用于接收数据的缓冲区指针。接收到的数据将会被复制到这个缓冲区中。
  • xTicksToWait:等待时间,即在队列中没有数据可接收时,任务将等待的时间。如果设置为0,则表示立即返回。

函数返回值:

  • pdPASS:数据成功接收。
  • errQUEUE_EMPTY:队列为空,没有数据可接收。
  • errQUEUE_FULL:队列已满,无法接收数据。

下面是一个示例代码,演示如何使用xQueueReceive函数从队列中接收数据:

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"

#define QUEUE_LENGTH 5
#define ITEM_SIZE    sizeof(int)

void task1(void *pvParameters) {
    QueueHandle_t xQueue = (QueueHandle_t)pvParameters;
    int count = 0;

    while (1) {
        vTaskDelay(pdMS_TO_TICKS(500));  // 0.5秒延迟

        // 发送计数到队列
        xQueueSend(xQueue, &count, 0);
        count++;
    }
}

void task2(void *pvParameters) {
    QueueHandle_t xQueue = (QueueHandle_t)pvParameters;
    int receivedData;

    while (1) {
        if (xQueueReceive(xQueue, &receivedData, portMAX_DELAY) == pdPASS) {
            // 接收到数据后的处理
            printf("Received data: %d\n", receivedData);
        }
    }
}

void app_main() {
    QueueHandle_t xQueue = xQueueCreate(QUEUE_LENGTH, ITEM_SIZE);
  
    xTaskCreate(task1, "Task1", 1024, NULL, 1, NULL);
    xTaskCreate(task2, "Task2", 1024, NULL, 2, NULL);
}

        在这个示例代码中,有两个任务:task1和task2。task1每0.5秒向队列发送一个计数值,而task2则从队列中接收数据并进行处理。通过使用xQueueReceive函数,task2可以在队列中有数据可接收时获取数据并进行相应的处理。文章来源地址https://www.toymoban.com/news/detail-507119.html

到了这里,关于五分钟学会使用FreeRTOS队列的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 5分钟学会GitHub基本使用方法,保姆级教程

    导读:我们先来了解一下 Git 和 Github 是什么,有什么功能 先说结论,Git 和 GitHub 是两个东西,Git 是一个软件/工具/系统,GitHub 是一个网站/平台,GitHub 这个网站使用了 Git 这个工具。 1.1 Git Git是一个分布式 版本控制系统 。 版本控制系统(version control system)像个数据库,它

    2024年02月20日
    浏览(56)
  • 一分钟学会MobaXterm当Linux客户端使用

    MobaXterm是一款功能强大的远程计算机管理工具,它集成了各种网络工具和远程连接协议,可以帮助用户在Windows系统上轻松管理远程计算机。MobaXterm支持SSH、Telnet、RDP、VNC等多种远程连接协议,同时还集成了X11服务器,可以实现远程图形化界面操作。此外,MobaXterm还具有文件传

    2024年02月22日
    浏览(33)
  • 【建议收藏】|3分钟让你学会Scala Trait 使用

    ** ** Scala 是一种强大的静态类型编程语言,其中的 Trait 是一种重要的特性。Trait 可以被看作是一种包含方法和字段定义的模板,可以被其他类或 Trait 继承或混入。在本文中,我们将介绍 Scala Trait 的边界(Boundary)的概念,并展示如何使用它来限制 Trait 的使用范围。 Trait 可以

    2024年02月16日
    浏览(38)
  • 使用cpolar内网穿透实现公网远程访问,十分钟就可以学会使用

    1.自己有公网IP,进入路由器做映射 2.自己有公网服务器搭建内网穿透 3.通过第三方公网服务器进行流量转发,映射本地端口 比较常见是第三种方式,不需要自己搭建服务,也不用去申请公网IP、不用设置路由器,不论是本地开发测试,远程联机还是远程访问都支持,随时可用

    2024年02月12日
    浏览(57)
  • 五分钟学会在微信小程序中使用 vantUI 组件库

    我们在开发微信小程序时,设计和实现好用的用户界面无疑是至关重要的一步。但是微信小程序官方自带的 UI 组件库无法满足很多使用场景,这个时候就需要我们使用一些第三方的 UI 组件库。而 vant Weapp 作为一款优秀的前端 UI 组件库,可以帮助我们快速地构建漂亮而且易用

    2023年04月24日
    浏览(73)
  • 一分钟学会怎么让chatGPT帮你写python代码(含使用地址)

    1、给定角色定位 2、提出要求 3、提出要求的细节 效果还是不错的,界面也还可以,简单的加减乘除运算都没有问题 1.现在加入就送内含5-18美元的 ChatGPT 开发者账号 2.外面卖888元的ChatGPT系列课程星球内免费看 3.不用魔法,直接使用 ChatGPT 4.大量 ChatGPT 相关帖子学习 5.可以晒自

    2024年02月02日
    浏览(43)
  • STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

      参考帖子:https://blog.csdn.net/freedompoi/article/details/122350866 目前想要实现STM32F4自带的DMA双缓冲区,尝试过一版,结果不能预期,就使用了RxHalfCplt和RxCplt去实现DMA双缓冲区的效果。 现在有时间了,又重新实现STM32F4自带的DMA双缓冲区,作为参考。   MCU:STM32F429ZIT6 开发环境:

    2024年02月08日
    浏览(51)
  • 10分钟从实现和使用场景聊聊并发包下的阻塞队列

    上篇文章12分钟从Executor自顶向下彻底搞懂线程池中我们聊到线程池,而线程池中包含阻塞队列 这篇文章我们主要聊聊并发包下的阻塞队列 阻塞队列 什么是队列? 队列的实现可以是数组、也可以是链表,可以实现先进先出的顺序队列,也可以实现先进后出的栈队列 那什么是

    2024年02月09日
    浏览(42)
  • 二、FreeRTOS目录文件概述

    (1)官网下载FreeRTOS源码。 (2)FreeRTOS源码目录树。(由目录树生成工具zDirTree生成) (3)Demo目录。 Demo目录下是示例工程文件,以“芯片和编译器”组合成一个名字。 比如:CORTEX_STM32F103_Keil。 (4)Source目录。 Source根目录下是核心文件,这些文件是通用的。 Source/portable目录下是移植时

    2024年02月12日
    浏览(55)
  • FreeRTOS——队列及其实战

    1)队列是任务到任务、任务到中断、中断到任务数据交流的一种机制(消息传递) 2)队列类似数组,只能存储有限数量、相同类型的数据,在创建时需指定队列长度与队列项大小 3)出队入队阻塞: 若阻塞时间为0 :直接返回不会等待; 若阻塞时间为0~port_MAX_DELAY :等待设

    2024年02月03日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包