裸机中环形队列与RTOS中消息队列的区别

💡 原文中文,约4400字,阅读约需11分钟。
📝

内容提要

环形队列和消息队列是嵌入式领域常用的数据结构,分别用于通信和任务间通信。环形队列适合资源较小的系统,消息队列结合RTOS应用更灵活。建议研究这两种队列。

🔎

延伸解读

环形队列判空判满的两种实现思路

文章指出环形队列的关键是区分队空和队满,因为head与tail相等时既可能为空也可能为满。为此给出两种方法:一是附加tag标志位,head追上tail时tag=0表示空,tail追上head时tag=1表示满;二是限制tail追上head,即队尾与队首之间至少留一个元素空间,此时队空条件为head==tail,队满条件为(tail+1)%MAXN==head。两种方法各有取舍,前者多用一个标志位,后者牺牲一个存储单元。

RTOS消息队列的阻塞与优先级机制

文章以FreeRTOS为例说明,消息队列的读写均支持超时阻塞。发送时若队列已满且不允许覆盖,任务会按指定超时时间阻塞,直到有任务读取使队列未满,或超时后返回errQUEUE_FULL。接收时若队列为空,任务同样阻塞等待数据有效。当多个任务阻塞在同一队列上时,系统按任务优先级排序,优先级高的任务优先获得队列访问权。这一机制是消息队列区别于裸机环形队列的重要特性。

选型参考:资源占用与系统依赖

文章对比指出,环形队列可以独立使用,也可结合操作系统,占用资源更小,更适合资源有限的系统;消息队列则依赖RTOS,但结合RTOS应用更灵活,例如支持延时、中断传输数据等。两者结构中都包含头、尾、标志等信息,都分配连续内存空间,且都可分配多个队列,应用场景类似,尤其在通信领域有大量吞吐数据时。选型时需权衡资源开销与系统灵活性。

❓

Q&A

环形队列在嵌入式通信中有什么优势?

环形队列是一种首尾相连的FIFO数据结构,采用数组的线性空间实现,数据组织简单,可以快速判断队列是否为空或已满,并且能以很快的速度存取数据,因此适合资源较小的系统,常用于UART、USB、CAN、网络等通信领域。

如何判断环形队列是空还是满?

有两种常用方法:一是附加标志位tag,当head赶上tail时队列空,令tag=0;当tail赶上head时队列满,令tag=1。二是限制tail赶上head,即队尾与队首之间至少留一个元素空间,此时队列空条件为head==tail,队列满条件为(tail+1)%MAXN==head。

RTOS中的消息队列支持哪些特性?

RTOS消息队列常见特性包括:支持先进先出和后进先出(LIFO)两种排队方式;支持异步读写和超时机制;允许不同长度(不超过队列节点最大值)的任意类型消息;一个任务可以从任意队列收发消息,多个任务可以从同一个队列收发消息;使用结束后可通过删除队列函数释放资源。

消息队列的阻塞机制是如何工作的?

出队阻塞:当队列为空时,任务可以指定阻塞超时时间等待数据,一旦有数据写入,任务自动由阻塞态转为就绪态;超时后即使无数据也会转为就绪态。入队阻塞:当队列已满时,发送者根据指定的阻塞超时时间等待队列有空闲空间,期间若有其他任务读取数据使队列未满,则发送任务转为就绪态;超时后发送失败并返回错误码errQUEUE_FULL。多个任务阻塞时,优先级高的任务优先获得队列访问权。

环形队列和消息队列的主要区别是什么?

主要区别有:1. 环形队列可以独立使用,也可以结合操作系统使用;而消息队列依赖RTOS。2. 环形队列占用资源更小,更适合资源较小的系统;消息队列结合RTOS应用更加灵活,比如支持延时、中断传输数据等。

在FreeRTOS中如何创建和使用消息队列?

在FreeRTOS中,使用xQueueCreate(QUEUE_LEN, QUEUE_SIZE)创建消息队列,系统会为队列控制块分配内存,保存头指针pcHead、尾指针pcTail、消息大小uxItemSize和队列长度uxLength等信息。任务或中断可以发送消息到队尾(或队头发送紧急消息),接收任务可以从队列读取消息,并支持阻塞超时机制。使用完毕后应调用删除队列函数释放资源。

🏷️

标签

➡️

继续阅读