feat: 实现事件驱动应用框架,支持前台/后台分离、事件优先级和CPU占用控制

This commit is contained in:
2026-07-10 11:30:48 +08:00
parent 00c00fb60e
commit b4fabf85b5
11 changed files with 2487 additions and 541 deletions

262
App/appmgr.c Normal file
View File

@@ -0,0 +1,262 @@
#include "appmgr.h"
#include "../Drivers/lcd.h"
/* =========================================================================
* 应用管理器内部变量
* ========================================================================= */
// 应用注册表:存储所有已注册的应用
static WristbandApp app_registry[APP_ID_MAX];
// 当前活跃的前台应用指针
static WristbandApp *active_app = NULL;
// 默认应用(时钟)
#define DEFAULT_APP_ID APP_ID_CLOCK
/* =========================================================================
* 应用生命周期辅助函数
* ========================================================================= */
static void AppManager_ExecuteOnStart(WristbandApp *app)
{
if (app != NULL && app->OnStart != NULL)
{
app->OnStart();
app->is_active = 1;
app->is_running = 1;
}
}
static void AppManager_ExecuteOnClose(WristbandApp *app)
{
if (app != NULL && app->onClose != NULL)
{
app->onClose();
app->is_active = 0;
app->is_running = 0;
}
}
static void AppManager_ExecuteOnRun(WristbandApp *app)
{
if (app != NULL && app->onRun != NULL && app->is_running)
{
// CPU占用控制记录开始时间
u16 start_tick = ms_tick;
// 执行应用的onRun回调
app->onRun();
// 检测执行时间是否超限
u16 elapsed_ticks = ms_tick - start_tick;
if (elapsed_ticks > APP_ONRUN_MAX_TICKS)
{
// 应用执行时间过长,强制标记为非活跃
// 但不直接关闭,允许应用在下一次循环中恢复
app->is_running = 0;
}
}
}
static EventResult AppManager_ExecuteOnEvent(WristbandApp *app, SystemEvent evt)
{
if (app != NULL && app->onEvent != NULL)
{
return app->onEvent(evt);
}
return EVENT_IGNORED;
}
/* =========================================================================
* 应用管理器核心实现
* ========================================================================= */
void AppManager_Init(void)
{
u8 i;
// 初始化所有应用描述符
for (i = 0; i < APP_ID_MAX; i++)
{
app_registry[i].app_id = (AppID)i;
app_registry[i].app_type = APP_TYPE_FOREGROUND;
app_registry[i].app_name = "UNREGISTERED";
app_registry[i].OnStart = NULL;
app_registry[i].onRun = NULL;
app_registry[i].onClose = NULL;
app_registry[i].onEvent = NULL;
app_registry[i].is_active = 0;
app_registry[i].is_running = 0;
}
// 默认启动时钟应用
active_app = &app_registry[DEFAULT_APP_ID];
AppManager_ExecuteOnStart(active_app);
}
void AppManager_StartApp(AppID app_id)
{
// 参数有效性检查
if (app_id >= APP_ID_MAX)
{
return;
}
// 获取目标应用指针
WristbandApp *target_app = &app_registry[app_id];
// 目标应用必须是前台应用
if (target_app->app_type != APP_TYPE_FOREGROUND)
{
return;
}
// 目标应用必须已注册有OnStart回调
if (target_app->OnStart == NULL)
{
return;
}
// 如果目标应用已经是活跃应用,直接返回
if (active_app == target_app)
{
return;
}
// 关闭当前活跃应用
if (active_app != NULL)
{
AppManager_ExecuteOnClose(active_app);
}
// 切换到新应用
active_app = target_app;
// 启动新应用
AppManager_ExecuteOnStart(active_app);
}
void AppManager_CloseApp(void)
{
// 关闭当前活跃应用
if (active_app != NULL)
{
AppManager_ExecuteOnClose(active_app);
active_app = NULL;
}
// 启动默认应用(时钟)
active_app = &app_registry[DEFAULT_APP_ID];
AppManager_ExecuteOnStart(active_app);
}
AppID AppManager_GetActiveAppID(void)
{
if (active_app != NULL)
{
return active_app->app_id;
}
return DEFAULT_APP_ID;
}
void AppManager_DispatchEvent(SystemEvent evt)
{
EventResult result;
// 步骤1优先分发给当前活跃的前台应用
if (active_app != NULL && active_app->is_active)
{
result = AppManager_ExecuteOnEvent(active_app, evt);
// 前台应用已处理,无需继续分发
if (result == EVENT_HANDLED)
{
return;
}
}
// 步骤2前台未处理分发给所有后台应用
// 遍历应用注册表,找到所有后台应用
u8 i;
for (i = 0; i < APP_ID_MAX; i++)
{
WristbandApp *bg_app = &app_registry[i];
// 跳过前台应用和未注册应用
if (bg_app->app_type != APP_TYPE_BACKGROUND ||
bg_app->onEvent == NULL ||
!bg_app->is_running)
{
continue;
}
// 调用后台应用的事件处理函数
result = AppManager_ExecuteOnEvent(bg_app, evt);
// 如果后台应用处理了事件,停止继续分发
if (result == EVENT_HANDLED)
{
return;
}
}
// 步骤3所有应用都未处理事件被丢弃
// 可以在这里添加日志记录(如果需要)
}
void AppManager_RunActiveApp(void)
{
// 执行当前活跃应用的onRun回调带CPU占用控制
if (active_app != NULL && active_app->is_active)
{
AppManager_ExecuteOnRun(active_app);
}
}
void AppManager_BroadcastToBackground(SystemEvent evt)
{
// 广播事件给所有后台应用
u8 i;
for (i = 0; i < APP_ID_MAX; i++)
{
WristbandApp *bg_app = &app_registry[i];
// 仅发送给后台应用
if (bg_app->app_type == APP_TYPE_BACKGROUND &&
bg_app->onEvent != NULL &&
bg_app->is_running)
{
AppManager_ExecuteOnEvent(bg_app, evt);
}
}
}
/* =========================================================================
* 应用注册接口(供各应用模块调用)
* ========================================================================= */
void AppManager_RegisterApp(AppID app_id, AppType app_type, char *app_name,
AppStartFunc on_start, AppRunFunc on_run,
AppCloseFunc on_close, AppEventFunc on_event)
{
if (app_id >= APP_ID_MAX)
{
return;
}
WristbandApp *app = &app_registry[app_id];
app->app_type = app_type;
app->app_name = app_name;
app->OnStart = on_start;
app->onRun = on_run;
app->onClose = on_close;
app->onEvent = on_event;
// 后台应用默认处于运行状态
if (app_type == APP_TYPE_BACKGROUND)
{
app->is_running = 1;
}
}