refactor(event): replace global 60s inactivity timer with per-second tick event

Adds KEY_EVENT_SECOND_TICK, generated once per real second from
Clock_IncMS() via a new second_tick_flag and pushed through the normal
event queue, so every foreground App's onEvent() receives it and
decides independently whether to act. Removes the old global
inactivity_timer (60s sleep from anywhere) entirely. HomeApp now
accumulates its own idle-second counter and sleeps after 10s idle
specifically while on the home screen; MenuApp's existing 10s
auto-close is converted from onRun() polling to the same tick+reset
pattern for consistency. Any non-tick key event resets each app's own
counter to 0.
This commit is contained in:
edisondeng
2026-07-31 18:49:03 +08:00
parent cbd480eea3
commit 2a83079007
8 changed files with 70 additions and 54 deletions

View File

@@ -49,7 +49,6 @@ Sensor_Slot xdata sensor_list[16];
// 全局滴答与定时中断计数变量,位于 volatile 防止被编译器优化
volatile u16 ms_tick = 0; // 定时中断 1ms 基准滴答累加器
volatile u16 inactivity_timer = 0; // 用户闲置计时器,用于无操作判定(单位: 10ms
volatile u32 pair_timeout_ms = 0; // 传感器配对对码超时毫秒计时器 (上限 30000ms 即 30s)
volatile u16 alarm_timer_ms = 0; // 入侵报警马达震动时序计数器
volatile u16 motor_timer_ms = 0; // 独立马达震动时长计数器
@@ -120,7 +119,6 @@ void RGB_Diagnostic_Test(void)
void Debug_ProcessCommand(char cmd)
{
SystemEvent debug_evt;
inactivity_timer = 0; // 收到指令,立即重置用户的无操作闲置计时器
debug_evt.extra_data = 0;
debug_evt.extra_size = 0;
@@ -206,8 +204,11 @@ void Debug_ProcessCommand(char cmd)
}
Uart_SendString("[UART] State: DISARMED\r\n");
} else if (cmd == 'z' || cmd == 'Z') {
inactivity_timer = 6000; // 模拟闲置 60 秒超时,强制触发主循环深度休眠
// 直接强制进入低功耗休眠,测试用 (原来靠伪造全局闲置计时器触发,现改为直接调用)
Uart_SendString("[UART] Force Entering Sleep mode!\r\n");
current_state = STATE_SLEEP;
Enter_Low_Power_Sleep();
AppManager_SwitchToForeground(&home_app); // 唤醒后强制重绘时钟画面
} else if (cmd == 'q' || cmd == 'Q') {
RGB_Diagnostic_Test(); // 启动 RGB 物理颜色通道排查测试
} else if (cmd == 't' || cmd == 'T') {
@@ -316,6 +317,21 @@ void main(void)
Event_KeyScan_Poll();
}
/* 0.5 检查整秒滴答标志 (由 Clock_IncMS 每秒置位一次),转换为事件入队分发;
* 各 App 自行决定要不要用它累计自己的闲置时长 (收到任何按键事件就清零)
* 不再由主循环维护一个全局的休眠倒计时。 */
if (second_tick_flag) {
second_tick_flag = 0;
{
SystemEvent tick_evt;
tick_evt.key_event = KEY_EVENT_SECOND_TICK;
tick_evt.priority = EVENT_PRIORITY_LOW;
tick_evt.extra_data = 0;
tick_evt.extra_size = 0;
EventQueue_Push(tick_evt);
}
}
/* 1. 串口非阻塞指令捕获 -> 装配为事件方式入队 */
cmd = Uart_RxChar();
if (cmd != '\0') {
@@ -329,15 +345,6 @@ void main(void)
/* 3. 应用调度中心:运行当前处于前台活跃状态的应用(集成了 CPU 运行时间超时挂起保护) */
AppManager_RunActiveApp();
/* 4. 自动休眠判定:常态无操作闲置达到 60 秒 (6000 * 10ms = 60s) 时,切入低功耗停机休眠 */
if (inactivity_timer >= 6000) {
inactivity_timer = 0;
current_state = STATE_SLEEP; // 系统置为休眠状态
Enter_Low_Power_Sleep(); // 该函数是阻塞的MCU 将在此挂起。唤醒后将自动从其后继续执行
current_state = STATE_NORMAL; // 唤醒后重新置为正常待机状态
AppManager_StartApp(APP_ID_HOME); // 重新开启时钟应用以刷新画面和背光
}
}
}