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

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

3天内不再提示

RTOS消息队列的多种用途

星星科技指导员 来源:嵌入式计算设计 作者:Jean Labrosse 2022-06-29 14:57 次阅读

RTOS 是一种软件,可以尽可能高效地管理中央处理单元 (CPU)、微处理单元 (MPU) 甚至数字信号处理器DSP) 的时间。大多数 RTOS 内核都是用 C 编写的,需要一小部分用 ASSEMBLY 语言编写的代码来使内核适应不同的 CPU 架构。

RTOS 内核为程序员提供了许多有用的服务,例如多任务处理、中断管理、通过消息队列的任务间通信、信令、资源管理、时间管理、内存分区管理等等。

应用程序(即最终产品)基本上分为多个任务,每个任务负责应用程序的一部分。任务是一个简单的程序,它认为它自己拥有 CPU。每个任务都根据任务的重要性分配一个优先级。

什么是消息队列?

如图 1 所示,消息队列是一个内核对象(即数据结构),消息通过它从中断服务例程 (ISR) 或任务发送(即,发布)到另一个任务(即,挂起)。一个应用程序可以有任意数量的消息队列,每个队列都有自己的用途。例如,消息队列可用于将从通信接口 ISR 接收到的数据包传递给任务,该任务又负责处理数据包。另一个队列可用于将内容传递给将负责正确更新显示的显示任务。

poYBAGK7-BCAa0fqAADeuVJW2Rk395.png

图 1.消息队列是用于将内容传递给任务的内核对象。

消息通常是指向包含实际消息的存储区域的空指针。但是,指针可以指向任何东西,甚至是接收任务要执行的函数。因此,消息的含义取决于应用程序。每个消息队列都可以配置其将容纳的存储量。可以将消息队列配置为保存单个消息(也称为邮箱)或N条消息。队列的大小取决于应用程序以及接收任务在队列填满之前处理消息的速度。

如果一个任务挂起(即等待)一条消息并且队列中没有消息,那么该任务将阻塞,直到一条消息被发布(即发送)到队列中。由于 RTOS 运行其他任务,因此等待任务在等待消息时不消耗 CPU 时间。如图 1 所示,挂起的任务可以指定一个超时时间。如果在指定的超时时间内没有收到消息,则当该任务成为最高优先级任务时,将允许该任务恢复执行(即解除阻塞)。当任务执行时,它基本上被告知它被恢复的原因是因为超时,因此没有收到消息。

消息队列通常实现为先进先出 (FIFO),这意味着接收到的第一条消息将是从队列中提取的第一条消息。但是,某些内核允许您发送被认为比其他内核更重要的消息,因此可以在队列的头部发布。换句话说,按照后进先出 (LIFO) 的顺序,使该消息成为任务提取的第一个消息。

消息队列的一个重要方面是消息本身需要从发送到处理期间保持在范围内。这意味着您不能将指针传递给堆栈变量、可以被其他代码更改的全局变量等等。为了使消息保持在范围内,您通常会填充从池中获取的结构如图 2 所示。发送消息的 ISR 或任务将从池中获取一个结构,填充该结构,并将指向该结构的指针发布到队列中。接收任务将从队列中提取指针,处理结构,完成后将结构返回到池中。当然,发送方和接收方都需要使用同一个池,除非数据结构中的字段指示使用了哪个池。

poYBAGK7-BiAUElQAABCfnUEn9Q907.png

图 2.消息存储区池

在 RTOS 中消息队列的许多实现中,如果队列已满,发送到队列的消息将被丢弃。通常这不是问题,应用程序的逻辑可以从这种情况中恢复。但是,实现一种机制相当容易,这样发送任务将阻塞,直到接收方提取其中一条消息,如图 3 所示:

1.计数信号量初始化为队列可以接受的最大条目数对应的值。

2.在允许发送消息到队列之前,发送任务在信号量上挂起。如果信号量值为零,则发送方等待。

3.如果该值非零,则信号量计数递减,并且发送方将其消息发布到队列中。

4.消息的接收者像往常一样在消息队列中挂起一个。

5.当接收到消息时,接收者从队列中提取指向消息的指针并向信号量发出信号,表明队列中的条目已被释放。

poYBAGK7-B-AHFZkAADUyYSwCO4928.png

图 3.如果队列已满,则阻止发送者。

如图所示,此机制仅适用于两个任务,因为不允许 ISR 挂在信号量上。

消息队列的其他用途

图 4 显示了消息队列的不同用途:

1-4。如前所述,消息队列通常用于将消息从 ISR 或任务发送到另一个任务。

5.但是,如果消息适合指针的字长,则不必发送实际消息并分配存储区域。例如,如果指针是 32 位宽,那么您可以将从 12 位 ADC 读取的模数转换器ADC) 转换为指针并通过消息队列发送它。只要接收者知道将值转换回整数,它就是完全合法的。

6-7。如果任务知道消息不会发送给它,它可以使用超时机制将自己延迟一段时间。在这种情况下,能够容纳单个条目的队列就足够了。事实上,如果另一个任务或 ISR 发送消息,延迟将被中止,这可能是您想要实现的行为。

8.消息队列可以用作信号量来简单地向任务发出事件发生的信号。在这种情况下,消息可以是任何东西。队列的大小取决于应用程序需要缓冲多少信号。

9-10。消息队列也可以用作二进制信号量或计数信号量以进行资源共享。对于二进制信号量,队列将包含单个消息,并且将在队列中放置一条消息(任何值)。要访问资源,任务将在队列中挂起。如果队列中有消息,则任务将获得对资源的访问权。一旦完成资源,队列将被发布,从而根据需要放弃资源以供其他任务使用。相同的机制适用于实现具有N个 资源的计数信号量,并且队列将预先填充N个 虚拟消息。

11.消息实际上可用于模拟事件标志,其中 32 位指针大小变量(转换为整数)的每一位都可以表示一个事件。

12.可以使用消息队列来实现栈结构。这基本上是 LIFO 机制的另一种用法。

poYBAGK7-CmAQBrlAAFPIRAHHRg171.png

图 4.消息队列的许多用途中的一些。

概括

消息队列可以以多种不同的方式使用。事实上,您可以编写可能只使用消息队列的相当复杂的应用程序。仅使用消息队列可以减少代码的大小(即占用空间),因为可以模拟许多其他服务(信号量、时间延迟和事件标志)。

审核编辑:郭婷

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

    关注

    68

    文章

    10434

    浏览量

    206521
  • MPU
    MPU
    +关注

    关注

    0

    文章

    297

    浏览量

    48360
  • RTOS
    +关注

    关注

    20

    文章

    775

    浏览量

    118781
收藏 人收藏

    评论

    相关推荐

    裸机中环形队列RTOS中消息队列有何区别呢?

    “环形队列”和“消息队列”在嵌入式领域有应用非常广泛,相信有经验的嵌入式软件工程师对它们都不陌生。
    的头像 发表于 01-26 09:38 243次阅读
    裸机中环形<b class='flag-5'>队列</b>与<b class='flag-5'>RTOS</b>中消息<b class='flag-5'>队列</b>有何区别呢?

    聊一聊消息队列技术选型的7种消息场景

    我们在做消息队列的技术选型时,往往会结合业务场景进行考虑。今天来聊一聊消息队列可能会用到的 7 种消息场景。
    的头像 发表于 12-09 17:50 919次阅读
    聊一聊消息<b class='flag-5'>队列</b>技术选型的7种消息场景

    无锁队列解决的问题

    为什么需要无锁队列 无锁队列解决了什么问题?无锁队列解决了锁引起的问题。 cache失效 当CPU要访问主存的时候,这些数据首先要被copy到cache中,因为这些数据在不久的将来可能又会被处理器
    的头像 发表于 11-10 15:33 263次阅读
    无锁<b class='flag-5'>队列</b>解决的问题

    消息队列的发展历史

    上一篇我们用一个秒杀案例探讨了我们为什么需要消息队列。今天我们来回顾一下消息队列的发展历史。
    的头像 发表于 10-30 10:49 395次阅读
    消息<b class='flag-5'>队列</b>的发展历史

    两个栈实现一个队列方法

    栈和队列是比较基础的数据结构。无论在工作中,还是在面试中,栈和队列都用的比较多。在计算机的世界,你会看到队列和栈,无处不在。 栈:一个先进后出的数据结构 队列:一个先进先出的数据结构
    的头像 发表于 10-08 15:54 579次阅读

    uC/OS-II队列原理 队列相关函数介绍

    消息队列是线程间通讯的一种,主要用作数据缓冲,用途非常广泛。一般情况下遵循先进先出原则。
    的头像 发表于 09-11 15:04 532次阅读
    uC/OS-II<b class='flag-5'>队列</b>原理 <b class='flag-5'>队列</b>相关函数介绍

    一种基于单片机实现的队列功能模块

    基于单片机实现的队列功能模块,主要用于8位、16位、32位非运行RTOS的单片机应用,兼容大多数单片机平台。
    的头像 发表于 08-14 11:09 486次阅读
    一种基于单片机实现的<b class='flag-5'>队列</b>功能模块

    RTOS中Queue的工作原理

    Queue即消息队列是通过RTOS内核提供的一种服务。它是一种线程间同步数据的安全方法。
    的头像 发表于 07-25 15:45 1842次阅读
    <b class='flag-5'>RTOS</b>中Queue的工作原理

    FreeRTOS消息队列结构体

    有一个结构体用于描述队列,叫做 Queue_t,这个结构体在文件 queue.c 中定义。 3、队列创建 在使用队列之前必须先创建队列,有两种创建
    的头像 发表于 07-06 17:03 675次阅读
    FreeRTOS消息<b class='flag-5'>队列</b>结构体

    FreeRTOS消息队列介绍

    队列是为了任务与任务、任务与中断之间的通信而准备的,可以在任务与任务、任务与中断之间传递消息,队列中可以存储有限的、大小固定的数据项目。任务与任务、任务与中断之间要交流的数据保存在队列中,叫做
    的头像 发表于 07-06 16:58 484次阅读
    FreeRTOS消息<b class='flag-5'>队列</b>介绍

    了解一下RTOS消息队列的应用

    基于RTOS的应用中,通常使用队列机制实现任务间的数据交互,一个应用程序可以有任意数量的消息队列,每个消息队列都有自己的用途。 什么是消息
    发表于 06-12 14:17

    RTOS消息队列的应用

    基于RTOS的应用中,通常使用队列机制实现任务间的数据交互,一个应用程序可以有任意数量的消息队列,每个消息队列都有自己的用途
    发表于 05-29 10:49 420次阅读
    <b class='flag-5'>RTOS</b>消息<b class='flag-5'>队列</b>的应用

    单片机消息队列的实现原理和机制

    单片机开发过程中通常会用到“消息队列”,一般实现的方法有多种。 本文给大家分享一下队列实现的原理和机制。
    的头像 发表于 05-26 09:50 860次阅读
    单片机消息<b class='flag-5'>队列</b>的实现原理和机制

    利用C++提供的队列封装一个消息队列

    最近的C++项目中,需要用到消息队列,但是C++中又没有原生的消息队列,就在网上找了一下相关资料,利用C++提供的队列,自己封装一个消息队列,以后的项目也可以复用。
    的头像 发表于 05-20 15:16 1096次阅读
    利用C++提供的<b class='flag-5'>队列</b>封装一个消息<b class='flag-5'>队列</b>

    嵌入式环形队列和消息队列是如何去实现的?

    嵌入式环形队列和消息队列是实现数据缓存和通信的常见数据结构,广泛应用于嵌入式系统中的通信协议和领域。
    发表于 05-20 14:55 669次阅读