重构手环软件架构:实现动态挂载前后台 App 框架,解耦拆分源文件,并引入统一日志宏 xtell.h
This commit is contained in:
91
App/main.c
91
App/main.c
@@ -5,17 +5,20 @@
|
||||
#include "database.h"
|
||||
#include "ui.h"
|
||||
#include "system.h"
|
||||
#include "clock.h"
|
||||
#include "xtell.h"
|
||||
#include "../Drivers/rf.h"
|
||||
#include "../Drivers/lcd.h"
|
||||
|
||||
// 声明外部射频模拟变量
|
||||
extern volatile u32 mock_rx_addr;
|
||||
extern volatile u8 mock_rx_data;
|
||||
extern volatile bit mock_rf_ready;
|
||||
|
||||
/* =========================================================================
|
||||
* 系统全局变量定义
|
||||
* ========================================================================= */
|
||||
SystemState current_state = STATE_NORMAL; // 系统整体的当前运行状态,默认为正常时钟待机页
|
||||
u8 current_hour = 10; // 系统软时钟:小时 (默认初始化为 10 点)
|
||||
u8 current_min = 35; // 系统软时钟:分钟 (默认初始化为 35 分)
|
||||
u8 current_sec = 0; // 系统软时钟:秒
|
||||
volatile u8 clock_updated = 0; // 分钟跳变标志位,置位后用于驱动 UI 刷新时间显示
|
||||
|
||||
u8 menu_select = 0; // 主菜单当前选中的行高亮索引 (0~2)
|
||||
u32 captured_addr = 0; // 配对或报警时,捕获到的传感器 24 位 EV1527 射频物理地址
|
||||
@@ -46,17 +49,6 @@ volatile u16 comb_hold = 0; // ▲ + ▼ 组合键按下时长累
|
||||
* ========================================================================= */
|
||||
/**
|
||||
* @brief 解析通过串口 1 发送来的键盘及测试模拟指令
|
||||
* @param cmd 接收到的 ASCII 字符命令
|
||||
* @details 负责将字符指令转化对应的系统按键或射频事件,并推入事件队列以测试软件架构:
|
||||
* - 'u'/'U': 模拟短按/长按 ▲ 键。
|
||||
* - 'd'/'D': 模拟短按/长按 ▼ 键。
|
||||
* - 's'/'S': 模拟短按/长按 SOS 物理键(优先插入队首)。
|
||||
* - 'c'/'C': 模拟组合键触发。
|
||||
* - 'a'/'A': 模拟无线传感器入侵触发警报信号,地址固定为 0x123456,zone=1。
|
||||
* - 'p'/'P': 模拟对码期间捕获的 24 位无线对码信号,地址固定为 0x789ABC。
|
||||
* - '1'/'2'/'3': 模拟系统的正常、已布防、已撤防状态切换。
|
||||
* - 'z'/'Z': 模拟超时,强行使闲置计数器置 6000,触发自动深度休眠。
|
||||
* - 't'/'T': 触发屏幕与无线控制引脚测试。
|
||||
*/
|
||||
void Debug_ProcessCommand(char cmd)
|
||||
{
|
||||
@@ -67,39 +59,32 @@ void Debug_ProcessCommand(char cmd)
|
||||
|
||||
if (cmd == 'u') {
|
||||
debug_evt.key_event = KEY_EVENT_UP_CLICK;
|
||||
debug_evt.priority = EVENT_PRIORITY_NORMAL;
|
||||
EventQueue_Push(debug_evt); // 压入队尾
|
||||
Uart_SendString("[UART] KEY_UP Clicked\r\n");
|
||||
XTELL_LOG("[UART] KEY_UP Clicked\r\n");
|
||||
} else if (cmd == 'U') {
|
||||
debug_evt.key_event = KEY_EVENT_UP_LONG;
|
||||
debug_evt.priority = EVENT_PRIORITY_NORMAL;
|
||||
EventQueue_Push(debug_evt);
|
||||
Uart_SendString("[UART] KEY_UP Long Pressed\r\n");
|
||||
XTELL_LOG("[UART] KEY_UP Long Pressed\r\n");
|
||||
} else if (cmd == 'd') {
|
||||
debug_evt.key_event = KEY_EVENT_DOWN_CLICK;
|
||||
debug_evt.priority = EVENT_PRIORITY_NORMAL;
|
||||
EventQueue_Push(debug_evt);
|
||||
Uart_SendString("[UART] KEY_DOWN Clicked\r\n");
|
||||
XTELL_LOG("[UART] KEY_DOWN Clicked\r\n");
|
||||
} else if (cmd == 'D') {
|
||||
debug_evt.key_event = KEY_EVENT_DOWN_LONG;
|
||||
debug_evt.priority = EVENT_PRIORITY_NORMAL;
|
||||
EventQueue_Push(debug_evt);
|
||||
Uart_SendString("[UART] KEY_DOWN Long Pressed\r\n");
|
||||
XTELL_LOG("[UART] KEY_DOWN Long Pressed\r\n");
|
||||
} else if (cmd == 's') {
|
||||
debug_evt.key_event = KEY_EVENT_SOS_CLICK;
|
||||
debug_evt.priority = EVENT_PRIORITY_URGENT;
|
||||
EventQueue_InsertFront(debug_evt); // 紧急事件插入队首
|
||||
Uart_SendString("[UART] KEY_SOS Clicked\r\n");
|
||||
XTELL_LOG("[UART] KEY_SOS Clicked\r\n");
|
||||
} else if (cmd == 'S') {
|
||||
debug_evt.key_event = KEY_EVENT_SOS_LONG;
|
||||
debug_evt.priority = EVENT_PRIORITY_URGENT;
|
||||
EventQueue_InsertFront(debug_evt);
|
||||
Uart_SendString("[UART] KEY_SOS Long Pressed\r\n");
|
||||
XTELL_LOG("[UART] KEY_SOS Long Pressed\r\n");
|
||||
} else if (cmd == 'c' || cmd == 'C') {
|
||||
debug_evt.key_event = KEY_EVENT_UP_DOWN_COMB;
|
||||
debug_evt.priority = EVENT_PRIORITY_NORMAL;
|
||||
EventQueue_Push(debug_evt);
|
||||
Uart_SendString("[UART] KEY_UP+DOWN Combined\r\n");
|
||||
XTELL_LOG("[UART] KEY_UP+DOWN Combined\r\n");
|
||||
} else if (cmd == 'a' || cmd == 'A') {
|
||||
u32 mock_addr = 0x123456; // 设定模拟的报警射频源地址
|
||||
u8 mock_slot;
|
||||
@@ -107,48 +92,39 @@ void Debug_ProcessCommand(char cmd)
|
||||
if (!Check_Sensor_ID(mock_addr, &mock_slot)) {
|
||||
Add_Sensor_With_Zone(mock_addr, 0, 1);
|
||||
}
|
||||
debug_evt.key_event = KEY_EVENT_NONE;
|
||||
debug_evt.priority = EVENT_PRIORITY_HIGH; // 入侵报警设为 HIGH 优先级
|
||||
debug_evt.extra_data = mock_addr;
|
||||
debug_evt.extra_size = 4;
|
||||
EventQueue_InsertFront(debug_evt); // 高优先级插队
|
||||
Uart_SendString("[UART] Mock RF Alarm\r\n");
|
||||
mock_rx_addr = mock_addr;
|
||||
mock_rx_data = 0x01;
|
||||
mock_rf_ready = 1; // 触发射频模拟
|
||||
XTELL_LOG("[UART] Mock RF Alarm Triggered\r\n");
|
||||
} else if (cmd == 'p' || cmd == 'P') {
|
||||
// 只有当手环切入 Pair 模式时,模拟对码信号才有效
|
||||
if (AppManager_GetActiveAppID() == APP_ID_PAIR) {
|
||||
debug_evt.key_event = KEY_EVENT_NONE;
|
||||
debug_evt.priority = EVENT_PRIORITY_NORMAL;
|
||||
debug_evt.extra_data = 0x789ABC; // 设定模拟对码硬件地址
|
||||
debug_evt.extra_size = 4;
|
||||
EventQueue_Push(debug_evt);
|
||||
Uart_SendString("[UART] Mock RF Pair Signal\r\n");
|
||||
} else {
|
||||
Uart_SendString("[UART] Not in PAIR mode\r\n");
|
||||
}
|
||||
mock_rx_addr = 0x789ABC;
|
||||
mock_rx_data = 0x01;
|
||||
mock_rf_ready = 1; // 触发射频模拟
|
||||
XTELL_LOG("[UART] Mock RF Pair Triggered\r\n");
|
||||
} else if (cmd == '1') {
|
||||
// 模拟切换至 正常撤防 (NORMAL) 状态并刷新时钟
|
||||
if (AppManager_GetActiveAppID() == APP_ID_CLOCK) {
|
||||
current_state = STATE_NORMAL;
|
||||
UI_ShowClockPage(current_state, current_hour, current_min);
|
||||
}
|
||||
Uart_SendString("[UART] State: NORMAL\r\n");
|
||||
XTELL_LOG("[UART] State: NORMAL\r\n");
|
||||
} else if (cmd == '2') {
|
||||
// 模拟切换至 已布防 (ARMED) 状态,普通门磁可触发警报
|
||||
if (AppManager_GetActiveAppID() == APP_ID_CLOCK) {
|
||||
current_state = STATE_ARMED;
|
||||
UI_ShowClockPage(current_state, current_hour, current_min);
|
||||
}
|
||||
Uart_SendString("[UART] State: ARMED\r\n");
|
||||
XTELL_LOG("[UART] State: ARMED\r\n");
|
||||
} else if (cmd == '3') {
|
||||
// 模拟切换至 已撤防 (DISARMED) 状态,忽略普通报警
|
||||
if (AppManager_GetActiveAppID() == APP_ID_CLOCK) {
|
||||
current_state = STATE_DISARMED;
|
||||
UI_ShowClockPage(current_state, current_hour, current_min);
|
||||
}
|
||||
Uart_SendString("[UART] State: DISARMED\r\n");
|
||||
XTELL_LOG("[UART] State: DISARMED\r\n");
|
||||
} else if (cmd == 'z' || cmd == 'Z') {
|
||||
inactivity_timer = 6000; // 模拟闲置 60 秒超时,强制触发主循环深度休眠
|
||||
Uart_SendString("[UART] Force Entering Sleep mode!\r\n");
|
||||
XTELL_LOG("[UART] Force Entering Sleep mode!\r\n");
|
||||
} else if (cmd == 't' || cmd == 'T') {
|
||||
Loopback_Test(); // 调用回环测试验证屏幕
|
||||
RF_Test_Pin(); // 无线射频测试
|
||||
@@ -176,20 +152,24 @@ void main(void)
|
||||
Delay_ms(50); // 等待电压充盈稳定,避开浪涌
|
||||
LCD_Init(); // 初始化 Truly AMOLED 屏幕控制寄存器序列
|
||||
Uart1_Init(); // 初始化串口 1 波特率 115200 供调试日志
|
||||
Uart_SendString("Wristband System Initialized!\r\n");
|
||||
XTELL_LOG("Wristband System Initialized!\r\n");
|
||||
|
||||
Load_Database(); // 从 IAP Flash 第 254 扇区读取所有已绑定的传感器数据至 RAM
|
||||
|
||||
/* 步骤 1: 初始化事件环形缓冲区队列 */
|
||||
EventQueue_Init();
|
||||
|
||||
/* 步骤 2+5: 初始化应用管理器并登记所有前台应用,默认加载 ClockApp */
|
||||
/* 步骤 2: 初始化应用管理器 */
|
||||
AppManager_Init();
|
||||
|
||||
/* 步骤 3: 动态挂载待机时钟应用到前台,并挂载后台射频监控应用 */
|
||||
AppManager_SwitchToForeground(&clock_app);
|
||||
AppManager_AttachToBackground(&rf_monitor_app);
|
||||
|
||||
/* 启动 1ms 系统基准定时器 Timer1 */
|
||||
Timer1_Init();
|
||||
|
||||
Uart_SendString("[SYS] Event-driven framework ready\r\n");
|
||||
XTELL_LOG("[SYS] Event-driven framework ready\r\n");
|
||||
|
||||
// ====== 主循环 ======
|
||||
while (1) {
|
||||
@@ -204,18 +184,19 @@ void main(void)
|
||||
Event_Dispatcher_Loop();
|
||||
}
|
||||
|
||||
/* 3. 应用调度中心:运行当前处于前台活跃状态的应用(集成了 CPU 运行时间超时挂起保护) */
|
||||
/* 3. 应用调度中心:运行前后台所有已挂载激活的应用 */
|
||||
AppManager_RunActiveApp();
|
||||
|
||||
/* 4. 自动休眠判定:常态无操作闲置达到 60 秒 (6000 * 10ms = 60s) 时,切入低功耗停机休眠 */
|
||||
if (inactivity_timer >= 6000) {
|
||||
inactivity_timer = 0;
|
||||
current_state = STATE_SLEEP; // 系统置为休眠状态
|
||||
Enter_Low_Power_Sleep(); // 该函数是阻塞的,MCU 将在此挂起。唤醒后将自动从其后继续执行
|
||||
Enter_Low_Power_Sleep(); // 挂起 MCU
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 唤醒源事件标志,由对应的外部中断 ISR 写入
|
||||
volatile u8 p0_wakeup_flag = 0; // P0 端口按键唤醒标志
|
||||
volatile u8 p2_wakeup_flag = 0; // P2 端口按键唤醒标志
|
||||
|
||||
Reference in New Issue
Block a user