邮箱

本页依据 文档基线与后续更新 中记录的 Zephyr main 快照更新。

邮箱用消息描述符协调线程之间的数据交换,支持可变长度数据,以及指定发送者或接收者。 它适合需要匹配和处理完成确认的通信。邮箱面向线程,不用于 ISR 收发。

消息描述符

struct k_mbox_msg 包含传输长度、应用定义的 info、发送数据地址以及匹配线程等字段。 发送端设置 tx_target_thread,接收端设置 rx_source_thread;K_ANY 表示不限定线程。 info 可在双方交换应用层信息,不需要载荷时也可使用长度为 0 的消息。

同步发送与接收

#include <zephyr/kernel.h>

K_MBOX_DEFINE(requests);

int send_value(uint32_t value)
{
    struct k_mbox_msg msg = {
        .size = sizeof(value),
        .tx_data = &value,
        .tx_target_thread = K_ANY,
    };
    return k_mbox_put(&requests, &msg, K_MSEC(100));
}

int receive_value(uint32_t *value)
{
    struct k_mbox_msg msg = {
        .size = sizeof(*value),
        .rx_source_thread = K_ANY,
    };
    return k_mbox_get(&requests, &msg, value, K_MSEC(100));
}

此例双方约定载荷固定为一个 uint32_t。一般协议应检查接收后的 msg.size 和 info,不要假设对端一定发送了预期长度。接收缓冲区容量通过接收描述符的 size 表达,实际交换长度受双方约束。

同步发送的超时边界

k_mbox_put() 的超时只约束“等待接收者接收消息”阶段。 一旦匹配接收者,发送者还会等待接收者处理/取走数据,这一阶段可以超过原超时, 甚至无限等待。不能把 100 ms 参数解释为函数一定在 100 ms 内返回。

k_mbox_get(..., NULL, ...) 可先接收描述符、延后取数据。 此后必须用 k_mbox_data_get() 取出数据或显式丢弃,完成消息处理;否则同步发送者 可能持续阻塞。数据缓冲区在交换完成前必须有效。

异步发送与完成通知

k_mbox_async_put() 支持异步发送,可传入完成信号量,消息处理结束时由邮箱 give。 完成信号量有助于决定何时复用发送缓冲区。异步不意味着可立即释放载荷。

CONFIG_NUM_MBOX_ASYNC_MSGS 是 整数容量,不是布尔开关;设为 0 禁用异步消息支持。 异步描述符来自系统共享的有限资源池。本次固定提交在资源池耗尽时会等待空闲描述符, 因此应按所有邮箱的在途消息总量设计流控。该函数没有用于报告排队失败的整型返回值。

返回值

同步 put/get 成功返回 0,不等待且不能完成时返回 -ENOMSG,等待接收超时返回 -EAGAIN。涉及异步路径时,应使用完成通知和应用层约束跟踪消息生命周期。

上游依据