# 编码实现 - 事件总线与缓冲路由 (Docs/60_coding/mod-event.md) 本文件对应环形事件缓冲区(Event Queue)与事件路由分发器的具体编码实现细节。 ## 1. 对应代码源文件 * [App/main.c](file:///c:/workfile/105/stc32g12k128/App/main.c) (事件队列定义、`Event_Queue_Push` / `Event_Queue_Pop` / `Event_Dispatcher_Loop` 的底层 C 语言实现) * [App/config.h](file:///c:/workfile/105/stc32g12k128/App/config.h) (`KeyEvent` 枚举量定义) ## 2. 关键代码片段与逻辑实现 ### 2.1 环形队列定义与入队出队函数 在 `main.c` 中,定义深度为 4 级的事件队列缓冲数组及读写位置指针: ```c #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()` 中,系统定时轮询事件总线,读取事件并路由给前后台应用: ```c 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); } } ```