0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

RTOS中Queue的工作原理

冬至子 来源:ITRelief 作者:Sachefgh Xu 2023-07-25 15:45 次阅读

Queue概述

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

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

图片

  • 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.
*/
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • CMSIS
    +关注

    关注

    0

    文章

    39

    浏览量

    11871
  • RTOS
    +关注

    关注

    21

    文章

    809

    浏览量

    119417
  • FreeRTOS
    +关注

    关注

    12

    文章

    483

    浏览量

    61996
  • Queue
    +关注

    关注

    0

    文章

    16

    浏览量

    7254
  • FIFO存储
    +关注

    关注

    0

    文章

    103

    浏览量

    5963
收藏 人收藏

    评论

    相关推荐

    感光太阳能灯工作原理。#工作原理大揭秘

    太阳工作原理DIY
    jf_24750660
    发布于 :2022年11月07日 22:26:04

    RTOS的定时功能

    RTOS
    橙群微电子
    发布于 :2023年02月27日 09:42:16

    【MiCOKit试用体验】庆科MiCO系统篇(4)MiCO RTOS消息队列

    对象的最大数量(2)OSStatus mico_rtos_push_to_queue(mico_queue_t* queue, void* message, uint32_t tim
    发表于 10-24 17:03

    Queue Management、Queue Proxy Regions和Queue Peek Region几个寄存器的主要区别是什么?

    Queue Management、Queue Proxy Regions和Queue Peek Region几个寄存器的主要区别是什么? 我看到手册上介绍的 Queue N Regis
    发表于 06-19 04:28

    消息队列Queue相关资料推荐

    消息队列QueueAPItx_queue_createtx_queue_deletex_queue_flushtx_queue_front_sendtx_queue_receivetx_queue_send_notifyAPItx_queue_createtx_queue_deletetx_queue_flushtx_qu
    发表于 02-22 06:53

    RT-Thread的data_queue是什么?怎样去使用

    1. data_queue 是什么data_queue 直接翻译过来是 数据队列。这个名字和 消息队列 很像。那么他们有什么区别呢?消息队列:消息队列能够接收来自线程或中断服务例程不固定
    发表于 04-15 15:56

    请问使用httpd_queue_work的目的是什么?

    您好,我正在查看 http 服务器组件并找到了这个函数:httpd_queue_work。追溯源码发现,它只是要求http服务器线程立即调用工作回调。回调不会在独立线程调用。我想知道使用这个功能
    发表于 03-02 08:28

    Linux之work_queue_share教程

    Linux之work_queue_share教程,很好的Linux资料,快来学习吧
    发表于 04-15 17:49 13次下载

    Linux之work_queue_custom教程

    Linux之work_queue_custom教程,很好的Linux自学资料,快来学习吧。
    发表于 04-15 17:49 8次下载

    Linux之work_queue_delay_work教程

    Linux之work_queue_delay_work教程,很好的Linux自学资料,快来学习吧。
    发表于 04-15 17:54 12次下载

    ThreadX(九)------消息队列Queue

    消息队列QueueAPItx_queue_createtx_queue_deletex_queue_flushtx_queue_front_sendtx_queue_receivetx_queue_send_notifyAPItx_queue_createtx_queue_deletetx_queue_flushtx_qu
    发表于 12-28 19:35 2次下载
    ThreadX(九)------消息队列<b class='flag-5'>Queue</b>

    队列Queue的常用方法有哪些

    FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue。
    的头像 发表于 08-19 10:24 5626次阅读
    队列<b class='flag-5'>Queue</b>的常用方法有哪些

    什么是queue

    queue 容器,又称队列容器,是简单地装饰deque容器而成为另外的一种容器。
    的头像 发表于 02-27 15:43 1524次阅读

    电源电容工作原理 电源设计的电容选用规则

    电源电容工作原理 电源设计的电容选用规则  电源的电容器是电路设计不可缺少的元件之一。它在电源的
    的头像 发表于 11-29 11:35 907次阅读

    基于RTOS的应用进程的典型线程

    RTOS的关键因素是最小的中断延迟和最小的线程切换延迟。RTOS的价值在于它的响应速度或可预测性,而不是它在给定时间段内可以执行的工作量。
    发表于 03-05 09:32 521次阅读
    基于<b class='flag-5'>RTOS</b>的应用进程<b class='flag-5'>中</b>的典型线程