news 2026/5/1 6:44:35

Freertos——使用队列集优化数据传输

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Freertos——使用队列集优化数据传输

队列集

  • 通常在实际的产品设计中,我们对硬件的原始数据队列和参与操作的软件数据队列应该是分开设计
  • 这样能保证我们的业务逻辑能更加清晰独立,并且硬件读取逻辑可以再不同产品中复用
  • 会导致一个问题,我们需要在每个硬件读取后进行相应的数据转化任务,如果硬件过多会导致任务栈占据过多的内存,且使任务切换过于频繁污染了时间片
  • 因此我们可以使用到队列集,使得写入同一个业务的软件队列的原始数据队列转换达成统一,使得任务数量减少,并且更容易修改移植我们的代码

业务逻辑

红外遥控器驱动程序里,它只应该把键值记录下来、写入某个队列,它不应该把键值转换为游戏的控制键。在红外遥控器的驱动程序里,不应该有游戏相关的代码,这样,切换使用场景时,这个驱动程序还可以继续使用。把红外遥控器的按键转换为游戏的控制键,应该在游戏的任务里实现。要支持多个输入设备时,我们需要实现一个“InputTask”,它读取各个设备的队列,得到数据后再分别转换为游戏的控制键。
队列集的本质也是队列,只不过里面存放的是“队列句柄”。使用过程如下:

  1. 创建队列A,它的长度是n1
  2. 创建队列B,它的长度是n2
  3. 创建队列集S,它的长度是“n1+n2”
  4. 把队列A、B加入队列集S
  5. 这样,写队列A的时候,会顺便把队列A的句柄写入队列集S
  6. 这样,写队列B的时候,会顺便把队列B的句柄写入队列集S
  7. InputTask先读取队列集S,它的返回值是一个队列句柄,这样就可以知道哪个队列有有数据了;然后InputTask再读取这个队列句柄得到数据。

内部机制

每当在一个队列写入数据,系统自动在这个队列在的队列集的队列中写入一个此队列句柄,当队列集读取时就会依次返回出他的队列中存放的句柄,然后再凭借返回的句柄操作对应的队列

创建队列集

QueueSetHandle_txQueueCreateSet(constUBaseType_t uxEventQueueLength)

uxQueueLength:队列集长度,可存放的队列句柄数
返回值非0:成功,返回句柄,以后使用句柄来操作队列
NULL:失败,因为内存不足

加入队列

BaseType_txQueueAddToSet(QueueSetMemberHandle_t xQueueOrSemaphore,QueueSetHandle_t xQueueSet);

xQueueOrSemaphore:队列句柄,要放入的队列
xQueueSet:队列集句柄
返回值pdTRUE:成功
pdFALSE:失败

读取非空队列

QueueSetMemberHandle_txQueueSelectFromSet(QueueSetHandle_t xQueueSet,TickType_tconstxTicksToWait);

xQueueSet:队列集句柄
xTicksToWait:如果队列集空则无法读出数据,可以让任务进入阻塞状态,如果被设为0,无法读出数据时函数会立刻返回;如果被设为portMAX_DELAY,则会一直阻塞直到有数据可写
返回值NULL:失败
队列句柄:成功

从队列集移除成员

BaseType_txQueueRemoveFromSet(QueueSetMemberHandle_t xQueueOrSemaphore,QueueSetHandle_t xQueueSet);

xQueueOrSemaphore:队列句柄,要放入的队列
xQueueSet:队列集句柄
返回值pdTRUE:失败
pdFALSE:成功

删除队列集

voidvQueueDeleteSet(QueueSetHandle_t xQueueSet);

xQueueSet:队列集句柄
注意:需先移除所有成员,否则可能导致内存泄漏!!!

简单程序示例

// 1. 创建队列和队列集QueueHandle_t xKeyQueue=xQueueCreate(5,sizeof(uint8_t));// 按键队列QueueHandle_t xUartQueue=xQueueCreate(3,sizeof(char));// 串口队列QueueSetHandle_t xInputSet=xQueueCreateSet(5+3);// 队列集// 2. 将队列加入队列集xQueueAddToSet(xKeyQueue,xInputSet);xQueueAddToSet(xUartQueue,xInputSet);// 3. 数据写入任务(例如:按键中断、串口中断)voidvWriteTask(void*pvParameters){uint8_tkey=0x01;xQueueSend(xKeyQueue,&key,0);// 写入按键队列,自动触发队列集}// 4. InputTask:统一处理voidvInputTask(void*pvParameters){QueueSetMemberHandle_t xActivatedMember;uint8_tkeyData;charuartData;while(1){// 等待队列集有数据xActivatedMember=xQueueSelectFromSet(xInputSet,portMAX_DELAY);// 判断是哪个队列有数据if(xActivatedMember==xKeyQueue){xQueueReceive(xKeyQueue,&keyData,0);// 处理按键数据(如转换为游戏控制键)}elseif(xActivatedMember==xUartQueue){xQueueReceive(xUartQueue,&uartData,0);// 处理串口数据}}}

注意事项

  1. 队列集长度的设置
    队列集长度需 ≥ 所有成员队列的总长度(或信号量的最大计数值之和)。例如:队列 A 长度为 5,队列 B 长度为 3,则队列集长度应 ≥ 8,最坏情况下,两个队列同时满,队列集需存放 8 个句柄
  2. 成员的 “独占性”
    队列 / 信号量加入队列集后,不应再直接读写,否则会导致队列集状态不同步。需通过队列集机制间接访问,先xQueueSelectFromSet() 获取句柄,再读写对应队列,这个函数类似于xQueueReceive()的阻塞机制
  3. 中断中使用队列集
    若在中断中操作队列集成员,需使用中断安全的队列读取函数( xQueueSendFromISR())
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 6:42:31

开发流程skill模板和优化方案

# Skill: 业务模块全流程交付触发方式:当用户说"开发 XX 模块"、"实现 XX 功能"、"交付 XX" 时,按此流程推进。---## 总体原则- 每步有明确产出物,编译或验证通过再进下一步 - 关键设计决策必须等用户确认&…

作者头像 李华
网站建设 2026/5/1 6:41:25

工业机器人RV减速器摆线轮故障诊断【附代码】

✅ 博主简介:擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导,毕业论文、期刊论文经验交流。 ✅ 如需沟通交流,扫描文章底部二维码。(1)基于自适应变分模态分解的摆线轮振动特征增强:RV…

作者头像 李华
网站建设 2026/5/1 6:40:28

CyberClaw:构建透明可控AI智能体的开源架构实战指南

1. 项目概述最近在折腾AI智能体,发现一个挺头疼的问题:这玩意儿好用是好用,但很多时候它到底在“想”什么、准备“做”什么,完全是个黑箱。你让它写个脚本,它可能顺手就把你系统目录给删了;你让它查个资料&…

作者头像 李华
网站建设 2026/5/1 6:38:24

为编程助手 Claude Code 配置 Taotoken 作为后端模型服务提供方

为编程助手 Claude Code 配置 Taotoken 作为后端模型服务提供方 1. 准备工作 在开始配置前,请确保已安装 Claude Code 并拥有 Taotoken 平台的有效 API Key。登录 Taotoken 控制台,在「模型广场」页面可以查看支持的模型 ID,例如 claude-so…

作者头像 李华
网站建设 2026/5/1 6:33:26

Legacy-iOS-Kit终极指南:如何免费让旧iPhone和iPad重获新生

Legacy-iOS-Kit终极指南:如何免费让旧iPhone和iPad重获新生 【免费下载链接】Legacy-iOS-Kit An all-in-one tool to restore/downgrade, save SHSH blobs, jailbreak legacy iOS devices, and more 项目地址: https://gitcode.com/gh_mirrors/le/Legacy-iOS-Kit …

作者头像 李华
网站建设 2026/5/1 6:31:43

VoXtream2流式TTS架构与动态语速控制技术解析

1. VoXtream2技术架构解析VoXtream2的核心创新在于其独特的流式处理架构和动态语速控制机制。该系统采用模块化设计,主要由以下几个关键组件构成:1.1 增量式语音合成流水线与传统TTS系统的批处理模式不同,VoXtream2实现了真正的流水线化处理。…

作者头像 李华