LwEVT 入门:注册回调,dispatch 广播事件

声明: LwEVT 是一个开源项目,作者为 Tilen MAJERLE。本文是阅读该项目源码和文档后整理的入门笔记。本文作者不是该项目的开发者,未参与该项目的任何代码贡献。 示例代码已在本机 GCC 与 ARM GCC 下编译运行验证。

项目仓库:github.com/MaJerle/LwEVT

这篇文章帮你完成一件事:把 LwEVT 跑起来,实现"按键按下发一个事件、温度采集完发一个带数据的事件"。全程只用 5 个 API,不需要理解内部实现。

LwEVT 的调用流程

LwEVT 是事件分发器:事件(event)由类型 type 区分,监听器(listener)就是普通回调函数。核心动作只有两个:

  1. LwEVT_register() 注册回调,可注册多个,最多 LwEVT_CFG_MAX_EVT_LISTENERS 个(默认 8)
  2. LwEVT_dispatch() 广播事件给所有已注册回调,逐个调用

LwEVT 分发流程

示例代码:按键与温度事件

先建两个文件:LwEVT_opts.h(配置)和 LwEVT_types.h(事件类型),从仓库的 LwEVT_opts_template.hLwEVT_types_template.h 复制改名即可。

LwEVT_types.h 定义事件类型。LwEVT_TYPE_BASIC 定义不带数据的事件,LwEVT_TYPE_EXT 定义带数据的事件,数据声明成 C 结构体:

LwEVT_TYPE_BASIC(LwEVT_TYPE_BTN_PRESSED)
LwEVT_TYPE_BASIC(LwEVT_TYPE_BTN_RELEASED)
LwEVT_TYPE_EXT(LwEVT_TYPE_TEMP_READY, struct { int16_t temp_x10; } temp)

main.c 完整流程:

#include "LwEVT/LwEVT.h"
#include <stdint.h>

static uint32_t btn_press_count;

/* 监听器 1:按键计数 + 温度判断 */
static void on_event(LwEVT_t *evt)
{
    switch (evt->type) {
    case LwEVT_TYPE_BTN_PRESSED:
        btn_press_count++;
        break;
    case LwEVT_TYPE_TEMP_READY:
        /* 零拷贝:直接读句柄 union 里的数据 */
        if (evt->msg.temp.temp_x10 > 300) {
            /* 超过 30.0 °C */
        }
        break;
    default:
        break;
    }
}

/* 监听器 2:只关心温度,独立记录 */
static void on_temp_log(LwEVT_t *evt)
{
    if (evt->type == LwEVT_TYPE_TEMP_READY) {
        /* 把温度写入日志缓冲区 */
    }
}

int main(void)
{
    LwEVT_t *evt;

    LwEVT_init();                 /* 1. 初始化 */
    LwEVT_register(on_event);     /* 2. 注册监听器 1 */
    LwEVT_register(on_temp_log);  /* 3. 注册监听器 2 */

    /* 4. 无数据事件:直接 dispatch */
    LwEVT_dispatch(LwEVT_TYPE_BTN_PRESSED);

    /* 5. 带数据事件:先拿句柄写数据,再 dispatch */
    evt = LwEVT_get_handle();
    evt->msg.temp.temp_x10 = 315;
    LwEVT_dispatch(LwEVT_TYPE_TEMP_READY);

    return 0;
}

运行输出(验证版加 printf):

button pressed, count=1
temp=31.5 C
over 30.0 C
temp logged=315

关键点:dispatch 是广播,所有已注册监听器都会收到每个事件(上例两个监听器各处理一次);监听器自己判断关心哪种事件(用 switch 或 if)。注册顺序就是调用顺序,同一函数指针重复注册会被去重。

LwEVT_opts.h 配置项

LwEVT 的特色

适用边界