下载 FreeRTOS
 

出色的 RTOS & 嵌入式软件

内核
最新资讯
简化任何设备的身份验证云连接。
利用 CoAP 设计节能型云连接 IoT 解决方案。
11.0.0 版 FreeRTOS 内核简介:
FreeRTOS 路线图和代码贡献流程。
使用 FreeRTOS 实现 OPC-UA over TSN。

RTOS 消息缓冲区
[流缓冲区和消息缓冲区]


本页面包含:
  1. 简介
  2. 入门
  3. 设置消息缓冲区大小
  4. 阻塞读取和写入
  5. 发送和接收完整宏(用于多核)


简介

消息缓冲区允许长度可变的离散消息从中断服务程序传递至 一个任务,或从一个任务传递至另一个任务。 例如,长度为 10、20 和 123 字节的消息 都可以在同一个消息缓冲区写入或读取 。 与使用流缓冲区不同的是, 长度为 10 个字节的消息只能作为 10 个字节的消息读取,而不能 以单独的字节读取。 消息缓冲区构建在流缓冲区之上(即它们使用 流缓冲区实现)。

消息通过副本在消息缓冲区中传递——发送方将数据复制到 缓冲区中,并通过读取将其从缓冲区复制出来。

另请参阅 configMESSAGE_BUFFER_LENGTH_TYPE 配置参数的定义。

不同于大多数其他 FreeRTOS 通信原语, 流缓冲区以及消息缓冲区 针对单个读取者和单个写入者场景进行了优化, 例如将数据从中断服务程序传递到任务, 或从双核 CPU 上的一个微控制器内核传递到另一个微控制器内核。

通过将 FreeRTOS/source/stream_buffer.c 源文件包含在构建中 来启用消息缓冲区功能。

消息缓冲区实现采用 直达任务通知。 因此,调用使调用任务进入阻塞状态的 消息缓冲区 API 函数可以更改调用任务的 通知状态和通知值。

重要提示: 在 FreeRTOS 对象中独一无二的是, 流缓冲区实现( 消息缓冲区 构建在流缓冲区之上,所以消息缓冲区实现也是如此)假设只有一个任务或 中断会写入缓冲区(写入者), 并且只有一个任务或中断将从缓冲区读取(读取者)。 写入者和读取者可以是不同的任务或中断,这样是安全的, 但不同于 其他 FreeRTOS 对象,具有多个写入者或读取者 并不安全。 如果有多个不同的写入者, 则应用程序编写者必须将每个 写入 API 函数的调用(如 xStreamBufferSend())放在一个临界区中, 并以 “0” 为发送阻塞时间。 同样, 如果存在多个不同的读取者,那么应用程序编写者必须将 每个读取 API 函数的调用(如 xStreamBufferReceive()) 放在临界区中,并以 “0” 为接收阻塞时间。


入门指南

FreeRTOS/Demo/Common/Minimal/MessageBufferAMP.c 源文件 提供一个有大量注释的示例,该示例展示了如何使用消息缓冲区将可变长度数据 在一个多核 MCU 上从一个 MCU 核心传递到另一个 MCU 核心。 这是一个相当 高级的场景,但创建消息缓冲区,向缓冲区发送和从缓冲区接收的机制 与更简单的单核场景中的机制是相同的, 与演示不同, 此场景不需要覆盖 sbSEND_COMPLETE() 宏。

请参阅用户文档中的消息缓冲区部分查阅和消息缓冲区相关的 API 函数列表, 许多情况下, 还包含演示所用函数的 代码片段。


设置消息缓冲区大小

要使消息缓冲区能够处理可变大小的消息, 在将消息写入消息缓冲区之前,需将每条消息的长度 先写入消息缓冲区(通过 FreeRTOS API 函数在内部完成)。 长度 存储在变量中,其类型由 configMESSAGE_BUFFER_LENGTH_TYPE 变量 (位于 FreeRTOSConfig.h 中)设置。 如果未定义,则默认 configMESSAGE_BUFFER_LENGTH_TYPE 为 size_t 类型。 在 32 位架构上,size_t 通常 为 4 个字节。 因此,作为示例,当 configMESSAGE_BUFFER_LENGTH_TYPE 为 4 个字节时, 将 10 字节长度的消息写入消息缓冲区实际上会消耗 14 字节的缓冲区空间。 同理,将一条 100 字节长度的消息 写入消息缓冲区实际上将占用 104 字节的缓冲区空间。


阻塞读取和写入

xMessageBufferReceive())用于 从 RTOS 任务的消息缓冲区读取数据。 xMessageBufferReceiveFromISR())用于 从中断服务程序 (ISR) 的消息缓冲区读取数据。 xMessageBufferSend())用于 将数据发送到 RTOS 任务的消息缓冲区。 xMessageBufferSendFromISR())用于 将数据从中断服务程序 (ISR) 发送到消息缓冲区。

如果任务使用 xMessageBufferReceive() 从消息缓冲区读取数据, 而该消息缓冲区正好是空的,此时如果指定了非零的阻塞时间,则任务将 进入阻塞状态(因此它不会消耗任何 CPU 时间,且其他任务可以运行) 直到消息缓冲区中的任一数据变得可用,或超过 阻塞时间。

如果任务使用 xMessageBufferSend() 将消息写入消息缓冲区, 而该消息缓冲区正好已满,此时如果指定了非零的阻塞时间,则任务将 进入阻塞状态(因此它不会消耗任何 CPU 时间,且其他任务可以运行) 直到消息缓冲区中的任一空间变得可用,或超过 阻塞时间。


发送并接收完整宏

由于消息缓冲区构建在流缓冲区上,sbSEND_COMPLETE() 和 sbRECEIVE_COMPLETE() 宏的行为 与流缓冲区说明页面所述完全相同。






Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.