重构手环软件架构:实现动态挂载前后台 App 框架,解耦拆分源文件,并引入统一日志宏 xtell.h

This commit is contained in:
Antigravity IDE
2026-07-17 09:08:53 +08:00
parent 8fdbb32f42
commit c0d1fe74f5
18 changed files with 1380 additions and 1155 deletions

View File

@@ -2,6 +2,8 @@
#include "app_manager.h"
#include "database.h"
#include "system.h"
#include "clock.h"
#include "xtell.h"
// 定义事件环形队列的最大深度为 8
#define EVENT_QUEUE_DEPTH 8
@@ -64,7 +66,6 @@ SystemEvent EventQueue_Pop(void)
SystemEvent evt;
// 默认空事件属性
evt.key_event = KEY_EVENT_NONE;
evt.priority = EVENT_PRIORITY_LOW;
evt.extra_data = 0;
evt.extra_size = 0;
@@ -118,46 +119,17 @@ void Event_Dispatcher_Loop(void)
inactivity_timer = 0; // 捕获到有效事件,清零休眠计时器,重置闲置超时
// 串口打印调试信息
Uart_SendString("[EVENT] key=");
Uart_SendHex8((u8)evt.key_event);
Uart_SendString(", pri=");
Uart_SendHex8((u8)evt.priority);
Uart_SendString("\r\n");
XTELL_LOG("[EVENT] key=");
XTELL_LOG_HEX8((u8)evt.key_event);
XTELL_LOG("\r\n");
// SOS 按键紧急处理:若非处于 SOS 呼救状态下,接收到 SOS 键动作,立即强行切入到 SOS_APP 并执行求救
// SOS 按键紧急处理:若当前前台不为 SOS 应用,接收到 SOS 键动作,立即强行切入到 SOS_APP 并执行求救
if ((evt.key_event == KEY_EVENT_SOS_CLICK || evt.key_event == KEY_EVENT_SOS_LONG) &&
AppManager_GetActiveAppID() != APP_ID_SOS) {
AppManager_StartApp(APP_ID_SOS);
return;
}
// 传感器入侵报警过滤与跳转处理:
// 当接收到高优先级且带有 4 字节射频地址的数据包,说明有传感器触发了发射
if (evt.priority == EVENT_PRIORITY_HIGH && evt.extra_size >= 4) {
u8 slot;
// 在本地数据库中检索该传感器地址是否合法登记过
if (Check_Sensor_ID(evt.extra_data, &slot)) {
// 在不处于 SOS 的情况下,可正常强行切入 ALARM_APP 触发声光振警报
if (AppManager_GetActiveAppID() != APP_ID_SOS) {
captured_addr = evt.extra_data; // 缓存报警地址
alarm_sensor_slot = slot; // 缓存报警槽位
AppManager_StartApp(APP_ID_ALARM); // 强制切入报警前台
return;
}
}
}
// 无线对码捕获处理:
// 若系统正处于对码应用 (APP_ID_PAIR),遇到普通优先级无线射频包,则将其派发给该应用进行匹配与登记
if (evt.priority == EVENT_PRIORITY_NORMAL && evt.extra_size >= 4) {
captured_addr = evt.extra_data; // 缓存捕获的待配对地址
captured_type = menu_select; // 将主菜单选择的类型传给配对缓存
if (AppManager_GetActiveAppID() == APP_ID_PAIR) {
AppManager_DispatchEvent(evt); // 派发给对码应用
return;
}
}
// 常规事件(如普通的按键点击)直接透传分发给当前处于前台活跃的应用
AppManager_DispatchEvent(evt);
}
@@ -182,89 +154,14 @@ void Timer1_Init(void)
/**
* @brief 定时器 1 中断服务程序 (每 1ms 触发一次)
* @details 承担了系统软时钟计算、报警与求救下的马达控制状态机以及 10ms 周期性按键消抖扫描的功能。
* @details 承担了系统软时钟计算、10ms 周期性按键消抖扫描的功能。马达等特定业务已剥离至 App 内部。
*/
void Timer1_Isr(void) interrupt 3
{
SystemEvent evt;
// 1ms 递增滴答
ms_tick++;
if (ms_tick >= 1000) {
ms_tick = 0; // 1秒时间已到归零
current_sec++;
if (current_sec >= 60) {
current_sec = 0; // 1分钟时间已到
current_min++;
if (current_min >= 60) {
current_min = 0; // 1小时时间已到
current_hour++;
if (current_hour >= 24) current_hour = 0; // 小时循环
}
clock_updated = 1; // 标志位置1提示前台时钟应用刷新显示
}
}
// 如果处于对码等待状态,对码超时计时器增加 (30秒超时判断)
if (current_state == STATE_PAIR_WAIT) {
pair_timeout_ms++;
}
/* 振动马达定时状态机逻辑控制 */
if (current_state == STATE_SOS_EMITTED) {
// SOS 模式:交替规律震动 (震动 1000ms静音 200ms)
alarm_timer_ms++;
if (alarm_timer_ms >= 1200) alarm_timer_ms = 0;
if (alarm_timer_ms < 1000) MOTOR = 1; else MOTOR = 0;
} else if (current_state == STATE_ALARM) {
// 报警状态:根据触发警报的传感器类型,输出对应的差异化震动波形以便触觉分辨
u8 stype = sensor_list[alarm_sensor_slot].type;
alarm_timer_ms++;
if (alarm_timer_ms >= 5000) alarm_timer_ms = 0; // 5秒一周期
if (stype == 0) {
// 门磁警报波形:单次震动 300ms停 4700ms
if (alarm_timer_ms < 300) MOTOR = 1; else MOTOR = 0;
} else if (stype == 1) {
// PIR 警报波形:震动 300ms停 200ms再震动 300ms停 4200ms
if (alarm_timer_ms < 300) MOTOR = 1;
else if (alarm_timer_ms >= 300 && alarm_timer_ms < 500) MOTOR = 0;
else if (alarm_timer_ms >= 500 && alarm_timer_ms < 800) MOTOR = 1;
else MOTOR = 0;
} else if (stype == 2) {
// 烟感警报波形:急促短闪三下 200ms-150ms-200ms-150ms-200ms
if (alarm_timer_ms < 200) MOTOR = 1;
else if (alarm_timer_ms >= 200 && alarm_timer_ms < 350) MOTOR = 0;
else if (alarm_timer_ms >= 350 && alarm_timer_ms < 550) MOTOR = 1;
else if (alarm_timer_ms >= 550 && alarm_timer_ms < 700) MOTOR = 0;
else if (alarm_timer_ms >= 700 && alarm_timer_ms < 900) MOTOR = 1;
else MOTOR = 0;
} else if (stype == 3) {
// 燃气报警波形:快频连续四下
if (alarm_timer_ms < 200) MOTOR = 1;
else if (alarm_timer_ms >= 200 && alarm_timer_ms < 300) MOTOR = 0;
else if (alarm_timer_ms >= 300 && alarm_timer_ms < 500) MOTOR = 1;
else if (alarm_timer_ms >= 500 && alarm_timer_ms < 600) MOTOR = 0;
else if (alarm_timer_ms >= 600 && alarm_timer_ms < 800) MOTOR = 1;
else if (alarm_timer_ms >= 800 && alarm_timer_ms < 900) MOTOR = 0;
else if (alarm_timer_ms >= 900 && alarm_timer_ms < 1100) MOTOR = 1;
else MOTOR = 0;
} else if (stype == 4) {
// 水浸警报波形:慢速双长震波 600ms 和 600ms
if (alarm_timer_ms < 600) MOTOR = 1;
else if (alarm_timer_ms >= 600 && alarm_timer_ms < 900) MOTOR = 0;
else if (alarm_timer_ms >= 900 && alarm_timer_ms < 1500) MOTOR = 1;
else MOTOR = 0;
} else {
// 缺省状态默认单次 300ms
if (alarm_timer_ms < 300) MOTOR = 1; else MOTOR = 0;
}
} else {
// 其他常态下彻底关闭震动马达并归零计时器
MOTOR = 0;
alarm_timer_ms = 0;
motor_timer_ms = 0;
}
// 1ms 定时更新软时钟
Clock_IncMS();
// 报警屏幕红边框以 100ms 周期亮灭,进行颜色爆闪指示
alarm_flash_flag = (ms_tick / 100) % 2;
@@ -294,12 +191,11 @@ void Timer1_Isr(void) interrupt 3
evt.extra_data = 0;
evt.extra_size = 0;
// 双键组合判定:▲ 键 ▼ 键同时按下的消抖与生成
// 双键组合判定:▲ 键 and ▼ 键同时按下的消抖与生成
if (raw_up && raw_down) {
comb_hold++;
if (comb_hold == 300) { // 持续按下达 3 秒 (300 * 10ms = 3s)
evt.key_event = KEY_EVENT_UP_DOWN_COMB;
evt.priority = EVENT_PRIORITY_NORMAL;
EventQueue_Push(evt); // 压入队列
}
key_up_hold = 0; // 清零单个按键计数,防止双击事件干扰
@@ -312,14 +208,12 @@ void Timer1_Isr(void) interrupt 3
key_up_hold++;
if (key_up_hold == 300) { // 达到 3 秒判定为长按
evt.key_event = KEY_EVENT_UP_LONG;
evt.priority = EVENT_PRIORITY_NORMAL;
EventQueue_Push(evt);
}
} else {
// 如果松开时按下计数在消抖阈值20ms至长按阈值3s之间则判定为一次短按
if (key_up_hold >= 2 && key_up_hold < 300) {
evt.key_event = KEY_EVENT_UP_CLICK;
evt.priority = EVENT_PRIORITY_NORMAL;
EventQueue_Push(evt);
}
key_up_hold = 0; // 释放归零
@@ -330,13 +224,11 @@ void Timer1_Isr(void) interrupt 3
key_down_hold++;
if (key_down_hold == 300) { // 长按 3 秒
evt.key_event = KEY_EVENT_DOWN_LONG;
evt.priority = EVENT_PRIORITY_NORMAL;
EventQueue_Push(evt);
}
} else {
if (key_down_hold >= 2 && key_down_hold < 300) {
evt.key_event = KEY_EVENT_DOWN_CLICK;
evt.priority = EVENT_PRIORITY_NORMAL;
EventQueue_Push(evt);
}
key_down_hold = 0; // 释放归零
@@ -347,13 +239,11 @@ void Timer1_Isr(void) interrupt 3
key_confirm_hold++;
if (key_confirm_hold == 300) { // 长按 3 秒打开主菜单
evt.key_event = KEY_EVENT_CONFIRM_LONG;
evt.priority = EVENT_PRIORITY_NORMAL;
EventQueue_Push(evt);
}
} else {
if (key_confirm_hold >= 2 && key_confirm_hold < 300) {
evt.key_event = KEY_EVENT_CONFIRM_CLICK;
evt.priority = EVENT_PRIORITY_NORMAL;
EventQueue_Push(evt);
}
key_confirm_hold = 0; // 释放归零
@@ -362,15 +252,13 @@ void Timer1_Isr(void) interrupt 3
// SOS 物理求救按键状态机
if (raw_sos) {
key_sos_hold++;
if (key_sos_hold == 300) { // 长按 3 秒,发出 URGENT 优先级求救,插入队首
if (key_sos_hold == 300) { // 长按 3 秒,发出求救,插入队首
evt.key_event = KEY_EVENT_SOS_LONG;
evt.priority = EVENT_PRIORITY_URGENT;
EventQueue_InsertFront(evt);
}
} else {
if (key_sos_hold >= 2 && key_sos_hold < 300) { // 短按即呼救,插入队首
evt.key_event = KEY_EVENT_SOS_CLICK;
evt.priority = EVENT_PRIORITY_URGENT;
EventQueue_InsertFront(evt);
}
key_sos_hold = 0; // 释放归零