|
|
3a1111e99d
|
plan(rtc-only): Phase 9 取消 + Phase 10/11/12 规划(LVGL → esp_emote_gfx)
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>
|
2026-05-15 13:37:34 +08:00 |
|
|
|
3dc6cadf49
|
diag(rtc-only): Phase 8 - 音频卡顿根因诊断埋点 + 数据采集报告
数字人 RTC 模式音频卡顿根因定位。通过 4 类 ESP_LOGW 埋点采集运行时
数据,对照表格判定根因,输出 Phase 9 实施分支决策。
埋点实现(main/application.cc,PHASE8_DIAG_ENABLE 宏开关,关闭后零开销):
- DIAG-1 queue 深度:3 处(出队 + WebSocket 入队 + RTC 入队),50ms 节流
- DIAG-2 codec->OutputData 写入耗时:>15ms 阈值告警
- DIAG-3 WiFi RSSI:OnClockTimer 1Hz
- DIAG-4 heap 快照 + 碎片率:OnClockTimer 1Hz
实测结论(见 DIAG_REPORT.md):用户感知卡顿 = 两个独立根因
- A. 开机播报阶段 ③' codec init 时序缺陷(ES7210 I2C 失败 +
126 次 write_slow 集中在 2-13s)
- B. RTC 对话阶段 ⑤ Opus/WebSocket 应用层帧到达抖动
(queue 突发堆积 19 + queue=0 出现 58 次,但 codec 写入 0 次 slow)
完全排除:① CPU 争抢、② PSRAM 带宽、④ WiFi 丢包(RSSI -24~-33dBm
极强)、⑥ 内存碎片(heap 全程稳定)
Phase 9 推荐分支 B'(双线修复,原 A/C 的 EAF 方案不适用):
- 9.1 应用层 jitter buffer(fill-threshold + drain)—— 解 B
- 9.2 开机 codec init 时序修复(ES7210 reset + ready 等待)—— 解 A
- 估时 1 天
ROADMAP 同步:Phase 7 矫正为 battery_psm(实际状态)、Phase 8 新增
诊断、Phase 9 占位待 Phase 8 决策、原"集成测试"挪到 Phase 10。
新增 .planning/STATE.md 记录 roadmap evolution。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-15 11:40:42 +08:00 |
|
|
|
4b7b1949d4
|
perf(rtc-only): Phase 6 收尾 - 卡顿优化 + PowerSaveTimer 守卫 + 开机加速
代码改动:
- AudioLoop 加 vTaskDelay(1),让出 Core 1 idle task 防 WiFi/RTC 饥饿
- BackgroundTask 优先级 2 → 5,提升 Opus 解码实时性
- LVGL 刷新 5ms → 16ms (60Hz),CPU 占用降 60%
- GIF 定时器 20ms → 33ms (3 处),PSRAM 流量减半
- AI 字幕推送 100ms 节流,避免 LVGL 锁争抢
- EnterIdleHibernate 清空 audio_decode_queue_,防 standby_sound 残留误触发首帧
- PowerSaveTimer OnEnterSleepMode 加 device_state 守卫,拦截 dialog/connecting
期间关功放(修复欢迎语期间被静音 bug)
- 取消开机 ADC 阻塞采样,开机播报响应从 6 秒缩到 < 3 秒
新增规划:
- Phase 7 占位文档:电量保护 + PowerSaveTimer 重构 + 唤醒杂音根治 + RTC 抖动缓解
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-05-14 11:38:48 +08:00 |
|
|
|
b8a5fe958f
|
feat(rtc-only): Phase 6 - RTC 空闲软休眠(B+C 双源 + 真退房 + 字幕提示 + 内存兜底)
按 GSD 框架 .planning/milestones/digital_human_rtc/phases/phase_06_idle_hibernate/
规划完成 Phase 6 软退出 RTC 机制。替代旧的"40s 硬重启退出"方案。
## 核心变更
### 1. 倒计时刷新(B+C 双源方案)
| 方案 | 监听源 | 实施位置 | 状态 |
|------|--------|---------|------|
| A 扬声器流 | I2S/PCM 输出 | application.cc audio output 3 处 | **宏关闭**(PHASE6_ENABLE_AUDIO_FALLBACK) |
| **B 字幕监听** | RTC subtitle 消息 | application.cc:1300 subtitle 分支 | **启用** |
| **C 智能体状态** | RTC conv_status 消息 | application.cc:1260 conv_status 分支 | **启用** |
复用现有 DIALOG_IDLE_COUNTDOWN_SECONDS=40 不新增常量。
### 2. 真退出 RTC 房间(释放 License)
- 新增 Protocol 基类虚函数 LeaveRoom(默认回退到 CloseAudioChannel)
- VolcRtcProtocol::LeaveRoom 覆写:volc_rtc_stop + volc_rtc_destroy
- 火山官方文档明确:真退房必须 leaveRoom + destroyRTCEngine
- CloseAudioChannel 只 stop 不够(真人仍在房间继续计费)
- 服务端 AI 任务在 180s 内自动清理(火山平台机制)
### 3. EnterIdleHibernate / WakeFromHibernate
EnterIdleHibernate 流程(严格顺序):
1. protocol_->LeaveRoom() # 真退房
2. codec->EnableInput/Output(false) # 重置 codec 状态机
3. recorder_pipeline_close()
4. hibernating_.store(true) # 关键:先设标志阻止 PowerSaveTimer
5. esp_pm_configure(light_sleep=false) # 双保险禁用 Light Sleep
6. SetDeviceState(kDeviceStateIdle)
7. idle_cycles_++ + NVS 持久化
8. 字幕"已自动退出RTC对话,按BOOT键重新连接RTC"(5 次重试间隔 200ms)
WakeFromHibernate 流程:
1. 检查 idle_cycles_ >= 50 → 硬重启清理碎片(兜底)
2. 清空字幕
3. ToggleChatState → OpenAudioChannel → 自动重建 rtc_handle_
4. RTC 重新加入房间(实测 2-3s 完成)
### 4. CanEnterSleepMode 加 hibernating 检查
防止 hibernate 期间 PowerSaveTimer 触发 esp_pm_configure(light_sleep=true)
导致 I2C 总线进入低功耗 → 唤醒后 ES7210/ES8311 通信失败 abort。
### 5. Dialog Watchdog 触发动作改造
旧:esp_restart() 整机重启(黑屏 15-25s + WiFi 重连)
新:Schedule(EnterIdleHibernate) 软退房(不熄屏 + 字幕提示)
### 6. BOOT 唤醒走 WakeFromHibernate 路径
iot_button 回调中检测 IsHibernating(),派发到独立 task 执行
WakeFromHibernate(避免阻塞 esp_timer 任务,CLAUDE.md 经验)。
### 7. OpenAudioChannel 适配重建
LeaveRoom 销毁 rtc_handle_ 后,OpenAudioChannel 头部检测 NULL
触发 Start() 异步重建,轮询 5s 等待就绪。NVS 缓存 device_secret
所以重建通常 100ms 完成。
## 实测验证(用户协作)
| 阶段 | 时间 |
|------|------|
| 40s 触发软休眠 | ✅ |
| LeaveRoom 真退房 | ✅ "✓ 已真退出 RTC 房间(leaveRoom + destroyRTCEngine)" |
| 屏幕保持 + 字幕显示 | ✅ "已自动退出RTC对话,按BOOT键重新连接RTC" |
| BOOT 按键唤醒 | ✅ |
| RTC 实例重建 | ✅ 100ms |
| RTC 重新加入房间 | ✅ 2-3s |
| 连续 2 次软休眠+唤醒 | ✅ 无 abort/I2C 失败 |
| 时间对比 | 旧硬重启 15-25s → 软休眠 3-5s(省 80%) |
## 6 个关键踩坑修复(详见 HIBERNATE_REPORT.md)
1. codec 状态机未重置 → 唤醒后 I2C abort
2. PowerSaveTimer Light Sleep 干扰 I2C 总线
3. hibernating_ 设置时序错误
4. dynamic_cast 在 -fno-rtti 下编译失败 → 改基类虚函数
5. LeaveRoom 后 OpenAudioChannel 直接失败 → 加重建逻辑
6. 字幕 LVGL 锁竞争 → 推迟到最后 + 5 次重试
## 文档产出(同时提交)
- .planning/.../phase_06_idle_hibernate/PLAN.md(含实施变更记录 V1-V6)
- .planning/.../phase_06_idle_hibernate/HIBERNATE_REPORT.md(验证报告)
- .planning/.../ROADMAP.md(Phase 1-5 ✅ + Phase 6 进行中状态更新)
- docs/Rtc_AIavatar/数字人表情渲染方案_云端预渲染+BLE+OTA.md
新增第 19 章 RTC 空闲倒计时方案选型与软退出(9 小节)
- docs/Rtc_AIavatar/RTC软退出方案_移植参考.md
完整移植参考(10 章 + 3 附录,可移植到其他火山 RTC 项目)
- docs/Rtc_AIavatar/音频卡顿_全局资源分析.md
全局资源分析 + 13 项优化建议(不改代码)
|
2026-05-13 17:28:36 +08:00 |
|
|
|
f2be9922b6
|
feat(rtc-only): Phase 5 - RTC 字幕显示恢复(透明背景 + 2 行黑字 + 锁优化)
按 GSD 框架 .planning/milestones/digital_human_rtc/phases/phase_05_subtitle_restore/
规划完成 Phase 5 字幕显示恢复。
## 核心变更(main/dzbj/ai_chat_ui.c)
### 1. chat_container 重构
- 新增 static chat_container 变量(lv_obj 父容器)
- 尺寸 320×56(= 2 行字 + padding 4px*2)
- 位置 LV_ALIGN_BOTTOM_MID 距底 10px
- 完全透明背景(LV_OPA_TRANSP),无灰底
- 初始 HIDDEN,有内容时显示
### 2. chat_label 改造
- 黑色文本(用户反馈白字在浅色背景上不清晰)
- 尺寸 312×48 限制最多 2 行
- LV_LABEL_LONG_WRAP → LV_LABEL_LONG_DOT,超出 2 行自动 ... 截断
- font_puhui_20_4 中文字体不变
### 3. ai_chat_set_chat_message() 实现
原为空函数(PoC 期间 return),本 Phase 完整实现:
- 锁外去重:static last_content[256],相同内容直接返回
- lvgl_port_lock 200ms → 500ms(GIF 解码繁忙时给予更长等待)
- 内容空时隐藏容器,非空显示
- 成功更新后缓存 last_content
### 4. z-index 修复
bg_gif_demo_start() 后立即 lv_obj_move_foreground(chat_container)
否则 bg_img/gif_obj 后于 chat_container 创建会遮挡字幕
## 实测验证(用户协作)
60s 对话期间:
- ✅ AI 字幕完整推送 3 次(含 54 字符长字幕)
- ✅ LVGL 锁超时 14 次 → 0 次(锁外去重生效)
- ✅ 表情切换 + 字幕同步工作
- ✅ 长字幕自动 2 行截断
- ✅ 无 abort/重启
## 调用链(已对接 application.cc 现有逻辑,无需改协议层)
RTC 字幕 → display->SetChatMessage(role, msg)
→ AiChatDisplay::SetChatMessage
→ ai_chat_set_chat_message() ← 本 Phase 实现
## GSD 文档
- PLAN.md
- SUBTITLE_REPORT.md(含锁优化对比 + 布局规划 + 用户决策记录)
|
2026-05-13 13:35:41 +08:00 |
|
|
|
497c1b4654
|
feat(rtc-only): Phase 4 - 情绪标签 → 数字人 hiyori GIF 映射 + 切换接口
按 GSD 框架 .planning/milestones/digital_human_rtc/phases/phase_04_emotion_mapping/
规划完成 Phase 4 情绪映射 + 运行时切换。
## 核心变更
### bg_gif_demo 新增运行时切换接口
```c
esp_err_t bg_gif_demo_switch_gif(const char *new_gif_path);
```
实现要点:
- 先 heap_caps_free(g_gif_data) 释放旧 PSRAM,再加载新 GIF,单峰仅一份
- 内部 static last_gif_path 去重(相同路径直接返回 ESP_OK)
- 切换后立即 lv_timer_set_period(timer, 20) 防止 lv_gif_set_src 重建为默认 10ms
- LVGL 锁保护 200ms 超时
### 22 情绪 → 3 hiyori GIF 映射表
定义在 main/dzbj/ai_chat_ui.c USE_BG_GIF_POC 包裹内:
| GIF | 情绪标签 (个数) |
|-----|----------------|
| m06 (默认/积极) | neutral, happy, laughing, funny, loving, relaxed, delicious, kissy, confident, silly, blink, curious (12) |
| m07 (思考/疲倦) | sleepy, thinking, confused, embarrassed, dizzy (5) |
| m03 (负面/严肃) | sad, crying, angry, surprised, shocked (5) |
22 个标准情绪 100% 覆盖,未映射的情绪默认 fallback 到 m06。
### ai_chat_set_emotion 改造
PoC 模式下优先切换数字人大图(不再切隐藏的 emoji 200x89):
```c
#ifdef USE_BG_GIF_POC
if (bg_gif_demo_is_running()) {
const char *path = find_hiyori_gif(emotion);
bg_gif_demo_switch_gif(path);
return;
}
#endif
// 非 PoC 模式 fallback emoji 路径保留
```
## 调用链(已与现有 RTC 字幕解析对接,无需改 application.cc)
RTC 字幕 → application.cc:1419 display->SetEmotion(emo)
→ AiChatDisplay::SetEmotion (display/ai_chat_display.cc)
→ ai_chat_set_emotion (dzbj/ai_chat_ui.c)
→ bg_gif_demo_switch_gif (PoC 模式)
→ 数字人 hiyori GIF 切换
## 烧录验证(用户实测)
监控 60s 期间捕获情绪切换:
- neutral / happy → m06(已在播,去重)
- thinking → m07 切换成功 (590ms 延迟)
- confused → m07 去重跳过
- AI 回复结束 → 自动回到 neutral
- 无 abort / 重启
m06 ↔ m07 切换屏幕可视确认,m03 走相同代码路径无需重复测试。
## GSD 文档(同时提交)
- .planning/milestones/digital_human_rtc/phases/phase_04_emotion_mapping/PLAN.md
- .planning/milestones/digital_human_rtc/phases/phase_04_emotion_mapping/EMOTION_REPORT.md
|
2026-05-13 11:59:38 +08:00 |
|
|
|
7d1c7dc1f0
|
feat(rtc-only): Phase 3 - 数字人 GIF 资源准备(hiyori m03/m06/m07,209x360)
按 GSD 框架 .planning/milestones/digital_human_rtc/phases/phase_03_gif_resources/
规划完成 Phase 3 数字人表情 GIF 资源处理。
## 处理方式(与 PoC 阶段 hiyori_m05.gif 一致)
```bash
gifsicle --resize _x360 -O3 input.gif -o output.gif
```
- 高度 = LCD 360px,宽度按原比例自动算 → 209px
- 不裁剪(保持源 GIF 完整人物)
- 不加 --lossy / --colors(保留 256 色,画质优先)
- 只用 -O3 优化文件大小
## 处理结果
| GIF | 用途 | 源 | 处理后 | 节省 |
|-----|------|-----|--------|------|
| m03 | 负面/严肃 | 407×700 3.3MB | 209×360 1.15MB | 66% |
| m06 | 默认/积极 | 407×700 1.3MB | 209×360 0.44MB | 66% |
| m07 | 思考/疲倦 | 407×700 1.2MB | 209×360 0.40MB | 66% |
| 合计 | — | 5.7MB | 1.94MB | 66% |
## 决策过程(避免后续重复犯错)
Phase 3 初稿曾尝试裁剪到 240×320 + PIL 全帧 bbox 居中裁剪,
用户烧录后反馈"视觉感官不好"——角色被横向压扁(240×320 纵横比 0.75
vs 源 407×700 纵横比 0.583)。回归 PoC 等比例缩放方式后效果与 PoC 一致。
PoC 处理标准已写入用户级 feedback memory(feedback_hiyori_gif_processing.md),
后续 hiyori GIF 处理一律用本方式,除非用户主动要求修改。
## 显示效果(用户已目视确认)
LCD 360×360 居中显示 209×360 GIF:
- 垂直方向: 360 = 360,完全充满
- 横向: 209 < 360,左右各 75.5px 留边显示背景图
- 角色比例: 完整保留源 GIF 的 407:700 = 0.582 纵横比,人物细高自然
## 删除项
- spiffs_image/hiyori_m05.gif (2.3MB) 已删除 - 被 m06/m07/m03 替代
文件历史保留在 git,可通过 git show eb96130:spiffs_image/hiyori_m05.gif 恢复
## 默认表情切换
main/dzbj/ai_chat_ui.c:234:
- PoC: bg_gif_demo_start(..., "/spiflash/hiyori_m05.gif")
- Phase 3: bg_gif_demo_start(..., "/spiflash/hiyori_m06.gif")
## 烧录运行时验证
- 烧录后 0 次重启(连续监控 18 秒)
- BG_GIF: GIF 已加载到 PSRAM: /spiflash/hiyori_m06.gif (441.8 KB)
- AudioCodec: Audio codec started(首次冷启动直接成功)
- 用户目视确认显示效果良好
## GSD 文档(同时提交)
- .planning/milestones/digital_human_rtc/phases/phase_03_gif_resources/PLAN.md
- .planning/milestones/digital_human_rtc/phases/phase_03_gif_resources/GIF_REPORT.md
## SPIFFS 容量
新 SPIFFS 4.94MB 当前实际占用 ~2MB(40%),余量 ~2.94MB 充足。
|
2026-05-13 11:42:30 +08:00 |
|
|
|
ce7a3aad63
|
feat(rtc-only): Phase 2 - 16MB Flash 分区调整(OTA 5.5MB + SPIFFS 4.9MB)
按 GSD 框架 .planning/milestones/digital_human_rtc/phases/phase_02_partition_resize/
规划完成 Phase 2 分区表调整,为 Phase 3 数字人 GIF 资源扩容铺路。
## 分区表变更
| 分区 | 旧 | 新 | 变化 |
|------|-----|-----|------|
| model | 0x10000 / 64KB | — 已移除 | -64KB |
| ota_0 | 0x20000 / 6.5MB | 0x10000 / 5.5MB | -1MB |
| ota_1 | 0x6A0000 / 6.5MB | 0x590000 / 5.5MB | -1MB |
| storage | 0xD20000 / 2.875MB | 0xB10000 / 4.9375MB | +2.0625MB |
合计:16MB(不变),SPIFFS 净扩容 2.0625MB
## 决策依据
- 当前 =n 固件 4.63MB,5.5MB ota 留 19% 成长 buffer
- SPIFFS 4.9MB 为 3 个 hiyori GIF + 背景图扩容(Phase 3 预算 ~3.9MB)
- 移除未使用的 64KB model 分区
- NVS 分区位置/大小不变,WiFi 凭据等数据完整保留
## 验收结果(详见 PARTITION_REPORT.md)
- =n 编译:✅ kapi.bin 4.63MB ≤ 5.5MB ota_0
- =y 双模式编译:链接通过但 6.05MB > 5.5MB ota(**预期降级**,
数字人 RTC 单一形态只用 =n 固件,Phase 3 资源精简后或可恢复)
- 烧录运行时验证:
✅ Running partition: ota_0
✅ NVS 数据完整保留(WiFi 凭据/设备配置)
✅ SPIFFS 自动挂载,hiyori_m05.gif 加载成功
✅ AI 对话模式启动,Codec 工作,WiFi 连接,RTC WebSocket 协议初始化
✅ free_heap=5.2MB(无 regression)
## GSD 文档(同时提交)
- .planning/milestones/digital_human_rtc/phases/phase_02_partition_resize/PLAN.md
- .planning/milestones/digital_human_rtc/phases/phase_02_partition_resize/PARTITION_REPORT.md
|
2026-05-13 11:00:35 +08:00 |
|
|
|
672506e7c7
|
feat(rtc-only): Phase 1 - 通过 CONFIG_BAJI_BADGE_MODE 屏蔽电子吧唧模式
按 GSD 框架 .planning/milestones/digital_human_rtc/ 规划完成 Phase 1。
源代码全部保留,通过 Kconfig 开关 + CMakeLists 条件编译 + #ifdef 调用点保护
实现"吧唧模式不进固件但代码可恢复"。
## 核心变更
### Kconfig 开关(默认关闭)
- 新增 CONFIG_BAJI_BADGE_MODE(main/Kconfig.projbuild)
- sdkconfig.defaults 默认 =n
- =y 时恢复双模式(电子吧唧 + AI 对话)
- =n 时仅 AI 数字人 RTC 模式
### CMakeLists 剥离(剥离式不重写)
- 9 个 dzbj/ 吧唧专属 + 9 个 ui/screens/ 吧唧 UI 进入 if(CONFIG_BAJI_BADGE_MODE) 条件块
- 公共保留: dzbj/lcd.c, ai_chat_ui.c, sprite_demo.c, dual_gif_demo.c,
bg_gif_demo.c, pages_pwm.c, dzbj_init.c, fatfs.c
- 修正 PLAN 漏判:dzbj_init/fatfs 公共化(AI 模式调用 dzbj_hw_display_init/DecodeImg)
### 调用点 #ifdef 保护
- application.cc: L20 include, L63-66 background_task, L536 device_mode 分支
- movecall_moji_esp32s3.cc: dzbj headers, init_spiffs_image_list extern,
dzbj_boot_click_handler extern, device_mode_is_badge 分支, InitializeBadgeMode,
InitializeBadgeModeButtons, mode_switch_combo 注册, device_mode_in_switch_suppress
- 保留公共 extern: ai_chat_screen_init, ai_chat_resume_animation, pwm_init
### 整体文件级 #ifdef 包裹
- dzbj/dzbj_button.c/h
- dzbj/sleep_mgr.c
- sleep_mgr/include/sleep_mgr.h
### 6 个文件显式 #include "sdkconfig.h"
- ESP-IDF 不会 force-include,必须手动 include 才能拿到 CONFIG_* 宏
## G7 验收双向编译
- =n 模式 build: ✅ EXIT=0(数字人 RTC 单一形态)
- =y 模式 build: ✅ EXIT=0(双模式恢复可用)
## 固件大小变化
| 段 | =n | =y | 节省 |
|----|-----|------|------|
| .text | 2.03 MB | 2.06 MB | 27 KB |
| .rodata | 2.48 MB | 3.87 MB | 1.39 MB |
| Total | 4.63 MB | 6.05 MB | 1.45 MB |
## GSD 文档(同时提交)
- .planning/milestones/digital_human_rtc/MILESTONE.md
- .planning/milestones/digital_human_rtc/ROADMAP.md
- .planning/milestones/digital_human_rtc/INTEL.md
- .planning/milestones/digital_human_rtc/phases/phase_01_kconfig_isolation/PLAN.md
- .planning/milestones/digital_human_rtc/phases/phase_01_kconfig_isolation/SIZE_REPORT.md
- .planning/milestones/digital_human_rtc/phases/phase_01_kconfig_isolation/BADGE_MODE_ISOLATION_MAP.md
- 编译大小原始数据: size_*.txt
## 已知事项
- =n 固件 4.63 MB 仍 > 4 MB 目标,Phase 2 调整分区 + Phase 3 物理移除图片资源解决
- main/dzbj/ 下所有源文件完整保留,无任何物理删除
|
2026-05-13 10:22:48 +08:00 |
|