diff --git a/docs/问题记录/GD5F2GQ5UE_Trap_Records.md b/docs/问题记录/GD5F2GQ5UE_Trap_Records.md index fb84c90f..9758b737 100644 --- a/docs/问题记录/GD5F2GQ5UE_Trap_Records.md +++ b/docs/问题记录/GD5F2GQ5UE_Trap_Records.md @@ -132,3 +132,63 @@ if (ok) { - 返回“连续区间”的辅助函数,其返回值是起点还是终点必须在注释/命名中明确, 调用方与实现必须一致 - 这类错位 bug 往往只在“区间贴到设备边界”时才触发,正常情况能过,建议测试覆盖边界块 + +## Trap 05 — FatFs 探针文件名非法 → 无限重格式化(已修复,2026-09-20) + +**发现时间**:2026-09-20(症状自卷健康探针引入之日起长期存在) + +**现象**: +每次软件复位(ST-LINK Reset&Run / 上电)开机日志都出现 +`[FS] volume FAT invalid (fr=6), reformatting...`,`/config.ini` 永远 +"file missing, factory template generated";journal head 每 boot 前进 +~300 页(持续磨损);in-boot 一切正常(挂载/写文件都好)。 + +**真根因(纯软件,NAND/驱动/电源全部无罪)**: +卷健康探针 `f_open("/.fschk", FA_WRITE|FA_OPEN_ALWAYS)` 的名字非法—— +本移植 `FF_USE_LFN=0`,`ff.c create_short` 把 `.fschk` 点后的 "FSCHK" +当**扩展域**解析(5 字符 > 3 上限)→ `f_open` 返回 `FR_INVALID_NAME(6)`, +**纯 RAM 名字判定、根本不碰盘**(FF_RPATH≠0 时点开头还会走 `.`/`..` +特殊目录分支同样拒绝)。而 `FR_INVALID_NAME` 被误归入"结构性错误集合" +→ 每 boot 假失败 → 触发 `f_mkfs` → **无限重格式化**。 + +**修复**(commit 81a11c8): +1. 探针文件名改 `/fschk.tmp`(严格 8.3:名≤8、扩展≤3、不以点开头); +2. `FR_INVALID_NAME` 移出重格式化触发集合(名字语法错误与卷健康无关)。 + +**验证**(gen 45~48,@test 连续复位): +`Map resumed: 197→198→199→200 sectors used`(卷随 boot 正常增量持久)、 +无 reformat 行、`[CFG] load: OK (523B)`(config.ini 跨复位存活)、VERDICT PASS。 + +**调查中被证伪的假设(重要反面记录)**: +1. **低 VDD"幻影编程"假设——证伪**:怀疑 3.1V 供电下 program 状态报成功 + 但 cell 未 latch。裸 NAND 持久性自检(块 2040/2041:擦→写 4 页图案→ + 立即回读→跨复位再回读 seq 递增)实测 4/4 全过:芯片、驱动原语、供电 + 在同一台架上的持久性完全正常。 +2. **"journal 混合页/数据损坏"假设——误读**:所谓"LPN16 恒为 `RRaA` + 垃圾、LPN0 全零、LPN15 全 FF"实为**合法卷内容**——本移植 + `f_mkfs(FM_FAT32)` 创建的是 **MBR 分区卷**(分区起点 LBA 63): + LPN0=MBR 页(前 446 字节引导区本来就全零)、LPN15 页尾(扇区 63)=BPB + (页首扇区 60-62 未用=FF)、LPN16 页首=备份 FSInfo(`52 52 61 41` = + 0x41615252 "RRaA" 是合法签名!)。判定"损坏"前默认了几何=整盘 FAT32, + 把合法结构当成了花屏。 +3. 三个先前修复(mkfs 前清 FTL 树 ac2087e、page_read 二次发令 38b70ad、 + 读后 2ms settle)**都没有终结循环**——它们是合理硬化(全部保留), + 但不是根因。 + +**定界决定性手段**: +- 裸 NAND 跨复位持久性自检 → 排除介质/驱动/电源,指向文件系统层; +- glue 层 wsrc/flush/proglog 写链路追踪 → 暴露 mkfs 真实落盘几何 + (boot 记录写向扇区 63/64/69/70/95 = 标准 MBR 布局); +- `fr=6=FR_INVALID_NAME` 枚举语义 → "路径名格式非法"不可能来自盘。 + +**经验教训**: +- `FF_USE_LFN=0` 时一切文件名必须严格 8.3,`.hidden` 风格点开头名字 + 完全不可用;新建文件的代码路径先按 `create_short` 解析规则推演一遍 +- 磁盘健康探针必须**按错误语义分诊**:名字/参数类纯软件错误 + (FR_INVALID_NAME / FR_INVALID_PARAMETER 等)绝不能触发整卷擦除 +- 判定"存储数据损坏"前必须先确认**实际卷几何**(f_mkfs 默认 MBR 分区、 + b_vol=63;全零/全 FF/RRaA/EB FE 90 都可能是合法结构而非花屏) +- 分层定界优先做**最小闭环自下而上测试**(裸介质跨复位持久性), + 一次实验即可排除/坐实整个故障域,远胜在上层猜机制 +- 探针自身也可能有 bug:错误码要记录"是哪次调用返回的 + 枚举语义"—— + 本例 fr=6 在日志里挂了几十个 boot 没人查过枚举表