存储栈RAM优化P0-1:BBT缓冲按实际载荷272B收紧,编程回读校验整体移除(向业界靠拢),新增存储栈RAM优化调研报告

This commit is contained in:
2026-09-21 11:23:15 +08:00
parent 07c97cb3cd
commit f86cb8824b
3 changed files with 76 additions and 34 deletions
@@ -0,0 +1,70 @@
# 存储栈 RAM 优化调研
> 版本 v1.0 日期 2026-09-21 作者 AI 辅助调研
> 数据来源:`data/ram_report_20260921.md`(.map 静态占用)+ 逐行代码核验(`nand_ftl.c` / `gd5f2gq5ue.c` / `Lib/dhara` / `Lib/FatFs/ffconf.h` / `lftpd*`)
> 定位:`RAM使用分析与优化方案.md` 的存储专项补充;优化项编号 P0/P1/P2,与总方案 §6 的 S 序号在"规划"一节对齐
## 1. 现状盘点(2026-09-21 基线)
存储栈静态 RAM 全部在 **RW_IRAM1(主 SRAM 128KB)**,合计 **≈15.5 KB(占已用 82,048B 的 18.9%)**。运行期堆占用(CCM)仅 lftpd 路径串/`DIR` 约 ≤100B 瞬态,FatFs/dhara 无大块堆分配。
| 模块 (.o) | RW+ZI | 主要构成 | 约束 |
|---|---:|---|---|
| nand_ftl.o | 6,216 | `s_page_buf` 2,048(dhara journal checkpoint,协议要求整页)+ `s_cache_buf` 2,048(512B 扇区 RMW 写回缓存)+ `s_copy_buf` 2,048(GC 拷贝暂存)+ dhara map/journal 结构 ~120 | 页缓冲走 SPI1 DMA(>阈值 1024B),DMA 不可达 CCM |
| gd5f2gq5ue.o | 2,596 | `s_bbt_page_buf` 2,048 + `s_bbt`/`s_bbt_best` 位图 2×256 + 保留池 16 + 状态 | 同上 |
| lftpd.o | 4,768 | 9 处函数级 static:2×1024(STOR/RETR 数据块)、512×3(response/read_buffer/arg_buf)、256×3(message/name×2)+ 256(log) | 纯 CPU 访问,无 DMA |
| lftpd_io.o | 556 | `s_ftp_file`(FIL,内含 512B 私有扇区窗) | 纯 CPU |
| freertos.o 内 `default_fatfs` | ~576 | FATFS 对象(`win[512]` 共享窗 + 卷状态) | 纯 CPU |
| cfg_file.o | 724 | 配置引擎静态态 | 纯 CPU |
| ff.o + ffsystem.o | 16 | 文件系统对象指针 + 同步原语 | `FF_FS_REENTRANT=1`(defaultTask/ftpTask 并发所需,保留) |
FatFs 配置已是低 RAM 取向:`FF_MAX_SS=512`、`FF_USE_LFN=0`、`FF_VOLUMES=1`、`FF_FS_LOCK=0`。
## 2. 调研发现
- **F1 BBT 页缓冲超配 10 倍**:`s_bbt_page_buf[2048]`,但实际读写只有 `GD5F_BBT_HDR_SIZE(16)+GD5F_BBT_SIZE(256)=272B`(`gd5f2gq5ue.c:925` 读 272B、`:1010` program_load 272B)。缩到 272B 行为零变化。
- **F2 ~~GC 搬迁路径 program verify 空转~~(已随校验整体移除而消失,留档备查)**:2026-09-21 前 `dhara_nand_copy()` 回读缓冲与源同址(`s_copy_buf`),memcmp 恒真自比对(空校验);2026-09-21 编程回读校验整体移除(选项 (b),向 Linux mtd 形态靠拢)后该缺陷不复存在。教训:任何比对式校验必须在**两份独立副本**间进行(U-Boot `sf test` 双缓冲形态)——若未来在测试构建恢复回读诊断,勿重蹈此坑。
- **F3 3×2KB 页缓冲是结构成本,不可直缩**:dhara journal 要求整页 checkpoint(`journal.c:196` 整页 memset);512B 扇区落 2KB 页必须整页 RMW。可动的只有 `s_copy_buf`(改分段暂存)。
- **F4 CCM 迁移功能上安全**:`gd5f_dma_buf_ok()` 运行时守卫会把 DMA 不可达缓冲自动回落 CPU 轮询(2026-09-21 加固),把 NAND 页缓冲挪进 CCM 不会静默失败,代价只是每页零点几 ms CPU(轮询 vs DMA 卸载)。CPU-only 缓冲(lftpd/cfg/FATFS win)迁 CCM 则零代价。
- **F5 栈上 FIL 重复占深链**:syslog 两处、cfg 存储两处、开机探针各一个局部 `FIL`(每个含 512B buf,≈552B),全部压在 defaultTask 最坏链 2,776B 内——这是 `FF_FS_TINY` 的靶点(见 P1-4)。
## 3. 方案清单
| # | 方案 | 省 RAM | 区域 | 风险 | 验证 |
|---|---|---:|---|---|---|
| P0-1 | `s_bbt_page_buf` 2048→272(按实际读写字节数定义) | **−1,776B** | SRAM1 | 极低(一行宏+数组维) | `@build` + 开机 BBT 加载 + `@test` |
| P0-2 | `s_copy_buf` 2048→512:GC 拷贝改分段 read→program_load(`program_load`/`read_from_cache` 支持列地址)【性质变更 2026-09-21:回读校验整体移除后,此项变为**纯 RAM 优化**(GC 拷贝暂存减半),无校验语义风险,与原"分块+修 F2"解耦】 | **−1,536B(可选,不计入当前预期)** | SRAM1 | 低(仅动拷贝机制) | 待 RAM 余量需要时再议 |
| P0-3 | lftpd 缓冲收紧:response 512→256、read_buffer 512→256、arg_buf 512→256、name 256→128 ×2(本卷仅 8.3 短名,路径深度浅);数据块 2×1024 与 message 不动 | **−1,024B** | SRAM1 | 低(FTP 客户端实测行长远低于新值) | `@build` + FTP 上传/下载/LIST 闭环 + `@test` |
| P1-4 | `FF_FS_TINY=1`:删每 FIL 私有的 512B buf,文件数据走 `FatFs->win` 共享窗 | 静态 **−528B**;且栈上每处 FIL 峰值 **−528B**(defaultTask 最坏链 2,776→~2,250,实测峰 2,136→~1,600) | SRAM1 + CCM 栈 | 中(所有文件 I/O 经 512B 窗 bounce,FTP 吞吐 −20~40%;LIST 与文件读交错只影响速度) | 存储套件 + FTP 吞吐实测 + 日志/配置闭环;**与 S7 缩栈捆绑**(直接支撑 defaultTask 降档) |
| P1-5 | `APP_CCM_ENABLE` 门(与 S6 同宏):①CPU-only 缓冲迁 CCM——lftpd static 3.6K + cfg_file 0.7K + FATFS win 0.6K + lftpd_io ≈ **−4.9K** 零代价;②DMA 页缓冲(nand_ftl 4.6K + gd5f 位图/页 0.8K)迁 CCM 走轮询 ≈ **−5.4K**,需实测吞吐 | **−10.3K** | SRAM1→CCM | 低①/中② | 分段实施;每步跑 `ram_report.py` + `@test` + FTP 吞吐 |
| P2-6 | NAND copy-back 命令(0x15→0x10)替代主机搬页:省 `s_copy_buf` 的拷贝用途 + 减半 SPI 流量 | −512B(P0-2 后) | SRAM1 | 高(片上 ECC 在 copy-back 下的语义须台架实证) | 仅评估,暂缓 |
| P2-7 | lftpd 数据块 2×1024→512 | −1,024B | SRAM1 | 吞吐 −~30% | RAM 仍紧时才做 |
| P2-8 | syslog/cfg 共享一个静态 FIL(同任务串行) | 净≈0(静态+528/栈−528) | — | 不推荐:P1-4 已覆盖同一收益面 | — |
**明确不做**:移除 dhara(丢掉电一致性与坏块重映射,代价不对称);journal checkpoint 分片(违反 dhara 协议);调 `gc_ratio`(无 RAM 收益);`FF_FS_REENTRANT=0`(defaultTask+ftpTask 并发访问 FatFs 必需)。
**实施记录**:
| # | 状态 | 日期 | 验证 |
|---|---|---|---|
| P0-1 | ✅ 已落地 | 2026-09-21 | `@build` 0/0;`@test` PASS(BBT 开机加载闭环);.map RW_IRAM1 82,048→80,272(**−1,776B**,精确命中) |
| P0-2 | ⏸ 搁置(性质已变) | 2026-09-21 | 回读校验整体移除后,此项由"校验分块+修 F2"变为 **GC 拷贝纯 RAM 优化**(`s_copy_buf` 2048→512 分段 read→load);无紧急性,待 RAM 余量需要时再议 |
| 编程回读校验整体移除 | ✅ 已落地 | 2026-09-21 | 先改编译开关 `GD5F_PROG_VERIFY`,同日按选项 (b) **整体移除**(向 Linux mtd / U-Boot / dhara 上游形态靠拢:数据路径无回读比对,编程正确性以 P_FAIL 状态位+读时 ECC+journal 读时门为准);代码/宏/开关全部移除,"实证失效"误记录同步更正(幻影编程假设已被 Trap 05 证伪,本板无实测编程失效);F2 自比对缺陷随之消失;产品构建 `@build` 0/0 + `@test` PASS |
| P0-3 / P1-4 / P1-5 | 待实施 | — | — |
## 4. 分阶段规划(与总方案 §6 S 序号对齐)
| 阶段 | 内容 | 收益(SRAM1 已用 82,048B 基础上) | 前置 |
|---|---|---:|---|
| **第一步 P0**(独立小批) | P0-1(已落地)+ P0-3(P0-2 搁置,性质已变为纯拷贝优化) | **−2,800B**(P0-1 已省 1,776B) | 无 |
| **第二步**(并入 S7 缩栈批) | P1-4 `FF_FS_TINY=1` → 复跑 `stack_report.py` → defaultTask 降档(最坏链 ~2,250 支撑 3,584B 配置,余量 37%)+ 其余任务按 S7 目标 | −528B 静态 + 栈档下调释放 CCM 堆 | 第一步合入 |
| **第三步**(与 S6/S8 同批) | 先 S8 堆 48K→32K(CCM 释放 ~16K),再 P1-5 ①→② 分批迁 CCM | SRAM1 再 **−10.3K**;CCM 占用 +10.3K(由 S8 腾挪覆盖) | S8 或同批评估 CCM 水位 |
**全部落地后存储栈预期**:SRAM1 常驻从 15.5KB 降至 **~1.9KB**(仅小状态量),页缓冲驻 CCM(轮询),静态合计挪入 CCM 换回 SRAM1 ≈ **−13.6KB**(P0-2 搁置(性质已变为纯拷贝优化),其 −1,536B 不计);叠加 S5(LVGL 40K→16K)后 SRAM1 余量 >65KB。
## 5. 风险与回归要求
- 回读校验移除(2026-09-21 落地):产品构建 `@build` 0/0 + `@test` 开机闭环(编程路径仅余 P_FAIL 状态检查);GD5F/STORAGE 测试构建各编译 0/0(套件 ECC 写读用例经读路径覆盖编程正确性);台架破坏性套件 + 掉电 resume 随下次存储改动照常执行。
- P1-4 前后各跑一次 `stack_report.py` + `ram_report.py`(AGENTS.md 门禁),FTP 吞吐留实测数字(当前基线可先记一轮 RETR/STOR 速率)。
- P1-5 的 ②(页缓冲入 CCM 走轮询)须以实测吞吐定去留:若 NAND 读吞吐降幅 >30%,则只迁 CPU-only 侧(①)。
- 本文数字均可由 `data/ram_report_20260921.md` 与上表代码行号复核;实施后重生成基线报告并回填本文状态列。