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

    文章

    10824

    浏览量

    211100
  • MPU
    MPU
    +关注

    关注

    0

    文章

    345

    浏览量

    48729
  • RTOS
    +关注

    关注

    21

    文章

    809

    浏览量

    119413
收藏 人收藏

    评论

    相关推荐

    嵌入式环形队列与消息队列的实现原理

    嵌入式环形队列,也称为环形缓冲区或循环队列,是一种先进先出(FIFO)的数据结构,用于在固定大小的存储区域中高效地存储和访问数据。其主要特点包括固定大小的数组和两个指针(头指针和尾指针),分别指向队列的起始位置和结束位置。
    的头像 发表于 09-02 15:29 323次阅读

    freertos和rtos区别是什么

    FreeRTOS 和 RTOS(实时操作系统)是两个不同的概念,但它们之间有紧密的联系。FreeRTOS 是一个特定的开源实时操作系统,而 RTOS 是实时操作系统的一般概念。 概念定义 RTOS
    的头像 发表于 09-02 14:18 940次阅读

    RTOS与Linux有什么区别

    RTOS(Real-Time Operating System,实时操作系统)与Linux是两种在不同应用场景下发挥重要作用的操作系统,它们在设计理念、功能特性、应用场景以及性能表现等方面存在显著差异。以下是对RTOS与Linux区别的详细分析。
    的头像 发表于 08-20 16:05 2942次阅读

    RTOS的特性和类型

    实时操作系统(RTOS)是一种可运行实时计算应用程序的软件平台,用于处理具有明确时间约束的事件和数据。与通用操作系统(GPOS)不同,RTOS必须在有限的硬件资源上调度应用程序之间的处理和数据共享
    的头像 发表于 08-20 11:29 486次阅读

    RTOS开发最佳实践

    基于RTOS编写应用程序时,有一些要注意事项。在本节中,您将学习RTOS开发最佳实践,例如POSIX合规性、安全性和功能安全认证。
    的头像 发表于 08-20 11:24 401次阅读

    玩转RT-Thread之消息队列的应用

    在嵌入式系统开发中,实时处理串口和ADC数据是一项重要的任务。本文将介绍如何在RT-Thread实时操作系统中,利用消息队列来同时处理来自串口和ADC的数据。通过这种方法,我们能够高效地管理和处理
    的头像 发表于 07-23 08:11 545次阅读
    玩转RT-Thread之消息<b class='flag-5'>队列</b>的应用

    ESP8266_RTOS3.0串口0传输大量数据丢包的原因?

    传输数据最大1500字节,使用的ESP8266_RTOS3.0,先使用的example示例中的uart_events,结果发现当我向串口0发送长度大约800字节的数据时,重复收到消息队列,数据被分为
    发表于 07-09 06:32

    进程间通信的消息队列介绍

    消息队列是一种非常常见的进程间通信方式。
    的头像 发表于 04-08 17:27 284次阅读

    MCU专属队列功能模块之QueueForMcu应用

    当需要从队列头部获取多个数据,但又不希望数据从队列中删除时,可以使用 Queue_Peek_Array 函数来实现,该函数的参数与返回值与 Queue_Pop_Array 完全相同。
    发表于 03-20 11:44 415次阅读
    MCU专属<b class='flag-5'>队列</b>功能模块之QueueForMcu应用

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

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

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

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

    有没有办法或示例来编写一个函数来检查CAN硬件的接收缓冲区并以更符合RTOS的轮询方式提取任何新消息?

    CAN 接收缓冲区并将它们放入 RTOS 队列。 我面临的挑战是,唯一的 CAN 接收示例使用中断驱动的回调,这需要全局范围的命名函数。 这是非常具有挑战性的,因为我可以直接链接到类函数的名称,而无
    发表于 01-25 06:47

    labview 队列最前端插入的应用

    LabVIEW是一种用于实时测试、测量和控制系统的高级系统设计软件。它采用了数据流编程方式,提供了一种直观、可视化的方法来构建复杂的测试和测量应用程序。其中一个重要的功能是队列,它可以在软件设计中
    的头像 发表于 01-08 11:45 1146次阅读

    labview队列有什么实际作用

    LabVIEW队列是一种数据结构,常用于解决多任务并发处理的问题。它被广泛应用于科学研究、工程项目和自动化控制等领域。在LabVIEW中,队列提供了一种高效、方便的方式来处理不同任务之间的数据
    的头像 发表于 01-05 16:42 1496次阅读

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

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