返回 IPC 通信机制 核心模块 / 任务间通信
HRTOS / IPC MECHANISM

邮箱机制 Mailbox

邮箱用于在任务之间传递单个数据值或状态信息。根据当前页面描述的实现, 它围绕资源单元中的 value 字段组织通信,并结合等待任务管理完成同步。 理解邮箱的关键,是区分“保存一个当前值”与“按顺序保存多条消息”这两种不同的数据模型。

单值消息模型 任务间通信 等待与唤醒 IPC

一、机制概述

Mailbox 是一种面向单个当前值的轻量通信模型。发送方将数据写入邮箱对应的资源单元; 接收方读取该值,并根据实现规则决定是否清空内容以及是否继续等待。

按照本页所描述的 HRTOS 实现,邮箱利用 OS_RES 资源结构中的 value 字段承载内容,并使用等待任务相关字段配合任务同步。

核心区别: 邮箱的数据存储模型是单值槽位,不应直接等同于 FIFO 消息队列。 如果业务要求每条消息都按顺序保留并处理,应进一步评估消息队列机制。

二、核心接口

以下列出本模块页面所涉及的接口名称。实际参数类型、返回值、错误处理及调用约束应以当前 HRTOS 头文件和 API 定义为准。

os_mailbox_init() os_mailbox_clear() os_mailbox_query() os_mailbox_send() os_mailbox_receive()
接口 页面描述的用途 需要核对的语义
os_mailbox_init() 初始化邮箱相关资源。 参数、资源编号、初始化状态及返回值。
os_mailbox_send() 写入要传递的数据,并可能唤醒等待任务。 覆盖规则、并发访问、唤醒条件及失败处理。
os_mailbox_receive() 读取邮箱数据;无可用数据时可能进入等待。 阻塞条件、超时语义、读取后是否清空。
os_mailbox_query() 查询当前邮箱内容。 返回值是否能区分空邮箱与数值为零的消息。
os_mailbox_clear() 清除邮箱当前内容。 清空操作是否影响等待任务,以及清空后的状态定义。
接口准确性: 本页保留原页面给出的接口名称,但未提供参数列表。发布前应与项目当前版本的头文件逐项核对,避免总览文档与实际 API 不一致。

三、数据模型

原页面描述的资源字段如下。此处用于解释邮箱与资源管理结构之间的关系,不应替代真实头文件中的结构定义。

OS_RESOURCE { value // 邮箱当前内容 owner // 原页面标注为未使用 wait_mask // 等待任务位图 wait_cnt // 等待任务计数 }

value 表示当前存储的数据; wait_mask 和 wait_cnt 则用于描述等待任务状态。 邮箱的内容存储与任务等待管理是两个相互关联、但概念上不同的部分。

注意零值: 原实现说明使用 value = 0 表示空状态,并在接收后清空。 如果零值本身也可能是合法消息,必须确认接口是否另有有效标志或其他判定规则; 否则,零值消息可能无法与空邮箱状态区分。

四、发送流程

按照原页面给出的实现思路,发送操作在保护共享状态的临界区内更新邮箱内容, 再检查等待状态并执行相应的唤醒处理。

01 · 进入临界区 保护共享状态
02 · 写入数据 更新当前 value
03 · 检查等待 判断等待任务状态
04 · 结束操作 按内核规则唤醒并退出
逻辑示意,并非可直接编译的源码
进入临界区 写入邮箱当前值 检查等待任务状态 如满足条件,执行相应唤醒处理 退出临界区
覆盖行为: 如果发送操作直接写入单个 value,且没有额外的满槽保护或排队机制, 新数据可能覆盖尚未读取的旧数据。需要以实际实现确认覆盖条件,以及发送方能否获知旧数据被覆盖。

五、接收流程

接收方需要判断邮箱当前是否存在可读取的数据。 按原页面描述,无数据时可能进入 WAIT_MAILBOX 等待状态; 被唤醒后再读取内容,并执行对应的清空处理。

01 · 检查状态 判断是否有可读数据
02 · 读取或等待 根据当前状态决定
03 · 获取内容 读取邮箱当前值
04 · 更新状态 按实现规则处理清空
原页面描述的逻辑示意
检查邮箱当前状态 如果存在可读取的数据: 读取数据 按接口规则更新邮箱状态 否则: 按等待机制进入等待状态 被唤醒后: 按接口定义继续检查并获取数据
实现边界: “等待后再次检查”通常是更稳妥的内核设计原则,但具体循环、调度和清空顺序必须与实际源码一致。 不应仅凭这份逻辑示意推断超时、竞态处理或中断上下文行为。

六、关键行为语义

操作 需要理解的核心问题
Send 写入当前值;是否覆盖旧数据,以及何时唤醒等待任务。
Receive 读取数据;是否阻塞,以及读取后如何更新邮箱状态。
Query 获取当前内容;是否修改状态,以及如何识别空邮箱。
Clear 清除当前内容;是否影响等待任务及其他并发操作。

对实时系统而言,接口的边界行为与正常路径同样重要。 在使用邮箱前,应明确数据覆盖策略、等待条件、并发保护方式和接口的调用上下文要求。

七、典型应用场景

  • 状态传递:将当前状态值传递给负责处理的任务。
  • 轻量数据交接:在两个任务之间传递一个当前数据值。
  • 控制信息:传递不要求逐条排队保存的控制数据。
  • 驱动与业务任务协作:在符合接口调用约束的前提下,交接状态或数据。
中断场景提醒: 如果计划在 ISR 中调用邮箱接口,必须先确认该接口是否允许在中断上下文使用, 包括是否可能阻塞、是否触发调度,以及临界区和嵌套中断方面的限制。不要仅凭“轻量”就认定接口可在 ISR 中安全调用。

八、邮箱、消息队列与事件的区别

机制 主要关注点 选型时重点检查
邮箱 Mailbox 一个当前值或单槽数据交接。 覆盖规则、空状态、读取后清空。
消息队列 Message Queue 多条消息的排队与传递。 容量、消息顺序、队列满时的行为。
事件 Event 事件状态通知与任务同步。 触发、清除、等待和唤醒语义。
信号量 Semaphore 计数或同步条件。 计数规则、获取与释放语义。
互斥锁 Mutex 共享资源的互斥访问。 所有权、释放责任及优先级相关行为。
简单判断:需要传递当前值时,评估邮箱;需要保留多条消息的处理顺序时,评估消息队列; 只需要表达某个状态或条件时,评估事件机制。最终选型仍应依据 HRTOS 的实际接口语义与资源开销。

九、总结

邮箱机制的价值在于以相对简单的数据模型完成任务间的数据交接。 理解它时,应重点关注当前值的有效性、发送时的数据覆盖、接收后的状态变化, 以及等待任务的唤醒规则。

在具体项目中,建议将邮箱接口与实际数据协议一起设计,并在多任务并发、连续发送、 零值数据和无消息等待等边界条件下进行验证。