当前位置: 首页 > news >正文

【CI130x】音频传输的数据结构——FreeRTOS的消息队列

一句话概括

xQueueCreate 是 FreeRTOS 实时操作系统中用于动态创建消息队列的函数。它负责分配内存并返回一个可以用于发送和接收数据的队列句柄。


详细解释

1. 什么是消息队列?

在深入函数本身之前,理解“队列”的概念至关重要。你可以把它想象成一个管道传送带

  • 生产者:任务或中断服务程序将数据(消息)放入队列的一端(发送)。

  • 消费者:任务从队列的另一端取出数据(接收)。

  • 先进先出:数据按照被送入队列的顺序被取出,就像在超市排队结账一样。

队列是 FreeRTOS 中最重要的任务间通信机制之一,它允许任务安全、有序地传递信息,而不用担心并发访问导致的数据损坏。

2. xQueueCreate 的作用

xQueueCreate 就是用来创建这样一个“管道”的工具。它主要做两件事:

  1. 分配内存:从 FreeRTOS 的堆中分配两块内存。

    • 一块用于存储队列的结构体,其中包含了管理队列所需的所有信息(如头指针、尾指针、队列长度、项目大小等)。

    • 另一块用于作为队列的存储区,这是一个字节数组,实际的数据就存储在这里。

  2. 初始化队列:将队列结构体中的各个字段设置为初始状态(例如,队列为空)。

  3. 返回句柄:如果创建成功,它返回一个指向这个队列的句柄。后续所有对队列的操作(如发送、接收)都需要使用这个句柄来指定操作哪个队列。


函数原型

QueueHandle_t xQueueCreate( UBaseType_t uxQueueLength, // 队列长度UBaseType_t uxItemSize     // 每个队列项目的大小(字节));

参数说明

  • uxQueueLength

    • 队列能够存储的最大项目数量

    • 例如,如果你设置为 5,那么这个队列最多可以同时存放 5 条消息。

  • uxItemSize

    • 队列中每个项目所占的字节数

    • 如果你要发送一个整数,在 32 位系统上就是 sizeof(int) = 4 字节。

    • 如果你要发送一个结构体,就是 sizeof(my_struct_t)

返回值

  • 成功:返回一个非 NULL 的 QueueHandle_t 类型的句柄。这个句柄需要被你保存起来,供后续使用。

  • 失败:返回 NULL。失败通常是因为没有足够的堆内存来创建队列。


工作流程示意图

假设我们创建一个队列:xQueueCreate(3, sizeof(int))

这表示一个能存放 3 个整数的队列。

  1. 创建后(初始状态)

     
    队列存储区: [ 空 | 空 | 空 ]^写指针 & 读指针

    队列为空,读写指针都指向起始位置。

  2. 发送一个数据(例如 10)

     
    队列存储区: [ 10 | 空 | 空 ]^     ^读指针 写指针
  3. 再发送一个数据(例如 20)

     
    队列存储区: [ 10 | 20 | 空 ]^         ^读指针     写指针
  4. 接收一个数据

    • 从读指针位置取出数据 10

    • 读指针移动到下一个位置。

    text
     
     
    队列存储区: [ 空 | 20 | 空 ]^    ^读指针 写指针

    现在队列里只有一个数据 20


代码示例

下面是一个简单的示例,演示如何创建和使用队列。

#include <FreeRTOS.h>
#include <task.h>
#include <queue.h>// 1. 定义队列句柄变量
QueueHandle_t xIntegerQueue;// 发送任务
void vSenderTask(void *pvParameters) {int value_to_send = 0;for(;;) {// 2. 发送数据到队列if(xQueueSend(xIntegerQueue, &value_to_send, portMAX_DELAY) == pdPASS) {// 发送成功}value_to_send++;vTaskDelay(pdMS_TO_TICKS(1000)); // 每隔1秒发送一次}
}// 接收任务
void vReceiverTask(void *pvParameters) {int received_value = 0;for(;;) {// 3. 从队列接收数据if(xQueueReceive(xIntegerQueue, &received_value, portMAX_DELAY) == pdPASS) {// 成功接收到数据,可以处理 received_value// 例如,打印出来}}
}void main(void) {// 4. 创建队列:长度为5,每个项目是一个intxIntegerQueue = xQueueCreate(5, sizeof(int));// 检查队列是否创建成功if(xIntegerQueue != NULL) {// 创建任务...xTaskCreate(vSenderTask, "Sender", 1000, NULL, 1, NULL);xTaskCreate(vReceiverTask, "Receiver", 1000, NULL, 1, NULL);// 启动调度器vTaskStartScheduler();} else {// 队列创建失败!可能是内存不足// 处理错误}// 程序不应该运行到这里for(;;);
}

重要注意事项

  1. 动态内存xQueueCreate 使用 pvPortMalloc 动态分配内存,因此你需要确保 FreeRTOS 的堆配置得足够大。

  2. 替代函数xQueueCreateStatic。这是一个静态创建版本,它允许你提供存储队列结构体和存储区的内存缓冲区,而不是由函数内部动态分配。这在内存受限或不允许动态分配的系统中非常有用。

  3. 线程安全:队列的发送和接收函数是原子的,可以被多个任务或中断安全地调用,无需额外的保护。

  4. 阻塞:当队列已满时尝试发送,或者队列为空时尝试接收,任务可以进入阻塞状态等待,直到条件满足。这由 xQueueSend 和 xQueueReceive 的第三个参数(阻塞时间)控制。

总结

xQueueCreate 是 FreeRTOS 中构建任务间通信桥梁的基石函数。通过指定队列的容量和每个消息的大小,它为你创建了一个安全、可靠的数据通道,是多任务程序设计中不可或缺的工具。

http://www.hskmm.com/?act=detail&tid=39633

相关文章:

  • 量子力学作业3
  • #20232408 2025-2026-1 《网络系统与攻防技术》实验三实验报告 - 20232408
  • C_结构体学习_1
  • 嵌入式音频开发很好的博主
  • 实验3 C语言函数应用编程
  • 人工智能之编程基础 Python 入门:第一章 Python 的简介和安装
  • P5405 [CTS2019] 氪金手游 题解
  • 杂记选做 #1
  • 20232319 2025-2026-1 《网络与系统攻防技术》实验三实验报告
  • 2025.10.26 闲话-单位根反演
  • 题解:B4205 [常州市赛 2021] 特殊字符
  • 郭念海 - coder
  • 数据采集与融合技术实践第一次作业
  • ECC 学习笔记
  • 转化漏斗(随笔)
  • Halcon算法——区域生长
  • Windows11文件夹右键-删除多余选项-加快打开速度
  • 20231326《密码系统设计》第五周预习报告
  • 2025年实木家具厂家权威推荐榜:原木/全实木/北美黑胡桃/樱桃木/榫卯工艺/高端定制/全屋整装,烘干/白胚/木蜡油保养工艺深度解析
  • 2025年摘星搜荐怎么样:全面评测摘星AI的功能与优势
  • 实验 2
  • 2025 年 10 月系统门窗十大品牌榜单揭晓,技术研发实力与市场口碑深度解读
  • 【安卓】
  • 2025年TPU厂家权威推荐榜单:TPU加纤,TPU改性生产,专业定制与技术创新实力解析
  • 2025 年 10 月系统门窗十大品牌榜单揭晓,技术核心实力与市场口碑深度解读
  • 【万元奖金】第二届CCF算法能力大赛开始啦!名校云集、名企汇聚,免费参赛!
  • 切空间、切丛与收缩算子
  • 2025年仿石漆厂家推荐排行榜,外墙仿石漆,内墙仿石漆,防霉仿石漆,水包水仿石漆,水包砂仿石漆,耐污仿石漆,自洁仿石漆公司推荐
  • 2025年中央空调主机保养/维修/清洗/维保/维护公司推荐排行榜,水处理维保,物业公司/医院/写字楼/商场中央空调主机维保厂家精选
  • 变盲从为探索:专注听课,深耕实干