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

91 lines
2.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 编码实现 - 事件总线与缓冲路由 (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);
}
}
```