GD5F 补 DMA 守卫负路径用例 TC-704/705,导出阈值宏并对齐测试指南

This commit is contained in:
2026-09-21 03:01:49 +08:00
parent 45a3d0d06b
commit 5d386cedfb
4 changed files with 142 additions and 36 deletions
+51 -11
View File
@@ -28,7 +28,7 @@
| 总块数 | 2048 | `GD5F_TOTAL_BLOCKS` |
| 总容量 | 256 MB | `GD5F_TOTAL_SIZE` |
| 最小擦除单位 | 1 块(128 KB) | 不可按页/字节擦除 |
| DMA 阈值 | 32 B | `GD5F_DMA_THRESHOLD`,>32B 走 `HAL_SPI_*_DMA` |
| DMA 阈值 | 1024 B | `GD5F_DMA_THRESHOLD`,>1024B 走 `HAL_SPI_*_DMA`;非 SRAM 缓冲由运行时守卫回落轮询(见阶段 7) |
### 寄存器与状态位
@@ -422,9 +422,12 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10`
---
## 8. 阶段 7:DMA 边界(阈值 32 字节)
## 8. 阶段 7:DMA 边界与 DMA 可达性守卫(阈值 1024 字节)
> 驱动 `GD5F_DMA_THRESHOLD=32`:`size>32` 走 `HAL_SPI_*_DMA`,否则轮询。两路径结果必须一致。
> 驱动 `GD5F_DMA_THRESHOLD=1024`:`size>1024` 走 `HAL_SPI_*_DMA`,否则轮询。两路径结果必须一致。
> **前置约束**:DMA 源/目的缓冲必须落在 SRAM(`RW_IRAM1`,0x20000000~0x2001FFFF)。CCM(0x10000000)
> 为 DMA1/DMA2 物理不可达区,误用会静默不落地;驱动已加运行时守卫 `gd5f_dma_buf_ok()`,
> 越界缓冲自动回落轮询并打印 `[ERR][NAND] … not DMA-reachable … fallback poll`。
### TC-GD5F-701: 阈值下界(轮询路径)
@@ -433,9 +436,9 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10`
| **ID** | TC-GD5F-701 |
| **优先级** | P1 |
| **类型** | 边界测试 |
| **标题** | size=32 走非 DMA 路径,读写正确 |
| **标题** | size=1024(= `GD5F_DMA_THRESHOLD`)走非 DMA 路径,读写正确 |
| **前置条件** | 目标块已擦除 |
| **测试步骤** | 写/读 32 字节并比对 |
| **测试步骤** | 写/读 1024 字节并比对 |
| **通过标准** | 数据一致 |
| **覆盖原则** | `GD5F_DMA_THRESHOLD` 下界 |
@@ -446,9 +449,9 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10`
| **ID** | TC-GD5F-702 |
| **优先级** | P1 |
| **类型** | 边界测试 |
| **标题** | size=33 走 DMA 路径,读写正确 |
| **标题** | size=1025(= `GD5F_DMA_THRESHOLD`+1)走 DMA 路径,读写正确 |
| **前置条件** | 目标块已擦除 |
| **测试步骤** | 写/读 33 字节并比对 |
| **测试步骤** | 写/读 1025 字节并比对 |
| **通过标准** | 数据一致 |
| **覆盖原则** | `GD5F_DMA_THRESHOLD` 上界 |
@@ -465,6 +468,41 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10`
| **通过标准** | 数据一致 |
| **覆盖原则** | DMA 大数据路径 |
### TC-GD5F-704: DMA 可达性守卫负路径(读方向)
| 字段 | 值 |
|------|-----|
| **ID** | TC-GD5F-704 |
| **优先级** | P0 |
| **类型** | 边界/健壮性测试 |
| **标题** | 目的缓冲位于 CCM(不可达区)时守卫应拒绝 DMA 并回落轮询,数据仍正确 |
| **前置条件** | FreeRTOS 堆驻留 CCM(scatter `RW_CCM`);探针缓冲由 `pvPortMalloc(2048)` 取得(堆不在 CCM 时用例跳过) |
| **测试步骤** | 1. 先用 SRAM 静态缓冲参考读同页<br>2. 探针缓冲预填参考值的反码<br>3. `gd5f2gq5ue_read()` 整页读入 CCM 探针缓冲<br>4. 与参考缓冲逐字节比对 |
| **通过标准** | 数据与参考完全一致,且串口出现 `[ERR][NAND] RX DMA buffer not DMA-reachable (p=0x1000xxxx size=2048), fallback poll` |
| **判定依据** | 本板实证 DMA 对 CCM 静默不落地:若误走 DMA,探针缓冲保持预填反码必失配——故"数据一致"即证明回落真实发生,而非仅"未报错" |
| **覆盖原则** | DMA 可达性守卫(读方向);堆缓冲禁入 DMA 的运行时强制(内存分配策略 R3) |
### TC-GD5F-705: DMA 可达性守卫负路径(写方向)
| 字段 | 值 |
|------|-----|
| **ID** | TC-GD5F-705 |
| **优先级** | P0 |
| **类型** | 边界/健壮性测试 |
| **标题** | 源缓冲位于 CCM(不可达区)时守卫应拒绝 DMA 并回落轮询,数据仍正确落盘 |
| **前置条件** | 同 TC-GD5F-704;目标块已擦除 |
| **测试步骤** | 1. 探针缓冲填入 `i^0x5A` 图案<br>2. `gd5f2gq5ue_write()` 整页写入<br>3. 读回 SRAM 静态缓冲逐字节比对 |
| **通过标准** | 写读一致,且串口出现 `[ERR][NAND] TX DMA buffer not DMA-reachable … fallback poll` |
| **判定依据** | 同 TC-GD5F-704(写方向 DMA 读 CCM 同样不落地) |
| **覆盖原则** | DMA 可达性守卫(写方向);堆缓冲禁入 DMA 的运行时强制(内存分配策略 R3) |
> ⚠ **卷破坏警告**:阶段 8 会调用 `nand_ftl_format()` 清空 dhara map,阶段 9 会写入文件——
> 整轮 GD5F 套件(含 Phase 8/9)运行后卷数据即失效,且大写入可能使 dhara 把若干块记为
> 运行期坏块(2026-09-21 实测:一次整轮运行容量 95248 → 95200,日志见
> `[ERR][NAND_FTL] program verify: data mismatch, blk 305`,该块由 dhara 自行隔离,测试仍 68/68 通过)。
> 需要恢复干净态时,启用 `ENABLE_STORAGE_RECOVERY_TESTS` 跑一次 STORAGE 套件的 TC-STO-04
> (重建 BBT + 重新格式化)。
## 9. 阶段 8:FTL 层(nand_ftl)
### TC-GD5F-801: nand_ftl_init 成功
@@ -673,9 +711,11 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10`
| TC-GD5F-603 | block_erase 原语 | P1 | PASS |
| TC-GD5F-604 | write_enable WEL 位 | P2 | PASS |
| TC-GD5F-605 | wait_busy 正常返回 | P2 | PASS |
| TC-GD5F-701 | DMA 阈值下界(32) | P1 | PASS |
| TC-GD5F-702 | DMA 阈值上界(33) | P1 | PASS |
| TC-GD5F-701 | DMA 阈值下界(1024) | P1 | PASS |
| TC-GD5F-702 | DMA 阈值上界(1025) | P1 | PASS |
| TC-GD5F-703 | 大块 DMA 一致性 | P1 | PASS |
| TC-GD5F-704 | DMA 守卫负路径(读,CCM) | P0 | PASS |
| TC-GD5F-705 | DMA 守卫负路径(写,CCM) | P0 | PASS |
| TC-GD5F-801 | nand_ftl_init | P0 | PASS |
| TC-GD5F-802 | nand_ftl_format | P1 | PASS |
| TC-GD5F-901 | FatFS 挂载写读 | P2 | PASS |
@@ -688,7 +728,7 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10`
| TC-STO-03 | 坏块注入下存储写入 | P1 | PASS |
| TC-STO-04 | BBT 重建 + 重新格式化(恢复) | P1 | 受 `ENABLE_STORAGE_RECOVERY_TESTS` 控制(默认关) |
> 当前实测:`TEST_SUITE_GD5F` 构建一次运行全部阶段,结尾输出 `=== GD5F2GQ5UE Tests: 65/65 PASSED (failed=0) ===`(65 为各 TC 内部断言总数,含 TC-GD5F-205~207 BBT 持久化用例;TC 覆盖见上表)。`TEST_SUITE_STORAGE` 套件结尾输出 `=== Storage Tests: 11/11 PASSED (failed=0) ===`(TC-STO-01/02/03 各含若干内部断言,且 TC-STO-01 依赖的 `s_cached_lpn` 哨兵 bug 已修复)。两套件均 0 错误 0 警告通过 MDK 编译。
> 当前实测:`TEST_SUITE_GD5F` 构建一次运行全部阶段,结尾输出 `=== GD5F2GQ5UE Tests: 68/68 PASSED (failed=0) ===`(68 为各 TC 内部断言总数,含 TC-GD5F-205~207 BBT 持久化用例、TC-GD5F-704/705 DMA 守卫负路径;TC 覆盖见上表)。`TEST_SUITE_STORAGE` 套件结尾输出 `=== Storage Tests: 11/11 PASSED (failed=0) ===`(TC-STO-01/02/03 各含若干内部断言,且 TC-STO-01 依赖的 `s_cached_lpn` 哨兵 bug 已修复)。两套件均 0 错误 0 警告通过 MDK 编译。
---
@@ -733,7 +773,7 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10`
| 总块数 / 容量 | 2048 / 256 MB |
| ID | MID=0xC8, DID=0x52 |
| 擦除最小单位 | 1 块(128 KB,须对齐) |
| DMA 阈值 | 32 B(>32 走 DMA) |
| DMA 阈值 | 1024 B(>1024 走 DMA;非 SRAM 缓冲由守卫回落轮询) |
| 状态寄存器 | 0xC0;OIP=0, WEL=1, E_FAIL=2, P_FAIL=3, ECCS=4/5 |
| Feature 寄存器 | 0xB0;ECC_EN=4, QE=0 |
| Protect 寄存器 | 0xA0;init 后写 0x00 解除保护 |