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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[LitCTF 2023]Ping

因为直接ping会有弹窗。这里在火狐f12,然后f1选禁用javascript,然后ping 然后输入127.0.0.1;cat /flag 得到flag, 查看其他大佬的wp ,这里还可以抓包。但是不知道为什么我这里的burp 用不了

【Unity】坐标转换经纬度方法(应用篇)

【Unity】坐标转换经纬度方法(应用篇) 解决地图中经纬度坐标转换与unity坐标互转的问题。使用线性变换的方法,理论上可以解决小范围内所以坐标转换的问题。 之前有写过[Unity]坐标转换经纬度方法(原理篇),在实际使用中&#xff0c…

使用percona-xtrabackup备份MySQL数据

xtrabackup备份分为两种 本文参考链接1 本文参考链接2 全量备份 1.备份数据 要创建备份,请xtrabackup使用xtrabackup --backup option. 您还需要指定一个xtrabackup --target-dir选项,即备份的存储位置,如果InnoDB数据或日志文件未存储在同…

Debian 10驱动Broadcom 无线网卡

用lspci命令查询无线网卡品牌: 运行下面代码后,重启即可。 apt-get install linux-image-$(uname -r|sed s,[^-]*-[^-]*-,,) linux-headers-$(uname -r|sed s,[^-]*-[^-]*-,,) broadcom-sta-dkms

Kotlin~Bridge桥接模式

概念 抽象和现实之间搭建桥梁,分离实现和抽象。 抽象(What)实现(How)用户可见系统正常工作的底层代码产品付款方式定义数据类型的类。处理数据存储和检索的类 角色介绍 Abstraction:抽象 定义抽象接口&…

泛微E8配置自定义触发流程失败

在新公司接了个配置泛微流程触发的活。因为泛微的官方文档并没有详细的操作指引,在测试环境配置之后、要触发的流程可以手工提交,但是触发一直不成功。简单记录下业务场景和其他处理信息,以供参考。 应用版本 目前使用了泛微 E8 &#xff0…

Spring Clould 注册中心 - Eureka,Nacos

视频地址:微服务(SpringCloudRabbitMQDockerRedis搜索分布式) Eureka 微服务技术栈导学(P1、P2) 微服务涉及的的知识 认识微服务-服务架构演变(P3、P4) 总结: 认识微服务-微服务技…

探索Python中的数据可视化利器:Plotly Express

一、引言 在数据分析和可视化领域,数据的有效呈现是至关重要的。Python作为一种强大的编程语言,提供了多种数据可视化工具和库。其中,Plotly Express是一款受欢迎的数据可视化库,它提供了简单易用的接口和丰富的图表类型&#xf…

keepalived集群

keepalived概述 keepalived软件就是通过vrrp协议来实现高可用功能。 VRRP通信原理 VRRP就是虚拟路由冗余协议,它的出现就是为了解决静态路由的单点故障。 VRRP是通过一种竞选一种协议机制来将路由交个某台VRRP路由器。 VRRP 用IP多播的方式(多播地…

【.net】本地调试运行只能用localhost的问题

【.net】本地调试运行只能用localhost的问题 解决方案 找到到项目目录下 隐藏文件夹 .vs /项目名称/config/applicationhost.config <bindings><binding protocol"http" bindingInformation"*:1738:localhost" /></bindings> 再加一条你…

visual studio 2022配置

前提&#xff1a;我linux c 开发 一直在使用vscode 更新了个版本突然代码中的查找所用引用和变量修改名称不能用了&#xff0c;尝试了重新配置clang vc都不行&#xff0c;估计是插件问题&#xff0c;一怒之下改用visual studio 2022 为了同步2个IDE之间的差别&#xff0c;目前…

【计算机视觉|生成对抗】逐步增长的生成对抗网络(GAN)以提升质量、稳定性和变化

本系列博文为深度学习/计算机视觉论文笔记&#xff0c;转载请注明出处 标题&#xff1a;Progressive Growing of GANs for Improved Quality, Stability, and Variation 链接&#xff1a;[1710.10196] Progressive Growing of GANs for Improved Quality, Stability, and Vari…

musl libc ldso 动态加载研究笔记:01

前言 musl 是一个轻量级的标准C库&#xff0c;建立在系统调用之上&#xff0c;可以认为是【用户态】的C 库&#xff0c;与 glibc 或者 uClibc 属于同一类。 基于 musl 的 gcc 工具链包括交叉编译工具链&#xff0c;可以用于编译 Linux 或者其他的操作系统&#xff0c;如当前 L…

JVM——类加载器

回顾一下类加载过程 类加载过程&#xff1a;加载->连接->初始化。连接过程又可分为三步:验证->准备->解析。 一个非数组类的加载阶段&#xff08;加载阶段获取类的二进制字节流的动作&#xff09;是可控性最强的阶段&#xff0c;这一步我们可以去完成还可以自定义…

STM32 cubemx CAN

接收用到的结构体如下&#xff1a;CAN概念&#xff1a; 全称Controller Area Network&#xff0c;是一种半双工&#xff0c;异步通讯。 物理层&#xff1a; 闭环&#xff1a;允许总线最长40m&#xff0c;最高速1Mbps&#xff0c;规定总线两端各有一个120Ω电阻&#xff0c;闭环…

IC流程中 DFT 学习笔记(2)

引言 DFT是ASIC芯片设计流程中不可或缺的环节。其主要目的是在芯片前端设计验证完成后插入一些诸如寄存器链等可供测试的逻辑&#xff0c;算是IC后端设计的范畴&#xff0c;属于结构测试而非功能测试。主要是在ASIC芯片流片完成后&#xff0c;通过这些已插入的逻辑&#xff0c…

国家一带一路和万众创业创新的方针政策指引下,Live Market探索跨境产业的创新发展

现代社会&#xff0c;全球经济互联互通&#xff0c;跨境产业也因此而崛起。为了推动跨境产业的创新发展&#xff0c;中国政府提出了“一带一路”和“万众创业、万众创新”的方针政策&#xff0c;旨在促进全球经济的互联互通和创新发展。在这个大环境下&#xff0c;Live Market积…

华为PPPOE配置实验

华为PPPOE配置实验 网络拓扑图拓扑说明电信ISP设备配置用户拨号路由器配置查看是否拨上号是否看不懂&#xff1f; 看不懂就对了&#xff0c;只是记录一下命令。至于所有原理&#xff0c;等想写了再写 网络拓扑图 拓扑说明 用户路由器用于模拟家用拨号路由器&#xff0c;该设备…

github以及上传代码处理

最近在github上传代码的时候出现了&#xff1a; /video_parser# git push -u origin main Username for https://github.com: gtnyxxx Password for https://gtny2010github.com: remote: Support for password authentication was removed on August 13, 2021. remote: Plea…