Files
stc32g128k/Docs/60_coding/mod-event.md

2.6 KiB
Raw Blame History

编码实现 - 事件总线与缓冲路由 (Docs/60_coding/mod-event.md)

本文件对应环形事件缓冲区Event Queue与事件路由分发器的具体编码实现细节。

1. 对应代码源文件

  • App/main.c (事件队列定义、Event_Queue_Push / Event_Queue_Pop / Event_Dispatcher_Loop 的底层 C 语言实现)
  • App/config.h (KeyEvent 枚举量定义)

2. 关键代码片段与逻辑实现

2.1 环形队列定义与入队出队函数

main.c 中,定义深度为 4 级的事件队列缓冲数组及读写位置指针:

#define EVENT_QUEUE_SIZE 4

KeyEvent idata event_queue[EVENT_QUEUE_SIZE];
u8 event_write_ptr = 0;
u8 event_read_ptr = 0;
u8 event_count = 0;

// 初始化队列
void Event_Queue_Init(void) {
    event_write_ptr = 0;
    event_read_ptr = 0;
    event_count = 0;
}

// 压入事件入队 (非阻塞,中断安全)
bit Event_Queue_Push(KeyEvent evt) {
    if (event_count >= EVENT_QUEUE_SIZE) {
        return 0; // 缓冲区溢出,写入失败
    }
    
    event_queue[event_write_ptr] = evt;
    event_write_ptr = (event_write_ptr + 1) % EVENT_QUEUE_SIZE;
    
    // 保护临界区,避免中断嵌套冲突
    EA = 0;
    event_count++;
    EA = 1;
    
    return 1;
}

// 弹出事件出队
KeyEvent Event_Queue_Pop(void) {
    KeyEvent evt;
    if (event_count == 0) {
        return KEY_EVENT_NONE;
    }
    
    evt = event_queue[event_read_ptr];
    event_read_ptr = (event_read_ptr + 1) % EVENT_QUEUE_SIZE;
    
    EA = 0;
    event_count--;
    EA = 1;
    
    return evt;
}

2.2 事件轮询分发器 (Event Dispatcher)

在主循环 main() 中,系统定时轮询事件总线,读取事件并路由给前后台应用:

void Event_Dispatcher_Loop(void) {
    KeyEvent evt = Event_Queue_Pop();
    if (evt == KEY_EVENT_NONE) {
        return; // 队列为空,直接跳过
    }
    
    // 1. 优先判定物理抢占型事件 (如 SOS 键)
    if (evt == KEY_SOS_ACTIVE) {
        StartApp(APP_SOS); // 强行强占前台,启动紧急求救页面
        return;
    }
    
    // 2. 无线报警事件路由给后台进程进行防区匹配
    if (evt == RF_EVENT_ALARM || evt == RF_EVENT_PAIR) {
        BgApp_Process_RF(evt); // 后台比对数据库若匹配且在布防状态下唤醒强占报警App
        return;
    }
    
    // 3. 常规按键事件分发给当前活跃的前台 APP
    if (active_app && active_app->onEvent) {
        active_app->onEvent(evt);
    }
}