Phase 9 三轮增量优化(jitter buffer / codec init / Core 1 绑定)效果不 明显,用户决策完整切 EAF 验证 GIF 抢资源假设。 Phase 9 → CANCELLED: - v1 jitter buffer device_state 判错(漏 kDeviceStateDialog) - v1 ES7210 重试破坏 ES8311 init 导致开机播报无声 - v2 修正 device_state 后 jitter 工作但仍卡 - v3 background_task 绑 Core 1 + DIAG-5 未硬件验证 - 所有代码改动 git restore 回滚(无 commit),Phase 8 DIAG 埋点保留 - CANCELLED.md 记录教训 Phase 10 新增(数字人模式 LVGL → esp_emote_gfx 完整切换): - 添加 espressif2022/esp_emote_gfx ~3.0.5 依赖(已 reconfigure 拉取) - API 风险扫清:GFX_LABEL_LONG_WRAP 支持中文换行、 gfx_font_lv_load_from_binary 兼容 LVGL bitmap font - 双轨编译:CONFIG_BAJI_BADGE_MODE=y 保 LVGL,=n 走 EAF - PLAN.md 含 10 个子任务从依赖到完整 UI 切换 - 预估 3-5 天 Phase 11 占位:LVGL 释放的 ~40KB DRAM + ~80KB PSRAM 投到 WiFi 缓冲扩容(STATIC_RX 10→16、DYN_RX/TX 32→48、RX_BA_WIN 6→16)+ Opus/RTC SDK jitter buffer 扩容 Phase 12 占位:原 Phase 10 集成测试 + 推送,重编号 ROADMAP 同步更新,依赖关系矫正。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
22 KiB
ROADMAP — 数字人 RTC 项目
10 个阶段,按依赖关系串行。每个阶段产生原子 commit,可独立 revert。
阶段总览
Phase 1 (Kconfig 屏蔽吧唧) ──┐
├─→ Phase 3 (GIF 资源准备) ──┐
Phase 2 (分区表调整) ──┘ │
├─→ Phase 4 (情绪→GIF 映射)
│
└─→ Phase 5 (字幕恢复)
│
Phase 6 (RTC 空闲超时联动)
│
Phase 7 (电量保护 + 低功耗重构)
│
Phase 8 (音频卡顿根因诊断)
│
Phase 9 (音频卡顿实施优化 - 待定)
│
Phase 10 (集成测试 + 推送)
Phase 1: Kconfig 屏蔽电子吧唧模式 ⚠️ 结构性变更(条件编译,不删源码)
目标:通过 Kconfig 开关 + CMakeLists 条件编译 + 调用点 #ifdef 保护,让吧唧模式代码不进固件但保留在仓库中。Rtc_AIavatar 分支默认 CONFIG_BAJI_BADGE_MODE=n,main 分支默认 =y 保持双模式可恢复。
1.1 新增 Kconfig 开关
修改 main/Kconfig.projbuild,新增:
menu "Baji RTC Toy Configuration"
config BAJI_BADGE_MODE
bool "Enable electronic badge mode (双模式电子吧唧)"
default n
help
启用电子吧唧模式(图片浏览、APP传图、设备间分享、KEY2按键等)。
关闭后仅保留 AI 对话 + 数字人 RTC 功能,节省固件体积。
源代码不会被删除,可随时重新启用。
endmenu
并在 Rtc_AIavatar 分支的 sdkconfig.defaults 中追加:
CONFIG_BAJI_BADGE_MODE=n
1.2 CMakeLists.txt 条件化
修改 main/CMakeLists.txt,将吧唧专属 srcs 包裹在条件块中:
# AI 对话 + 数字人 RTC 核心(始终编译)
set(srcs
"main.cc"
"application.cc"
"ota.cc"
"bluetooth_provisioning.cc"
# ... RTC 协议、Opus、I2S、LCD、字幕等
"dzbj/lcd.c"
"dzbj/ai_chat_ui.c"
"dzbj/bg_gif_demo.c"
"dzbj/dual_gif_demo.c"
"dzbj/sprite_demo.c"
)
# 电子吧唧模式专属(条件编译)
if(CONFIG_BAJI_BADGE_MODE)
list(APPEND srcs
"dzbj/device_mode.c"
"dzbj/dzbj_ble.c"
"dzbj/ble_transfer.c"
"dzbj/dzbj_button.c" # KEY2 部分,BOOT 单键回调在公共模块
"dzbj/pages.c"
"dzbj/fatfs.c"
"dzbj/pages_pwm.c"
"dzbj/dzbj_battery.c"
"dzbj/dzbj_init.c"
"dzbj/sleep_mgr.c"
# UI Screens
"ui/screens/ui_ScreenHome.c"
"ui/screens/ui_ScreenImg.c"
"ui/screens/ui_ScreenSet.c"
"ui/screens/ui_ScreenPeiwang.c"
"ui/screens/ui_ScreenImageShar.c"
"ui/screens/ui_ScreenImageReception.c"
"ui/screens/ui_ScreenSharing.c"
"ui/screens/ui_ScreenReceiving.c"
"ui/screens/ui_ScreenUpdate.c"
)
endif()
1.3 调用点 #ifdef 保护
在所有引用吧唧符号的位置加保护,源代码不删除:
-
main/application.cc:#ifdef CONFIG_BAJI_BADGE_MODE #include "dzbj/device_mode.h" #endif void Application::Start() { // ... 公共代码 ... #ifdef CONFIG_BAJI_BADGE_MODE if (device_mode_get() == MODE_BADGE) { InitBadgeMode(); return; } #endif InitAiMode(); } -
main/boards/movecall-moji-esp32s3/movecall_moji_esp32s3.cc:所有 dzbj header include、初始化、BOOT+KEY2 组合键回调全部用#ifdef CONFIG_BAJI_BADGE_MODE包裹 -
main/dzbj/dzbj_button.c:BOOT 按键回调代码本身保留可编译(公共功能),KEY2 处理代码块用#ifdef CONFIG_BAJI_BADGE_MODE包裹 -
main/dzbj/ai_chat_ui.c:清理对吧唧界面的跳转(用#ifdef保护,不删代码)
1.4 头文件 stub 处理
对于条件编译后未链接的吧唧模块,其他保留模块若有引用:
- 头文件本身仍存在(包含 prototype)
- 若调用点未用
#ifdef保护就会链接报错 - 解决:在调用点全部加
#ifdef(首选);或在 .h 内提供 stub 实现(次选)
1.5 任务清单
- 修改
main/Kconfig.projbuild新增CONFIG_BAJI_BADGE_MODE开关 - 修改
main/CMakeLists.txt把吧唧 srcs 包裹在if(CONFIG_BAJI_BADGE_MODE)内 - 修改
main/application.cc加#ifdef保护 - 修改
main/boards/movecall-moji-esp32s3/movecall_moji_esp32s3.cc加#ifdef保护 - 修改
main/dzbj/ai_chat_ui.c跳转点加#ifdef保护 - 修改
main/dzbj/dzbj_button.cKEY2 代码块加#ifdef保护 - 修改
main/dzbj/sleep_mgr.c整体用#ifdef CONFIG_BAJI_BADGE_MODE包裹(Phase 6 改造为 RTC 联动版) - 修改
sdkconfig.defaults(或sdkconfig.ci)确保 Rtc_AIavatar 默认CONFIG_BAJI_BADGE_MODE=n - 产出
.planning/milestones/digital_human_rtc/BADGE_MODE_ISOLATION_MAP.md,列出所有#ifdef边界位置
完成标志:
- ✅
CONFIG_BAJI_BADGE_MODE=n时idf.py build编译通过 - ✅
CONFIG_BAJI_BADGE_MODE=y时idf.py build也编译通过(G7 验收,可恢复双模式) - ✅ 烧录
CONFIG_BAJI_BADGE_MODE=n版本:开机直接进入 AI 对话界面(无模式选择) - ✅
main/dzbj/下所有源文件仍然存在(未删除) - ✅
BADGE_MODE_ISOLATION_MAP.md已生成
风险点:
- C++ 类成员函数无法用
#ifdef完全屏蔽(如 Application 类的吧唧成员变量),需要把成员变量也用#ifdef包裹 - 头文件相互 include 可能导致循环
#ifdef,必要时改用 forward declaration
产出 commit:feat(kconfig): 引入 CONFIG_BAJI_BADGE_MODE 开关 - 吧唧模式可条件编译屏蔽
Phase 2: 分区表调整
目标:扩容 SPIFFS 到 6MB 装下 3 个 GIF + 背景图。
任务:
- 修改
partitions.csv:
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x4000
otadata, data, ota, 0xD000, 0x2000
phy_init, data, phy, 0xF000, 0x1000
ota_0, app, ota_0, 0x10000, 0x400000 # 4MB(从 6.5MB 缩)
ota_1, app, ota_1, 0x410000, 0x400000 # 4MB
storage, data, spiffs, 0x810000, 0x600000 # 6MB(从 2.875MB 扩)
# 删除 64KB model 分区(暂未用)
- 验证:
idf.py partition-table总和 = 16MB 减去引导区 - 烧录后:
heap_caps_get_free_size(MALLOC_CAP_SPIRAM)不变,SPIFFS 显示 6MB
完成标志:
- ✅
idf.py partition-table总和不超 Flash 大小 - ✅ 编译后固件 .bin < 4MB(确认应用分区够装)
- ✅ 烧录后
esp_spiffs_info("storage", &total, &used)返回 total ≈ 6MB
产出 commit:chore(partitions): app 双 OTA 4MB + SPIFFS 6MB(为数字人 GIF 扩容)
Phase 3: GIF 资源准备
目标:准备 m03/m06/m07 三个 hiyori GIF,gifsicle 处理 + 居中裁剪。
任务:
- 源 GIF 位置:
docs/Rtc_AIavatar/Resources/hiyori_free_zh/Export/m{03,06,07}/hiyori_m{03,06,07}.gif - 用 PIL 遍历所有帧找 bbox(吸取 PoC 经验):
# tools/sprite_poc/prepare_hiyori_3gifs.py(新写)
# 对每个 GIF:
# 1. PIL ImageSequence.Iterator 找全帧 bbox
# 2. 计算裁剪框(含全部动作幅度,宽 240,高从脚底向上 320)
# 3. gifsicle --crop X,Y+WxH --resize 240x320 -O3 --colors 256
# 4. 输出到 spiffs_image/hiyori_m{03,06,07}.gif
- 验证每个 GIF:
- 文件大小(合计 ≤ 5.5MB 留余量)
gifsicle --info检查每帧有 transparent 索引- 设备烧录单独测试每个 GIF(临时改
bg_gif_demo_start参数)
完成标志:
- ✅
spiffs_image/hiyori_m{03,06,07}.gif三个文件存在 - ✅ 每个文件 < 2MB,三个合计 < 5.5MB
- ✅ 设备烧录后三个 GIF 都能透明显示,无锯齿
产出 commit:feat(assets): 准备 hiyori 三表情 GIF(m03/m06/m07)+ Python 处理脚本
Phase 4: 情绪 → GIF 映射
目标:22 种情绪标签 → 3 个 GIF 的映射表,RTC 字幕情绪自动切换 GIF。
任务:
- 在
main/dzbj/ai_chat_ui.c设计映射表:
typedef struct {
const char *emotion; // RTC 协议情绪标签
const char *gif_path; // SPIFFS GIF 路径
} emotion_gif_map_t;
static const emotion_gif_map_t emotion_gif_table[] = {
// 默认/积极 → m06 轻松
{"neutral", "/spiflash/hiyori_m06.gif"},
{"happy", "/spiflash/hiyori_m06.gif"},
{"laughing", "/spiflash/hiyori_m06.gif"},
{"funny", "/spiflash/hiyori_m06.gif"},
{"cool", "/spiflash/hiyori_m06.gif"},
{"loving", "/spiflash/hiyori_m06.gif"},
{"relaxed", "/spiflash/hiyori_m06.gif"},
{"delicious", "/spiflash/hiyori_m06.gif"},
{"silly", "/spiflash/hiyori_m06.gif"},
{"winking", "/spiflash/hiyori_m06.gif"},
{"kissy", "/spiflash/hiyori_m06.gif"},
{"confident", "/spiflash/hiyori_m06.gif"},
// 思考/疲倦 → m07 睡眠
{"sleepy", "/spiflash/hiyori_m07.gif"},
{"thinking", "/spiflash/hiyori_m07.gif"},
{"confused", "/spiflash/hiyori_m07.gif"},
{"embarrassed","/spiflash/hiyori_m07.gif"},
// 负面/严肃 → m03 中等
{"sad", "/spiflash/hiyori_m03.gif"},
{"crying", "/spiflash/hiyori_m03.gif"},
{"angry", "/spiflash/hiyori_m03.gif"},
{"surprised", "/spiflash/hiyori_m03.gif"},
{"shocked", "/spiflash/hiyori_m03.gif"},
{"serious", "/spiflash/hiyori_m03.gif"},
};
- 实现
ai_chat_set_emotion(const char *emotion):- 查表 → 调用
bg_gif_demo_switch_gif(path) - 静态变量
last_gif_path去重避免重复加载
- 查表 → 调用
- 在
bg_gif_demo.c加switch_gif()接口:- 释放旧 GIF PSRAM
- 加载新 GIF
lv_gif_set_src(g_gif_obj, &g_gif_dsc)- 重新设置定时器周期 20ms(避免恢复默认 10ms)
- 在
application.cc/volc_rtc_protocol.cc字幕回调中调用ai_chat_set_emotion() - 字幕到达时立即触发(不等 is_final),用
last_subtitle_emotion去重
完成标志:
- ✅ AI 回复"(happy)你好"时 GIF 切到 m06
- ✅ AI 回复"(sad)抱歉"时 GIF 切到 m03
- ✅ 切换间无内存泄漏(连续切 50 次 PSRAM 不持续减少)
产出 commit:feat(emotion): 情绪标签 → hiyori GIF 映射 + bg_gif_demo 切换接口
Phase 5: RTC 字幕恢复
目标:屏幕底部半透明字幕显示,不遮挡数字人。
任务:
- 修改
main/dzbj/ai_chat_ui.c:- 第 165 行删除
lv_obj_add_flag(chat_label, LV_OBJ_FLAG_HIDDEN) - 第 342 行删除
if (USE_BG_GIF_POC) return - 调整
chat_label创建参数:lv_obj_align(chat_label, LV_ALIGN_BOTTOM_MID, 0, -70)- 宽度 300px,wrap 模式
- 字体
font_puhui_20_4,颜色 0xFFFFFF(白色,背景半透明更显眼) - 父容器:半透明黑色 box(
lv_obj_set_style_bg_opa(LV_OPA_50)),rounded corner,padding 10px
- 第 165 行删除
- 创建顺序确保层级:
lv_img_create(scr)背景图(最底层)lv_gif_create(scr)数字人 GIFlv_obj_create(scr)字幕容器(最上层)
- 字幕长文本自动换行 + 滚动(>3 行截断)
完成标志:
- ✅ AI 回复时字幕实时显示在屏幕底部,半透明背景
- ✅ 字幕不遮挡数字人头部
- ✅ 长文本超过 3 行时合理截断或滚动
产出 commit:feat(subtitle): RTC 字幕恢复 - 屏幕底部半透明,避让数字人
Phase 6: RTC 空闲超时联动
目标:60s 无对话 → 自动断 RTC + 熄屏;旧 sleep_mgr 代码用 #ifdef CONFIG_BAJI_BADGE_MODE 保留可恢复。
任务:
main/dzbj/sleep_mgr.c整体用#ifdef CONFIG_BAJI_BADGE_MODE包裹(Phase 1 已做)—— 代码保留可参考- 不删除 CMakeLists.txt 中对应 srcs(Phase 1 已包裹在
if(CONFIG_BAJI_BADGE_MODE)内) - 在
main/application.cc中新增RTC 空闲超时逻辑(不依赖 sleep_mgr):- 复用现有
listening_idle_ticks_机制 - 60s 阈值触发时:
- 调用
CloseAudioChannel()(断 RTC) - 调用
pwm_set_brightness(0)熄屏 - 暂停 LVGL 刷新
- 设置
rtc_screen_off_ = true(新变量,避免与吧唧 sleep_mgr 全局状态冲突)
- 调用
- 复用现有
- 唤醒路径:
- BOOT 按键回调 → 检查
rtc_screen_off_→ 恢复亮度 + 重连 RTC - 长按可选:触发 WiFi 重置(与配网逻辑不冲突)
- BOOT 按键回调 → 检查
- 字幕/GIF 状态在熄屏前清空(避免唤醒后残留)
RTC 空闲超时逻辑与吧唧 sleep_mgr 的隔离:
- 吧唧的
sleep_mgr_init/notify_activity/is_screen_off全部在#ifdef CONFIG_BAJI_BADGE_MODE内 - 新增的 RTC 空闲超时逻辑在 application.cc 中独立实现,使用独立的状态变量
- 这样两种模式的低功耗机制完全独立,互不干扰,将来如果再启用吧唧模式不会冲突
完成标志:
- ✅ 60s 无 RTC 交互 → 自动断开 + 熄屏
- ✅ BOOT 单击 → 屏幕亮起 + 重连 RTC(数字人 GIF 重新加载)
- ✅ 系统稳定运行 30 分钟无内存累积
- ✅ sleep_mgr.c 源代码仍在仓库中(可通过 Kconfig 重新启用)
产出 commit:feat(idle): 新增 RTC 空闲超时联动熄屏(保留 sleep_mgr 源码可恢复)
Phase 7: 电量保护 + 低功耗管理重构
目标:把开机电量保护异步化 + 屏幕低电 UI + PowerSaveTimer 状态机重写 + esp_pm_configure 收口受守卫保护,重构成连贯系统而非局部打补丁。
详细规格:见 phases/phase_07_battery_psm/README.md
完成标志:
- ✅ 开机不再被电池采样 6 秒阻塞
- ✅ 屏幕分级低电 UI 提示(>25% / 15-25% / <15% / <5%)
- ✅ PowerSaveTimer
in_sleep_mode_状态机无边角 - ✅ esp_pm_configure 调用统一收口到 callback 内部
产出 commit:refactor(power): Phase 7 - 电量保护异步化 + 低功耗状态机重写
Phase 8: 数字人 RTC 音频卡顿根因诊断
目标:通过 4 类 ESP_LOGW 日志埋点采集运行时数据,定位 RTC 音频卡顿真实根因(CPU 争抢 / PSRAM 带宽 / DMA / WiFi / Opus 抖动 / 内存碎片),让数据驱动 Phase 9 的实施策略决策。
详细规格:见 phases/phase_08_audio_glitch_diag/README.md
完成标志:
- ✅ 4 处日志埋点编译通过并正常输出
- ✅ 实际复现一次卡顿,采集到包含卡顿瞬间的日志
- ✅ 产出
DIAG_REPORT.md明确根因判定 - ✅ 给出 Phase 9 实施分支推荐(A/B/C/D 之一)
产出 commit:diag(rtc-only): Phase 8 - 音频卡顿根因诊断埋点 + 数据采集报告
Phase 9: ❌ 已取消 — 音频卡顿增量优化尝试
取消原因:用户决策(2026-05-15)— 增量修补效果不明显(v1 引入 ES8311 dev 30 regression,v2 jitter buffer 工作但仍卡,v3 未来得及实测),改为方案 C 完整切 EAF(见 Phase 10)。
保留:phase_09_audio_jitter_codecinit/CANCELLED.md 记录 v1/v2/v3 实验教训供未来参考。
回滚:Phase 9 所有代码改动通过 git restore 已回滚,Phase 8 DIAG 埋点保留作为 Phase 10 验证基准。
Phase 10: 数字人模式 LVGL → esp_emote_gfx 完整切换
目标:仅在 CONFIG_BAJI_BADGE_MODE=n 分支下弃用 LVGL,采用乐鑫 esp_emote_gfx 框架 + EAF 动画格式。Phase 8 数据排除了"调度"问题(codec write 0 慢),用户决策直接验证 EAF 显示效果。释放 ~40KB DRAM + ~80KB PSRAM 留作 Phase 11 资源再分配。
驱动:用户假设 "GIF 与 RTC 抢占资源 + WiFi 缓冲不够",方案 C 是该假设的最彻底验证 —— LVGL/GIF 完全消失后看显示效果与音频感知。
关键改动范围:
- 添加
esp_emote_gfx组件依赖(idf_component.yml) - EAF Packer 工具链:hiyori_m{03,06,07}.gif → .eaf(4-bit + Heatshrink + 透明)
- 重写
main/display/lcd_display.cc数字人分支:接管 display 改为gfx_emote_add_disp - 重写
main/dzbj/ai_chat_ui.c(458 行):lv_obj→gfx_obj,lv_gif→gfx_anim,lv_label→gfx_label - CMakeLists 条件编译切换(仅
CONFIG_BAJI_BADGE_MODE=n走 EAF) - 字体接驳:
font_puhui_20_4.c复用(EAF 官方支持 LVGL bitmap font) - 触摸路径:cst816s →
gfx_touch(如数字人模式需要)
预估工时:3-5 天
完成标志:
- ✅
CONFIG_BAJI_BADGE_MODE=n编译通过 - ✅ 烧录后数字人 GIF 动画正常显示(hiyori 三个表情切换)
- ✅ 字幕显示(中文 + 自动换行 + 双行居中)
- ✅ RTC 对话听感主观验证:扬声器卡顿是否消失(这是核心 PoC 目的)
- ✅
idf.py size对比:Flash/DRAM/PSRAM 变化 - ✅ DRAM 净结余 ≥ 30KB 用于 Phase 11
产出 commit:feat(ui): Phase 10 - 数字人模式 LVGL → esp_emote_gfx 完整迁移
关键风险:
gfx_label中文自动换行 + 双行居中支持验证(实施前先跑 PoC)- 数字人模式如有触摸交互,需重写
- 资源转 EAF 工具链稳定性
ui_ScreenUpdate(吧唧模式 BLE 收图 UI)共用 lv_gif,方案 C 仅影响数字人模式,吧唧模式保持 LVGL(双轨编译)
Phase 11: 内存优化 + WiFi 缓冲扩容
目标:把 Phase 10 释放的 ~40KB DRAM + ~80KB PSRAM 重新分配到 WiFi RX/TX 缓冲、Opus jitter buffer、RTC SDK jitter buffer,最大化 RTC 体验。
关键改动:
sdkconfig.defaults:CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM: 10 → 16CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM: 32 → 48CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM: 32 → 48CONFIG_ESP_WIFI_RX_BA_WIN: 6 → 16(AMPDU 窗口扩大减少重传)
- Opus decode pool 上限扩容(如 SDK 暴露)
- 火山 RTC SDK jitter buffer 配置扩容(如 SDK 暴露)
heap_caps_print_heap_info前后对比
预估工时:1 天
完成标志:
- ✅ sdkconfig 改动编译通过且烧录稳定
- ✅ DRAM 投入 ≤ 15KB 后剩余可用 ≥ Phase 8 baseline
- ✅ Phase 8 DIAG 埋点对比:queue=0 次数下降、WiFi 重传减少
- ✅ 用户主观:扬声器流畅度提升
产出 commit:perf(rtc-only): Phase 11 - WiFi 缓冲扩容 + jitter buffer 强化
Phase 12: 集成测试 + 推送
目标:端到端验证 MILESTONE.md 第 6 节全部验收项,推送到 gitea + GitHub。
任务:
- 整机端到端测试(按 MILESTONE.md 成功标准清单逐项验证)
- 内存/CPU 监控:
heap_caps_print_heap_info(MALLOC_CAP_INTERNAL)heap_caps_print_heap_info(MALLOC_CAP_SPIRAM)- 30 分钟持续对话压测
- 用
idf.py size对比阉割前后固件大小 - 更新
docs/Rtc_AIavatar/数字人表情渲染方案_云端预渲染+BLE+OTA.md章节:阉割成果汇报 - 提交 + 推送:
git push origin Rtc_AIavatar(gitea)git push https://github.com/Leo-z8/Baji_Rtc_Toy.git Rtc_AIavatar
完成标志:
- ✅ MILESTONE.md 第 6 节成功标准全部 ✓
- ✅ Phase 10/11 音频卡顿问题已解决
- ✅ gitea + GitHub 远程已同步
- ✅ 文档更新完成
产出 commit:docs(milestone): 数字人 RTC 项目完成 - 验收报告 + 性能数据
阶段依赖与并行性
- Phase 1 ⊥ Phase 2(独立,可并行做)
- Phase 3 依赖 Phase 2(需要 6MB SPIFFS)
- Phase 4/5 依赖 Phase 1(dzbj 模块清理完成)+ Phase 3(GIF 资源就位)
- Phase 4 ⊥ Phase 5(情绪映射和字幕显示独立,可并行)
- Phase 6 依赖 Phase 1(清理 sleep_mgr 调用点)
- Phase 7 依赖 Phase 6(PowerSaveTimer 状态机重写需 Phase 6 守卫到位)
- Phase 8 依赖 Phase 6(卡顿症状在 Phase 6 收尾发现,需要 RTC 链路稳定)
- Phase 9 已取消(增量优化效果不明显,改走 Phase 10 完整切 EAF)
- Phase 10 依赖 Phase 8(数据排除调度问题后用户决策完整切 EAF 验证显示效果)
- Phase 11 依赖 Phase 10(用 Phase 10 释放的 DRAM/PSRAM 做资源再分配)
- Phase 12 必须最后(依赖 Phase 11 完成)
建议串行执行顺序:1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10 → 11 → 12
当前状态
| Phase | 状态 |
|---|---|
| Phase 1 | ✅ 完成(commit 672506e,已推送 gitea + GitHub) |
| Phase 2 | ✅ 完成(commit ce7a3aa) |
| Phase 3 | ✅ 完成(commit 7d1c7dc) |
| Phase 4 | ✅ 完成(commit 497c1b4) |
| Phase 5 | ✅ 完成(commit f2be992) |
| Phase 6 | ✅ 完成(commit b8a5fe9 + 4b7b194 收尾) |
| Phase 7 | 🔄 进行中(phase_07_battery_psm 规格已写,实施待启动) |
| Phase 8 | ✅ 完成(commit 3dc6cad,4 类 DIAG 埋点 + 根因报告) |
| Phase 9 | ❌ 已取消(v1/v2/v3 增量优化未解决,CANCELLED.md 记录教训) |
| Phase 10 | ⏳ 待启动(数字人模式 LVGL→EAF 完整切换,新增) |
| Phase 11 | ⏸️ 阻塞中(内存优化 + WiFi 缓冲扩容,依赖 Phase 10 完成) |
| Phase 12 | ⏳ 待启动(集成测试 + 推送,原 Phase 10 重编号) |