消息队列在RTOS的应用

简介: 版权声明:本文为半吊子子全栈工匠(wireless_com,同公众号)原创文章,未经允许不得转载。
版权声明:本文为半吊子子全栈工匠(wireless_com,同公众号)原创文章,未经允许不得转载。 https://blog.csdn.net/wireless_com/article/details/79544020

传说互联网应用有两大利器,一个是缓存,另一个就是消息队列。 一直相对消息队列做一下梳理,希望早日另有成文。 一叶知秋,实际上消息队列在嵌入式系统中同样有着广泛的应用。 近来致力于IoT和智能硬件,现学习一下消息队列在RTOS中的应用场景。

RTOS是一个管理CPU的软件, 即微处理单元(MPU) , 还可能管理高效的DSP。 大多数 RTOS 内核是用 c 语言编写的, 同时需要用汇编语言编写一小部分代码来适应不同的 CPU 架构。一个 RTOS 内核为开发者提供了许多有用的服务, 如多任务处理、中断管理、通过消息队列、信号量、资源管理、时间管理、内存分区管理等等。

应用程序或者最终地产品基本上会划分为多个任务, 每个任务负责应用程序的一部分。 一个任务就是一个简单的程序, 它有自己的 CPU使用时间。 根据任务的重要性, 每个任务都被赋予了优先级。

RTOS中的消息队列

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

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

消息通常是指向包含实际消息存储区域的void指针。 这些指针可以指向任何东西, 甚至可以指向接收任务执行的函数。 因此, 它的实际含义取决于应用程序。 每个消息队列都可以根据它将保存的存储量进行配置。 消息队列可以配置为保存单个消息或者 n 个消息。 队列的大小取决于应用程序以及消费者的处理速度。

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

消息队列通常作为先入先出(FIFO)实现, 这意味着收到的第一个消息将是从队列中提取的第一个消息。 然而, 有些内核允许发送被认为比其他内核更重要的消息, 从而排在队列的首位。 换句话说, 在"先入先出"顺序中, 使该消息成为任务提取的第一条信息。

消息队列的另一个重要方面是, 消息本身需要保持从发送到处理的时间范围。 这意味着不能将指针传递给栈变量等等。 为了将消息保持在作用域中, 通常会填充一个结构, 并从这些消息池中获取, 如图2所示。 


图2 消息池的存储区域

发送消息的 ISR 或任务将从池中获取结构, 填充结构, 并将指针指向队列的结构。 接收任务将从队列中提取指针, 处理结构, 完成后将结构返回到池中。 当然, 发送方和接收方都需要使用相同的池, 除非数据结构中的字段指示使用了哪个池。

在 RTOS 中的许多消息队列实现中, 如队列已满, 则发送到队列的消息将被丢弃。 通常这不是一个问题, 应用程序的逻辑可以从这种情况中恢复。 然而, 如图3所示, 实现一个发送任务会发送消息的机制是相当容易的:

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

  1. 计数信号的初始化值与队列可接受的最大条目数相对应

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

  3. 如果值为非零, 则信号量减少, 发送方将消息发送到队列中

  4. 消息的接收方像往常一样将消息队列分隔开来

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

如图所示, 这个机制只适用于两个任务, 因为 ISR 不允许在信号量上分配信号。

消息队列的典型用法

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

1-4. 消息队列通常用于从 ISR 发送消息或将任务发送到另一个任务, 如前面所讨论的那样

5.但是, 如果消息符合指针的大小, 则不必发送实际消息及分配存储区域。 例如, 如果一个32位指针, 那么可以将模拟转换器(ADC)从一个12位 ADC 读取到一个指针, 并通过消息队列发送,只要接收这知道将值返回整数即可, 这是完全合法的

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

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

9-10 消息队列也可以用作二进制信号量或用于资源共享的计数信号量。 对于二进制信号量, 队列将包含单个消息, 并在队列中放置消息(任何值)。 为了访问资源, 可以在队列上分配一个任务。 如果队列中有消息, 则该任务将获得对资源的访问。 一旦使用了资源, 队列就会被发布, 从而根据需要放弃资源, 供其他任务使用。 同样的机制也适用于使用 n 个资源实现计数信号, 队列将预先填入n个虚拟消息。

11.消息实际上可以用来模拟事件标志, 其中32位指针大小的变量中,每一位可以代表一个事件

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

总而言之,消息队列有许多不同方式的使用场景。 事实上, 通过消息队列,可以编写相当复杂的应用程序。 使用消息队列可以减少代码的大小, 可以被模拟(信号、时间延迟和事件标志)许多其他的服务。

编译自http://www.embedded-computing.com/dev-tools-and-os/the-many-uses-of-rtos-message-queues


目录
相关文章
|
7月前
|
消息中间件 分布式计算 监控
Python面试:消息队列(RabbitMQ、Kafka)基础知识与应用
【4月更文挑战第18天】本文探讨了Python面试中RabbitMQ与Kafka的常见问题和易错点,包括两者的基础概念、特性对比、Python客户端使用、消息队列应用场景及消息可靠性保证。重点讲解了消息丢失与重复的避免策略,并提供了实战代码示例,帮助读者提升在分布式系统中使用消息队列的能力。
239 2
|
7月前
|
消息中间件 监控 大数据
Kafka消息队列架构与应用场景探讨:面试经验与必备知识点解析
【4月更文挑战第9天】本文详尽探讨了Kafka的消息队列架构,包括Broker、Producer、Consumer、Topic和Partition等核心概念,以及消息生产和消费流程。此外,还介绍了Kafka在微服务、实时数据处理、数据管道和数据仓库等场景的应用。针对面试,文章解析了Kafka与传统消息队列的区别、实际项目挑战及解决方案,并展望了Kafka的未来发展趋势。附带Java Producer和Consumer的代码示例,帮助读者巩固技术理解,为面试做好准备。
722 0
|
7月前
|
消息中间件 NoSQL Java
Redis Streams在Spring Boot中的应用:构建可靠的消息队列解决方案【redis实战 二】
Redis Streams在Spring Boot中的应用:构建可靠的消息队列解决方案【redis实战 二】
1137 1
|
6月前
|
消息中间件 Java RocketMQ
消息队列 MQ产品使用合集之当SpringBoot应用因网络不通而启动失败时,该如何解决
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
6月前
|
消息中间件 存储 Java
Java中的消息队列应用与性能优化
Java中的消息队列应用与性能优化
|
6月前
|
消息中间件 Arthas 监控
消息队列 MQ产品使用合集之每次重置reconsumeTimes就无法达到死信阈值,重试次数是否就要应用方控制
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
消息队列 MQ产品使用合集之每次重置reconsumeTimes就无法达到死信阈值,重试次数是否就要应用方控制
|
5月前
|
消息中间件 监控 Java
在Java应用中实现微服务间的消息队列通信
在Java应用中实现微服务间的消息队列通信
|
5月前
|
消息中间件 存储 Java
Java中的消息队列应用与性能优化
Java中的消息队列应用与性能优化
|
6月前
|
消息中间件 Serverless Windows
消息队列 MQ产品使用合集之MQTT协议是否可以应用于社交软件的系统通知场景
阿里云消息队列MQ(Message Queue)是一种高可用、高性能的消息中间件服务,它允许您在分布式应用的不同组件之间异步传递消息,从而实现系统解耦、流量削峰填谷以及提高系统的可扩展性和灵活性。以下是使用阿里云消息队列MQ产品的关键点和最佳实践合集。
|
7月前
|
消息中间件 存储 传感器
Kafka消息队列原理及应用详解
【5月更文挑战第6天】Apache Kafka是高性能的分布式消息队列,常用于实时数据管道和流应用。它提供高性能、持久化、分布式和可伸缩的消息处理,支持解耦、异步通信和流量控制。Kafka的核心概念包括Broker、Topic、Partition、Producer、Consumer和Consumer Group。其特点是高吞吐、低延迟、数据持久化、分布式架构和容错性。常见应用包括实时数据流处理、日志收集、消息传递和系统间数据交换。