【Freertos基础入门】队列(queue)的使用

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、队列是什么?
  • 二、队列的操作
  • 二、示例代码
  • 总结


前言

本系列基于stm32系列单片机来使用freerots

FreeRTOS是一个广泛使用的开源实时操作系统(RTOS),它提供了丰富的功能和特性,使嵌入式系统的开发更加简单和高效。队列是FreeRTOS中常用的一种通信机制,它用于在任务之间传递数据。


一、队列是什么?

队列是一种先进先出(FIFO)的数据结构,允许任务将数据项放入队列的末尾,并从队列的前端取出数据项。队列提供了一种线程安全的方式来实现任务之间的数据传输,尤其适用于生产者-消费者模式的应用。
在这里插入图片描述

二、队列的操作

1. xQueueCreate():
函数原型: QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength, UBaseType_t uxItemSize);
作用: 创建一个队列并返回队列的句柄。
参数:

uxQueueLength: 队列中的最大项数,即队列的深度。
uxItemSize: 单个队列项的大小(以字节为单位)。

2. xQueueCreate():
函数原型: BaseType_t xQueueSend(QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait);
作用: 将一个数据项发送到队列中。
参数:

xQueue: 队列的句柄。
pvItemToQueue: 要发送的数据项的指针。
xTicksToWait: 阻塞等待的时间,如果队列已满,将会等待指定的时间,直到队列有空间可用。

3. xQueueReceive():
函数原型: BaseType_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait);
作用: 从队列中接收一个数据项。
参数:

xQueue: 队列的句柄。
pvBuffer: 接收数据项的缓冲区指针。
xTicksToWait: 阻塞等待的时间,如果队列为空,将会等待指定的时间,直到队列中有数据可用。

4. uxQueueMessagesWaiting():
函数原型: UBaseType_t uxQueueMessagesWaiting(const QueueHandle_t xQueue);
作用: 获取队列中当前等待处理的数据项数量。
参数:

xQueue: 队列的句柄。

5. vQueueDelete():
vQueueDelete():
函数原型: void vQueueDelete(QueueHandle_t xQueue);
作用: 删除一个已创建的队列及其相关资源。
参数:

xQueue: 队列的句柄。

6.xQueueCreateStatic()
作用:静态分配queue内存
函数原型:QueueHandle_t xQueueCreateStatic( UBaseType_t uxQueueLength, UBaseType_t uxItemSize, uint8_t *pucQueueStorageBuffer, StaticQueue_t *pxQueueBuffer );

参数:uxQueueLength 队列长度,最多能存放多少个数据(item)
uxItemSize 每个数据(item)的大小:以字节为单位
pucQueueStorageBuffer
如果uxItemSize非0,pucQueueStorageBuffer必须指向一个
uint8_t数组,
此数组大小至少为"uxQueueLength * uxItemSize"
pxQueueBuffer 必须执行一个StaticQueue_t结构体,用来保存队列的数据结构
返回值 非0:成功,返回句柄,以后使用句柄来操作队列
NULL:失败,因为pxQueueBuffer为NULL

7.xQueueReset();
作用:队列刚被创建时,里面没有数据;使用过程中可以调用 xQueueReset() 把队列恢复为初始状态
函数原型:BaseType_t xQueueReset( QueueHandle_t pxQueue);参数为要复位的队列。

8.xQueueSendToBack()
函数原型:BaseType_t xQueueSendToBack( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait );
作用:往队列尾部写入数据,如果没有空间,阻塞时间为xTicksToWait。
参数为要写的队列,数据,等待的时间

8.xQueueSendToBackFromISR()
函数原型:BaseType_t xQueueSendToBackFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken );
作用:往队列尾部写入数据,此函数可以在中断函数中使用,不可阻塞

9.xQueueSendToFront()
作用:往队列头部写入数据,如果没有空间,阻塞时间为xTicksToWait
函数原型:BaseType_t xQueueSendToFront( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait );
10.xQueueSendToFrontFromISR()
作用:往队列头部写入数据,此函数可以在中断函数中使用,不可阻塞
函数原型:BaseType_t xQueueSendToFrontFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken );

11.xQueueReceiveFromISR()
作用:读函数,此函数可以在中断内使用,不可阻塞
函数原型:BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxTaskWoken );
参数为要读的队列,存储的位置,一个指向 BaseType_t 变量的指针,在正常情况下被置为 pdFALSE。它用于通知内核是否有任务的优先级因为该操作而发生了改变。

12.uxQueueSpacesAvailable()
作用: 返回队列中可用空间的个数

函数原型:UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );
参数为要查询的队列

13.xQueueOverwrite()与xQueueOverwriteFromISR()
作用:当队列满时,这些函数会覆盖里面的数据,这也意为着这些函数不会被阻塞。
函数原型:

/* 覆盖队列
* xQueue: 写哪个队列
* pvItemToQueue: 数据地址
* 返回值: pdTRUE表示成功, pdFALSE表示失败
*/
BaseType_t xQueueOverwrite(
QueueHandle_t xQueue,
const void * pvItemToQueue
);
BaseType_t xQueueOverwriteFromISR(
QueueHandle_t xQueue,
const void * pvItemToQueue,
BaseType_t *pxHigherPriorityTaskWoken
);

14.xQueuePeek()与xQueuePeekFromISR()函数
作用:偷看要取出队列的第二个元素
这些函数会从队列中复制出数据,但是不移除
数据。这也意味着,如果队列中没有数据,那么"偷看"时会导致阻塞;一旦队列中有数据以后每次"偷看"都会成功。
函数原型:

/* 偷看队列
* xQueue: 偷看哪个队列
* pvItemToQueue: 数据地址, 用来保存复制出来的数据
* xTicksToWait: 没有数据的话阻塞一会
* 返回值: pdTRUE表示成功, pdFALSE表示失败
*/
BaseType_t xQueuePeek(
QueueHandle_t xQueue,
void * const pvBuffer,
TickType_t xTicksToWait
);
BaseType_t xQueuePeekFromISR(
QueueHandle_t xQueue,
void *pvBuffer,
);

二、示例代码

下面是一个简单的示例代码,演示了如何使用FreeRTOS队列实现一个生产者任务和一个消费者任务之间的数据传输:

// 创建一个队列句柄
QueueHandle_t xQueue;void vProducerTask(void *pvParameters) 
{int data = 0;while (1) {// 生产数据data = generateData();// 发送数据到队列if (xQueueSend(xQueue, &data, portMAX_DELAY) != pdPASS) {// 处理发送失败的情况}// 延时,模拟生产速度vTaskDelay(pdMS_TO_TICKS(1000));}
}void vConsumerTask(void *pvParameters) 
{int receivedData;while (1) {// 从队列接收数据if (xQueueReceive(xQueue, &receivedData, portMAX_DELAY) == pdPASS) {// 处理接收到的数据processData(receivedData);}}
}int main() 
{
// 创建队列,队列长度为5,每个数据项的大小为sizeof(int)
xQueue = xQueueCreate(5, sizeof(int));// 创建生产者任务
xTaskCreate(vProducerTask, "Producer", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);// 创建消费者任务
xTaskCreate(vConsumerTask, "Consumer", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);// 启动调度器
vTaskStartScheduler();return 0;
}

总结

队列是FreeRTOS中一种有用的通信机制,可用于在任务之间传递数据。通过使用队列,我们可以实现任务之间的数据共享和同步。在使用队列时,需要注意队列的深度和每个数据项的大小,并选择适当的阻塞等待时间以避免资源争用和任务饥饿等问题。
在后面我们还将介绍到信号量,互斥锁,任务通知等任务的通信机制,他们都是为了解决任务的通信研究出来的技术和算法。

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

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

相关文章

CVE-2015-5254漏洞复现

1.漏洞介绍。 Apache ActiveMQ 是美国阿帕奇(Apache)软件基金会所研发的一套开源的消息中间件,它支持 Java 消息服务,集群,Spring Framework 等。Apache ActiveMQ 5.13.0之前 5.x 版本中存在安全漏洞,该漏…

CW4-3A-S(004)CW4-6A-S(004)CW4-10A-S(004)CW4-20A-S(004)CW4-30A-S(004)端子台式滤波器

CW4L3-3A-S(003) CW4L3-6A-S(003) CW4L3-10A-S(003) CW4L3-20A-S(003) CW4L3-30A-S(003)端子台式滤波器 CW4-3A-S(004) CW4-6A-S(004) CW4-10A-S(004) CW4-20A-S(004) CW4-30A-S(004)端子台式滤波器 CW4L4-3A-R CW4L4--6A-R CW4L4-10A-R CW4L4-20A-R CW4L4-30A-R端…

使用SSH隧道将Ubuntu云服务器Jupyter Notebook端口映射到本地

本文主要实现了在Ubuntu云服务器后台运行Jupyter Notebook,并使用SSH隧道将服务器端口映射到本地 1. 生成配置文件 运行以下命令生成Jupyter Notebook的配置文件: jupyter notebook --generate-config这将在用户主目录下生成一个名为.jupyter的文件夹&…

集群、负载均衡集群、高可用集群简介,LVS工作结构、工作模式、调度算法和haproxy/nginx模式拓扑介绍

一.集群的定义 1.定义 2.分类 (1)负载均衡集群(LBC/LB) (2)高可用集群(HAC) 二.使用集群的意义 1.高性价比和性能比 2.高可用性 3.可伸缩性强 4.持久和透明性高 三.常见的…

java面试基础 -- 普通类 抽象类 接口

目录 抽象类语法 抽象类特性 普通类 & 抽象类 抽象类 & 接口 什么是接口 语法 接口方法 变量 接口特性 抽象类&接口的区别 抽象类语法 在Java中,一个类如果被 abstract 修饰称为抽象类,抽象类中被 abstract 修饰的方法称为抽象…

无涯教程-Perl - splice函数

描述 此函数从LENGTH元素的OFFSET元素中删除ARRAY元素,如果指定,则用LIST替换删除的元素。如果省略LENGTH,则从OFFSET开始删除所有内容。 语法 以下是此函数的简单语法- splice ARRAY, OFFSET, LENGTH, LISTsplice ARRAY, OFFSET, LENGTHsplice ARRAY, OFFSET返回值 该函数…

Linux 网络发包流程

哈喽大家好,我是咸鱼 之前咸鱼在《Linux 网络收包流程》一文中介绍了 Linux 是如何实现网络接收数据包的 简单回顾一下: 数据到达网卡之后,网卡通过 DMA 将数据放到内存分配好的一块 ring buffer 中,然后触发硬中断CPU 收到硬中…

动态loading中转页

动态loading中转页 template <div class"loading"><div class"wavy"><!-- --i是自定义属性&#xff0c;可通过var函数调用 --><span style"--i: 1">登</span><span style"--i: 2">录</span>…

【代码随想录-Leetcode第六题:209. 长度最小的子数组】

209. 长度最小的子数组 题目思路代码实现 题目 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl1, …, numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回…

ARM 作业1

一、思维导图 二、 1. 2. .text 文本段 .globl _start 声明_start:mov r0,#0mov r1,#0fun:cmp r1,#100bhi stopadd r0,r0,r1add r1,r1,#1b fun stop:b stop .end

【Unity每日一记】进行发射,位置相关的方法总结

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

C语言好题解析(三)

目录 选择题一选择题二选择题三选择题四编程题一编程题二 选择题一 以下程序段的输出结果是&#xff08;&#xff09;#include<stdio.h> int main() { char s[] "\\123456\123456\t"; printf("%d\n", strlen(s)); return 0; }A: 12 B: 13 …