事件对象

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

事件对象维护 32 位事件集合。线程可等待任意一个或全部指定事件,线程或 ISR 可投递事件。 在 prj.conf 中启用 CONFIG_EVENTS=y。

设置、合并与清除

  • k_event_set() 用新的位集合替换当前集合。

  • k_event_post() 将指定位置位,保留其他已有位。

  • k_event_clear() 清除指定的位。

  • k_event_set_masked() 只更新掩码指定的位。

事件位表示状态,重复 post 同一位不会累计次数。需记录每次发生的事件时使用计数或队列。

等待与原子消费

k_event_wait() 等待任意位,k_event_wait_all() 等待全部位;返回匹配位,超时返回 0。 这两个接口不会自动移除收到的事件。 reset=true 的含义是在开始等待前清空当前事件集合,不是“返回后自动清除”。 多个线程共享对象时,这样清空可能丢失其他线程关注的事件。

当前 API 还提供 k_event_wait_safe() 和 k_event_wait_all_safe(),在收到时原子地 清除匹配事件,避免“wait 返回后再 clear”之间的竞争。它们表达消费语义;多个消费者 不能把同一事件位当成各自独立的消息副本。

#include <zephyr/kernel.h>
#include <zephyr/sys/util.h>

K_EVENT_DEFINE(input_events);
#define EVENT_RX BIT(0)
#define EVENT_STOP BIT(1)

void notify_rx(void)
{
    k_event_post(&input_events, EVENT_RX);
}

uint32_t wait_input(void)
{
    return k_event_wait_safe(&input_events, EVENT_RX | EVENT_STOP,
                             false, K_MSEC(100));
}

ISR 只能进行不阻塞的事件操作;查询/等待必须使用 K_NO_WAIT。 若事件位对应某块共享缓冲区,事件 API 仍不能代替缓冲区所有权管理。

上游依据