实机测试规划更名为实机测试实施指南:与文档性质(常设执行判据)对齐,H1/README索引同步,引用面仅1处
This commit is contained in:
@@ -0,0 +1,407 @@
|
||||
# 实机测试实施指南(On-Board Test Guide)
|
||||
|
||||
> 本文档描述项目的**上板(真机)测试执行判据**与**当前待上板事项**:
|
||||
> 每项给出「现状 → 判据(可观测、量化)→ 执行步骤(含精确命令)→ 风险/回滚」。
|
||||
> **前置铁律**:本文所有步骤**均在接上 MCU / 串口 / ST-LINK 之后**执行;
|
||||
> 无实机时**只读本文,不执行任何烧录**。
|
||||
> **上游**:`错误码传播审计.md`(E-xx)· `审查记录/测试与架构改进建议.md`(S7/S9/S11/S5/S4)·
|
||||
> `审查记录/下一步任务规划.md`(阶段 A)· `待处理内容.md`(登记簿)·
|
||||
> `子系统设计/看门狗设计说明.md`(§10 台架步骤)。
|
||||
> **约定**:本文事项完成后**先销上游登记**,再在文末变更记录留一行;
|
||||
> 结论与证据沉淀进对应模块文档/问题记录(2026-10-02 台架窗口的完整取证链——
|
||||
> IWDG PR/RLR 静默错配 / dhara resume 回滚 / ORE 僵尸通道——见 `看门狗设计说明.md` 2026-10-02 变更记录、
|
||||
> `STM32F4-Base存储架构说明.md` §5.4.1、`控制台单写者日志设计说明.md` §12;修复已随 `930215f` 提交)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 事项总览
|
||||
|
||||
台架窗口就绪后,按 **P0 → P1 → P2 → P3** 批次顺序执行:
|
||||
|
||||
| 批次 | 事项 | 性质 | 章节 |
|
||||
|---|---|---|---|
|
||||
| **P0-A** | 环境预检(串口/ST-LINK/`@build`/`.map` 基线) | 前置 | §2 |
|
||||
| **P0-B** | 产品 `@test` 闭环 + 自检结果判定(S7 + A1~A4) | 待上板 | §3 |
|
||||
| **P1-A** | IWDG 故障注入 V2/V4 + 长跑 V5(N-03) | 可靠性 | §4 |
|
||||
| **P1-B** | 堆低水位告警实测(S11) | 可观测性 | §5 |
|
||||
| **P2-A** | GD5F 错误通道(S9 = 上游 C2)+ 套件回归 | 结构债 | §6 |
|
||||
| **P2-B** | 网络重建恢复(P1-8)+ 存量网络项重锁(N-2/N-3) | 稳定性 | §7 |
|
||||
| **P3** | `test/` 静态检查基线(S5)+ 用例追溯(S4)+ 待核实项 | 工程卫生 | §8 |
|
||||
|
||||
> **每批出口**:`@build` 0/0 → 一轮 `@test` PASS → ST-LINK 全片回读 `No difference found` →
|
||||
> 上游登记销项 + 文末变更记录留痕。
|
||||
|
||||
---
|
||||
|
||||
## 2. 环境预检(P0-A,每次上台架前必跑)
|
||||
|
||||
> **目的**:避免"改动没问题、台架有问题"的误判(历史上多次把接线/权限问题误判为代码缺陷)。
|
||||
|
||||
| # | 检查 | 命令 | 通过判据 |
|
||||
|---|---|---|---|
|
||||
| A1 | 工作区干净 | `git status --short` | 无输出(或有明确待提交项) |
|
||||
| A2 | 产品构建 0/0 | `& "MDK-ARM\build.bat"` | 末行 `BUILD_OK: 0 errors, 0 warnings` |
|
||||
| A3 | 构建产物为**产品态** | 检查 `test/board/test_config.h` L30-33 | 四个 `TEST_SUITE_*` **全部注释** |
|
||||
| A4 | `.map` 非测试态 | 看 `MDK-ARM/STM32F407-Demo/STM32F407-Demo.map` 的 `ER_IROM1` | 产品态基线随已接受的修复增长:262,100(初版)→ 262,836 B(10-02 round 1~6)→ **264,284 B(当前,含 round 7~9)**;明显阶跃 ≈3.7KB 及以上(10-02 实测产品 262,836 → 套件 266,540)= 停在套件态 → 重跑 A2 |
|
||||
| A5 | 全量静态门禁 | `pre-commit run --all-files` | **16/16 Passed** |
|
||||
| A6 | ST-LINK 探针可见 | `& "MDK-ARM\reset.bat" list`(CLI 经 `DTU_STLINK_CLI` / PATH 解析) | 列出探针 SN `0B250D12A218303030303032` |
|
||||
| A7 | 串口端口正确 | 检查 `.opencode/serial_config.json` 的 `portName` | 端口单一配置源 = 此文件(当前 COM6,2026-09-21 台架重插后由 COM7 变更);变更后先杀旧 daemon 再 `open` |
|
||||
| A8 | 串口助手 daemon 可用 | `& '.venv\Scripts\python.exe' tools/serial_tool/serial_tool.py status` | 返回 JSON,`open: true/false` 可读 |
|
||||
|
||||
> ⚠️ **A4 的陷阱**(2026-10-02 实测):`@build` 是**增量**构建,`run_all_suites.py` 跑完
|
||||
> 套件后 `.map` 会停在**测试套件体积**;仅还原 `test_config.h` 不够,**必须再编一次产品固件**
|
||||
> (`run_all_suites.py` 已在 `finally` 内自动补这一步)。
|
||||
|
||||
**预检失败处置**:任一项 FAIL → **不上台架**,先修到全绿(避免"带病测试"浪费台架窗口)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 产品 @test 闭环 + 自检结果判定(P0-B)
|
||||
|
||||
### 3.1 自检结果判定(S7,已落地并投用)
|
||||
|
||||
**现状**:`@test` 闭环除串口标记外,还判定设备侧自检结论(v1 只记故障、不记通过):
|
||||
|
||||
- `verify_log.py --require-selftest-pass`(可带路径参数):退出码 0 = PASS / 1 = FAIL;
|
||||
判定语义 = `selftest.log` **缺失/0 字节 → 无故障 → PASS**;`filesize/64 > 0`(任一 64B 定长记录)
|
||||
= 有故障 → FAIL,并打印故障条目(时间戳 + 描述)便于定位;
|
||||
- `run_boot_test.py --require-selftest-pass`:未给本地副本时**自动经 FTP 抓取** `/log/selftest.log`
|
||||
(设备侧 450"文件不存在"按正常路径处理——"仅故障才写"语义下干净设备本就没有该文件;
|
||||
2026-10-02 修复:原实现把 450 当异常抛出,会让本该 PASS 的闭环在最后一步崩掉)。
|
||||
|
||||
**执行**:
|
||||
|
||||
```bash
|
||||
# 一键闭环(selftest.log 自动 FTP 抓取;无故障记录 = PASS)
|
||||
& '.venv\Scripts\python.exe' test/host/run_boot_test.py --require-selftest-pass --device-ip 192.168.1.100
|
||||
|
||||
# 或手动联合判定(本轮串口日志 + selftest.log 本地副本)
|
||||
& '.venv\Scripts\python.exe' test/host/verify_log.py \
|
||||
--log-path <本轮串口日志> \
|
||||
--require-selftest-pass \
|
||||
--selftest-log <下载的 selftest.log 本地副本>
|
||||
# 判据:退出码 0;输出含 "[OK] selftest: no fault record"
|
||||
```
|
||||
|
||||
### 3.2 待上板事项 A1~A4(代码状态 2026-10-02 核对)
|
||||
|
||||
> 来源:`审查记录/下一步任务规划.md` 阶段 A。各项**代码状态以当日对现网代码的核对为准**:
|
||||
|
||||
| 序 | 事项 | 代码状态(2026-10-02 核对) | 上板判据 | 命令/入口 |
|
||||
|---|---|---|---|---|
|
||||
| **A1** | **P0-1 `cfg_file` 堆分配改造** | **已落地**(分配收进 `cfg_store_alloc/free` 平台后端;模拟器用宿主堆,**照不出** `Heap_Size=0x200`(512B)约束——真机是最后一道门) | 串口日志出现 `/config.ini` **`load: OK`**;Forbidden `FAIL`/`[ERR]` 零命中;**保存配置后复位,值持久** | `& '.venv\Scripts\python.exe' test/host/run_boot_test.py` |
|
||||
| **A2** | **P1-8 网络重建失败恢复** | **部分落地**:首启链路超时已有 `comms fault` 自检(`net_task.c` L131);重建(reconfig)失败路径仅一条 `DBG_ERROR`,**无自检记录、无周期重试**;首启 `net_init` 失败 = netTask 无限驻留(L206-210) | 补码后:失败路径写 syslog 自检 + 30s 周期重试;**不自驻留死循环**;恢复后各 TCP 服务据代次号重建监听;`@test` PASS | 补码 → `@build` → `@test`;UI 网口设置页改 IP;`test/host/e02_probe.py` |
|
||||
| **A3** | **E-34 CH395F 字节命令超时** | **未落地**(`ch395f.c` L181/195/210 仍 `HAL_MAX_DELAY` → SPI 异常时 netTask 永久挂死) | 补码后:有限超时(100~500ms)+ 返回值检查;构建 0/0;**正常通信零回归**(FTP 传输正常) | 补码 → `@build` + `@test` |
|
||||
| **A4** | **E-04 `remo_send` 返回值** | **未落地**(`ui_net_sink.c` L119 仍丢弃 `net_send` 返回值;短写 → 客户端 CRC 失败 → 画面卡死黑屏而设备侧日志全正常) | 补码后:改返回 `int` 校验 `ret == len`;短写 `DBG_ERROR` + 连续失败强制重连;**UI 推流压力下无黑屏** | 补码 → `@build` + UI 远显推流压力回归 |
|
||||
|
||||
> **A5(P1-7 MAC 写入顺序)**:**先查手册**(CH395F §9.2.1 INIT 是否锁存 MAC),
|
||||
> 再决定改或文档化"无需调整"——**属离线可做部分**,不在本文强绑。
|
||||
|
||||
### 3.3 自检项清单(S7 判定对象,18 处)
|
||||
|
||||
> 来源:全库 `syslog_post(SYSLOG_SELFTEST, ...)` 调用点。**这是 S7 的判定覆盖面基准**。
|
||||
|
||||
| 文件 | 自检描述串 |
|
||||
|---|---|
|
||||
| `App/app/app_main.c` | `watchdog reset` / `clock chip fault` / `NAND fault` / `ADC fault` |
|
||||
| `App/cfg/cfg_file.c` | `cfg heap alloc fail`(×3) / `cfg template write fail` / `cfg load oversized` / `cfg load read fail` / `cfg save read fail` / `cfg save overflow` / `cfg save write fail` / `cfg poll oversized` |
|
||||
| `App/task/default_task.c` | `filesystem fault`(×2) / `storage fault`(×2) |
|
||||
| `App/task/net_task.c` | `comms fault` |
|
||||
|
||||
**联动**:`syslog_post` 的两级自愈(L1 文件级重试 / L2 错误去重 `s_fault_reported[]`)
|
||||
决定**持续故障只留第一条**——故 S7 判定"有记录即 FAIL"是**充分**的(不会被去重掩盖)。
|
||||
|
||||
---
|
||||
|
||||
## 4. IWDG 故障注入与长跑(P1-A,N-03 收尾)
|
||||
|
||||
> 来源:`子系统设计/看门狗设计说明.md` §10 步骤 7~10;`待处理内容.md` N-03。
|
||||
> 判定状态机与 IWDG 配置(PR/RLR 按设计值写入)已落地并经真机验证(2026-10-02,`930215f`,
|
||||
> 见设计说明 2026-10-02 变更记录);缺的是下述**故障注入 + 长跑**验收。
|
||||
|
||||
### 4.1 三个验收用例
|
||||
|
||||
| # | 用例 | 注入方法 | 通过判据 |
|
||||
|---|---|---|---|
|
||||
| **V2** | 任务饿死 | 临时在 `netTask` 循环插 `while(1);` | 800 ms 后串口 `[ERR] WATCHDOG: task stall mask=0x...`;≤2.5 s 复位;重启后 `[WD] reset cause=watchdog reset` |
|
||||
| **V4** | 关中断死循环 | 临时插 `taskDISABLE_INTERRUPTS(); while(1);` | ≤2.5 s 复位(检验 IWDG **独立于中断**);`cause=watchdog reset` |
|
||||
| **V5** | 长期不误杀(**核心验收项**) | FTP 大文件传输 + UI 菜单遍历 + 配置保存 + 网络重配 **≥30 min** | **零复位**(重点验证 §4.4 白名单是否完备) |
|
||||
|
||||
> ⚠️ **V5 是核心验收项**:误杀比不杀更有害。必须在**真实业务负载**下跑足时长。
|
||||
|
||||
### 4.2 执行步骤
|
||||
|
||||
```bash
|
||||
# --- V2/V4(故障注入,需临时改码)---
|
||||
# 1) 基线:跑一轮产品 @test 确认无复位
|
||||
& '.venv\Scripts\python.exe' test/host/run_boot_test.py
|
||||
|
||||
# 2) 注入:按设计说明 §10 在 netTask 循环插 while(1);(或 taskDISABLE_INTERRUPTS(); while(1);)
|
||||
# —— 改完 @build,然后烧录
|
||||
& "MDK-ARM\build.bat"
|
||||
& "MDK-ARM\reset.bat" flash MDK-ARM\STM32F407-Demo\STM32F407-Demo.hex
|
||||
|
||||
# 3) 抓串口日志,确认 [ERR] WATCHDOG task stall + 复位原因
|
||||
# 4) 回读校验复位后镜像(ST-LINK_CLI 经 DTU_STLINK_CLI 解析,未设时回退 PATH,不写死路径)
|
||||
$cli = if ($env:DTU_STLINK_CLI) { $env:DTU_STLINK_CLI } else { (Get-Command ST-LINK_CLI.exe).Source }
|
||||
& $cli -c SWD -CmpFile MDK-ARM\STM32F407-Demo\STM32F407-Demo.hex 0x08000000
|
||||
# 判据:No difference found
|
||||
|
||||
# 5) 撤销注入,@build 回产品态,再跑一轮 @test 确认正常
|
||||
|
||||
# --- V5(长跑,需真实负载)---
|
||||
# 1) 用 test/host/ftp_speed_test.py / ftp_up_dl_test.py 持续传输大文件
|
||||
& '.venv\Scripts\python.exe' test/host/ftp_speed_test.py
|
||||
# 2) 同时人工/脚本遍历 UI 菜单 + 反复保存配置 + 触发网络重配
|
||||
# 3) 持续 ≥30 min,全程串口记录
|
||||
# 判据:零复位(日志无 "reset cause=watchdog reset");业务不中断
|
||||
```
|
||||
|
||||
**风险/回滚**:
|
||||
- 故障注入用例**会复位设备多次**——确认设备非在用/非已部署。
|
||||
- 长跑涉及 NAND 写入(FTP 上传)**消耗 NAND 块**——若设备已接近容量上限,改用只读传输。
|
||||
- ⚠️ **R5 风险**(设计说明 §9):NAND 擦写偶发超 800 ms 可能误复位——若 V5 出现偶发复位,
|
||||
先按设计说明增大容忍次数或把存储操作改分段置位,**不要盲目放宽全局超时**。
|
||||
|
||||
---
|
||||
|
||||
## 5. 堆低水位告警实测(P1-B,S11)
|
||||
|
||||
**现状证据**:上一轮实测 `free=8,784 / min_ever=4,848 B`(初始 `configTOTAL_HEAP_SIZE` 48KB),
|
||||
**min_ever 已低于 5KB**,余量不到 10%——新增任务/缓冲可能触发分配失败。
|
||||
现有代码仅有周期性 `[STACK]` 报告(每周期打印 `heap free/min_ever`),**无阈值告警、不写自检记录**。
|
||||
|
||||
**待补代码**(约 15 行 + 1 个编译期常量,在 `defaultTask` 低频循环(LED 闪烁节拍)内):
|
||||
检查 `xPortGetMinimumEverFreeHeapSize()`,低于阈值(建议 **4096 B**)时
|
||||
`DBG_ERROR("[HEAP] low water: %u B")` + 写 syslog selftest。
|
||||
|
||||
**判据**:台架长跑(复用 §4.2 V5 窗口)下,若发生低水位 → 串口出现告警行 + `selftest.log` 有记录;
|
||||
若全程未触发 → 记录"当前负载下 min_ever 仍高于阈值"作为基线。
|
||||
|
||||
**执行步骤**:
|
||||
```bash
|
||||
# 1) 代码改动(约 15 行 + 1 个编译期常量)在 defaultTask 低频循环内
|
||||
# 2) @build 0/0 后,与 §4.2 V5 长跑合并执行
|
||||
# 3) 长跑结束读取 min_ever:
|
||||
# - 串口 [HEAP] 告警行(若有)
|
||||
# - 或 FTP 取 /log/selftest.log
|
||||
# 4) 更新 docs/内存管理/RAM使用分析与优化方案.md 的 min_ever 基线
|
||||
```
|
||||
|
||||
**成本/回滚**:约 15 行 + 零额外缓冲;阈值设编译期常量便于按新基线调整。
|
||||
若长跑中频繁触发但系统正常 → 说明阈值偏紧,据实测值调整(不是缺陷)。
|
||||
|
||||
---
|
||||
|
||||
## 6. GD5F 错误通道统一(P2-A,S9 = 上游 C2)
|
||||
|
||||
> **来源**:`错误码传播审计.md` 第二档 #1(E-10/E-42/E-53/E-54/E-56/E-57);
|
||||
> `测试与架构改进建议.md` §2.3 / §4.2 四要素骨架。
|
||||
|
||||
**现状证据**:`ch395f.c`(1330 行) 与 `gd5f2gq5ue.c`(1496 行) 是同代驱动,但**只有 CH395F**
|
||||
形成了"分类 + 传播 + 审计"完整体系;GD5F 错误处理散落各函数,`Trap_Records` 仅 198 行。
|
||||
|
||||
**统一错误通道四要素**(以 CH395F 为范式):
|
||||
|
||||
| 要素 | 内容 | 对应缺陷 |
|
||||
|---|---|---|
|
||||
| ① **分类** | `wait_busy` 区分「超时 / 真故障 / 参数错」——不得混为一个返回码 | E-53 |
|
||||
| ② **透传** | 底层错误码逐层上报,不吞不猜(禁 `(void)ret`) | E-10 / E-42 |
|
||||
| ③ **分级** | 可恢复(重试)/ 不可恢复(上报自检 + 降级)显式判定 | E-54 / E-56 |
|
||||
| ④ **留痕** | 不可恢复项写 syslog selftest;可恢复项计数并在 UI/日志可见 | E-57 |
|
||||
| — | 返回类型统一 `int32_t` | E-57 |
|
||||
|
||||
**实施顺序**(数据安全优先):
|
||||
1. 先建**分类函数**(`gd5f_wait_busy` 内检查三次 HAL 调用)——所有下游判断的基础;
|
||||
2. 再修**最危险的**:`gd5f_bbt_scan` 失败**放弃持久化**(保护好副本)——**数据安全优先**;
|
||||
3. 补 **init 全链路检查 + 重试 1~2 次**;
|
||||
4. 回读 **B0h 校验 ECC 使能**(bit4);
|
||||
5. `gd5f2gq5ue_read` 的 raw 契约文档化或加 ECCS 检查;
|
||||
6. 全程在 `GD5F2GQ5UE_Trap_Records.md` 留痕,同步 `GD5F2GQ5UE_Test_Guide.md`。
|
||||
7. **RAM 预算**:新增错误分支**不得引入新的大缓冲**(先跑 `ram_report.py` 核算)。
|
||||
|
||||
**判据**:
|
||||
- **E-10 / E-42 / E-53 / E-54 / E-56 / E-57 全部销项**;
|
||||
- **GD5F 套件回归 PASS**:
|
||||
```bash
|
||||
# 套件回归(需实机)
|
||||
& '.venv\Scripts\python.exe' test/run_all_suites.py --suite gd5f
|
||||
# 判据:=== GD5F Tests: N/M PASSED (failed=0) === 且 N>0
|
||||
|
||||
# 只编译验证(离机,改动后随手跑)
|
||||
& '.venv\Scripts\python.exe' test/run_all_suites.py --check-build
|
||||
```
|
||||
|
||||
> ⚠️ **纪律**(呼应 `AGENTS.md` 铁律):自愈逻辑**严禁**把"名字/参数类错误码"
|
||||
> (如 `FR_INVALID_NAME`)归入"卷损坏触发集"——`.fschk` 无限重格式化事故即此类(2026-09-20)。
|
||||
> ⚠️ **破坏性用例**:GD5F 套件默认只跑只读;`ENABLE_DESTRUCTIVE_TESTS` 跑一次消耗一个 NAND 块
|
||||
> (实测 95248→95200),**仅在产线首启或明确需要时打开**。
|
||||
|
||||
---
|
||||
|
||||
## 7. 网络稳定性与基线重锁(P2-B)
|
||||
|
||||
### 7.1 P1-8 网络重建失败恢复(与 §3.2 A2 同一项,此处给网络专项视角;代码状态见 A2 行)
|
||||
|
||||
**判据**:拔插网线/改 IP 触发重建后——
|
||||
- 失败路径**写 syslog 自检**(不再零日志);
|
||||
- **30s 周期重试**,不自驻留死循环;
|
||||
- 恢复后各 TCP 服务(FTP 21 等)**据代次号重建监听**,功能正常。
|
||||
|
||||
**验证手段**:`test/host/e02_probe.py`(网络探针)+ UI 网口设置页改 IP。
|
||||
|
||||
### 7.2 N-2:49s 全系统日志静默复现与定位
|
||||
|
||||
**现状证据**(登记簿 N-2):2026-09-22 台架实测,串口日志 **49s 无行**
|
||||
(testTask/netTask/[STACK] 行全缺),期间 net 栈照常处理外部连接 → **日志管线停滞**,
|
||||
队列满后各任务日志行被丢;系统功能不受损。
|
||||
|
||||
**目标**:复现条件定位(NAND 写/GC 长尾 vs UART TX 卡滞)+ 队列满的丢弃计数/告警
|
||||
(**现静默丢行,排障不可见**)。
|
||||
|
||||
**判据**:
|
||||
- 复现 49s 静默并定位到具体卡点(NAND GC / UART TX);
|
||||
- 实现**队列满丢弃计数**(至少一个 `DBG_ERROR` 或计数器经 UI/日志可见)。
|
||||
|
||||
**执行步骤**:长跑(§4.2 V5)期间周期性打点 + 对照 `CH395F` 无关的 SD2506 侧日志判别卡点。
|
||||
|
||||
### 7.3 N-3:L5 队列往返基线重验
|
||||
|
||||
**现状**:L5 基线(1223/988µs)属**分片时代**;L3 对该路径逐位不变 → 机制上无影响,
|
||||
但严格重锁需跑一轮 Phase 13(**需 PC peer**)。
|
||||
|
||||
**判据**:Phase 13 窗口跑一轮,基线数值与阈值余量(>8×)对照,重锁数值。
|
||||
|
||||
---
|
||||
|
||||
## 8. 工程卫生(P3)
|
||||
|
||||
### 8.1 S5:`test/` 代码宽松静态检查
|
||||
|
||||
**现状证据**:`test/` 完全豁免 pre-commit("自律"要求),而 `test/board/` 下 **6300+ 行 C 代码**
|
||||
(实测 `.c`+`.h` 合计 6,313 行)**且编入固件**。曾出现 `s_rx_buf` 使用先于声明。
|
||||
|
||||
**目标**:抓 `test/board/` 固件测试代码的**真实缺陷**(未初始化/越界/空指针),
|
||||
但不引入存量 style 噪音。
|
||||
|
||||
**执行步骤(先跑基线,离机可做)**:
|
||||
```bash
|
||||
# 1) 基线统计(不需实机)
|
||||
cppcheck --enable=warning --error-exitcode=1 test/ 2>&1 | tee test_cppcheck_baseline.txt
|
||||
|
||||
# 2) 若存量可控(建议 <20 条)→ 加 test-cppcheck 钩子,只开 warning
|
||||
# 3) 若存量较多 → 先建 suppress 清单(明确每条豁免理由),再挂钩子
|
||||
# 4) 务必排除模拟器桩/第三方头(test/host/watchdog/stub/ 等)
|
||||
```
|
||||
**判据**:`test-cppcheck` 在 CI PASS;新增测试代码越界/未初始化被自动拦截。
|
||||
> **注意**:若基线告警过多,**保持现状亦可接受**——此时应把该决策写明确("理由:存量 N 条")。
|
||||
|
||||
### 8.2 S4:用例追溯脚本
|
||||
|
||||
**现状**:文档声称 91 个 TC、代码有 222 个 `TEST_CHECK`(断言点数 > 用例数是正常的),
|
||||
但**双向是否一一对应无人校验**。
|
||||
|
||||
**目标**:新增 `[计划] scripts/check_test_traceability.py`——
|
||||
输入 `test/board/*_test_task.c` 的 TC 注释 + `docs/测试说明/*Test_Guide.md` 的 TC 编号;
|
||||
输出 ① 文档有、代码无(未实现)② 代码有、文档无(未登记)。
|
||||
**默认仅告警(warning),不阻断提交**(与 `doc-links` 演进路径一致)。
|
||||
|
||||
**判据**:一键列出双向差异清单;差异收敛后再考虑升为门禁。
|
||||
|
||||
### 8.3 待核实项:`TEST_SUITE_SELECTED` 未含 `TEST_SUITE_RTC`
|
||||
|
||||
**现状证据**(`test/board/test_config.h`):
|
||||
- L45 互斥检查**已包含** `TEST_SUITE_RTC`(4 个套件互斥正确);
|
||||
- **L49-51 的 `TEST_SUITE_SELECTED` 只含前三个**(CH395F / STORAGE / GD5F),**未含 RTC**。
|
||||
|
||||
**疑似影响**:`TEST_SUITE_SELECTED` 被用于 `defaultTask` 是否空闲、是否创建 `testTask` 等分支——
|
||||
若 RTC 套件构建下 `TEST_SUITE_SELECTED` 未定义,**testTask 可能不被创建 → RTC 套件不执行**。
|
||||
但 `run_all_suites.py --check-build` 实测 RTC 套件**能编译通过**(那只是编译,不是运行)。
|
||||
|
||||
**判据**:有实机时,选 `TEST_SUITE_RTC` 构建并烧录,观察:
|
||||
- 串口是否出现 `=== RTC Tests: N/M PASSED ===` 汇总行;
|
||||
- 若**无汇总行** → 证实缺陷,`TEST_SUITE_SELECTED` 需补 `|| defined(TEST_SUITE_RTC)`;
|
||||
- 若**有汇总行** → 说明另有分支覆盖,属"有意为之",在 `test_config.h` 注释说明。
|
||||
|
||||
**执行步骤**:
|
||||
```bash
|
||||
# 1) 改 test_config.h:取消注释 TEST_SUITE_RTC(其余保持注释)
|
||||
& "MDK-ARM\build.bat"
|
||||
# 2) 烧录(注意 reset.bat flash 后必须 -Rst -Run)
|
||||
& "MDK-ARM\reset.bat" flash MDK-ARM\STM32F407-Demo\STM32F407-Demo.hex
|
||||
# 3) 抓串口日志,grep 汇总行
|
||||
# 4) 还原 test_config.h 为产品态 + 重建产品固件(避免 .map 污染)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 实测陷阱(2026-10-02 台架窗口,照做可少绕一天)
|
||||
|
||||
1. **写入"复位后消失"的两层原因**(窗口最大坑,根因均已修复,详见模块文档):
|
||||
- **L1 dhara checkpoint 回滚**(`架构设计/STM32F4-Base存储架构说明.md` §5.4.1):环回绕后
|
||||
`dhara_journal_resume()` 恢复旧 checkpoint,**之后写的一切整段丢弃**
|
||||
(已修:epoch 锚点改比较两候选的新旧)。
|
||||
- **L2 FTL 单页写回缓存**:任何磁盘改动(截断/新建/追加)在**写到另一个 LPN / 另一个文件
|
||||
或 `CTRL_SYNC`** 之前只存在于 RAM(`nand_ftl.c` 的 `s_cache_buf/s_cache_dirty`);
|
||||
硬复位(含 IWDG 误复位)会丢失最后一次未跨页的写(`N-14` 已登记;`CTRL_SYNC` 已实现,
|
||||
但**没有周期性/掉电前强制 flush**,属残余风险)。
|
||||
→ 排查写入丢失时**先看开机日志的 head/tail/epoch**(`Map head=… tail=… epoch=…`,
|
||||
纯内存字段、零 I/O):head 复位后倒退 = L1(resume 错);head 正常 = L2(缓存未刷)。
|
||||
日常"清台账/写证据后写另一个文件"的 flush 诱导只对 L2 有效。
|
||||
2. **FTP 路径**:lftpd 相对路径基准是**根目录**(`SIZE selftest.log` → 550),一律用
|
||||
绝对路径 `/log/xxx`;`LIST /log` 实测列的是**根目录**内容(lftpd 怪癖)——查状态只用
|
||||
`SIZE` / `RETR`。
|
||||
3. **0 字节 STOR 的数据连接**存活期仅 ~10~50ms,短于芯片/网络层轮询粒度 → 芯片只见
|
||||
`DISCONNECTED (chip tcp=0x00)` → accept 失败(425 或控制连接被重置);2026-10-02 实测客户端
|
||||
`PASV→STOR` 间隔达 **11 s**(数据口 LISTEN 半开)。这是**与看门狗误复位不同的另一类
|
||||
问题**(CH395F 数据通道);若修复后仍复现 425,转 §7.1 专项。
|
||||
4. **串口采集铁律**:`open` → `clear` → 烧录/复位 → `wait-idle --timeout 90 --settle-ms 8000
|
||||
--max-ms 45000` → **直接 Read/Grep `tools/serial_tool/state/serial.log`**
|
||||
(`log --grep` 子命令不可信);daemon 残留 → `taskkill /F /PID <旧>` 后重新 `open`。
|
||||
5. **只用 `.venv\Scripts\python.exe`**(PATH 里的 `python` 是 msys64);每次烧录后**必须**
|
||||
ST-LINK 全片回读 `No difference found`。
|
||||
6. **误复位会使台账 +1 条** `watchdog reset`:取证/修复期间台账只会增长,
|
||||
属预期(清台账留到最后一次修复后的出口闭环)。
|
||||
7. **ST-LINK_CLI 取证三硬知识**(完整用法见 `ST-LINK_CLI_复位使用说明.md`):
|
||||
- `-R32` **不会 halt 内核**(`-CoreReg` 才 halt,实测约 30ms/次且可重复)→ 用 `-R32` 做
|
||||
**无扰动**存活性采样,只在需要 PC 时用 `-CoreReg`(halt 期间 TIM7 ISR 不执行,
|
||||
会让中断计数出现"假停顿",须用非 halt 读法甄别)。
|
||||
- `-R32 <addr> <count>` 的 `count` 单位是**字节**(`-R32 0x1000FF00 16` 得 4 个字);
|
||||
按字理解会把读取**静默截断**。
|
||||
- `-W32 <addr> <data>` 的 `data` 按**十六进制**解析(写 `1249` 会变成 `0x1249`,
|
||||
被 12 位 RLR 截断成 `0x249`=585);要写十进制 1249 得传 `0x4E1`。另 `IWDG->KR` 是
|
||||
**只写**寄存器(读回恒 0),`-W32` 写 KR 必报 `Error!`——那是 ST-LINK 的写-回读
|
||||
校验失败,**写入其实成功**。
|
||||
- 现场改寄存器(如 IWDG PR/RLR 验证手段)须在**一次调用**内完成整段键序列
|
||||
(解锁→参数→键锁)——分多次调用会超过看门狗超时、中途被复位;寄存器随复位丢失,
|
||||
只能用于验证,不是修复。
|
||||
|
||||
---
|
||||
|
||||
## 10. 与既有文档的引用闭环
|
||||
|
||||
| 本文项 | 上游文档 | 下游落地文档 |
|
||||
|---|---|---|
|
||||
| S7 自检判定 | `审查记录/测试与架构改进建议.md` §3.7 | `测试说明/自动化测试流程.md`(参数已落地,`4a4cd29`) |
|
||||
| V2/V4/V5 | `子系统设计/看门狗设计说明.md` §10 | `待处理内容.md` N-03(销项) |
|
||||
| S11 堆告警 | `测试与架构改进建议.md` §4.4 | `内存管理/RAM使用分析与优化方案.md`(基线更新) |
|
||||
| S9 GD5F | `问题记录/错误码传播审计.md` 第二档 #1 | `问题记录/GD5F2GQ5UE_Trap_Records.md`、`测试说明/GD5F2GQ5UE_Test_Guide.md` |
|
||||
| N-2 日志静默 | `待处理内容.md` N-2 | `问题记录/错误码传播审计.md` E-02 |
|
||||
| P1-8 网络重建 | `审查记录/下一步任务规划.md` 阶段 A | `网络/Net层阻塞模型架构设计.md` |
|
||||
| S5/S4 | `测试与架构改进建议.md` §3.4/§3.5 | `测试说明/测试开发标准流程.md` |
|
||||
| 模拟器差距 | `测试说明/模拟器差距清单.md` §3 决策规则 | 本文为"需回真机"项的执行面 |
|
||||
|
||||
> **模拟器差距清单 §3 的六条"必须回真机"规则**决定"哪些改动**必须在本规划内验证——
|
||||
> 改动触及 `Drivers/BSP/` 寄存器时序 / H-1~H-7 硬件项 / L-2~L-4 / 网络重建并发 / 启动段 / 内存预算,
|
||||
> 一律在本文件找到对应批次。
|
||||
|
||||
---
|
||||
|
||||
## 变更记录
|
||||
|
||||
| 日期 | 变更 |
|
||||
|---|---|
|
||||
| 2026-10-02 | **更名**:`实机测试规划.md` → `实机测试实施指南.md`(与文档性质对齐——常设执行判据,非规划;引用面改造后仅剩 `docs/README.md` 索引 1 处,同步更新) |
|
||||
| 2026-10-02 | 初版:无 MCU 窗口建立。汇总 P0-A 环境预检 / P0-B `@test`+S7 / P1-A IWDG V2/V4/V5 / P1-B S11 / P2-A S9 / P2-B P1-8+N-2+N-3 / P3 S5+S4+待核实项,共 **7 批**。每项含现状证据 / 目标 / 判据(量化)/ 执行步骤(精确命令)/ 风险回滚。18 处自检调用点清单 + 模拟器差距清单 §3 决策规则交叉引用 |
|
||||
| 2026-10-02 | **台架窗口执行交接**:新增 **§0.5**(P0-A 通过;S7 已落地并提交 `4a4cd29`;P0-B 唯一阻断 = 0 字节 STOR → IWDG 误复位(round 3~6 后仍 5/5 复现);round 1~6 修复集摘要;**round 7 纯取证埋点设计 + 判据表**;P0-B 出口闭环(含 FTL flush 诱导式清台账);设备/台账/本地证据快照;**7 条实测陷阱**);§2.1 标注 S7 已落地、命令形态已确认 |
|
||||
| 2026-10-02 | **文档改造**(同 `本地工具路径环境变量方案.md` 思路):删除一次性台架窗口状态(原 §0.5——round 1~9 取证全过程、快照、未提交警告:结论已沉淀 `看门狗设计说明.md`/`STM32F4-Base存储架构说明.md` §5.4.1/`控制台单写者日志设计说明.md` §12,修复随 `930215f` 提交)与规划框架(预估耗时/阶段措辞),重组为执行判据说明——§1 事项总览 / §2 环境预检 / §3 `@test` 闭环+自检判定+待上板项 / §4 IWDG 注入长跑 / §5 堆告警 / §6 GD5F 错误通道 / §7 网络基线 / §8 工程卫生 / §9 实测陷阱 / §10 引用闭环;A1~A4 代码状态按当日代码核对改写(A1 已落地 / A2 部分 / A3、A4 未补码);A4 基线更新 264,284 B、A7 端口更正 COM6;原 §0.5.x 的 8 处代码注释、`待处理内容.md` 3 行、`看门狗设计说明.md` 变更记录、`docs/README.md` 同步重指向模块文档 |
|
||||
Reference in New Issue
Block a user