Nucleus SE邮箱:配置与使用实战指南
查看RTOS Revealed系列
邮箱在早期文章中作为Nucleus SE中最简单的任务间通信机制之一被引入——仅次于信号。它们提供低成本、高灵活性的方式在任务间传递简单数据。
使用邮箱
在Nucleus SE中,邮箱在构建时定义。每个应用最多可配置16个邮箱。若配置零邮箱,编译器省略所有相关数据结构和API代码,保持二进制精简。
邮箱本质是可容纳单个ADDR类型变量的存储槽。同一时间仅允许一个任务写入邮箱。一旦满,后续写入尝试将失败,直到邮箱被读取或重置。视API选项而定,写满邮箱尝试可能返回错误或挂起任务直至有空间。
邮箱 vs 队列
某些操作系统用单入口队列替代邮箱。队列可模仿邮箱行为,但额外开销——头尾指针、更大数据结构、更多代码路径——导致更高内存占用和执行时间。
在Nucleus SE中,您可选择邮箱或队列。若设计用大量队列但仅少量邮箱,以队列替代邮箱将略增数据大小但移除邮箱专用API代码,简化维护。易于测试两种配置对比内存占用和性能。
队列将在后续文章介绍。
配置邮箱
邮箱数量
nuse_config.h中关键宏是NUSE_MAILBOX_NUMBER。默认值0表示不启用邮箱。可设为1至16任意整数。nuse_config_check.h中编译时检查会在值超范围触发错误。
设非零值激活邮箱子系统:数据结构定尺寸,API启用符号被处理。
API启用
每个邮箱API调用在nuse_config.h有对应#define:
NUSE_MAILBOX_SENDNUSE_MAILBOX_RECEIVENUSE_MAILBOX_RESETNUSE_MAILBOX_INFORMATIONNUSE_MAILBOX_COUNT
默认全为FALSE,禁用调用及实现。使用API时,将对应宏设为TRUE启用。无邮箱配置时启用API会导致编译时错误(除NUSE_Mailbox_Count()始终可用)。使用禁用API会产生链接时错误。
/* 系统邮箱数量 – 0-16 */ #define NUSE_MAILBOX_NUMBER 0 /* 服务调用启用器: */ #define NUSE_MAILBOX_SEND FALSE #define NUSE_MAILBOX_RECEIVE FALSE #define NUSE_MAILBOX_RESET FALSE #define NUSE_MAILBOX_INFORMATION FALSE #define NUSE_MAILBOX_COUNT FALSE 邮箱服务调用
Nucleus SE提供九个邮箱相关服务调用。SE中实现的有:
- NUSE_Mailbox_Send() – 向邮箱写消息。
- NUSE_Mailbox_Receive() – 从邮箱读消息。
- NUSE_Mailbox_Reset() – 清空邮箱不挂起任务。
- NUSE_Mailbox_Information() – 查询邮箱状态。
- NUSE_Mailbox_Count() – 返回配置邮箱数量。
创建、删除、批量检索、广播等其他功能在SE中未实现。
写与读操作
邮箱支持两核心操作:发送(写)和接收(读)。两API在Nucleus RTOS和Nucleus SE均可用,灵活性和错误处理有差异。
发送到邮箱
Nucleus RTOS中NU_Send_To_Mailbox支持邮箱满时无限或定时挂起。Nucleus SE提供简化版:挂起可选、不支持超时。
Nucleus SE示例原型:
STATUS NUSE_Mailbox_Send(NUSE_MAILBOX mailbox, ADDR *message, U8 suspend); 参数:
mailbox– 邮箱索引。message– 指向ADDR变量的指针。suspend–NUSE_NO_SUSPEND或NUSE_SUSPEND。
返回值含NUSE_SUCCESS、NUSE_INVALID_MAILBOX、NUSE_MAILBOX_FULL、NUSE_MAILBOX_WAS_RESET。
实现概览
禁用阻塞时,例程检查邮箱状态标志。若邮箱为空,写入数据并标记为满;否则返回NUSE_MAILBOX_FULL。
启用阻塞时,代码循环直到消息成功投递或任务被接收操作唤醒。若任务挂起于邮箱,成功发送后立即恢复。
以下片段演示启用阻塞时核心逻辑(为可读性简化):
do { if (!NUSE_Mailbox_Status[mailbox]) { // 邮箱空 – 存储数据并唤醒等待任务(若有) } else if (suspend == NUSE_NO_SUSPEND) { return NUSE_MAILBOX_FULL; } else { // 挂起任务直至邮箱变空 } } while (suspend == NUSE_SUSPEND); 总之,邮箱API平衡简洁与灵活,让开发者按应用时序需求选择立即失败或任务挂起。
嵌入式