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

    文章

    37

    浏览量

    11767
  • RTOS
    +关注

    关注

    20

    文章

    776

    浏览量

    118796
  • FreeRTOS
    +关注

    关注

    12

    文章

    473

    浏览量

    61349
  • Queue
    +关注

    关注

    0

    文章

    14

    浏览量

    7218
  • FIFO存储
    +关注

    关注

    0

    文章

    102

    浏览量

    5895
收藏 人收藏

    评论

    相关推荐

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

    太阳工作原理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

    定时器的基本工作原理

    一、定时器的基本概述通过滴漏和漏沙瓶这两个例子简单讲述定时器的基本工作原理。STM32的常见的定时器资源:系统嘀嗒定时器SysTick、看门狗定时器WatchDog、实时时钟RTC、基本定时器、通用
    发表于 08-02 08:45

    消息队列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

    基于Small RTOS51的汽车动态称重仪的设计

    介绍了基于嵌入式实时操作系统Small RTOS51的汽车动态称重仪设计方案,包括软件和硬件设计。描述了硬件的组成和工作原理,以及使用Small RTOS51软件设计,包括任务的划分、信号量
    发表于 12-23 16:37 45次下载

    光耦的工作原理

    光耦的工作原理 光耦的工作原理 光耦的工作原理
    发表于 12-25 15:10 0次下载

    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次下载

    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 5153次阅读
    队列<b class='flag-5'>Queue</b>的常用方法有哪些

    什么是queue

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