全球最实用的IT互联网信息网站!

AI人工智能P2P分享&下载搜索网页发布信息网站地图

当前位置:诺佳网 > 电子/半导体 > 嵌入式技术 >

RTOS中Queue的工作原理

时间:2023-07-25 15:45

人气:

作者:admin

标签:     原理  Queue  工作  RTOS 

导读:Queue即消息队列是通过RTOS内核提供的一种服务。它是一种线程间同步数据的安全方法。...

Queue概述

Queue即消息队列是通过RTOS内核提供的一种服务。它是一种线程间同步数据的安全方法。

队列(Queue)是与栈对应的概念;栈是FILO结构,而队列是FIFO结构。FreeRTOS原生的队列支持从高位添加新数据,但CMSIS简化删去了这一功能,即只能从队列底部推入数据并且对数据类型有限制,这一简化一般不影响使用。

  • RTOS中Queue的工作原理

图片

  • API Description:
    1.使用**osMessageQueueNew() 创建队列
    该函数会涉及
    osMessageQueueAttr_t **配置结构体;主要用于配置Control Block和名称;一旦使用该结构体将导致只能使用静态方式创建队列;一般传入NULL即可
osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr);/*
创建新的Queue队列
@retval    -队列地址(Queue Identifier)
@param     msg_count -队列可容纳的消息(变量)数量
@param     msg_size  -消息(变量)占用的空间[通常用sizeof()填入]
@param     *attr     -配置结构体对象,一般为NULL。 当传入NULL时,仅使用xQueueCreate()动态创建对应大小、数量的队列;
*/

2.使用**osMessageQueueDelete() **删除队列

该函数能释放队列占用的空间并清除其中内容和任务规划。队列删除后可通过**osMessageQueueNew() **重新创建。

osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id);/*删除队列
@retval     -osOK: the message queue object has been deleted.
            -osErrorParameter: parameter mq_id is NULL or invalid.
            -osErrorResource: the message queue is in an invalid state.
            -osErrorISR: osMessageQueueDelete cannot be called from interrupt service routines.
*/

3.获取队列配置信息

uint32_t osMessageQueueGetCapacity (osMessageQueueId_t  mq_id );
/*获取队列可容纳的消息(变量)数量; []
*/
uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t  mq_id );
/* 获取消息(变量)占用的空间 [单位byte]
*/
uint32_t osMessageQueueGetSpace (osMessageQueueId_t  mq_id );/*
  查询队列中空位(未填入变量)的数量
*/
uint32_t osMessageQueueGetCount (osMessageQueueId_t  mq_id );/*
  查询队列中已写入的消息(变量)数量
*/

4.※ 读取(取出)/写入队列

关于阻塞超时时间:

①读取(取出)阻塞超时:当任务读一个消息队列时,可通过osMessageQueueGet()设置阻塞超时时间。在这段时间中,如果队列为空(无变量),该任务将保持BLOCK状态以等待队列数据有效。在此期间当任务检测到其等待的队列中写入了数据时,将自动由BLOCK态转移为READY态。当等待的时间超过了指定的阻塞时间,即使队列中尚无数据,任务也会自动从阻塞态转移为READY态。此时程序会返回osErrorTimeout错误。若没有设置阻塞超时且参数正确,返回osErrorResource错误**。**

由于队列可以被多个任务读取,所以对单个队列而言,也可能有多个任务处于BLOCK
状态以等待队列数据有效。这种情况下,一旦队列数据有效,所有等待任务中优先级最高的任务被执行。而如果所有等待任务的优先级相同,那么被解除阻塞的任务将是等待最久的任务。

②写入阻塞超时: 同读队列一样,任务也可以在写队列时指定一个阻塞超时时间。这个时间是当被写队列已满时,任务进入BLOCK态以等待队列空间有效的最长时间。当等待的时间超过了指定的阻塞时间,即使队列中尚无数据,任务也会自动从BLOCK态转移为READY态。此时程序会返回osErrorTimeout错误。若没有设置阻塞超时且参数正确,返回osErrorResource错误。由于队列可以被多个任务写入,所以对单个队列而言,也可能有多个任务处于BLOCK
状态以等待队列空间有效。这种情况下,一旦队列空间有效,所有等待任务中优先级最高的任务被执行。而如果所有等待任务的优先级相同,那么被解除阻塞的任务将是等待最久的任务。

阻塞超时时间(timeout 变量)有三种配置:

==  0U     //不设置阻塞超时时间,若出现上述队列异常函数将直接报错返回
 ==  osWaitForever  //任务将一直阻塞直到空队列被写入/满队列被取出数据
 ==  Ticks   //设置具体等待时间,单位为RTOS心跳数(Ticks)

①用 osMessageQueueGet() 取出数据**【※可在中断中使用】**

osStatus_t osMessageQueueGet ( osMessageQueueId_t  mq_id,
void *  msg_ptr,       //储存读取结果的变量地址
uint8_t *  msg_prio,  // ==NULL
uint32_t  timeout    //阻塞超时时间
);

①用 osMessageQueuePut() 写入**【※可在中断中使用】**

osStatus_t osMessageQueuePut ( osMessageQueueId_t  mq_id,
const void *  msg_ptr,     //储存写入内容的变量地址
uint8_t  msg_prio,        //==0U
uint32_t  timeout         //阻塞超时时间
);

读出/写入的返回状态值:

-osOK: 取出/写入成功
-osErrorTimeout: the message could not be retrieved from/put into the queue in the given time (timed-wait semantics).
-osErrorResource: nothing to get from the queue or no space to push.
-osErrorParameter: parameter mq_id is NULL or invalid, non-zero timeout specified in an ISR.

5.清空队列

osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id);/*
@retval:      -osOK: the message queue has been rest.
              -osErrorParameter: parameter mq_id is NULL or invalid.
              -osErrorResource: the message queue is in an invalid state.
              -osErrorISR: osMessageQueueReset cannot be called from interrupt service routines.
*/
温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信