H
HRTOS
IPC Core

消息队列

消息队列用于实现任务间FIFO顺序通信,支持多消息缓存与异步解耦, 是高频事件与数据流传输的核心机制之一。

核心特性

  • FIFO顺序缓存机制
  • 多消息异步通信
  • 生产者消费者解耦
  • 支持数据携带传输

应用场景

  • 传感器数据缓存
  • 通信帧缓冲处理
  • 按键事件队列
  • 批量数据传输
通信方式 异步FIFO队列
数据特性 携带数据,顺序消费
Principle

原理说明

消息队列是任务间通信的核心机制

消息队列(Message Queue)是一种基于FIFO(先进先出)的通信机制, 允许任务之间通过队列缓冲区进行异步数据传输。 生产者任务将消息发送到队列尾部,消费者任务从队列头部按顺序接收消息, 从而实现任务解耦和数据顺序一致性。

FIFO顺序缓存

消息队列采用先进先出机制,确保消息按照发送顺序被消费。 队列内部维护读写指针,实现高效的消息缓存和检索。

异步通信解耦

生产者和消费者运行节奏独立,无需同步等待。 生产者可连续发送消息,消费者按需接收,提高系统吞吐能力。

数据携带传输

与事件标志不同,消息队列可携带实际数据内容。 支持传输传感器读数、通信帧数据、状态信息等结构化数据。

多消息缓冲

队列可缓存多条消息,适应高频事件场景。 当生产者速度快于消费者时,队列起到缓冲作用,避免数据丢失。

核心判断: 消息队列 = 入队(Send) + FIFO缓存 + 出队(Recv) + 顺序消费, 是实现任务间异步数据传输和解耦的关键机制。
HRTOS Implementation

HRTOS 实现机制

HRTOS 如何实现消息队列通信

在 HRTOS 中,消息队列的实现围绕队列初始化、消息发送、消息接收和队列管理四个核心环节展开。 每个环节都经过精心设计,确保通信的高效性和可靠性。

队列初始化

初始化内容:分配队列缓冲区、设置队列容量、初始化读写指针

缓冲管理:使用静态数组作为消息存储空间

参数配置:指定队列大小和消息数据类型

状态设置:队列初始状态为空,等待消息写入

消息发送

发送方式:将消息写入队列尾部,更新写指针

队列检查:检测队列是否已满,满时返回失败

数据拷贝:将消息数据拷贝到队列缓冲区

任务唤醒:如有等待接收的任务,唤醒其运行

消息接收

接收方式:从队列头部读取消息,更新读指针

队列检查:检测队列是否为空,空时可阻塞等待

数据读取:从队列缓冲区拷贝消息数据到接收缓冲区

阻塞机制:支持非阻塞和阻塞两种接收模式

队列管理

指针管理:维护读指针和写指针,实现循环队列

状态跟踪:记录队列当前消息数量

溢出保护:防止队列溢出和数据覆盖

任务同步:管理等待发送和接收的任务列表

Workflow

工作流程

消息从发送到接收的完整执行路径

1队列初始化:hrtos_main 中调用 os_msgq_init 创建 FIFO 缓冲区
2任务创建:创建 producer 生产者任务和 consumer 消费者任务
3消息发送:producer 调用 os_msgq_send 将数据写入队列
4队列缓存:消息按 FIFO 顺序存储在队列缓冲区中
5消息接收:consumer 调用 os_msgq_recv 从队列读取数据
6数据处理:消费者处理接收到的消息数据并更新 LED 状态
hrtos_main → os_msgq_init → os_task_create(producer) → os_task_create(consumer) → producer发送 → os_msgq_send → 队列缓存 → os_msgq_recv → consumer接收 → 数据处理 → LED更新
Core Code

核心代码

消息队列通信的完整实现

生产者任务实现

producer 任务函数,持续发送消息到队列

#include "hrtos.h"

static os_msgq_t g_msgq;
static u8 g_msgq_buf[16];

sbit LED_P = P1^0;
sbit LED_C = P1^1;
sbit LED_Q = P1^2;

/* Producer */
void producer(void)
{
    u8 data = 0x10;

    while(1)
    {
        os_msgq_send(&g_msgq, 0, data, 0);
        LED_P = ~LED_P;

        LED_Q = 1;   // queue active
        data++;

        os_delay(3);
    }
}

消费者任务实现

consumer 任务函数,从队列接收并处理消息

/* Consumer */
void consumer(void)
{
    u8 data;

    while(1)
    {
        if(os_msgq_recv(&g_msgq, 0, &data, 0))
        {
            LED_C = ~LED_C;
            P1 = (P1 & 0xF0) | (data & 0x0F);
            LED_Q = 0;
        }

        os_delay(2);
    }
}

系统初始化与任务创建

hrtos_main 函数,初始化队列并创建生产者和消费者任务

void hrtos_main(void)
{
    os_msgq_init(&g_msgq, g_msgq_buf, sizeof(g_msgq_buf));

    os_task_create((unsigned int)producer, 1, 3, 5);
    os_task_create((unsigned int)consumer, 2, 2, 5);
}
Expected Result

运行结果

示例执行后的预期行为

LED_P 状态 生产者 LED 翻转,表示消息发送成功
LED_C 状态 消费者 LED 翻转,表示消息接收成功
LED_Q 状态 队列活动指示,发送时点亮,接收后熄灭
数据传输 数据值递增并通过队列传递,显示在 P1 端口低4位
系统本质: 本示例验证 HRTOS 消息队列机制:生产者和消费者通过 FIFO 队列实现异步数据传输, 任务运行节奏解耦,保证消息顺序一致性。
Important Notes

注意事项

使用本示例时需要关注的关键点

队列容量配置

g_msgq_buf 数组大小决定了队列容量,容量不足会导致消息发送失败。 本示例使用 16 字节缓冲区,实际应用中应根据消息频率和数据大小调整。

任务优先级设置

producer 优先级为 3,consumer 优先级为 2。 较低的消费者优先级确保队列不会因消费过快而空,体现缓冲作用。

阻塞与非阻塞

本示例使用非阻塞模式(超时参数为 0)。 实际应用中可根据需求设置超时时间,实现阻塞等待机制。

队列溢出处理

当生产者速度快于消费者时,队列可能满。 需要合理设计队列容量和任务调度策略,避免消息丢失。