消息队列
本页依据 文档基线与后续更新 中记录的 Zephyr main 快照更新。
消息队列传递固定大小的数据项。put 把消息内容复制到队列或等待接收者, get 把内容复制到接收缓冲区。因此小结构体可直接传递,结构体中的指针仍需另行管理生命周期。
定义与收发
#include <zephyr/kernel.h>
struct reading {
uint32_t sequence;
int32_t milli_value;
};
K_MSGQ_DEFINE(readings, sizeof(struct reading), 8, 4);
int publish_reading(uint32_t sequence, int32_t value)
{
const struct reading item = { sequence, value };
return k_msgq_put(&readings, &item, K_NO_WAIT);
}
int receive_reading(struct reading *item)
{
return k_msgq_get(&readings, item, K_MSEC(100));
}
消息缓冲区至少要容纳定义时指定的消息长度。
k_msgq_init() 可使用应用提供的存储;k_msgq_alloc_init() 支持动态分配,
需要检查失败并在生命周期结束后按接口约定 cleanup。
容量和返回值
返回 0:发送或接收成功。
-ENOMSG:无等待操作无法完成,或等待因队列清空而结束。-EAGAIN:限时等待超时。
队列满时,生产者可等待、丢弃新消息或实施流控。
k_msgq_purge() 丢弃整个队列中的消息,还可能影响正在等待的发送者,
不能把它当作无代价的重试动作。示例返回错误给调用者,由调用者决定策略。
查看与扩展操作
k_msgq_peek() 查看队首消息但不移除。
k_msgq_num_used_get() 和 k_msgq_num_free_get() 可用于统计,不能替代实际 put/get
的返回值判断。当前接口还包含非阻塞的 k_msgq_put_front(),用于插入队首;
应谨慎使用,持续的高优先消息可能推迟普通消息处理。
线程与 ISR
put/get 可在 ISR 中使用,但超时必须是 K_NO_WAIT。
复制大消息会延长临界区处理时间;需要传大块数据时可改传指针,并制定清晰的所有权规则,
或选用 FIFO 与 LIFO。