test(P1-10): 套件回归 forbidden 换成显式四 Fault 标签 + 台架记录 21/21

台架第一轮(boot log 20261025_050539)判 VERDICT FAIL,命中 469 条 [ERR],两类:
  1) [ERR][CH395] ch395f P2 boundary fault @get_state sn —— **设计内**:Phase 15 的
     sn 越界负向用例故意命中驱动守卫(Drivers/BSP/CH395F/ch395f.c 的
     ch395f_p2_fault_note():首次 DBG_ERROR、之后只计数),用例本身 PASS;
  2) [ERR][WD] task stall ×468 —— **设计外**,已在 a9ba8ec 单独修(掩码死分支),
     不用豁免去掩盖它。
本笔只管判据:套件回归这条路要豁免的是"设计内守卫 [ERR]",不是崩溃。

为什么不能只是把 [ERR] 从 forbidden 里删掉(核过 verify_log 源码与固件崩溃行):
四种 Fault 的崩溃行是 [ERR] HARDFAULT / MEMFAULT / BUSFAULT / USAGEFAULT
(Src/stm32f4xx_it.c 的 hard_fault_report 先打 "[ERR] " 再打标签),而 verify_log 的
forbidden 是**大小写不敏感的子串匹配**(fl in ln.lower())→ 默认集合
HardFault;assert;[ERR] 里的 HardFault 只兜得住硬Fault,**MEM/BUS/USAGE 三种平时
完全靠 [ERR] 兜**。据此:
- 新增 FORBIDDEN_SUITE =
  HardFault;MEMFAULT;BUSFAULT;USAGEFAULT;assert;bring-up FAIL
- CH395F 用它(原来吃默认值,含 [ERR]);
- GD5F 也用它——旧值 "HardFault;assert" 正是上面那个漏法(当初只为豁免
  TC-GD5F-704 的设计内 [ERR] 就把整条 [ERR] 摘了,等于顺手放走了三种 Fault),
  现在既保留豁免意图,又把崩溃判定补齐;
- STORAGE / RTC 不动(它们没有设计内 [ERR],继续吃含 [ERR] 的默认判据)。
边界写死在注释里:产品 @test 的判据(.serialtest/config.json 的 forbidden 含 [ERR])
**一个字节没动**,豁免只活在"套件回归"这条路上,渗不回产品路径。

test/board/ch395f_test.h:
- Phase 15 汇总实测 21/21(旧注释写"台架 20/20 PASS"是历史记录,已按本轮改正);
- 记一条台架档案:镜像 ch395f_hw_nopc_v2.hex 单次开机跑完 1/12/15,汇总行
  9/9、1/1、21/21,failed=0,全程无 Fault;并记下同轮暴露的掩码死分支结论与它的
  证据位置,后来人切阶段时不必再踩一遍。

验证:
- py_compile 通过;test/run_all_suites.py --check-build --suites CH395F 走**官方编排**
  实跑 PASS(BUILD_OK 0 错 0 警,Code=217468 RO=21452 RW=1268 ZI=134076),脚本自己
  还原 test_config.h 并重建产品固件;这个 Code 与上一笔实测表里"默认阶段 11/14"一行
  逐项相同 → 两个独立工具互证同一组数字。
- gate:id-check / no-mojibake / trailing-whitespace / end-of-file-fixer /
  doc-links / cppcheck(test/) / test-suite-switch(产品态 Skipped)全 0;
  未用 --no-verify。
- RAM/Flash 增量:0 B(Python 与注释,不进固件;test/board/*.h 的注释不改代码)。

下一轮台架等 lead:f2 镜像我会在 sync 到 A-3/B-3 之后重编(现在这份
ci-artifacts/p110_fw/ch395f_hw_nopc_f2.hex 戳 05:23:03,若中途主干动过固件就要重编),
判据用上面的 FORBIDDEN_SUITE;请顺手带回两个数:[ERR][WD] 总条数、mask 含 bit4(ui)
缺位的条数。
This commit is contained in:
2026-10-25 05:36:25 +08:00
parent a9ba8ec745
commit 5f1057ac74
2 changed files with 32 additions and 6 deletions
+8 -1
View File
@@ -68,7 +68,7 @@ extern "C" {
#define ENABLE_PHASE11_TESTS /* [网] KeepAlive 超时断开(判据见 CH395F_Test_Guide) */ #define ENABLE_PHASE11_TESTS /* [网] KeepAlive 超时断开(判据见 CH395F_Test_Guide) */
/* ---- 链路时延基线(M1;分段/阈值见 docs/测试说明/链路延迟测试说明.md)---- */ /* ---- 链路时延基线(M1;分段/阈值见 docs/测试说明/链路延迟测试说明.md)---- */
//#define ENABLE_PHASE12_TESTS /* [硬] SPI 字节命令 / DMA 时延基线(L1/L2,无需 PC)—— M1 已完成,基线见说明文档 §6.1 */ //#define ENABLE_PHASE12_TESTS /* [硬] SPI 字节命令 / DMA 时延基线(L1/L2,无需 PC)—— M1 已完成,基线见说明文档 §6.1 */
//#define ENABLE_PHASE15_TESTS /* [硬] 自愈驱动原语:状态回读一致性/cmd_done/sock_reset 状态机跑通/链路缓存(无需 PC)——TC 详见 docs/测试说明/CH395F_Test_Guide.md 阶段 15;台架 20/20 PASS */ //#define ENABLE_PHASE15_TESTS /* [硬] 自愈驱动原语:状态回读一致性/cmd_done/sock_reset 状态机跑通/链路缓存(无需 PC)——TC 详见 docs/测试说明/CH395F_Test_Guide.md 阶段 15;台架 21/21 PASS */
/* ---- 链路时延(M2/M3;分段/阈值见 docs/测试说明/链路延迟测试说明.md)---- */ /* ---- 链路时延(M2/M3;分段/阈值见 docs/测试说明/链路延迟测试说明.md)---- */
//#define ENABLE_PHASE13_TESTS /* [网] 芯片 + 队列时延(L3~L7/L10,需 PC peer)—— M2 已完成,基线见说明文档 §6.2 */ //#define ENABLE_PHASE13_TESTS /* [网] 芯片 + 队列时延(L3~L7/L10,需 PC peer)—— M2 已完成,基线见说明文档 §6.2 */
/* [网] 生产路径时延(L8~L11 + 模拟器 Δ)—— M3,需 peer --mode remo(:7003); /* [网] 生产路径时延(L8~L11 + 模拟器 Δ)—— M3,需 peer --mode remo(:7003);
@@ -94,6 +94,13 @@ extern "C" {
* NET 层全开 6~11/13/14 218,992 141,688 85,552 65.3% 35,034 B * NET 层全开 6~11/13/14 218,992 141,688 85,552 65.3% 35,034 B
* HW 层全开 1~5/12/15(最坏态) 229,256 147,176 90,952 69.4% 29,634 B * HW 层全开 1~5/12/15(最坏态) 229,256 147,176 90,952 69.4% 29,634 B
* HW 层无需 PC 1/12/15(台架冒烟用) 215,244 134,896 78,672 60.0% 41,914 B * HW 层无需 PC 1/12/15(台架冒烟用) 215,244 134,896 78,672 60.0% 41,914 B
* 台架冒烟(2026-10-25,_wt 同树构建 → 主树烧录,boot log 20261025_050539):
* 镜像 ch395f_hw_nopc_v2.hex(戳 suite=CH395F dstr=off)单次开机跑完 1/12/15 三段,
* 汇总行 Phase 1: 9/9、Phase 12: 1/1、Phase 15: **21/21**(failed=0),全程无 Fault。
* 同轮暴露两类设计外/设计内 [ERR]:P2 越界守卫留痕(设计内,见 ch395f.c)与
* [WD] task stall 刷屏 468 条(**设计外**:HW 层构建的必需心跳掩码没生效,
* 因为 App/util/task_watchdog.c 未 include test_config.h,看不到本文件的
* ENABLE_HW_LAYER_TESTS → 那段剔除 netTask 的分支自加入起就是死代码)。
* 该条目关心的 PHASE5 三块静态缓冲(3 x PHASE5_CHUNK_SIZE = 4093)确实进了链接: * 该条目关心的 PHASE5 三块静态缓冲(3 x PHASE5_CHUNK_SIZE = 4093)确实进了链接:
* hw_full 的 ch395f_test_task.o 数据段 = 12,285 B(3 x 4093 = 12,279 + 其余 6 B)。 * hw_full 的 ch395f_test_task.o 数据段 = 12,285 B(3 x 4093 = 12,279 + 其余 6 B)。
* "理论余量足够"由未实测转为已实测:最坏态还余 29,634 B,不必把 .sct 扩到 192 KB * "理论余量足够"由未实测转为已实测:最坏态还余 29,634 B,不必把 .sct 扩到 192 KB
+24 -5
View File
@@ -57,15 +57,34 @@ KEIL_BUILD = REPO_ROOT / ".dsh" / "skills" / "keil-build" / "scripts" / "keil_bu
STLINK_FLASH = REPO_ROOT / ".dsh" / "skills" / "stlink-flash" / "scripts" / "stlink_flash.py" STLINK_FLASH = REPO_ROOT / ".dsh" / "skills" / "stlink-flash" / "scripts" / "stlink_flash.py"
RUN_BOOT = REPO_ROOT / ".dsh" / "skills" / "serial-boot-test" / "scripts" / "run_boot_test.py" RUN_BOOT = REPO_ROOT / ".dsh" / "skills" / "serial-boot-test" / "scripts" / "run_boot_test.py"
# 套件态的 forbidden 覆盖(判据边界见下方注释块,正文只这一处)。
FORBIDDEN_SUITE = "HardFault;MEMFAULT;BUSFAULT;USAGEFAULT;assert;bring-up FAIL"
# 套件 -> (宏名, verify_log 需要的汇总行名称, 该套件的 Required 标记, --forbidden 覆盖) # 套件 -> (宏名, verify_log 需要的汇总行名称, 该套件的 Required 标记, --forbidden 覆盖)
# 汇总行名称与套件 `XXX_TEST_REPORT("...")` 里的字符串一致(见各模块 Test_Guide)。 # 汇总行名称与套件 `XXX_TEST_REPORT("...")` 里的字符串一致(见各模块 Test_Guide)。
# forbidden 覆盖:套件含"预期 [ERR]"的守卫负路径时须覆盖(空 = 用默认 `HardFault;assert;[ERR]`)。 # forbidden 覆盖:套件含"预期 [ERR]"的守卫负路径时须覆盖(空 = 用默认
# GD5F:TC-GD5F-704 故意用非 DMA 可达缓冲触发 `[ERR][NAND] RX DMA buffer not DMA-reachable` # `HardFault;assert;[ERR]`,与 .serialtest/config.json 的产品判据同源)。
# 回落轮询(用例 PASS)——按 verify_log.py 的说明去掉 [ERR],保留 HardFault/assert。 #
# 为什么不能只是"把 [ERR] 删掉"(2026-10-25 台架实测 + verify_log 源码核对):
# 四种 Fault 的崩溃行长这样:`[ERR] HARDFAULT|MEMFAULT|BUSFAULT|USAGEFAULT …`
# (Src/stm32f4xx_it.c 的 hard_fault_report),而 verify_log 的 forbidden 是**大小写
# 不敏感的子串匹配**(fl in ln.lower())→ 默认集合里的 `HardFault` 能命中硬Fault,
# 但 MEM/BUS/USAGE 三种**平时完全靠 [ERR] 兜**。所以旧 GD5F 只写 `HardFault;assert` 其实
# 放过了后三种崩溃。覆盖集合一律显式列出四个 Fault 标签 + assert + 起网失败字样:
# 豁免的是**设计内的守卫 [ERR]**,崩溃照旧判失败。
# 产品 @test 判据(.serialtest/config.json 的 forbidden 含 [ERR])**不在这里动**——
# 豁免只活在"套件回归"这条路上,渗不回产品路径。
# GD5F:TC-GD5F-704 故意用非 DMA 可达缓冲触发 `[ERR][NAND] RX DMA buffer not
# DMA-reachable` 回落轮询(用例 PASS)→ 需豁免设计内 [ERR]。
# CH395F:Phase 15 的 sn 越界负向用例命中驱动守卫 `[ERR][CH395] ch395f P2
# boundary fault @get_state sn`(Drivers/BSP/CH395F/ch395f.c 的
# ch395f_p2_fault_note():首次留痕、之后只计数)→ 同属设计内。
# 另外 `[ERR][WD] task stall` 那类**不是设计内**,是构建配置缺陷(HW 层
# 测试构建下必需心跳掩码仍含 netTask),已单独提修,不用豁免掩盖它。
SUITES = { SUITES = {
"CH395F": ("TEST_SUITE_CH395F", None, "", ""), "CH395F": ("TEST_SUITE_CH395F", None, "", FORBIDDEN_SUITE),
"STORAGE": ("TEST_SUITE_STORAGE", "Storage Tests", "=== Storage Tests:", ""), "STORAGE": ("TEST_SUITE_STORAGE", "Storage Tests", "=== Storage Tests:", ""),
"GD5F": ("TEST_SUITE_GD5F", "GD5F2GQ5UE Tests", "=== GD5F2GQ5UE Tests:", "HardFault;assert"), "GD5F": ("TEST_SUITE_GD5F", "GD5F2GQ5UE Tests", "=== GD5F2GQ5UE Tests:", FORBIDDEN_SUITE),
"RTC": ("TEST_SUITE_RTC", "RTC Tests", "=== RTC Tests:", ""), "RTC": ("TEST_SUITE_RTC", "RTC Tests", "=== RTC Tests:", ""),
} }