diff --git a/test/board/ch395f_test.h b/test/board/ch395f_test.h index 04b5f53b..b017a920 100644 --- a/test/board/ch395f_test.h +++ b/test/board/ch395f_test.h @@ -68,7 +68,7 @@ extern "C" { #define ENABLE_PHASE11_TESTS /* [网] KeepAlive 超时断开(判据见 CH395F_Test_Guide) */ /* ---- 链路时延基线(M1;分段/阈值见 docs/测试说明/链路延迟测试说明.md)---- */ //#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)---- */ //#define ENABLE_PHASE13_TESTS /* [网] 芯片 + 队列时延(L3~L7/L10,需 PC peer)—— M2 已完成,基线见说明文档 §6.2 */ /* [网] 生产路径时延(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 * 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 + * 台架冒烟(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)确实进了链接: * hw_full 的 ch395f_test_task.o 数据段 = 12,285 B(3 x 4093 = 12,279 + 其余 6 B)。 * "理论余量足够"由未实测转为已实测:最坏态还余 29,634 B,不必把 .sct 扩到 192 KB diff --git a/test/run_all_suites.py b/test/run_all_suites.py index ee45037b..913a782c 100644 --- a/test/run_all_suites.py +++ b/test/run_all_suites.py @@ -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" 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 覆盖) # 汇总行名称与套件 `XXX_TEST_REPORT("...")` 里的字符串一致(见各模块 Test_Guide)。 -# forbidden 覆盖:套件含"预期 [ERR]"的守卫负路径时须覆盖(空 = 用默认 `HardFault;assert;[ERR]`)。 -# GD5F:TC-GD5F-704 故意用非 DMA 可达缓冲触发 `[ERR][NAND] RX DMA buffer not DMA-reachable` -# 回落轮询(用例 PASS)——按 verify_log.py 的说明去掉 [ERR],保留 HardFault/assert。 +# forbidden 覆盖:套件含"预期 [ERR]"的守卫负路径时须覆盖(空 = 用默认 +# `HardFault;assert;[ERR]`,与 .serialtest/config.json 的产品判据同源)。 +# +# 为什么不能只是"把 [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 = { - "CH395F": ("TEST_SUITE_CH395F", None, "", ""), + "CH395F": ("TEST_SUITE_CH395F", None, "", FORBIDDEN_SUITE), "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:", ""), }