diff --git a/App/algo/README.md b/App/algo/README.md
index e218e991..76dc63d8 100644
--- a/App/algo/README.md
+++ b/App/algo/README.md
@@ -177,7 +177,7 @@ flowchart TD
- **Q10 定点**(×1024)与参考 `2^10` 折算口径一致;元数据表(地址/范围/默认)是
ROM 常量,校验和只覆盖 RAM 值区。
- **通讯地址逐项对照参考** `Comm/Pub/Const_CommSetPara.c` `g_tCommSetParaTab`
- (基址 0x8820);单测 TC-PS-006 保证地址不重复、`min ≤ def ≤ max`、投退项 0..1。
+ (基址 0x8820);单测 TC-PROTSET-006 保证地址不重复、`min ≤ def ≤ max`、投退项 0..1。
- ⚠ **默认值/范围为拟定值**(参考 EEPROM 出厂表不在本仓库),待对照修订——
见规划 §5.4 落实进度注。
- **B8 扩 8 项(32→40)**:`PS_OF_EN/OF_HZ/OF_DLY/UF_EN/UF_HZ/UF_DLY/RET_OF/RET_UF`
diff --git a/App/util/sys_clock.c b/App/util/sys_clock.c
index afdfb570..3133d0b1 100644
--- a/App/util/sys_clock.c
+++ b/App/util/sys_clock.c
@@ -77,7 +77,7 @@ static volatile uint32_t s_base_unix_secs = UINT32_MAX;
* 修改记录:
* 2026-10-02 修正:原式错用 (wy%100 + wy/100/4 - wy/100/15)(缺 K/4、
* 5J/世纪项,且把 1-based 月当 2-based 用),实测 1970~2099
- * 全部日期星期皆错(主机侧单测 TC-CLK-014/019 发现)。
+ * 全部日期星期皆错(主机侧单测 TC-SYSCLK-014/019 发现)。
*/
static uint8_t rtc_calc_week(uint16_t y, uint8_t m, uint8_t d) {
uint32_t wy = y;
diff --git a/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c b/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c
index cc2752b7..069ea82c 100644
--- a/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c
+++ b/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c
@@ -632,7 +632,7 @@ void gd5f2gq5ue_bbt_clear(void) {
* 返回值:GD5F_OK - 成功,其他 - 错误码
* 限定条件:gd5f2gq5ue_init() 已成功调用
* 函数说明:临时关闭 ECC 重新扫描每块 page0 spare[0] 的出厂坏块标记,覆盖 RAM BBT,
- * 再写回持久化 BBT 池(版本 +1,掉电安全),从而清除 TC-STO-03 等运行时
+ * 再写回持久化 BBT 池(版本 +1,掉电安全),从而清除 TC-STORAGE-03 等运行时
* 标记的坏块。调用后建议再执行 nand_ftl_format() 清空 dhara map。
*/
int32_t gd5f2gq5ue_bbt_rebuild(void) {
diff --git a/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h b/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h
index 828566c4..df53eb51 100644
--- a/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h
+++ b/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h
@@ -225,7 +225,7 @@ void gd5f2gq5ue_print_bbt(void);
* 入口参数:无
* 返回值:GD5F_OK - 成功,其他 - 错误码
* 限定条件:gd5f2gq5ue_init() 已成功调用
- * 函数说明:用于测试(如 TC-STO-03 注入坏块后)或出厂重置后恢复。
+ * 函数说明:用于测试(如 TC-STORAGE-03 注入坏块后)或出厂重置后恢复。
* 临时关闭 ECC 重新扫描每块 page0 spare[0] 的出厂坏块标记,覆盖 RAM BBT,
* 再写回持久化 BBT 池(版本 +1,掉电安全),从而清除运行时 mark 的坏块。
* 调用后建议再执行 nand_ftl_format() 清空 dhara map。
diff --git a/docs/代码规范/pre-commit使用说明.md b/docs/代码规范/pre-commit使用说明.md
index d7b25ce7..c8f7a297 100644
--- a/docs/代码规范/pre-commit使用说明.md
+++ b/docs/代码规范/pre-commit使用说明.md
@@ -455,7 +455,7 @@ cppcheck 是开源 C/C++ 静态分析工具,**不运行代码**,通过语法
| **八项校验**([示例] 本行引用的是各种非法形态示例,不是真实编号) | ①未登记前缀 ②形态不合规(裸形 `S3` / 空格形 `Trap 07` / 中文形 `陷阱 1` / 补零错 / 档位词带后缀 / 大写后缀 / 缺模块码)③悬空引用 ④重复定义 ⑤冻结前缀越游标 ⑥文档内编号未紧邻文档名 ⑦孤儿条目(告警)⑧可判定比例(只许涨不许跌) |
| **配置两份** | `scripts/id_registry.json`:前缀族 → 属主登记处 / 形态正则 / 是否冻结 / 游标,**逐项来自 `docs/编号规范.md` §4 总表**,游标取「规范记载值」与「全库实测最大号」的较大者,偏差写进 `cursor_note`(实测偏差见规范 §8.2);`scripts/id_aliases.json`:旧号 → 新号 / 作废标记(照搬 `section_aliases.json` 的成功范式) |
| **判定口径** | 「定义」= 字面量出现在该族**属主登记处文档**里(不依赖表格行首等易漂移形态)→ §5.5「销项 = 删行 + 清全库引用」只做一半,校验 ③ 立刻报(`N-31`/`N-32` 正是这条)。「重复定义」= 字面量出现在**定义位**(表格首格 / 标题行 / 列表项行首),正文提到不算,否则任何交叉引用都会误判成事故 |
-| **顺带收编** | `scripts/check_test_traceability.py`(TC 用例双向追溯)由本钩子一并调用:正则补齐 `TC-[A-Z]{1,4}-\d{3,4}[a-z]?` 与大写后缀 / 无模块码形态(旧 `TC-[A-Za-z0-9]+-\d+` **整条漏扫** `TC-AI-01A`),比对范围从「`test/board/*.c` ↔ `*_Test_Guide.md`」扩到 `test/host/` 一侧 + 7 篇「单元测试说明.md」(差异从 33 处涨到 326 处——**原口径漏的正是主机侧单测这一半**),另加 `--board-only` 回退旧口径 |
+| **顺带收编** | `scripts/check_test_traceability.py`(TC 用例双向追溯)由本钩子一并调用:正则补齐 `TC-[A-Z]{1,4}-\d{3,4}[a-z]?` 与大写后缀 / 无模块码形态(旧 `TC-[A-Za-z0-9]+-\d+` **整条漏扫** `TC-ADCIN-01A`),比对范围从「`test/board/*.c` ↔ `*_Test_Guide.md`」扩到 `test/host/` 一侧 + 7 篇「单元测试说明.md」(差异从 33 处涨到 326 处——**原口径漏的正是主机侧单测这一半**),另加 `--board-only` 回退旧口径 |
| **首轮实测(2026-10-20)** | 8271 处编号字面量 / 可判定 **82.3%**(6808/8271);错误级:②416 ③626 ⑥269,告警级:③239 ⑦88。错误集中在 `TC-PS-*`/`TC-PE-*`/`TC-AH-*`/`TC-SOE-*`(**主机侧单测有码无文档**,正是 §7.2 列的"缺文档 = 追溯断链")与报告自有编号被裸引(`D-x`/`R-x`/`F-x`/`P0-x`,属 §9 阶段 1-③)。逐项数字与口径见 `docs/编号规范.md` §8.1 |
| **有牙实测(牙齿)**([示例] 下列字面量是注入用的假编号) | 注入打在临时档(`git add -N` 进索引,跑完 `git rm --cached` + 删除,`git status` 干净):`Z-99`→①、裸形 `S3`→②、`TC-NET-9999`→③、第二篇属主文档重复定义 `DP-01`→④、`E-70`→⑤(`E-xx` 冻结于 `E-63`)、裸引 `D-7`→⑥;六项分别被对应校验点名,`--strict` 退出码 1 |
| **显式盲区(不是"检查通过")** | ① 裸形同字母多义(§1.2:`P1` 五义 / `L1` 四义 / `U1` 四义 / `D7` 三义)与元器件位号同形(§4.4)→ 裸形族**只在属主登记处文档内**判越游标,文档外降告警;② 圈号编号(①②③…)与正常列举无法机械区分,不入判定;③ `docs/芯片手册/`、`docs/硬件平台/` 整体排除(位号 `B1`/`C1`/`L1` 与编号同形,是撞形根源)。前两块收口属 §9 阶段 1-②/1-③ 迁移批次,落地后再扩判定范围——盲区登记在 `id_registry.json` 的 `blind_spots` / `unmanaged_bare` |
diff --git a/docs/内存管理/内存内容分配策略.md b/docs/内存管理/内存内容分配策略.md
index 1cdb8e11..d64ef180 100644
--- a/docs/内存管理/内存内容分配策略.md
+++ b/docs/内存管理/内存内容分配策略.md
@@ -127,7 +127,7 @@ LVGL 集合明细(均在 SRAM):LVGL 池 16,384B(`lv_mem_core_builtin.o`
1. `@build`(0 错误 0 警告)
2. 产品构建 `@test`(`.dsh/skills/serial-boot-test/scripts/run_boot_test.py`):标记校验 PASS,且**零 `[ERR]`**(默认 Forbidden 已含 `[ERR]`)
-3. 存储套件(`test_config.h` → `TEST_SUITE_STORAGE`):只读模式实测 **3/3 PASSED**(破坏性关,卷内容不变);开启 `ENABLE_DESTRUCTIVE_TESTS` 后为全量集成用例(2026-09-20 实测 **20/20 PASSED**,含 TC-STO-01/02/03/05/06)
+3. 存储套件(`test_config.h` → `TEST_SUITE_STORAGE`):只读模式实测 **3/3 PASSED**(破坏性关,卷内容不变);开启 `ENABLE_DESTRUCTIVE_TESTS` 后为全量集成用例(2026-09-20 实测 **20/20 PASSED**,含 TC-STORAGE-01/02/03/05/06)
4. GD5F 套件(`TEST_SUITE_GD5F`):只读模式实测 **16/16 PASSED**(含只读的守卫负路径 TC-GD5F-704);开启 `ENABLE_DESTRUCTIVE_TESTS` 后 **68/68 PASSED**,并确认日志出现 2 条守卫负路径 `[ERR]`(TC-GD5F-704/705)——破坏性模式运行须放宽 Forbidden(`--forbidden "FAIL;HardFault"`)
5. 恢复跑(`ENABLE_STORAGE_RECOVERY_TESTS`):期望 **3/3 PASSED**
6. **破坏性用例默认关闭**(见 `test_config.h` 的 `ENABLE_DESTRUCTIVE_TESTS`):写/擦 NAND、格式化、坏块注入与 FatFS 写类用例只在首次上电/产线首启或明确需要时开启——2026-09-21 实测一轮破坏性 GD5F 运行即让 dhara 多记一个坏块(容量 95248 → 95200,且该计数持久化在 dhara journal checkpoint 头里,`nand_ftl_format` 清不掉);日常回归请保持只读模式。容量满值 = **96064 pages(187 MB)**,被扣掉的容量可用 `ENABLE_STORAGE_RECOVERY_TESTS` + `STORAGE_RECOVERY_FULL_WIPE`(全片擦除 + 重建 BBT)恢复(实测 95200 → 96064 ✓)
diff --git a/docs/子系统设计/ADC采样节拍设计说明.md b/docs/子系统设计/ADC采样节拍设计说明.md
index fbf38a59..a7956fbf 100644
--- a/docs/子系统设计/ADC采样节拍设计说明.md
+++ b/docs/子系统设计/ADC采样节拍设计说明.md
@@ -318,7 +318,7 @@ t=1000 µs 下一个 TIM6 更新事件
只统计"从未成功过"、抓不到它。
**硬化排序**:① ✅ **已实施(2026-10-10)**——`stm32_scan()` 两条失败支路(启动失败 / 轮询
超时)都清 `s_stm32_valid` → 本拍 STM32 侧判为无有效数据,走既有 `skip` 整帧跳过路径,
- 下一拍成功自动恢复;主机侧新增 **TC-AI-070..078** 钉死并做反向验证(改回旧行为 3 条立即
+ 下一拍成功自动恢复;主机侧新增 **TC-ADCIN-070..078** 钉死并做反向验证(改回旧行为 3 条立即
FAIL)。② ✅ **已实施(2026-10-10)= DMA**:见 **§11**——TIM3 更新事件经 TRGO 硬件触发
ADC1 一轮 9 通道,`HAL_ADC_Start_DMA(&hadc1, buf, 18)`(乒乓双缓冲)由 DMA 自动搬运,
任务侧 `HAL_ADC_PollForConversion` **全部删除**,实测单拍 `adcp` **122 µs → 8 µs**;
diff --git a/docs/子系统设计/看门狗设计说明.md b/docs/子系统设计/看门狗设计说明.md
index 1a94e5b7..4a6a8a7f 100644
--- a/docs/子系统设计/看门狗设计说明.md
+++ b/docs/子系统设计/看门狗设计说明.md
@@ -588,7 +588,7 @@ python scripts/check_cubemx_survival.py --write # 确认改动无误后重建
等效采样间隔被拉长。当时 `idle` 占 3.2% → 窗长从 20.0 ms 漂到 ≈20.6 ms ≈ **3% 频率失配**
→ 幅值/相位**系统性误差**(不是随机噪声)。现仅 `r == 1` 压帧,上板印证 `ring == frames`。
- **失败拍静默沿用上一拍值**:失败支路不清 `s_stm32_valid` → 照样压环、`skip` 抓不到。
- 现失败即清标志走整帧跳过(`ADC采样节拍设计说明.md` §10.4;单测 TC-AI-070..078 钉死)。
+ 现失败即清标志走整帧跳过(`ADC采样节拍设计说明.md` §10.4;单测 TC-ADCIN-070..078 钉死)。
### 11.4 `[PROF]` / `[PROF2]` 字段语义与当前基线
diff --git a/docs/架构设计/STM32F4-Base存储架构说明.md b/docs/架构设计/STM32F4-Base存储架构说明.md
index 079bee36..09137307 100644
--- a/docs/架构设计/STM32F4-Base存储架构说明.md
+++ b/docs/架构设计/STM32F4-Base存储架构说明.md
@@ -582,7 +582,7 @@ if (nand_ftl_format() == 0) {
10. **FatFs 严格 8.3 短名** — 本移植 `Lib/FatFs/ffconf.h` 为 `FF_USE_LFN=0`,**只支持严格 8.3 短名**:主名 ≤8 字符、扩展 ≤3 字符、**不得以点开头**(2026-09-20 台架实证,`.fschk` 无限重格式化事故根因)。`.fschk` 会被 `ff.c` 的 `create_short` 把「点之后」当扩展域解析而超限 → `f_open` 恒返 `FR_INVALID_NAME`(6);这是**纯 RAM 里的名字判定,不碰盘**。`ff.c` `create_short` 全部拒绝点的地方已加 DEBUG 打印:`[ERR][FATFS] SFN reject (原因) seg='名字片段' bad_ch=坏字符`——非法名字调用看开机日志即可定位。自愈类逻辑**严禁**把名字/参数类错误码(`FR_INVALID_NAME` 等)归入"卷损坏"触发集(整卷重格式化不可逆)。补充:含冒号 `:` 的名字被 FatFs 先解析为**盘符前缀** → `f_open` 返回 `FR_INVALID_DRIVE`(11) 而非 `FR_INVALID_NAME`(6);两者都属合法拒绝(测试用例须同时接受)。
11. **FA_OPEN_APPEND 陷阱 / 短写** — `FA_OPEN_APPEND`(0x30) = `FA_OPEN_ALWAYS|FA_SEEKEND`,**不含 `FA_WRITE`(0x02)**——不带写位打开的文件 `f_write` 恒返回 `FR_DENIED`(7)(这是当年 `/log` 写失败的真根因);追加写必须写 `FA_WRITE | FA_OPEN_APPEND`(2026-09-20 台架实测,`Lib/FatFs` 移植版)。该移植的 `f_write` 在簇分配失败时返回 `FR_OK` + 短写(**没有错误码**)→ 判失败必须校验写回的字节数。标志位为**旧式编号**:`FA_READ`=0x01 / `FA_WRITE`=0x02 / `FA_CREATE_NEW`=0x04 / `FA_CREATE_ALWAYS`=0x08 / `FA_OPEN_ALWAYS`=0x10 / `FA_OPEN_APPEND`=0x30 / `FA_SEEKEND`=0x20(`ff.c` 内部定义),与上游 FatFs R0.14 不同,**勿照抄上游代码示例**。
12. **崩溃可观测性(勿屏蔽)** — 已开启 `configCHECK_FOR_STACK_OVERFLOW=2` + `configUSE_MALLOC_FAILED_HOOK` + HardFault 现场报告(`Src/stm32f4xx_it.c`:裸 UART 打印 PC/LR/xPSR + CFSR/HFSR/BFAR/MMFAR 后复位,对照 `.map` 定位符号)。defaultTask **1024** words、testTask **2048** words 是**实测下限,勿降**。开机日志出现 `[ERR] STACK OVERFLOW task=` / `[ERR] HARDFAULT ...` / `MALLOC FAILED` 是精确定位线索,禁止屏蔽或降级。
-13. **BBT 恢复模式** — 运行期坏块会随 TC-STO-03 注入累积;当介质被**误标脏**(如 DMA 误打 CCM 栈导致随机块被写坏并持久化)时,打开 `test/board/storage_test.h` 的 `ENABLE_STORAGE_RECOVERY_TESTS` 编译**恢复构建**,testTask 会执行 `gd5f2gq5ue_bbt_rebuild()`(出厂扫描清除运行期误标)+ `nand_ftl_format()` 清账后复位。恢复后容量回到基线(即扣除 BBT 保留池后的正常容量,非出厂裸容量)。
+13. **BBT 恢复模式** — 运行期坏块会随 TC-STORAGE-03 注入累积;当介质被**误标脏**(如 DMA 误打 CCM 栈导致随机块被写坏并持久化)时,打开 `test/board/storage_test.h` 的 `ENABLE_STORAGE_RECOVERY_TESTS` 编译**恢复构建**,testTask 会执行 `gd5f2gq5ue_bbt_rebuild()`(出厂扫描清除运行期误标)+ `nand_ftl_format()` 清账后复位。恢复后容量回到基线(即扣除 BBT 保留池后的正常容量,非出厂裸容量)。
14. **lftpd 路径口径(归档更正 2026-10-13:原误记于 `docs/问题记录/CH395F_Trap_Records.md`——非 CH395F 议题,移入本节)** — FTP STOR/CWD 曾频发 `FR_INVALID_NAME`(6):真约束即上条第 10 项的严格 8.3。原记录"FatFS 不接受 `/` 前缀 / 空字符串失败"两条与仓内 `Lib/FatFs/ff.c` 矛盾(`ff.c:3101-3109` 会剥前导分隔符、`:3127-3129` 空名返回根目录),**已删**。现行口径:`lftpd_io.c` 的 `to_fatfs_path()` 剥 `/` 前缀(行为正确,保留)+ 本仓路径用 `"0:"` 卷前缀(`FF_FS_RPATH=0` 下 `"."` 不是合法路径段)。长文件名需 `FF_USE_LFN=1` + `FF_LFN_UNICODE`(显著增 RAM,未启用)。
### 10.2 FTP 服务(lftpd)鉴权语义(2026-10-11,N-19)
diff --git a/docs/测试说明/ADC输入层单元测试说明.md b/docs/测试说明/ADC输入层单元测试说明.md
index df400a64..452317a9 100644
--- a/docs/测试说明/ADC输入层单元测试说明.md
+++ b/docs/测试说明/ADC输入层单元测试说明.md
@@ -114,34 +114,34 @@ test/host/adc_input/adc_input_test.c
| 用例 | 断言 | 验证的设计点 |
|---|---|---|
-| **TC-AI-001** | 前置:注入 `HAL_ADC_Start` 失败 → poll 后失败计数 = 1 | 统计可见性(前置构造) |
-| **TC-AI-002** | 前置:注入 TPAFE 有效帧 → poll 后 `UA` 可取数且值正确 | 取数通路(前置构造) |
-| **TC-AI-003** | `adc_input_init()` 返回 0 | 映射表自检通过 |
-| **TC-AI-004** | init 后 `adc_input_stm32_rc() == ADC_INPUT_RC_NOT_RUN` | 状态码复位 |
-| **TC-AI-005** | init 后 `adc_input_stm32_errs() == 0` | 失败计数归零 |
-| **TC-AI-006** | init 后 TPAFE / STM32 **两侧** `adc_input_raw()` 均返回 -2 | 有效标志被清(不会取到上一轮陈旧值) |
+| **TC-ADCIN-001** | 前置:注入 `HAL_ADC_Start` 失败 → poll 后失败计数 = 1 | 统计可见性(前置构造) |
+| **TC-ADCIN-002** | 前置:注入 TPAFE 有效帧 → poll 后 `UA` 可取数且值正确 | 取数通路(前置构造) |
+| **TC-ADCIN-003** | `adc_input_init()` 返回 0 | 映射表自检通过 |
+| **TC-ADCIN-004** | init 后 `adc_input_stm32_rc() == ADC_INPUT_RC_NOT_RUN` | 状态码复位 |
+| **TC-ADCIN-005** | init 后 `adc_input_stm32_errs() == 0` | 失败计数归零 |
+| **TC-ADCIN-006** | init 后 TPAFE / STM32 **两侧** `adc_input_raw()` 均返回 -2 | 有效标志被清(不会取到上一轮陈旧值) |
### 2.2 语义映射表(`adc_input_desc`)
| 用例 | 断言(语义 → 来源 / 下标) | 权威口径 |
|---|---|---|
-| **TC-AI-010** | `UA` → TPAFE `buf[6]` | `docs/硬件平台/ADC通道映射说明.md` |
-| **TC-AI-011** | `UB` → STM32 `CH14` | 同上 |
-| **TC-AI-012** | `UC` → STM32 `CH3` | 同上 |
-| **TC-AI-013** | `UN` → TPAFE `buf[5]` | 同上 |
-| **TC-AI-014** | `IA` → TPAFE `buf[2]` | 同上 |
-| **TC-AI-015** | `IB` → STM32 `CH6` | 同上 |
-| **TC-AI-016** | `IC` → STM32 `CH1` | 同上 |
-| **TC-AI-017** | `IN` → STM32 `CH2` | 同上 |
-| **TC-AI-018** | `TEMP` → STM32 `CH5`(V_ZL2) | 同上 |
-| **TC-AI-019** | `adc_input_desc(ADC_SEM_COUNT)` → `NULL` | 越界防御 |
-| **TC-AI-01A** | `adc_input_desc((adc_semantic_t)-1)` → `NULL` | 无符号比较兜底 |
+| **TC-ADCIN-010** | `UA` → TPAFE `buf[6]` | `docs/硬件平台/ADC通道映射说明.md` |
+| **TC-ADCIN-011** | `UB` → STM32 `CH14` | 同上 |
+| **TC-ADCIN-012** | `UC` → STM32 `CH3` | 同上 |
+| **TC-ADCIN-013** | `UN` → TPAFE `buf[5]` | 同上 |
+| **TC-ADCIN-014** | `IA` → TPAFE `buf[2]` | 同上 |
+| **TC-ADCIN-015** | `IB` → STM32 `CH6` | 同上 |
+| **TC-ADCIN-016** | `IC` → STM32 `CH1` | 同上 |
+| **TC-ADCIN-017** | `IN` → STM32 `CH2` | 同上 |
+| **TC-ADCIN-018** | `TEMP` → STM32 `CH5`(V_ZL2) | 同上 |
+| **TC-ADCIN-019** | `adc_input_desc(ADC_SEM_COUNT)` → `NULL` | 越界防御 |
+| **TC-ADCIN-01A** | `adc_input_desc((adc_semantic_t)-1)` → `NULL` | 无符号比较兜底 |
### 2.3 映射表自检(`map_check`,静态)
| 用例 | 断言 | 验证的设计点 |
|---|---|---|
-| **TC-AI-020** | `map_check() == 0` | 真实映射表自洽:TPAFE 下标 < 8;每个 STM32 映射通道都出现在扫描 Rank 内 |
+| **TC-ADCIN-020** | `map_check() == 0` | 真实映射表自洽:TPAFE 下标 < 8;每个 STM32 映射通道都出现在扫描 Rank 内 |
> 反向路径(表不自洽 → -1)**结构上不可达**,见 §4.1。
@@ -149,27 +149,27 @@ test/host/adc_input/adc_input_test.c
| 用例 | 断言 | 验证的设计点 |
|---|---|---|
-| **TC-AI-021** | 有新帧 → 返回 0 | 正常路径 |
-| **TC-AI-022** | `adc_input_stm32_rc() == RC_OK` | 状态码 |
-| **TC-AI-023** | 成功不计入失败计数 | 统计语义 |
-| **TC-AI-024** | `HAL_ADC_Start_DMA` 只在 `init()` 挂**一次** | 外设生命周期(每拍不重启) |
-| **TC-AI-025** | DMA 完成计数 `seq` = 1 | 计数只由 HAL 回调推进 |
-| **TC-AI-026** | ⭐ **Rank → 通道号映射**:`UB` = CH14 / rank9 = 108 | **本层核心判据**(板端无法验) |
-| **TC-AI-027** | `UC` = CH3 / rank4 = 103 | 同上 |
-| **TC-AI-028** | `IB` = CH6 / rank7 = 106 | 同上 |
-| **TC-AI-029** | `IC` = CH1 / rank2 = 101 | 同上 |
-| **TC-AI-02A** | `IN` = CH2 / rank3 = 102 | 同上 |
-| **TC-AI-02B** | `TEMP` = CH5 / rank6 = 105 | 同上 |
-| **TC-AI-02C** | 取帧后 `UA`(TPAFE)仍为 -2 | 两来源互相独立 |
-| **TC-AI-080..085** | ⭐ **乒乓双缓冲**:往"正在被 DMA 写的另一半区"填 900/800 系干扰值,`stm32_take()` 仍必须读到**刚完成那一半**(108 / 208) | **撕裂帧防线**(读错半区 = 半新半旧混合帧) |
-| **TC-AI-086..089** | 连投两帧不消费 → 取到最新帧(408)且 `gaps()` = 1、`errs()` = 0 | **丢帧与停摆分开计数**(消费者超拍 ≠ 节拍源停) |
-| **TC-AI-090..09A** | `HAL_ADC_ErrorCallback(&hadc1)` ×2 → `hw_errs()` = 2;用**别的句柄**调三个回调 → `seq` / `hw_errs` 均不动 | 三个 HAL 弱回调的 `hadc == &hadc1` **句柄守卫** |
-| **TC-AI-030..034** | `HAL_ADC_Start_DMA` 返回 `HAL_ERROR` → `init()` 返回 **-2**、状态码 `RC_START`、计数 +1、STM32 侧无有效数据 | 挂载失败(一次性,非每拍) |
-| **TC-AI-035..039** | 无任何 DMA 完成 → `RC_STALL`、**单拍不计故障**、`seq` 不前进、STM32 侧无有效数据 | 无新帧路径 + 相位伪影不误报 |
-| **TC-AI-03A..03E** | 连续两拍无新帧 → `errs()` = 1;第三拍 → 2;恢复拍成功且 `gaps()` 仍 0 | 停摆判据 = **连续 ≥2 拍**;跨次单调累计 |
-| **TC-AI-070..078** | ⭐ **停摆拍不得沿用上一拍旧值**:先成功一拍让 STM32 侧进入有效态(`UB`=108),再注入无新帧拍 → `adc_input_raw()` 必须返 **-2**;恢复拍重新可取数 | **陈旧帧**(2026-10-10 真机实测发现的缺陷,见下注) |
+| **TC-ADCIN-021** | 有新帧 → 返回 0 | 正常路径 |
+| **TC-ADCIN-022** | `adc_input_stm32_rc() == RC_OK` | 状态码 |
+| **TC-ADCIN-023** | 成功不计入失败计数 | 统计语义 |
+| **TC-ADCIN-024** | `HAL_ADC_Start_DMA` 只在 `init()` 挂**一次** | 外设生命周期(每拍不重启) |
+| **TC-ADCIN-025** | DMA 完成计数 `seq` = 1 | 计数只由 HAL 回调推进 |
+| **TC-ADCIN-026** | ⭐ **Rank → 通道号映射**:`UB` = CH14 / rank9 = 108 | **本层核心判据**(板端无法验) |
+| **TC-ADCIN-027** | `UC` = CH3 / rank4 = 103 | 同上 |
+| **TC-ADCIN-028** | `IB` = CH6 / rank7 = 106 | 同上 |
+| **TC-ADCIN-029** | `IC` = CH1 / rank2 = 101 | 同上 |
+| **TC-ADCIN-02A** | `IN` = CH2 / rank3 = 102 | 同上 |
+| **TC-ADCIN-02B** | `TEMP` = CH5 / rank6 = 105 | 同上 |
+| **TC-ADCIN-02C** | 取帧后 `UA`(TPAFE)仍为 -2 | 两来源互相独立 |
+| **TC-ADCIN-080..085** | ⭐ **乒乓双缓冲**:往"正在被 DMA 写的另一半区"填 900/800 系干扰值,`stm32_take()` 仍必须读到**刚完成那一半**(108 / 208) | **撕裂帧防线**(读错半区 = 半新半旧混合帧) |
+| **TC-ADCIN-086..089** | 连投两帧不消费 → 取到最新帧(408)且 `gaps()` = 1、`errs()` = 0 | **丢帧与停摆分开计数**(消费者超拍 ≠ 节拍源停) |
+| **TC-ADCIN-090..09A** | `HAL_ADC_ErrorCallback(&hadc1)` ×2 → `hw_errs()` = 2;用**别的句柄**调三个回调 → `seq` / `hw_errs` 均不动 | 三个 HAL 弱回调的 `hadc == &hadc1` **句柄守卫** |
+| **TC-ADCIN-030..034** | `HAL_ADC_Start_DMA` 返回 `HAL_ERROR` → `init()` 返回 **-2**、状态码 `RC_START`、计数 +1、STM32 侧无有效数据 | 挂载失败(一次性,非每拍) |
+| **TC-ADCIN-035..039** | 无任何 DMA 完成 → `RC_STALL`、**单拍不计故障**、`seq` 不前进、STM32 侧无有效数据 | 无新帧路径 + 相位伪影不误报 |
+| **TC-ADCIN-03A..03E** | 连续两拍无新帧 → `errs()` = 1;第三拍 → 2;恢复拍成功且 `gaps()` 仍 0 | 停摆判据 = **连续 ≥2 拍**;跨次单调累计 |
+| **TC-ADCIN-070..078** | ⭐ **停摆拍不得沿用上一拍旧值**:先成功一拍让 STM32 侧进入有效态(`UB`=108),再注入无新帧拍 → `adc_input_raw()` 必须返 **-2**;恢复拍重新可取数 | **陈旧帧**(2026-10-10 真机实测发现的缺陷,见下注) |
-> ⚠ **为什么 TC-AI-034 照不出这条缺陷**:它是"`adc_input_init()` 后**立刻**失败",此时
+> ⚠ **为什么 TC-ADCIN-034 照不出这条缺陷**:它是"`adc_input_init()` 后**立刻**失败",此时
> `s_stm32_valid` 本来就是 0,断言 -2 恒成立。真正的缺陷路径是**成功过之后再失败**:
> 本层只有一份 `s_stm32_raw[]`,而有效标志此前**只在成功时置 1、失败时从不清零** →
> 消费侧照样取数、照样压入采样环(`adc_input_poll()` 返回值只由 TPAFE 决定,
@@ -177,7 +177,7 @@ test/host/adc_input/adc_input_test.c
> 修复 = 失败支路清 `s_stm32_valid`(`App/algo/adc_input.c`)。
> **这组用例在轮询版与 DMA 版都保留**:触发条件从"轮询超时"变成"本拍无新帧",
> **同一条缺陷、同一个防线**。
-> **反向验证已做(v2.0)**:把停摆支路改回 `valid=1` → TC-AI-039 / 073 / 074 / 074B 四条立即
+> **反向验证已做(v2.0)**:把停摆支路改回 `valid=1` → TC-ADCIN-039 / 073 / 074 / 074B 四条立即
> FAIL(89/93 时点);把半区奇偶取反 → 11 条 FAIL;`STALL_RUN_MAX` 改 1 → 6 条 FAIL;
> gap 阈值改 `>2` → 1 条 FAIL → 证明这些用例真的咬得住。
@@ -185,45 +185,45 @@ test/host/adc_input/adc_input_test.c
| 用例 | 断言 | 验证的设计点 |
|---|---|---|
-| **TC-AI-040** | `out == NULL` → -1 | 参数防御 |
-| **TC-AI-041** | `ch == ADC_SEM_COUNT` → -1 | 越界防御 |
-| **TC-AI-042** | `ch == (adc_semantic_t)-1` → -1 | 负数兜底 |
-| **TC-AI-043** | 参数错时**不写** `*out` | 无副作用 |
-| **TC-AI-044** | TPAFE 无有效帧 → -2 | 有效标志语义 |
-| **TC-AI-045** | STM32 无有效扫描 → -2 | 有效标志语义 |
-| **TC-AI-049** | `UA` → `buf[6]` 的值(注入 3006) | 按**下标**取数(非按枚举序) |
-| **TC-AI-04A** | `UN` → `buf[5]` 的值(注入 2005) | 同上 |
-| **TC-AI-04B** | `IA` → `buf[2]` 的值(注入 **-1234**) | 16 位补码负值原样保留(不截断 / 不取绝对值) |
+| **TC-ADCIN-040** | `out == NULL` → -1 | 参数防御 |
+| **TC-ADCIN-041** | `ch == ADC_SEM_COUNT` → -1 | 越界防御 |
+| **TC-ADCIN-042** | `ch == (adc_semantic_t)-1` → -1 | 负数兜底 |
+| **TC-ADCIN-043** | 参数错时**不写** `*out` | 无副作用 |
+| **TC-ADCIN-044** | TPAFE 无有效帧 → -2 | 有效标志语义 |
+| **TC-ADCIN-045** | STM32 无有效扫描 → -2 | 有效标志语义 |
+| **TC-ADCIN-049** | `UA` → `buf[6]` 的值(注入 3006) | 按**下标**取数(非按枚举序) |
+| **TC-ADCIN-04A** | `UN` → `buf[5]` 的值(注入 2005) | 同上 |
+| **TC-ADCIN-04B** | `IA` → `buf[2]` 的值(注入 **-1234**) | 16 位补码负值原样保留(不截断 / 不取绝对值) |
### 2.6 采集一拍(`adc_input_poll`)
| 用例 | 断言 | 验证的设计点 |
|---|---|---|
-| **TC-AI-046** | 快照返回 1 → `poll()` 返回 1 | 返回码透传 |
-| **TC-AI-047** | 快照被请求 **8** 通道 | 与 `ADC_INPUT_TPAFE_CH_NUM` 一致 |
-| **TC-AI-048** | 快照目的缓冲非空 | 不传 NULL 给驱动 |
-| **TC-AI-050** | 快照返回 0(无新帧)→ `poll()` 返回 0 | 无新帧语义 |
-| **TC-AI-051** | 无新帧时 TPAFE 侧无效 | 不置有效标志 |
-| **TC-AI-052** | 同拍 STM32 扫描**照常执行**(`rc == RC_OK`) | 两侧独立 |
-| **TC-AI-053** | 快照返回 -1(参数错)→ `poll()` 返回 -1 | 错误透传 |
-| **TC-AI-054** | 参数错时 TPAFE 侧无效 | 不置有效标志 |
-| **TC-AI-055** | 已有有效帧后再"无新帧" → **保持**上次有效值 | 有效标志只置不清 |
-| **TC-AI-056** | STM32 失败**不影响** `poll()` 返回值(仍为 1) | 两侧解耦 |
-| **TC-AI-057** | STM32 失败不影响 TPAFE 取数 | 同上 |
-| **TC-AI-058** | STM32 失败另由 `adc_input_stm32_rc()` 暴露 | 故障通道分离 |
+| **TC-ADCIN-046** | 快照返回 1 → `poll()` 返回 1 | 返回码透传 |
+| **TC-ADCIN-047** | 快照被请求 **8** 通道 | 与 `ADC_INPUT_TPAFE_CH_NUM` 一致 |
+| **TC-ADCIN-048** | 快照目的缓冲非空 | 不传 NULL 给驱动 |
+| **TC-ADCIN-050** | 快照返回 0(无新帧)→ `poll()` 返回 0 | 无新帧语义 |
+| **TC-ADCIN-051** | 无新帧时 TPAFE 侧无效 | 不置有效标志 |
+| **TC-ADCIN-052** | 同拍 STM32 扫描**照常执行**(`rc == RC_OK`) | 两侧独立 |
+| **TC-ADCIN-053** | 快照返回 -1(参数错)→ `poll()` 返回 -1 | 错误透传 |
+| **TC-ADCIN-054** | 参数错时 TPAFE 侧无效 | 不置有效标志 |
+| **TC-ADCIN-055** | 已有有效帧后再"无新帧" → **保持**上次有效值 | 有效标志只置不清 |
+| **TC-ADCIN-056** | STM32 失败**不影响** `poll()` 返回值(仍为 1) | 两侧解耦 |
+| **TC-ADCIN-057** | STM32 失败不影响 TPAFE 取数 | 同上 |
+| **TC-ADCIN-058** | STM32 失败另由 `adc_input_stm32_rc()` 暴露 | 故障通道分离 |
### 2.7 状态码与失败计数观测
| 用例 | 断言 |
|---|---|
-| **TC-AI-060** | init 后未取帧 → `RC_NOT_RUN(-3)` |
-| **TC-AI-061** | init 后各计数 = 0 |
-| **TC-AI-062** | 一次成功后 `rc == OK` 且 `errs` 不变 |
-| **TC-AI-063** | 连续两拍无新帧 → `errs == 1`(单拍伪影不计) |
-| **TC-AI-064** | `rc` = **最近一次**(`RC_STALL`) |
-| **TC-AI-065** | 恢复成功后 `rc == OK` |
-| **TC-AI-066** | `errs` **单调不回退**(不因成功回落) |
-| **TC-AI-067** | `seq` 只由 DMA 完成回调推进(消费动作不改它) |
+| **TC-ADCIN-060** | init 后未取帧 → `RC_NOT_RUN(-3)` |
+| **TC-ADCIN-061** | init 后各计数 = 0 |
+| **TC-ADCIN-062** | 一次成功后 `rc == OK` 且 `errs` 不变 |
+| **TC-ADCIN-063** | 连续两拍无新帧 → `errs == 1`(单拍伪影不计) |
+| **TC-ADCIN-064** | `rc` = **最近一次**(`RC_STALL`) |
+| **TC-ADCIN-065** | 恢复成功后 `rc == OK` |
+| **TC-ADCIN-066** | `errs` **单调不回退**(不因成功回落) |
+| **TC-ADCIN-067** | `seq` 只由 DMA 完成回调推进(消费动作不改它) |
**当前结果**:**101/101 PASSED**(`failed=0`)。
diff --git a/docs/测试说明/GD5F2GQ5UE_Test_Guide.md b/docs/测试说明/GD5F2GQ5UE_Test_Guide.md
index 81b3132c..7a566160 100644
--- a/docs/测试说明/GD5F2GQ5UE_Test_Guide.md
+++ b/docs/测试说明/GD5F2GQ5UE_Test_Guide.md
@@ -526,7 +526,7 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10`
> - 健康满容量 = **96064 pages(187 MB)**(`No valid map found, creating fresh` 分支下的满值)。
> - 容量随 dhara 计到的坏块数递减,且该计数**持久化在 journal checkpoint 头里**
> (`journal.c` `hdr_set_bb_current/bb_last`);`dhara_journal_clear()` 只做
-> `bb_last = bb_current`(**不归零**)——所以 `nand_ftl_format()`(TC-STO-04 普通恢复)
+> `bb_last = bb_current`(**不归零**)——所以 `nand_ftl_format()`(TC-STORAGE-04 普通恢复)
> **清不掉被扣掉的容量**,断电重扫也一样。
> - 恢复满容量:启用 `ENABLE_STORAGE_RECOVERY_TESTS` **并叠加** `STORAGE_RECOVERY_FULL_WIPE`
> 跑一次 STORAGE 套件(擦净 dhara 可见区 2044 块 + 重建 BBT),随后断电重启——
@@ -643,7 +643,7 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10`
> 本套件独立于 GD5F 驱动套件,由 `test_config.h` 的 `TEST_SUITE_STORAGE` 选择,
> 入口 `storage_test_run()`(`test/board/storage_test_task.c`),统一在 `ch395fTestTask` 中调度。
> 当前 `storage_test_run()` 已覆盖 mkfs/mount/文件写读/性能(与阶段 9 FatFs 同类路径),
-> 并新增下列三项**集成测试**(TC-STO-01~03),覆盖 FTL journal 掉电恢复、大文件/随机访问、坏块注入下的存储可用性。
+> 并新增下列三项**集成测试**(TC-STORAGE-01~03),覆盖 FTL journal 掉电恢复、大文件/随机访问、坏块注入下的存储可用性。
> 三项均已于 STORAGE 套件实测通过(`=== Storage Tests: 11/11 PASSED (failed=0) ===`)。
>
> **已知陷阱(已修复)**:FTL 页缓存用 `s_cached_lpn = 0` 表示"缓存未加载",但 LPN 0 是合法页(FAT 引导扇区所在页)。
@@ -651,11 +651,11 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10`
> 引导扇区签名变成 `0000`,FatFs 报 `FR_NO_FILESYSTEM`。正常启动因 `f_mkfs` 兜底分支掩盖了此问题(第二次挂载才真正读盘)。
> 修复:将"缓存空"哨兵改为非法值 `(dhara_sector_t)-1`(0xFFFFFFFF,远超实际容量),涉及 `disk_initialize` / `nand_ftl_deinit` / `nand_ftl_format`。
-### TC-STO-01: FTL 掉电恢复(journal 持久化)
+### TC-STORAGE-01: FTL 掉电恢复(journal 持久化)
| 字段 | 值 |
|------|-----|
-| **ID** | TC-STO-01 |
+| **ID** | TC-STORAGE-01 |
| **优先级** | P1 |
| **类型** | 集成/可靠性测试 |
| **标题** | 写入文件并同步后,可经 `dhara_map_resume` 恢复映射,文件不丢 |
@@ -666,11 +666,11 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10`
| **依赖** | `nand_ftl_deinit()`(清 `s_initialized`/`s_cached_lpn`,使下次 init 真正重新 resume) |
| **实测** | PASS(STORAGE 套件:resume 后 `pl.dat` 内容逐字节一致;修复 `s_cached_lpn` 哨兵 bug 后通过) |
-### TC-STO-02: 大文件 / 多扇区 / 随机 seek
+### TC-STORAGE-02: 大文件 / 多扇区 / 随机 seek
| 字段 | 值 |
|------|-----|
-| **ID** | TC-STO-02 |
+| **ID** | TC-STORAGE-02 |
| **优先级** | P1 |
| **类型** | 功能/压力测试 |
| **标题** | 256KB 文件顺序写读 + 随机偏移 seek 读一致性 |
@@ -680,25 +680,25 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10`
| **覆盖原则** | FTL 大范围 LBA 映射 / 垃圾回收 / FatFs `f_lseek` + `f_read` |
| **实测** | PASS(STORAGE 套件:256KB 顺序 + 随机 seek 读回一致) |
-### TC-STO-03: 坏块注入下存储写入
+### TC-STORAGE-03: 坏块注入下存储写入
| 字段 | 值 |
|------|-----|
-| **ID** | TC-STO-03 |
+| **ID** | TC-STORAGE-03 |
| **优先级** | P1 |
| **类型** | 负向/健壮性测试 |
| **标题** | 运行时注入坏块后,FatFS 仍可正常写读且坏块未被占用 |
| **前置条件** | `gd5f2gq5ue_init()` 成功;FTL 已复位 |
| **测试步骤** | 1. `nand_ftl_format()` 清空旧 map → 选若干出厂好块 `gd5f2gq5ue_mark_block_bad()` 注入(更新并持久化 BBT)
2. `nand_ftl_deinit()` + `nand_ftl_init()` 使 dhara 经 `is_block_bad` 看到新坏块
3. `f_mkfs` 重建文件系统 → 正常文件写读 `bbt.dat` 并校验
4. 校验注入坏块仍 `gd5f2gq5ue_is_block_bad()==1` |
| **通过标准** | 文件内容完整;注入坏块未被 dhara 分配使用(仍报告坏),存储可用 |
-| **注意事项** | 本例会**永久**将若干好块标记为坏并持久化(测试设备专用);如需恢复,运行 TC-STO-04(启用 `ENABLE_STORAGE_RECOVERY_TESTS` 编译 STORAGE 套件一次)即可重建 BBT + 重新格式化 |
+| **注意事项** | 本例会**永久**将若干好块标记为坏并持久化(测试设备专用);如需恢复,运行 TC-STORAGE-04(启用 `ENABLE_STORAGE_RECOVERY_TESTS` 编译 STORAGE 套件一次)即可重建 BBT + 重新格式化 |
| **实测** | PASS(STORAGE 套件:注入 3 坏块后文件完整且坏块仍报告坏) |
-### TC-STO-04: 重建 BBT + 重新格式化(恢复)
+### TC-STORAGE-04: 重建 BBT + 重新格式化(恢复)
| 字段 | 值 |
|------|-----|
-| **ID** | TC-STO-04 |
+| **ID** | TC-STORAGE-04 |
| **优先级** | P1 |
| **类型** | 恢复/清理测试 |
| **标题** | 重建 BBT(重新扫描出厂坏块并持久化)并清空 dhara map,恢复设备干净态 |
@@ -753,22 +753,22 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10`
| TC-GD5F-1002 | size=0 | P2 | PASS |
| TC-GD5F-1003 | 未擦除写入 | P0 | PASS |
| TC-GD5F-1004 | 写保护解除 | P1 | PASS |
-| TC-STO-01 | FTL 掉电恢复(journal) | P1 | PASS |
-| TC-STO-02 | 大文件/随机 seek | P1 | PASS |
-| TC-STO-03 | 坏块注入下存储写入 | P1 | PASS |
-| TC-STO-04 | BBT 重建 + 重新格式化(恢复) | P1 | 受 `ENABLE_STORAGE_RECOVERY_TESTS` 控制(默认关) |
+| TC-STORAGE-01 | FTL 掉电恢复(journal) | P1 | PASS |
+| TC-STORAGE-02 | 大文件/随机 seek | P1 | PASS |
+| TC-STORAGE-03 | 坏块注入下存储写入 | P1 | PASS |
+| TC-STORAGE-04 | BBT 重建 + 重新格式化(恢复) | P1 | 受 `ENABLE_STORAGE_RECOVERY_TESTS` 控制(默认关) |
> 当前实测(2026-09-21,`ENABLE_DESTRUCTIVE_TESTS` 关闭 / 打开两种配置):
> 只读模式 `=== GD5F2GQ5UE Tests: 16/16 PASSED (failed=0) ===`(PHASE1/2/7 的 TC-704/10,无任何写操作,
> 卷内容与容量均不变);破坏性模式 `=== GD5F2GQ5UE Tests: 68/68 PASSED (failed=0) ===`(全部阶段)。
-> `TEST_SUITE_STORAGE` 只读模式实测 `=== Storage Tests: 3/3 PASSED (failed=0) ===`(mount + TC-STO-05,
-> 卷内容与容量不变);破坏性模式为全量集成用例(2026-09-20 实测 **20/20 PASSED**,含 TC-STO-01/02/03/05/06)。
+> `TEST_SUITE_STORAGE` 只读模式实测 `=== Storage Tests: 3/3 PASSED (failed=0) ===`(mount + TC-STORAGE-05,
+> 卷内容与容量不变);破坏性模式为全量集成用例(2026-09-20 实测 **20/20 PASSED**,含 TC-STORAGE-01/02/03/05/06)。
> 各套件在两种模式下均 0 错误 0 警告通过 MDK 编译。
>
> **破坏性用例清单**(仅在 `ENABLE_DESTRUCTIVE_TESTS` 打开时编译运行):
> GD5F:TC-GD5F-206/207、301~305、401~404、501~502、601~605、701~703、705、801~802、901、1003~1004
-> (TC-GD5F-704 为**只读**,两次运行都跑);存储:TC-STO-01、02、03、06 与内建文件系统写读/
-> 性能压测(TC-STO-05 为只读,始终运行);RTC:TC-RTC-002(写时间,跑完复原)、014(写 SRAM)、015(写报警)。
+> (TC-GD5F-704 为**只读**,两次运行都跑);存储:TC-STORAGE-01、02、03、06 与内建文件系统写读/
+> 性能压测(TC-STORAGE-05 为只读,始终运行);RTC:TC-RTC-002(写时间,跑完复原)、014(写 SRAM)、015(写报警)。
---
@@ -798,9 +798,9 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10`
| `gd5f_check_ecc` | TC-GD5F-501/502 |
| `nand_ftl_init` | TC-GD5F-801 |
| `nand_ftl_format` | TC-GD5F-802 |
-| `nand_ftl_deinit` | TC-STO-01 / TC-STO-03 |
-| `gd5f2gq5ue_bbt_rebuild` | TC-STO-04 |
-| `storage_test_run`(存储套件) | TC-STO-01/02/03/04 |
+| `nand_ftl_deinit` | TC-STORAGE-01 / TC-STORAGE-03 |
+| `gd5f2gq5ue_bbt_rebuild` | TC-STORAGE-04 |
+| `storage_test_run`(存储套件) | TC-STORAGE-01/02/03/04 |
---
diff --git a/docs/测试说明/卷锁单元测试说明.md b/docs/测试说明/卷锁单元测试说明.md
index ac3797a8..727bafcd 100644
--- a/docs/测试说明/卷锁单元测试说明.md
+++ b/docs/测试说明/卷锁单元测试说明.md
@@ -63,7 +63,7 @@ test/host/vol_lock/vol_lock_test.c
| **未创建 + 创建失败** | **`1`** | **否(零阻塞)** | **照常进入临界区**(无保护),事后 `release` 判空静默 |
即:**返回 1 = "你可以往下走"**,其代价是"可能没有真正持锁"。这保证了喂狗点在任何情况下
-都不会被锁阻塞。`TC-VL-008`(返回 1)与 `TC-VL-008b`(`osMutexWait` 调用次数 == 0)
+都不会被锁阻塞。`TC-VOLLOCK-008`(返回 1)与 `TC-VOLLOCK-008b`(`osMutexWait` 调用次数 == 0)
两条断言共同钉死该语义——只断言返回 1 是不够的,必须同时证明**没有进入任何等待路径**。
> `vol_lock_init()` 的返回值与 `wait()` 的语义**无关**:`init` 失败返回 `-1`,但
@@ -112,32 +112,32 @@ test/host/vol_lock/vol_lock_test.c
| 用例 | 断言 |
|---|---|
-| **TC-VL-001** | 首次调用返回 `0`;`osMutexNew` 恰好调用 1 次;模块静态态已持有句柄 |
-| **TC-VL-002** | 重复调用仍返回 `0`(幂等);**不再**创建第二个互斥量(`osMutexNew` 仍为 1 次) |
-| **TC-VL-003** | `osMutexNew` 返回 `NULL` 时 `init` 返回 `-1`;**不留下半初始化句柄**(`s_lock == NULL`) |
-| **TC-VL-004** | 失败后重试可成功(返回 `0`);重试确实**再次**调用了 `osMutexNew` |
+| **TC-VOLLOCK-001** | 首次调用返回 `0`;`osMutexNew` 恰好调用 1 次;模块静态态已持有句柄 |
+| **TC-VOLLOCK-002** | 重复调用仍返回 `0`(幂等);**不再**创建第二个互斥量(`osMutexNew` 仍为 1 次) |
+| **TC-VOLLOCK-003** | `osMutexNew` 返回 `NULL` 时 `init` 返回 `-1`;**不留下半初始化句柄**(`s_lock == NULL`) |
+| **TC-VOLLOCK-004** | 失败后重试可成功(返回 `0`);重试确实**再次**调用了 `osMutexNew` |
### 2.2 `vol_lock_wait` — 获取与 fail-open ⭐
| 用例 | 断言 |
|---|---|
-| **TC-VL-005** | 获取成功返回 `1`;`osMutexWait` 调用 1 次;**`timeout` 原样透传**(100 → 100) |
-| **TC-VL-014** | `wait(0)` 的 try 语义:返回 `1` 且透传值为 `0`(defaultTask 路径) |
-| **TC-VL-006** | `osMutexWait` 返回非 `osOK` → `wait` 返回 `0`;超时路径确实尝试过等待 |
-| **TC-VL-007** | 锁未创建时 `wait` **自动 `init`** 并正常获取(创建 1 次 + 等待 1 次) |
-| **TC-VL-008** ⭐ | **fail-open**:锁未创建且创建失败 → 返回 **`1`**;**`osMutexWait` 调用次数 == 0**(零阻塞);`s_lock` 仍为 `NULL` |
-| **TC-VL-009** | fail-open 之后 `release` 无害:`osMutexRelease` **未被调用**(判空静默返回) |
-| **TC-VL-010** | 已创建时多次 `wait` **不重复创建**(`osMutexNew` 恒 1 次);每次 `wait` 各等待一次 |
+| **TC-VOLLOCK-005** | 获取成功返回 `1`;`osMutexWait` 调用 1 次;**`timeout` 原样透传**(100 → 100) |
+| **TC-VOLLOCK-014** | `wait(0)` 的 try 语义:返回 `1` 且透传值为 `0`(defaultTask 路径) |
+| **TC-VOLLOCK-006** | `osMutexWait` 返回非 `osOK` → `wait` 返回 `0`;超时路径确实尝试过等待 |
+| **TC-VOLLOCK-007** | 锁未创建时 `wait` **自动 `init`** 并正常获取(创建 1 次 + 等待 1 次) |
+| **TC-VOLLOCK-008** ⭐ | **fail-open**:锁未创建且创建失败 → 返回 **`1`**;**`osMutexWait` 调用次数 == 0**(零阻塞);`s_lock` 仍为 `NULL` |
+| **TC-VOLLOCK-009** | fail-open 之后 `release` 无害:`osMutexRelease` **未被调用**(判空静默返回) |
+| **TC-VOLLOCK-010** | 已创建时多次 `wait` **不重复创建**(`osMutexNew` 恒 1 次);每次 `wait` 各等待一次 |
-> **TC-VL-008 是本套件存在的主要理由**:真机上需堆耗尽才可能触发,板端无法构造。
+> **TC-VOLLOCK-008 是本套件存在的主要理由**:真机上需堆耗尽才可能触发,板端无法构造。
### 2.3 `vol_lock_release` — 释放与判空
| 用例 | 断言 |
|---|---|
-| **TC-VL-011** | 已持锁时 `release` 调用 `osMutexRelease` **一次** |
-| **TC-VL-012** | 锁未创建时 `release` **静默返回**(不调用、不崩溃) |
-| **TC-VL-013** | 完整周期 `init → wait → release → wait → release`:全程只创建 **1** 个互斥量、释放 **2** 次、第二次 `wait` 的 `timeout` 透传正确(100) |
+| **TC-VOLLOCK-011** | 已持锁时 `release` 调用 `osMutexRelease` **一次** |
+| **TC-VOLLOCK-012** | 锁未创建时 `release` **静默返回**(不调用、不崩溃) |
+| **TC-VOLLOCK-013** | 完整周期 `init → wait → release → wait → release`:全程只创建 **1** 个互斥量、释放 **2** 次、第二次 `wait` 的 `timeout` 透传正确(100) |
**当前结果**:33/33 PASSED(`failed=0`)。
diff --git a/docs/测试说明/存储维护与容量恢复.md b/docs/测试说明/存储维护与容量恢复.md
index e31d6d94..66b1b7f6 100644
--- a/docs/测试说明/存储维护与容量恢复.md
+++ b/docs/测试说明/存储维护与容量恢复.md
@@ -36,12 +36,12 @@
5. 确认日志:
```
- === Storage Test: TC-STO-04 maintenance (recovery / full wipe) ===
- [PASS] TC-STO-04 bbt rebuild
+ === Storage Test: TC-STORAGE-04 maintenance (recovery / full wipe) ===
+ [PASS] TC-STORAGE-04 bbt rebuild
wipe progress: ... 2044/2044
wiped 2044 blocks (N skipped as bad, 2044 visible)
- [PASS] TC-STO-04 full wipe (2044 blocks erased)
- [PASS] TC-STO-04 persisted BBT version=N
+ [PASS] TC-STORAGE-04 full wipe (2044 blocks erased)
+ [PASS] TC-STORAGE-04 persisted BBT version=N
=== Storage Recovery: 3/3 PASSED (failed=0) ===
```
diff --git a/docs/测试说明/实机测试实施指南.md b/docs/测试说明/实机测试实施指南.md
index 63ba82e6..fd07c083 100644
--- a/docs/测试说明/实机测试实施指南.md
+++ b/docs/测试说明/实机测试实施指南.md
@@ -329,7 +329,7 @@ cppcheck --enable=warning --error-exitcode=1 test/ 2>&1 | tee test_cppcheck_base
**结论(✅ 已闭环,2026-10-03)**:`scripts/check_test_traceability.py` 已落地并跑通,
**默认仅告警(exit 0)、不阻断提交**。当前输出 **30 处差异**(26 处"文档有、代码无" +
-4 处"代码有、文档无":`TC-GD5F-1100/1101/1102`、`TC-STO-06`)。差异清单已收敛为
+4 处"代码有、文档无":`TC-GD5F-1100/1101/1102`、`TC-STORAGE-06`)。差异清单已收敛为
可追踪项,后续按需补登记;**暂不升门禁**(与 §8.2 目标一致)。
### 8.3 待核实项:`TEST_SUITE_SELECTED` 未含 `TEST_SUITE_RTC` · ✅ 已核实(非缺陷)
diff --git a/docs/测试说明/时间同步单元测试说明.md b/docs/测试说明/时间同步单元测试说明.md
index 46b030df..b567bd0d 100644
--- a/docs/测试说明/时间同步单元测试说明.md
+++ b/docs/测试说明/时间同步单元测试说明.md
@@ -127,52 +127,52 @@ test/host/time_sync/time_sync_test.c
> 命名 `TC-TS-NNN`(TS = Time Sync)。断言数(80)多于用例数(27),因为每个用例通常
> 包含 2~9 条子断言(后缀 `b` / `c` …)。桩状态在每用例前由 `fakes_reset()` 复位。
-### 2.1 `time_sync_delay_fed` — 分片喂心跳延时(TC-TS-001..006)
+### 2.1 `time_sync_delay_fed` — 分片喂心跳延时(TC-TIMESYNC-001..006)
| 用例 | 断言 |
|---|---|
-| **TC-TS-001** | `delay_fed(0)` 既不睡眠也不喂狗(零开销快路径) |
-| **TC-TS-002** | 恰好一片(50ms):1 次 `vTaskDelay(50)` + 1 次心跳 |
-| **TC-TS-003** | 非整片(120ms)切成 **50 / 50 / 20** 三片,每片喂一次心跳 |
-| **TC-TS-004** | 长延时(2000ms)= **40 片 × 50ms**,每片喂心跳(监听退避路径) |
-| **TC-TS-005** | 不足一片(49ms)单片处理,**不**被拆成 0 |
-| **TC-TS-006** | 总预算 30s = **600 片**,片长上限**恒** 50ms |
+| **TC-TIMESYNC-001** | `delay_fed(0)` 既不睡眠也不喂狗(零开销快路径) |
+| **TC-TIMESYNC-002** | 恰好一片(50ms):1 次 `vTaskDelay(50)` + 1 次心跳 |
+| **TC-TIMESYNC-003** | 非整片(120ms)切成 **50 / 50 / 20** 三片,每片喂一次心跳 |
+| **TC-TIMESYNC-004** | 长延时(2000ms)= **40 片 × 50ms**,每片喂心跳(监听退避路径) |
+| **TC-TIMESYNC-005** | 不足一片(49ms)单片处理,**不**被拆成 0 |
+| **TC-TIMESYNC-006** | 总预算 30s = **600 片**,片长上限**恒** 50ms |
-### 2.2 `time_sync_open_listener` — 监听建立与退避(TC-TS-010..015)
+### 2.2 `time_sync_open_listener` — 监听建立与退避(TC-TIMESYNC-010..015)
| 用例 | 断言 |
|---|---|
-| **TC-TS-010** | 首次成功:`socket` / `bind` / `listen` 各 1 次;端口经 `net_htons(8888)`;`sin_family` = `NET_AF_INET`;成功路径**无退避延时** |
-| **TC-TS-011** | `bind` 失败 → **关闭该 socket** + 退避 2000ms(40 片)+ 留痕 `DBG_ERROR`,随后重试成功 |
-| **TC-TS-012** | `listen` 失败 → 关闭该 socket + 退避 2000ms,随后重试成功 |
-| **TC-TS-013** | `socket` 连续失败 → **5 次后返回 -1**;5 条 `DBG_ERROR`;5 × 500ms 退避(50 片) |
-| **TC-TS-014** | 第 3 次重试成功并返回**新**描述符;恰好尝试 3 次;两次失败退避 500ms × 2 |
-| **TC-TS-015** | 心跳总次数 = 每轮重试(5)+ 每片延时(50);**心跳位恒为 `TASK_WD_TIMESYNC`** |
+| **TC-TIMESYNC-010** | 首次成功:`socket` / `bind` / `listen` 各 1 次;端口经 `net_htons(8888)`;`sin_family` = `NET_AF_INET`;成功路径**无退避延时** |
+| **TC-TIMESYNC-011** | `bind` 失败 → **关闭该 socket** + 退避 2000ms(40 片)+ 留痕 `DBG_ERROR`,随后重试成功 |
+| **TC-TIMESYNC-012** | `listen` 失败 → 关闭该 socket + 退避 2000ms,随后重试成功 |
+| **TC-TIMESYNC-013** | `socket` 连续失败 → **5 次后返回 -1**;5 条 `DBG_ERROR`;5 × 500ms 退避(50 片) |
+| **TC-TIMESYNC-014** | 第 3 次重试成功并返回**新**描述符;恰好尝试 3 次;两次失败退避 500ms × 2 |
+| **TC-TIMESYNC-015** | 心跳总次数 = 每轮重试(5)+ 每片延时(50);**心跳位恒为 `TASK_WD_TIMESYNC`** |
-### 2.3 `time_sync_handle_conn` — 时间包重组状态机(TC-TS-020..029)
+### 2.3 `time_sync_handle_conn` — 时间包重组状态机(TC-TIMESYNC-020..029)
| 用例 | 断言 |
|---|---|
-| **TC-TS-020** | 8 字节一次收齐 → **大端**解析 epoch + 更新墙钟 1 次 + 关连接;首次请求 16 字节;单次等待片长 = 50ms;留痕 `wall clock updated` |
-| **TC-TS-021** | 分段送达(4+4)→ 累积后解析正确;读了两次;第二次**只请求剩余 12 字节**;每片 50ms |
-| **TC-TS-022** | 一次到达 16 字节 → **只取前 8 字节**;一次读够即停 |
-| **TC-TS-023** | 前缀非 `"TIME"` → **不更新墙钟**,但仍关闭连接 |
-| **TC-TS-024** | 对端关闭(`n == 0`)→ 立即退出、不解析;关闭连接 |
-| **TC-TS-025** | 真错误(`n == -1`)→ 立即退出、不解析 |
-| **TC-TS-026** | 只收到 4 字节后 EOF → **不足 8 字节不解析**;期间继续等待后续字节 |
-| **TC-TS-027** | 30s 预算耗尽 → 不再读(只读 1 次)+ 留痕 `no TIME packet in 30s, drop conn` + 关连接 |
-| **TC-TS-028** | 剩余预算不足一片 → **末片按剩余(20ms)切分** |
-| **TC-TS-029** | **32 位 tick 回绕** → 预算计算仍正确(无符号减法) |
+| **TC-TIMESYNC-020** | 8 字节一次收齐 → **大端**解析 epoch + 更新墙钟 1 次 + 关连接;首次请求 16 字节;单次等待片长 = 50ms;留痕 `wall clock updated` |
+| **TC-TIMESYNC-021** | 分段送达(4+4)→ 累积后解析正确;读了两次;第二次**只请求剩余 12 字节**;每片 50ms |
+| **TC-TIMESYNC-022** | 一次到达 16 字节 → **只取前 8 字节**;一次读够即停 |
+| **TC-TIMESYNC-023** | 前缀非 `"TIME"` → **不更新墙钟**,但仍关闭连接 |
+| **TC-TIMESYNC-024** | 对端关闭(`n == 0`)→ 立即退出、不解析;关闭连接 |
+| **TC-TIMESYNC-025** | 真错误(`n == -1`)→ 立即退出、不解析 |
+| **TC-TIMESYNC-026** | 只收到 4 字节后 EOF → **不足 8 字节不解析**;期间继续等待后续字节 |
+| **TC-TIMESYNC-027** | 30s 预算耗尽 → 不再读(只读 1 次)+ 留痕 `no TIME packet in 30s, drop conn` + 关连接 |
+| **TC-TIMESYNC-028** | 剩余预算不足一片 → **末片按剩余(20ms)切分** |
+| **TC-TIMESYNC-029** | **32 位 tick 回绕** → 预算计算仍正确(无符号减法) |
-### 2.4 `time_sync_task` — 任务主循环(TC-TS-040..044)
+### 2.4 `time_sync_task` — 任务主循环(TC-TIMESYNC-040..044)
| 用例 | 断言 |
|---|---|
-| **TC-TS-040** | `sys_evtHandle == NULL` → **跳过就绪屏障**;`accept` 轮询 3 次(2 次无连接 + 1 次成功);收到时间包并更新墙钟;延时片数 = 4+4+1(200+200+50ms)且**全部按 50ms 分片**;心跳次数 = 主循环 1 + 退避 8 + 收连接 1 + 收尾 1 + 次轮 1 = **13**;所有心跳均打 `TASK_WD_TIMESYNC` 位 |
-| **TC-TS-041** | 就绪屏障轮询 3 次(2 次未就绪 + 1 次就绪);屏障等待按 **100ms 分片**;等待 `SYS_EVT_NET_READY` 位;`osFlagsWaitAny \| osFlagsNoClear`(**就绪位不被消费**);未就绪的两次各喂一次心跳;仍先 `task_wd_bind` 登记心跳路由 |
-| **TC-TS-042** | 屏障等待 4 次均未就绪 → **循环未挂死**(跳出并继续);每次未就绪后各喂一次心跳(2026-10-02 台架根因的**回归防线**) |
-| **TC-TS-043** | 网络代次变化 → **关闭旧监听**并重监听;留痕 `network re-init, relisten`(另含 2 条 listen 成功);每次循环只轮询一次 `accept` 即放弃 |
-| **TC-TS-044** | 监听建立失败 → 内部重试 5 次后放弃;6 条 `DBG_ERROR`(5 条 `net_socket FAIL` + 1 条 `retry later`);退避 5×500ms + 2000ms = **90 片**;心跳次数 = 2 + 5 + 50 + 40 = **97**;所有心跳均打 `TIMESYNC` 位 |
+| **TC-TIMESYNC-040** | `sys_evtHandle == NULL` → **跳过就绪屏障**;`accept` 轮询 3 次(2 次无连接 + 1 次成功);收到时间包并更新墙钟;延时片数 = 4+4+1(200+200+50ms)且**全部按 50ms 分片**;心跳次数 = 主循环 1 + 退避 8 + 收连接 1 + 收尾 1 + 次轮 1 = **13**;所有心跳均打 `TASK_WD_TIMESYNC` 位 |
+| **TC-TIMESYNC-041** | 就绪屏障轮询 3 次(2 次未就绪 + 1 次就绪);屏障等待按 **100ms 分片**;等待 `SYS_EVT_NET_READY` 位;`osFlagsWaitAny \| osFlagsNoClear`(**就绪位不被消费**);未就绪的两次各喂一次心跳;仍先 `task_wd_bind` 登记心跳路由 |
+| **TC-TIMESYNC-042** | 屏障等待 4 次均未就绪 → **循环未挂死**(跳出并继续);每次未就绪后各喂一次心跳(2026-10-02 台架根因的**回归防线**) |
+| **TC-TIMESYNC-043** | 网络代次变化 → **关闭旧监听**并重监听;留痕 `network re-init, relisten`(另含 2 条 listen 成功);每次循环只轮询一次 `accept` 即放弃 |
+| **TC-TIMESYNC-044** | 监听建立失败 → 内部重试 5 次后放弃;6 条 `DBG_ERROR`(5 条 `net_socket FAIL` + 1 条 `retry later`);退避 5×500ms + 2000ms = **90 片**;心跳次数 = 2 + 5 + 50 + 40 = **97**;所有心跳均打 `TIMESYNC` 位 |
**当前结果**:80/80 PASSED(`failed=0`)。
@@ -200,7 +200,7 @@ test/host/time_sync/time_sync_test.c
**取舍**:这比"把循环体抽成可测函数"更贴近真实——**测的就是任务主体本身**,
不需要为了可测性改动生产代码结构。代价是**必须精确设定跳出点**:跳出点设错
-(多一次或少一次桩调用)会导致断言数不符,`TC-TS-040` 的跳出点曾因此修正。
+(多一次或少一次桩调用)会导致断言数不符,`TC-TIMESYNC-040` 的跳出点曾因此修正。
### 4.2 ⚠ C 的"暂定定义"会静默合并同名静态量
diff --git a/docs/测试说明/测试开发标准流程.md b/docs/测试说明/测试开发标准流程.md
index 31fc09b2..fca9c53b 100644
--- a/docs/测试说明/测试开发标准流程.md
+++ b/docs/测试说明/测试开发标准流程.md
@@ -66,7 +66,7 @@ G0~G3 命令详见 §6 / §7;ui-verify 完整命令见 `UI_自动化测试流
| 对象 | 格式 | 现用示例 |
|---|---|---|
| 阶段 | `TM-{MOD}-{NN}` | TM-PHY-01 |
-| 测试用例 | `TC-{MOD}-{NNN}` | `TC-NET-601`(CH395F)、`TC-GD5F-205`、`TC-STO-03`、`TC-RTC-002` |
+| 测试用例 | `TC-{MOD}-{NNN}` | `TC-NET-601`(CH395F)、`TC-GD5F-205`、`TC-STORAGE-03`、`TC-RTC-002` |
| 设计原则 | `DP-{NN}` | DP-01(单连接 socket) |
模块缩写 `{MOD}` 在新模块测试文档立文档时确定(2~4 个大写字母);现有:`NET`=CH395F 网络、`GD5F`、`STO`=存储、`RTC`、`ADC`、`RS485`。
@@ -101,7 +101,7 @@ flowchart TD
| 套件 | 宏 | 文件 | 阶段组织 | 备注 |
|---|---|---|---|---|
| CH395F | `TEST_SUITE_CH395F` | `ch395f_test.h/.c` + `net_test_task.c` | 硬件层 1~5 / NET 层 6~11 | 两层互斥(`#error`);阶段 2/3/4/5 与 6/7/8/10/11 需 PC 端配合 |
-| STORAGE | `TEST_SUITE_STORAGE` | `storage_test.h` + `storage_test_task.c` | FTL + FatFS 集成(TC-STO-01~04) | 恢复测试(重建 BBT)默认关闭 |
+| STORAGE | `TEST_SUITE_STORAGE` | `storage_test.h` + `storage_test_task.c` | FTL + FatFS 集成(TC-STORAGE-01~04) | 恢复测试(重建 BBT)默认关闭 |
| GD5F | `TEST_SUITE_GD5F` | `gd5f_test.h` + `gd5f_test_task.c` | 10 阶段(选中时自动全开) | NAND 驱动全覆盖 |
| RTC | `TEST_SUITE_RTC` | `sd2506_test.h` + `sd2506_test_task.c` | 阶段 1 基本 / 阶段 2 API(默认全开) | SD2506 RTC |
@@ -598,7 +598,7 @@ CI 就静默停摆(2026-10-11 实测 run 16~21 共 12 个 job 零日志)。
| `test_common.h` | **板端测试公共断言内核**(`test_stats_t` + `TEST_CHECK_IMPL`/`TEST_REPORT_IMPL`) |
| `ch395f_test.h` / `ch395f_test_task.c` | CH395F 套件:阶段开关、断言宏、Phase 1~5 实现 |
| `net_test_task.h` / `net_test_task.c` | CH395F 套件 NET 层(6~11):TCP 监听循环 / Client 主动连接测试 |
-| `storage_test.h` / `storage_test_task.c` | STORAGE 套件:FTL + FatFS 集成(TC-STO-01~04)+ 恢复测试 |
+| `storage_test.h` / `storage_test_task.c` | STORAGE 套件:FTL + FatFS 集成(TC-STORAGE-01~04)+ 恢复测试 |
| `gd5f_test.h` / `gd5f_test_task.c` | GD5F 套件:NAND 驱动 10 阶段 |
| `sd2506_test.h` / `sd2506_test_task.c` | RTC 套件:SD2506 RTC 2 阶段组 |
| `run_boot_test.py` / `verify_log.py` + `serial_tool` | 自动化闭环三件套(纯 Python 标准库 / 仓库内置) |
diff --git a/docs/测试说明/测试文档模板规范.md b/docs/测试说明/测试文档模板规范.md
index 2282de70..38786f20 100644
--- a/docs/测试说明/测试文档模板规范.md
+++ b/docs/测试说明/测试文档模板规范.md
@@ -157,7 +157,7 @@ TC-{MOD}-{NNN}
```
- **分阶段套件**:序号**百位放阶段号**,编号即自文档化——`TC-NET-101` = CH395F Phase 1 第 1 项、`TC-NET-601` = Phase 6 第 1 项、`TC-NET-1101` = Phase 11 第 1 项;
-- **无阶段划分套件**:全局顺序编号(如 `TC-STO-03`、`TC-RTC-001`);
+- **无阶段划分套件**:全局顺序编号(如 `TC-STORAGE-03`、`TC-RTC-001`);
- 编号不复用:废弃用例保留编号并注明"已废弃"。
### 6.4 设计原则 ID
diff --git a/docs/测试说明/相量层单元测试说明.md b/docs/测试说明/相量层单元测试说明.md
index 27b19f4c..1e14f403 100644
--- a/docs/测试说明/相量层单元测试说明.md
+++ b/docs/测试说明/相量层单元测试说明.md
@@ -50,7 +50,7 @@ test/host/phasor/phasor_test.c
- **`fAmSQ = √(fRe² + fIm²)` 直接就是有效值(RMS)**,无需再除 √2;
- `fAm = √2 · fAmSQ` 是正弦峰值。
-判据是归一化恒等式 **`Σsin² = Σcos² = 1/N`**(`TC-PH-001/002` 逐项校验,防转录错)。
+判据是归一化恒等式 **`Σsin² = Σcos² = 1/N`**(`TC-PHASOR-001/002` 逐项校验,防转录错)。
术语权威见 `docs/算法/继电保护功能复现规划.md` §10.2:
`{fRe, fIm, fAm, fAmSQ}` = 实部 / 虚部 / **幅值** / **有效值**。
@@ -100,62 +100,62 @@ test/host/phasor/phasor_test.c
| 用例 | 断言 | 设计点 |
|---|---|---|
-| **TC-PH-001** | 逐项:`sin[k] == sin(2πk/N)·(√2/N)`、`cos[k] == cos(2πk/N)·(√2/N)`(k = 0..19) | L2-1 防转录错 |
-| **TC-PH-002** | 归一化 `Σsin² == Σcos² == 1/N`;精确零点 `sin@0,10`、`cos@5,15`;`sin[5] == √2/N` | L2-1 判据基础 |
+| **TC-PHASOR-001** | 逐项:`sin[k] == sin(2πk/N)·(√2/N)`、`cos[k] == cos(2πk/N)·(√2/N)`(k = 0..19) | L2-1 防转录错 |
+| **TC-PHASOR-002** | 归一化 `Σsin² == Σcos² == 1/N`;精确零点 `sin@0,10`、`cos@5,15`;`sin[5] == √2/N` | L2-1 判据基础 |
### 2.2 L2-3 / L2-4 基波幅值 / 有效值 / 相位
| 用例 | 断言 | 设计点 |
|---|---|---|
-| **TC-PH-003** | 纯基波:`fAmSQ == A/√2`(**有效值**)、`fAm == √2·fAmSQ`(幅值),误差 ≤ 1% | L2-3 |
-| **TC-PH-004** | `atan2(fIm, fRe)` == 注入相角(6 组幅值 / 相位) | L2-4 |
+| **TC-PHASOR-003** | 纯基波:`fAmSQ == A/√2`(**有效值**)、`fAm == √2·fAmSQ`(幅值),误差 ≤ 1% | L2-3 |
+| **TC-PHASOR-004** | `atan2(fIm, fRe)` == 注入相角(6 组幅值 / 相位) | L2-4 |
### 2.3 直流与谐波抑制 / 任意次谐波提取
| 用例 | 断言 | 设计点 |
|---|---|---|
-| **TC-PH-005** | 直流 + 2 / 3 / 5 次谐波被**完全滤除**(基波读数不变,误差 ≤ 1%,5 例) | L2-1 |
-| **TC-PH-006** | 任意次谐波提取(**索引步进 = 谐波次数**):k = 1 / 2 / 5 从混合信号中提取;纯基波下 2 / 5 次分量 ≈ 0 | L2-1 / L1-9 入口 |
+| **TC-PHASOR-005** | 直流 + 2 / 3 / 5 次谐波被**完全滤除**(基波读数不变,误差 ≤ 1%,5 例) | L2-1 |
+| **TC-PHASOR-006** | 任意次谐波提取(**索引步进 = 谐波次数**):k = 1 / 2 / 5 从混合信号中提取;纯基波下 2 / 5 次分量 ≈ 0 | L2-1 / L1-9 入口 |
### 2.4 频率敏感度
| 用例 | 断言 | 设计点 |
|---|---|---|
-| **TC-PH-007** | 幅值误差:50 Hz ≤ 0.1%、±1 Hz ≤ 1.5%、±2 Hz ≤ 3%(**最坏相位**) | L2-3 / L1-7 依据 |
+| **TC-PHASOR-007** | 幅值误差:50 Hz ≤ 0.1%、±1 Hz ≤ 1.5%、±2 Hz ≤ 3%(**最坏相位**) | L2-3 / L1-7 依据 |
### 2.5 L2 输入采样环(`sample_ring.c`)
| 用例 | 断言 | 设计点 |
|---|---|---|
-| **TC-PH-010** | `init` 清填充与帧计数;未攒满取窗 → -2;入环后取窗**按时序**(老 → 新);通道之间**互相独立**;填充量饱和于 `DEPTH` 但帧计数**不**饱和;回绕后取窗 == 最后 N 个值(有序);参数守卫:`n=0` / `n>DEPTH` / 越界通道 / `NULL out` / `NULL frame` / 错帧长 均拒绝 | L2 输入 |
+| **TC-PHASOR-010** | `init` 清填充与帧计数;未攒满取窗 → -2;入环后取窗**按时序**(老 → 新);通道之间**互相独立**;填充量饱和于 `DEPTH` 但帧计数**不**饱和;回绕后取窗 == 最后 N 个值(有序);参数守卫:`n=0` / `n>DEPTH` / 越界通道 / `NULL out` / `NULL frame` / 错帧长 均拒绝 | L2 输入 |
### 2.6 L2-2 实例层
| 用例 | 断言 | 设计点 |
|---|---|---|
-| **TC-PH-020** | 实例数 == 5;实例表可取 `name`;越界实例 → `NULL`;未攒满一周波 `phasor_get()` → -2;越界 index / `NULL out` → -1;攒满 20 帧后 `get()` == 0 且实例 0 的 RMS == `A/√2`;谐波实例(`C04-IA-F2` / `C05-IA-F5`)在纯基波下 ≈ 0;**逐实例复核"实例窗 == 独立 `phasor_calc()` 结果"** | L2-2 |
+| **TC-PHASOR-020** | 实例数 == 5;实例表可取 `name`;越界实例 → `NULL`;未攒满一周波 `phasor_get()` → -2;越界 index / `NULL out` → -1;攒满 20 帧后 `get()` == 0 且实例 0 的 RMS == `A/√2`;谐波实例(`C04-IA-F2` / `C05-IA-F5`)在纯基波下 ≈ 0;**逐实例复核"实例窗 == 独立 `phasor_calc()` 结果"** | L2-2 |
### 2.7 L2-6 滑动窗
| 用例 | 断言 | 设计点 |
|---|---|---|
-| **TC-PH-021** | 连续滑动 20 拍,基波读数**恒定**(误差 ≤ 1%) | L2-6 |
+| **TC-PHASOR-021** | 连续滑动 20 拍,基波读数**恒定**(误差 ≤ 1%) | L2-6 |
### 2.8 L2-7 双区指针原子交换
| 用例 | 断言 | 设计点 |
|---|---|---|
-| **TC-PH-022** | 使用区逐次产出**交替** 0 → 1 → 0 → 1;**连测 60 拍**:每拍 `get()` == 当前环窗的独立重算(幅值每 20 拍在 100 / 10 之间切换 → 读到陈旧区会立刻不相等);扫描后结果仍可读 | L2-7 |
+| **TC-PHASOR-022** | 使用区逐次产出**交替** 0 → 1 → 0 → 1;**连测 60 拍**:每拍 `get()` == 当前环窗的独立重算(幅值每 20 拍在 100 / 10 之间切换 → 读到陈旧区会立刻不相等);扫描后结果仍可读 | L2-7 |
### 2.9 `phasor_zero` / `phasor_init` 清零与幂等
| 用例 | 断言 | 设计点 |
|---|---|---|
-| **TC-PH-030** | 直接白盒调 `phasor_zero()` → 四字段(含 `fAm` / `fAmSQ`)全清零 | 静态辅助 |
-| **TC-PH-031** | 先把双区写脏 → `phasor_init()` 后**双区全零** | init 清零 |
-| **TC-PH-032** | `phasor_init()` 后使用区复位为 0 | init 复位 |
-| **TC-PH-033** | `phasor_init()` 后就绪标志清(`phasor_get()` → -2) | init 复位 |
-| **TC-PH-034** | 重复 `phasor_init()` 幂等 | 可重复调用 |
+| **TC-PHASOR-030** | 直接白盒调 `phasor_zero()` → 四字段(含 `fAm` / `fAmSQ`)全清零 | 静态辅助 |
+| **TC-PHASOR-031** | 先把双区写脏 → `phasor_init()` 后**双区全零** | init 清零 |
+| **TC-PHASOR-032** | `phasor_init()` 后使用区复位为 0 | init 复位 |
+| **TC-PHASOR-033** | `phasor_init()` 后就绪标志清(`phasor_get()` → -2) | init 复位 |
+| **TC-PHASOR-034** | 重复 `phasor_init()` 幂等 | 可重复调用 |
**当前结果**:57/57 PASSED(`failed=0`)。
@@ -178,7 +178,7 @@ test/host/phasor/phasor_test.c
每来一个新点,`phasor_run()` 对 20 点**整体重算**(滑动窗)。迭代法(加减首尾项)会累积
浮点误差且难以保证与"整体重算"逐位一致;暴力法的代价是每拍 `N × 实例数` 次乘加 + 取模,
-在 1 ms 节拍下仍有余量。本单测的 `TC-PH-022`(每拍 `get()` == 独立重算)正是这条取舍的
+在 1 ms 节拍下仍有余量。本单测的 `TC-PHASOR-022`(每拍 `get()` == 独立重算)正是这条取舍的
**回归防线**——一旦有人改成迭代法,逐位一致性断言会立刻失败。
### 4.2 主机侧合成波形**不代表真实硬件**
diff --git a/docs/测试说明/看门狗单元测试说明.md b/docs/测试说明/看门狗单元测试说明.md
index 897d41d6..d06f5acd 100644
--- a/docs/测试说明/看门狗单元测试说明.md
+++ b/docs/测试说明/看门狗单元测试说明.md
@@ -103,21 +103,21 @@ test/host/watchdog/watchdog_test.c
| 用例 | 断言 | 验证的设计点 |
|---|---|---|
-| **TC-WD-001** | 未启动时 `poll` 不喂狗、`is_armed()==0` | 启动前不判定(`s_started` 门卫) |
-| **TC-WD-016** | 未启动时即使全员置位也不喂、不更新 `last_mask` | 同上(位图无关) |
-| **TC-WD-014** | 重复 `task_wd_start()` 只启动 IWDG 一次 | 启动幂等(IWDG 不可逆,重复启动无意义) |
-| **TC-WD-015** | `start` 内部先喂一次(`feed_count==1`) | 首个抽样窗口从启动时刻起算,避免启动即超时 |
-| **TC-WD-002** | 50 ms 内 `poll` 不喂;累计 100 ms 喂 1 次 | 100 ms 抽样节流 |
-| **TC-WD-003** | 全员置位 → 喂狗 1 次;`last_mask==0x37` | 全员到位判定 + 掩码取值 |
-| **TC-WD-004** | 不重新置位则第二轮不喂 | **取走清零**语义(旧位不残留) |
-| **TC-WD-005** | 缺 UI(bit4)→ 不喂;`last_mask` 精确记录缺失位 | 必需掩码比较 + 缺失定位 |
-| **TC-WD-006** | 连续 1..7 次缺席不报;**第 8 次**打 `[WD] task stall`;缺席期间不喂 | `WD_MISS_TOLERANCE=8`(800 ms)停喂触发点 |
-| **TC-WD-007** | 停喂后**每 100 ms 复报**一条 stall(现状行为) | 见 §4 已知行为("最后遗言"持续到复位) |
-| **TC-WD-008** | 恢复全员到位 → 立即喂狗 + `streak` 归零 | 停顿可恢复(非锁死状态机) |
-| **TC-WD-009** | 99 ms 不判 / 100 ms 判 / 再 99 ms 不判 / 累计 100 ms 判 | 节流窗口**边界**(易错点) |
-| **TC-WD-010** | `tick` 跨 2^32 回绕后 100 ms 仍正确判 | 无符号差比较(回绕安全) |
-| **TC-WD-011** | `is_armed`/`last_mask`/`miss_count` 语义 | 观测接口正确性 |
-| **TC-WD-013** | 非法任务 ID(`>= TASK_WD_ID_MAX`)被忽略,不污染位图 | 防位图越界(`task_wd_beat` 的守卫) |
+| **TC-WATCHDOG-001** | 未启动时 `poll` 不喂狗、`is_armed()==0` | 启动前不判定(`s_started` 门卫) |
+| **TC-WATCHDOG-016** | 未启动时即使全员置位也不喂、不更新 `last_mask` | 同上(位图无关) |
+| **TC-WATCHDOG-014** | 重复 `task_wd_start()` 只启动 IWDG 一次 | 启动幂等(IWDG 不可逆,重复启动无意义) |
+| **TC-WATCHDOG-015** | `start` 内部先喂一次(`feed_count==1`) | 首个抽样窗口从启动时刻起算,避免启动即超时 |
+| **TC-WATCHDOG-002** | 50 ms 内 `poll` 不喂;累计 100 ms 喂 1 次 | 100 ms 抽样节流 |
+| **TC-WATCHDOG-003** | 全员置位 → 喂狗 1 次;`last_mask==0x37` | 全员到位判定 + 掩码取值 |
+| **TC-WATCHDOG-004** | 不重新置位则第二轮不喂 | **取走清零**语义(旧位不残留) |
+| **TC-WATCHDOG-005** | 缺 UI(bit4)→ 不喂;`last_mask` 精确记录缺失位 | 必需掩码比较 + 缺失定位 |
+| **TC-WATCHDOG-006** | 连续 1..7 次缺席不报;**第 8 次**打 `[WD] task stall`;缺席期间不喂 | `WD_MISS_TOLERANCE=8`(800 ms)停喂触发点 |
+| **TC-WATCHDOG-007** | 停喂后**每 100 ms 复报**一条 stall(现状行为) | 见 §4 已知行为("最后遗言"持续到复位) |
+| **TC-WATCHDOG-008** | 恢复全员到位 → 立即喂狗 + `streak` 归零 | 停顿可恢复(非锁死状态机) |
+| **TC-WATCHDOG-009** | 99 ms 不判 / 100 ms 判 / 再 99 ms 不判 / 累计 100 ms 判 | 节流窗口**边界**(易错点) |
+| **TC-WATCHDOG-010** | `tick` 跨 2^32 回绕后 100 ms 仍正确判 | 无符号差比较(回绕安全) |
+| **TC-WATCHDOG-011** | `is_armed`/`last_mask`/`miss_count` 语义 | 观测接口正确性 |
+| **TC-WATCHDOG-013** | 非法任务 ID(`>= TASK_WD_ID_MAX`)被忽略,不污染位图 | 防位图越界(`task_wd_beat` 的守卫) |
**当前结果**:39/39 PASSED(`failed=0`)。
@@ -139,7 +139,7 @@ test/host/watchdog/watchdog_test.c
## 4. 已知行为与可优化点
-### 4.1 stall 日志在停喂后复报(TC-WD-007,现状)
+### 4.1 stall 日志在停喂后复报(TC-WATCHDOG-007,现状)
实现(`task_watchdog.c`):
@@ -153,7 +153,7 @@ if (s_miss_streak >= WD_MISS_TOLERANCE) { DBG_ERROR("[WD] task stall: ..."); }
**评估**:这是**刻意的"最后遗言"**——复位前日志窗口内信息不丢。代价是日志冗余。
若改为"每停顿周期仅报一次",需加一个 `s_stall_reported` 标志(在 `streak` 归零时清除)。
-**当前保留现状**(单测按现状断言,行为变更须同步改 TC-WD-007 与本文)。
+**当前保留现状**(单测按现状断言,行为变更须同步改 TC-WATCHDOG-007 与本文)。
### 4.2 测试隔离依赖 `task_wd_test_reset()`
diff --git a/docs/测试说明/系统时钟单元测试说明.md b/docs/测试说明/系统时钟单元测试说明.md
index 9e89cdda..d6d92bc3 100644
--- a/docs/测试说明/系统时钟单元测试说明.md
+++ b/docs/测试说明/系统时钟单元测试说明.md
@@ -105,27 +105,27 @@ test/host/sys_clock/sys_clock_test.c
| 用例 | 断言 | 验证的设计点 |
|---|---|---|
-| **TC-CLK-000** | 未初始化时 `get()==UINT32_MAX`、`get_time()==-1`、`get_str()` 输出占位串 | "未初始化"哨兵语义(**必须最先跑**) |
-| **TC-CLK-001** | RTC 合法 → `init()==0`,基准 = 换算 Unix 秒;不写回 RTC | 正常初始化路径 |
-| **TC-CLK-002** | 2024-02-29 / 2000-02-29(世纪闰)换算正确;2/29→3/1 间隔恰 86400 s | 闰年规则(含世纪闰) |
-| **TC-CLK-003** | 1/31、2/28、4/30 精确值;平年 2/28→3/1 间隔 86400 s | 月末边界 |
-| **TC-CLK-004** | 2000-01-01 换算;2038-01-19 03:14:07 → `0x7FFFFFFF`;`set(0)` → 1970-01-01 | 世纪边界 / uint32 上限 |
-| **TC-CLK-005** | RTC 读失败 → `init()==-1`,降级为编译期默认时间,打 `DBG_ERROR` | RTC 读故障降级 |
-| **TC-CLK-006** | 年/月/日越界 → 自愈写回默认时间,`init()==0` | 越界自愈(启用默认值时) |
-| **TC-CLK-020** | 越界 + 写回失败 → 降级默认时间,`init()==-1` | 组合故障降级 |
-| **TC-CLK-007** | 越界 → 写回 RTC 一次,阴影 RTC 被修正,`init()==0` | 自愈写回 + 复验 |
-| **TC-CLK-008** | 999ms 不变 / 1000ms +1s / 再 +2500ms 共 +3s | 正常推进 + 亚秒截断 |
-| **TC-CLK-009** | +29 天线性推进(未达 30 天阈值,不触发再基准化) | 阈值下不触发 |
-| **TC-CLK-010** | 30 天 + 1500ms → 值无损(+30 天 1 秒);再 +500ms 补足 1 秒 | **惰性再基准化** + 余数结转 |
-| **TC-CLK-011** | 基准近 2^32,推进跨回绕 0x2000ms → +8s | tick 回绕(无符号差)安全 |
-| **TC-CLK-012** | 10 天步进 ×9(累计 90 天,含 3 轮再基准)零漂移 | 长期运行无漂移 |
-| **TC-CLK-013** | `get_str` 格式化 + 零点补零;未初始化占位串 | 字符串接口 |
-| **TC-CLK-014** | 2026-10-02 08:09:10 → 年月日时分秒 + `week==5`(周五) | 日历字段 + 星期 |
-| **TC-CLK-015** | `get_time(NULL) == -1` | NULL 参数防御 |
-| **TC-CLK-016** | `set` 更新基准 + 写回 RTC;写失败仍更新基准 + 打错误 | set 两条路径 |
-| **TC-CLK-017** | `set(..., NULL)` 不碰 RTC | 可选 RTC 写回 |
-| **TC-CLK-018** | `set_unix` 写回 RTC,日历字段 + `week` 正确 | Unix 时间戳校时 |
-| **TC-CLK-019** | 16 个已知日期(跨 1~12 月 / 世纪闰 / 闰日 / 范围首尾)星期对照 | **Zeller 全域正确性** |
+| **TC-SYSCLK-000** | 未初始化时 `get()==UINT32_MAX`、`get_time()==-1`、`get_str()` 输出占位串 | "未初始化"哨兵语义(**必须最先跑**) |
+| **TC-SYSCLK-001** | RTC 合法 → `init()==0`,基准 = 换算 Unix 秒;不写回 RTC | 正常初始化路径 |
+| **TC-SYSCLK-002** | 2024-02-29 / 2000-02-29(世纪闰)换算正确;2/29→3/1 间隔恰 86400 s | 闰年规则(含世纪闰) |
+| **TC-SYSCLK-003** | 1/31、2/28、4/30 精确值;平年 2/28→3/1 间隔 86400 s | 月末边界 |
+| **TC-SYSCLK-004** | 2000-01-01 换算;2038-01-19 03:14:07 → `0x7FFFFFFF`;`set(0)` → 1970-01-01 | 世纪边界 / uint32 上限 |
+| **TC-SYSCLK-005** | RTC 读失败 → `init()==-1`,降级为编译期默认时间,打 `DBG_ERROR` | RTC 读故障降级 |
+| **TC-SYSCLK-006** | 年/月/日越界 → 自愈写回默认时间,`init()==0` | 越界自愈(启用默认值时) |
+| **TC-SYSCLK-020** | 越界 + 写回失败 → 降级默认时间,`init()==-1` | 组合故障降级 |
+| **TC-SYSCLK-007** | 越界 → 写回 RTC 一次,阴影 RTC 被修正,`init()==0` | 自愈写回 + 复验 |
+| **TC-SYSCLK-008** | 999ms 不变 / 1000ms +1s / 再 +2500ms 共 +3s | 正常推进 + 亚秒截断 |
+| **TC-SYSCLK-009** | +29 天线性推进(未达 30 天阈值,不触发再基准化) | 阈值下不触发 |
+| **TC-SYSCLK-010** | 30 天 + 1500ms → 值无损(+30 天 1 秒);再 +500ms 补足 1 秒 | **惰性再基准化** + 余数结转 |
+| **TC-SYSCLK-011** | 基准近 2^32,推进跨回绕 0x2000ms → +8s | tick 回绕(无符号差)安全 |
+| **TC-SYSCLK-012** | 10 天步进 ×9(累计 90 天,含 3 轮再基准)零漂移 | 长期运行无漂移 |
+| **TC-SYSCLK-013** | `get_str` 格式化 + 零点补零;未初始化占位串 | 字符串接口 |
+| **TC-SYSCLK-014** | 2026-10-02 08:09:10 → 年月日时分秒 + `week==5`(周五) | 日历字段 + 星期 |
+| **TC-SYSCLK-015** | `get_time(NULL) == -1` | NULL 参数防御 |
+| **TC-SYSCLK-016** | `set` 更新基准 + 写回 RTC;写失败仍更新基准 + 打错误 | set 两条路径 |
+| **TC-SYSCLK-017** | `set(..., NULL)` 不碰 RTC | 可选 RTC 写回 |
+| **TC-SYSCLK-018** | `set_unix` 写回 RTC,日历字段 + `week` 正确 | Unix 时间戳校时 |
+| **TC-SYSCLK-019** | 16 个已知日期(跨 1~12 月 / 世纪闰 / 闰日 / 范围首尾)星期对照 | **Zeller 全域正确性** |
**当前结果**:100/100 PASSED(`failed=0`)。
@@ -145,7 +145,7 @@ test/host/sys_clock/sys_clock_test.c
>
> ⚠ **惰性再基准化的"正确用法"**:差值窗口必须恒 < 30 天。一次 `tick_advance`
> 推进超过 ~49.7 天会让 `uint32_t diff` 溢出混叠——那是**调用方违约**(不是模块
-> 缺陷),测试应按 <30 天步长周期性调用 `get()`。见 TC-CLK-012 的注释。
+> 缺陷),测试应按 <30 天步长周期性调用 `get()`。见 TC-SYSCLK-012 的注释。
---
@@ -166,7 +166,7 @@ test/host/sys_clock/sys_clock_test.c
| 目标状态 | 手段 |
|---|---|
-| **未初始化**(`UINT32_MAX`) | 只能靠 **进程首用例**(TC-CLK-000,在任何 `init`/`set` 之前)观测 |
+| **未初始化**(`UINT32_MAX`) | 只能靠 **进程首用例**(TC-SYSCLK-000,在任何 `init`/`set` 之前)观测 |
| **确定的已初始化状态** | `sys_clock_set(unix_secs, NULL)` —— 更新基准且**不碰 RTC**,是理想的隔离原语 |
| **RTC 阴影态** | `rtc_set(...)` + `clear_obs()` 直接重置阴影寄存器与观测计数 |
@@ -176,8 +176,8 @@ test/host/sys_clock/sys_clock_test.c
### 5.1 现象
-首次运行 TC-CLK-014/019 时,`2026-10-02`(真实为周五)返回 `week == 4`;
-TC-CLK-019 的 16 个已知日期中,**仅 `2038-01-19` 正确**,其余 9 个(3~12 月)
+首次运行 TC-SYSCLK-014/019 时,`2026-10-02`(真实为周五)返回 `week == 4`;
+TC-SYSCLK-019 的 16 个已知日期中,**仅 `2038-01-19` 正确**,其余 9 个(3~12 月)
全错。
### 5.2 根因
@@ -238,7 +238,7 @@ static uint8_t rtc_calc_week(uint16_t y, uint8_t m, uint8_t d) { /* m: 1-based
### 5.5 校验数据来源
-TC-CLK-019 的期望星期由 Python `datetime.date(...).weekday()` 独立生成
+TC-SYSCLK-019 的期望星期由 Python `datetime.date(...).weekday()` 独立生成
(`(weekday()+1) % 7` → 0=周日),**与被测实现算法正交**,避免"用错的算法
验证错的实现"。
diff --git a/docs/测试说明/配置文件单元测试说明.md b/docs/测试说明/配置文件单元测试说明.md
index 27201587..fe6f8428 100644
--- a/docs/测试说明/配置文件单元测试说明.md
+++ b/docs/测试说明/配置文件单元测试说明.md
@@ -112,51 +112,51 @@ test/host/cfg_file/cfg_file_test.c
| 用例 | 断言 | 验证的设计点 |
|---|---|---|
-| **TC-CFG-001** | UINT 1/2/4 字节往返(0 / 最大值);小端序(`0x1234` → `34 12`) | 小端编解码 |
-| **TC-CFG-002** | UINT 非法:空 / 非数字 / 带后缀 / 超范围 / 负数 / len=3 | 严格校验 |
-| **TC-CFG-003** | IP4:`0.0.0.0` / `255.255.255.255` / 常规;段数不足/超、>255、非数字、尾点、空 | 点分四段 |
-| **TC-CFG-004** | MAC:`:` / `-` / `.` 三种分隔符、大小写;过短/过长/非十六进制/坏分隔符 | 分隔符 = **字节边界**替代 |
-| **TC-CFG-005** | STR:正常 + NUL;恰好 `len-1` 放下;`len` 字符拒绝;空串 | 长度边界 |
+| **TC-CONFIG-001** | UINT 1/2/4 字节往返(0 / 最大值);小端序(`0x1234` → `34 12`) | 小端编解码 |
+| **TC-CONFIG-002** | UINT 非法:空 / 非数字 / 带后缀 / 超范围 / 负数 / len=3 | 严格校验 |
+| **TC-CONFIG-003** | IP4:`0.0.0.0` / `255.255.255.255` / 常规;段数不足/超、>255、非数字、尾点、空 | 点分四段 |
+| **TC-CONFIG-004** | MAC:`:` / `-` / `.` 三种分隔符、大小写;过短/过长/非十六进制/坏分隔符 | 分隔符 = **字节边界**替代 |
+| **TC-CONFIG-005** | STR:正常 + NUL;恰好 `len-1` 放下;`len` 字符拒绝;空串 | 长度边界 |
### 2.2 INI 解析
| 用例 | 断言 | 验证的设计点 |
|---|---|---|
-| **TC-CFG-010** | `;` 与 `#` 注释、空行忽略 | 注释语义 |
-| **TC-CFG-011** | LF-only 行结束符解析正常 | CRLF/LF 兼容 |
-| **TC-CFG-012** | 段名/键名大小写无关;`=` 两侧与值两侧空白修剪 | 宽松匹配 |
-| **TC-CFG-013** | 键值行 `=` 前后空白、值尾空白被修剪 | 值修剪 |
-| **TC-CFG-014** | 未知键 / 未知段 / 缺失键 → 保留工厂默认,不崩溃 | 前向兼容 |
-| **TC-CFG-014b** | 非法值 → 保留默认 + `DBG_ERROR` 留痕 | 无效键留痕 |
-| **TC-CFG-015** | 段头之前的键值行被忽略 | 段作用域 |
+| **TC-CONFIG-010** | `;` 与 `#` 注释、空行忽略 | 注释语义 |
+| **TC-CONFIG-011** | LF-only 行结束符解析正常 | CRLF/LF 兼容 |
+| **TC-CONFIG-012** | 段名/键名大小写无关;`=` 两侧与值两侧空白修剪 | 宽松匹配 |
+| **TC-CONFIG-013** | 键值行 `=` 前后空白、值尾空白被修剪 | 值修剪 |
+| **TC-CONFIG-014** | 未知键 / 未知段 / 缺失键 → 保留工厂默认,不崩溃 | 前向兼容 |
+| **TC-CONFIG-014b** | 非法值 → 保留默认 + `DBG_ERROR` 留痕 | 无效键留痕 |
+| **TC-CONFIG-015** | 段头之前的键值行被忽略 | 段作用域 |
### 2.3 段注册校验
| 用例 | 断言 | 验证的设计点 |
|---|---|---|
-| **TC-CFG-020** | 正常注册;重复段名拒绝;NULL 描述符 / NULL p_data 拒绝 | 参数防御 |
-| **TC-CFG-021** | UINT len=3、MAC len≠6、STR len>79、key len=0 拒绝 | 键定义校验 |
-| **TC-CFG-022** | 段名 ≥ `CFG_NAME_MAX`(16) 拒绝 | 段名长度 |
-| **TC-CFG-023** | 挂回调段 `data_size > CFG_SNAP_MAX`(64) 拒绝;同段不挂回调则接受 | 回调段快照约束 |
+| **TC-CONFIG-020** | 正常注册;重复段名拒绝;NULL 描述符 / NULL p_data 拒绝 | 参数防御 |
+| **TC-CONFIG-021** | UINT len=3、MAC len≠6、STR len>79、key len=0 拒绝 | 键定义校验 |
+| **TC-CONFIG-022** | 段名 ≥ `CFG_NAME_MAX`(16) 拒绝 | 段名长度 |
+| **TC-CONFIG-023** | 挂回调段 `data_size > CFG_SNAP_MAX`(64) 拒绝;同段不挂回调则接受 | 回调段快照约束 |
### 2.4 load / save / poll 契约
| 用例 | 断言 | 验证的设计点 |
|---|---|---|
-| **TC-CFG-030** | 文件缺失 → 生成出厂模板写盘 + 返回 0;模板含段头与键 | 首启建文件 |
-| **TC-CFG-031** | 文件存在 → 有效键进 RAM 副本 | 正常加载 |
-| **TC-CFG-032** | 超长文件 → 工厂默认 + 重建模板 + 自检留痕 + 返回 0 | 损坏自愈 |
-| **TC-CFG-033** | 读取失败 → 返回 -1,RAM 保持工厂默认 | 读故障 |
-| **TC-CFG-034** | 未注册任何段 → 返回 -1 | 前置校验 |
-| **TC-CFG-040** | 文件缺失 → 重建完整文档 | 整文档生成 |
-| **TC-CFG-041** | 外科手术:保留注释/未知段/未知键,**受管键原位改写** | ⭐ 核心特性 |
-| **TC-CFG-042** | 缺失受管段/键 → 文末补写 | 补写路径 |
-| **TC-CFG-043** | 输出超长 → 拒绝保存(-1) + 原文件不动 + 自检留痕 | 溢出保护 |
-| **TC-CFG-050** | 首轮 poll 建立基线,不重载 | 基线建立 |
-| **TC-CFG-051/052** | 沉降去抖(连续 2 次稳定才重载);与基线一致不重载 | 去抖语义 |
-| **TC-CFG-053** | 变更后重载 + 挂回调段差异触发回调 | 变更响应 |
-| **TC-CFG-055** | `(size, mtime)` 令牌不变 → 不重载(令牌 = 变更信号) | 令牌契约 |
-| **TC-CFG-054** | poll 检出超长 → 工厂默认 + 重建模板 + 留痕;**不触发回调** | 在线修复通道保留 |
+| **TC-CONFIG-030** | 文件缺失 → 生成出厂模板写盘 + 返回 0;模板含段头与键 | 首启建文件 |
+| **TC-CONFIG-031** | 文件存在 → 有效键进 RAM 副本 | 正常加载 |
+| **TC-CONFIG-032** | 超长文件 → 工厂默认 + 重建模板 + 自检留痕 + 返回 0 | 损坏自愈 |
+| **TC-CONFIG-033** | 读取失败 → 返回 -1,RAM 保持工厂默认 | 读故障 |
+| **TC-CONFIG-034** | 未注册任何段 → 返回 -1 | 前置校验 |
+| **TC-CONFIG-040** | 文件缺失 → 重建完整文档 | 整文档生成 |
+| **TC-CONFIG-041** | 外科手术:保留注释/未知段/未知键,**受管键原位改写** | ⭐ 核心特性 |
+| **TC-CONFIG-042** | 缺失受管段/键 → 文末补写 | 补写路径 |
+| **TC-CONFIG-043** | 输出超长 → 拒绝保存(-1) + 原文件不动 + 自检留痕 | 溢出保护 |
+| **TC-CONFIG-050** | 首轮 poll 建立基线,不重载 | 基线建立 |
+| **TC-CONFIG-051/052** | 沉降去抖(连续 2 次稳定才重载);与基线一致不重载 | 去抖语义 |
+| **TC-CONFIG-053** | 变更后重载 + 挂回调段差异触发回调 | 变更响应 |
+| **TC-CONFIG-055** | `(size, mtime)` 令牌不变 → 不重载(令牌 = 变更信号) | 令牌契约 |
+| **TC-CONFIG-054** | poll 检出超长 → 工厂默认 + 重建模板 + 留痕;**不触发回调** | 在线修复通道保留 |
**当前结果**:139/139 PASSED(`failed=0`)。
@@ -213,7 +213,7 @@ test/host/cfg_file/cfg_file_test.c
### 5.1 现象
-`TC-CFG-041`(外科手术保存)首次运行即失败:对**已存在**的 `/config.ini` 调用
+`TC-CONFIG-041`(外科手术保存)首次运行即失败:对**已存在**的 `/config.ini` 调用
`cfg_file_save()`,即使 RAM 副本的值已改(如 `u8: 1 → 200`),落盘文件仍是
**原值** `u8 = 1`。
@@ -264,7 +264,7 @@ if (s_encode(p_key, ..., v, sizeof(v)) >= 0) {
}
```
-修复后 `TC-CFG-041` / `TC-CFG-042` 转 PASS,`@build` 0 errors 0 warnings。
+修复后 `TC-CONFIG-041` / `TC-CONFIG-042` 转 PASS,`@build` 0 errors 0 warnings。
### 5.5 建议后续动作
diff --git a/docs/编号规范.md b/docs/编号规范.md
index c5270d6b..ed7fc15d 100644
--- a/docs/编号规范.md
+++ b/docs/编号规范.md
@@ -35,10 +35,10 @@
| **连字符/补零偷偷承载语义** | `R1`=风险、`R-2`=内存优化项;`D7`=验证窗口、`D-7`=文档门禁、`D1~D7`=设计决策;`N-2`(登记簿)与 `N-02`(报告)同号不同义 |
| **跨文档同号不同义** | `Trap 02` 在 CH395F 是"缓冲区重叠"、在 GD5F 是"测试缓冲越界";`B10` 在规划是"送检窗口"、在陷阱审计是"孤儿监听" |
| **语义进编号 → 事实一变编号就撒谎** | `P1-x` 把严重度写进号里,而审计中大量条目事后降级(`E-59` P0→P1、dhara `is_free` P1→P2):改号则引用全断,不改则号实不符 |
-| **孤儿编号(代码有、文档无)** | `I-1`/`I-2`、`Task #32` 会话号、`P1-01~P1-09`、`TC-GD5F-1100/1101/1102`、`TC-STO-06`、`TC-AH-*`、`TC-PE-*`(前两项项目已在 `docs/测试说明/实机测试实施指南.md` 自行承认) |
+| **孤儿编号(代码有、文档无)** | `I-1`/`I-2`、`Task #32` 会话号、`P1-01~P1-09`、`TC-GD5F-1100/1101/1102`、`TC-STORAGE-06`、`TC-AH-*`、`TC-PE-*`(前两项项目已在 `docs/测试说明/实机测试实施指南.md` 自行承认) |
| **悬空引用(引用了不存在的号)** | `Trap 19` 从未存在却被 `docs/测试说明/CH395F_Test_Guide.md` 引用;`N-5/N-8/N-19/N-30/N-31/N-32` 销项删行后仍被引用(`N-32` = 监听生命周期模块化,被 `docs/网络/` 三篇与代码注释多处引用) |
| **同一事物多种字面** | `Trap 07` / `TRAP-07` / `陷阱 1`;`gen 181` / `gen-288` / `gen68`;`TC-NET-704` / `TC704` / `TC-203` |
-| **规范自身就不自洽** | `docs/测试说明/测试文档模板规范.md` §6.3 同一行并列 `TC-STO-03`(2 位)与 `TC-RTC-001`(3 位);`docs/测试说明/测试文档模板规范.md` §6.2 已废止 `PHY` 模块码,而阶段 ID 至今仍是 `TM-PHY-01` |
+| **规范自身就不自洽** | `docs/测试说明/测试文档模板规范.md` §6.3 同一行并列 `TC-STORAGE-03`(2 位)与 `TC-RTC-001`(3 位);`docs/测试说明/测试文档模板规范.md` §6.2 已废止 `PHY` 模块码,而阶段 ID 至今仍是 `TM-PHY-01` |
| **机器校验只覆盖一个族** | (2026-10-15 现状,2026-10-20 已由 §8.1 收口)当时 31 个 pre-commit 钩子中只有 `TC` 有 `scripts/check_test_traceability.py`,且**未挂钩子、warn-only、正则 `TC-[A-Za-z0-9]+-\d+` 匹配不到大写后缀形态**;`E/N/S/B/C/D/A/U/O/gen/Trap` 全部裸奔 |
> **可借鉴的先例**:`§N.M` 章节引用当年 1,578 处也全靠自觉,靠「紧邻写法 + 别名表 + 可判定比例 + 钩子」把可判定比例做到 58% 并转为拦提交([`docs/文档规范.md`](文档规范.md) §3.5)。编号走同一条路径即可收口。
@@ -291,22 +291,24 @@
| 码 | 模块(源文件/目录) | 码 | 模块 |
|---|---|---|---|
-| `NET` | `Drivers/BSP/CH395F` + `Drivers/BSP/NET` | `AI` | `App/algo/adc_input` |
-| `GD5F` | `Drivers/BSP/GD5F2GQ5UE` | `AH` | `App/algo/adc_health` |
-| `STO` | 存储栈(FTL + FatFs + `App/fs`) | `PH` | `App/algo/phasor` + `sample_ring` |
-| `RTC` | `Drivers/BSP/SD2506` | `PS` | `App/algo/prot_set` |
-| `ADC` | 采集节拍与通道映射(`Src/adc.c`、TIM3) | `PE` | `App/algo/prot_elm` |
-| `RS485` | `Drivers/BSP/RS485` | `VL` | `App/fs/vol_lock` |
-| `UI` | `Drivers/BSP/UI` | `TS` | `App/sync/time_sync` |
-| `LOG` | `App/log` | `CLK` | `App/util/sys_clock` |
-| `CFG` | `App/cfg` + `Drivers/BSP/NETCFG` | `WD` | `App/util/task_watchdog` |
-| `SH` | `App/util/sha256` | `FA` | `Drivers/BSP/NET/lftpd` 鉴权 |
-| `I104` | `App/protocol/iec104` | `TOOL` | PC 端工具(串口助手等) |
+| `NET` | `Drivers/BSP/CH395F` + `Drivers/BSP/NET` | `ADCIN` | `App/algo/adc_input` |
+| `GD5F` | `Drivers/BSP/GD5F2GQ5UE` | `ADCHEALTH` | `App/algo/adc_health` |
+| `STORAGE` | 存储栈(FTL + FatFs + `App/fs`) | `PHASOR` | `App/algo/phasor` + `sample_ring` |
+| `RTC` | `Drivers/BSP/SD2506` | `PROTSET` | `App/algo/prot_set` |
+| `ADC` | 采集节拍与通道映射(`Src/adc.c`、TIM3) | `PROTELEM` | `App/algo/prot_elm` |
+| `RS485` | `Drivers/BSP/RS485` | `VOLLOCK` | `App/fs/vol_lock` |
+| `UI` | `Drivers/BSP/UI` | `TIMESYNC` | `App/sync/time_sync` |
+| `LOG` | `App/log` | `SYSCLK` | `App/util/sys_clock` |
+| `CONFIG` | `App/cfg` + `Drivers/BSP/NETCFG` | `WATCHDOG` | `App/util/task_watchdog` |
+| `SHA256` | `App/util/sha256` | `FTPAUTH` | `Drivers/BSP/NET/lftpd` 鉴权 |
+| `IEC104` | `App/protocol/iec104` | `TOOL` | PC 端工具(串口助手等) |
> 废止码:`PHY`(→ `NET`)、`NAND`(→ `GD5F`)。历史文档不回改,新文档按本表。
---
+
+> ⚠ **2026-10-20 批 2**:上表 16 个有歧义的码已单词化(`AI`→`ADCIN`、`AH`→`ADCHEALTH`、`PS`→`PROTSET`、`PE`→`PROTELEM`、`PH`→`PHASOR`、`TS`→`TIMESYNC`、`VL`→`VOLLOCK`、`NP`→`NANDPORT`、`CFG`→`CONFIG`、`CLK`→`SYSCLK`、`WD`→`WATCHDOG`、`STO`→`STORAGE`、`SH`→`SHA256`、`FA`→`FTPAUTH`、`FR`→`FREQ`、`104`→`IEC104`),全库 1,146 处随 `scripts/rename_ids.py` 改写,旧号入 `scripts/id_aliases.json`。`NET`/`GD5F`/`RTC`/`SOE`/`UI`/`ADC`/`LOG`/`RS485`/`TOOL` 不动(已是单词、芯片名或业界通用词)。**连带修门禁**:模块码变长到 9 位(`ADCHEALTH`),候选正则与族正则的 `{0,4}` 上界必须放宽到 `{0,9}`,否则改名后的号会整批从门禁眼里消失(实测漏掉 950 处——改名类批次必须连带复核识别面,不能只改数据不改判据)。
## 7. 迁移映射(legacy → 新号)
### 7.1 映射规则
@@ -331,8 +333,8 @@
| 审计模式 `P1~P9` | `PAT-01`~`PAT-09` | 正文冻结,新文档用新号 |
| 保护 `R1~R8`、看门狗 `R1~R7` | 各文档 `RSK-01`… | 文档内编号 + 引用带文档名 |
| 保护阶段 `P0~P5`、方案 `P0~P3` | 各文档 `ST-0`… | 与档位词 `P0` 解耦 |
-| `TC-STO-01~06` | `TC-STO-001~006` | 补零 |
-| `TC-AI-01A`/`02A`/`02B`/`02C`、`TC-VL-008b` | `TC-AI-001a`… / `TC-VL-008b` | 后缀统一小写字母,基号补零 |
+| `TC-STORAGE-01~06` | `TC-STORAGE-001~006` | 补零 |
+| `TC-ADCIN-01A`/`02A`/`02B`/`02C`、`TC-VOLLOCK-008b` | `TC-ADCIN-001a`… / `TC-VOLLOCK-008b` | 后缀统一小写字母,基号补零 |
| `TM-PHY-01~11` | `TM-NET-01~11` | 模块码 |
| `DP-01~04` | `DP-NET-01~04` | 加模块码 |
@@ -343,7 +345,7 @@
| `I-1`/`I-2`(`ui_net_sink.c`) | 就地展开成事实描述(原属主《网络Socket监听生命周期设计说明》已并入 `docs/网络/网络自愈架构设计.md` §9.3,不再补编号定义行) |
| `Task #32` 会话号及其小节引用 | 会话号,改写为可解析引用(结论已沉淀进 `docs/子系统设计/看门狗设计说明.md` §11) |
| `P1-01~P1-09`(`ch395f_test_task.c`) | 改指 `TC-NET-101`…,或补文档条目 |
-| `TC-GD5F-1100/1101/1102`、`TC-STO-06` | 补进 `docs/测试说明/GD5F2GQ5UE_Test_Guide.md` |
+| `TC-GD5F-1100/1101/1102`、`TC-STORAGE-06` | 补进 `docs/测试说明/GD5F2GQ5UE_Test_Guide.md` |
| `TC-AH-*`、`TC-PE-*`、iec104 `TC-014/015/024` | 补单测说明文档(缺文档 = 追溯断链) |
| `Trap 19` | 悬空引用,删除或改指实际条目 |
@@ -400,7 +402,7 @@ git grep -n '<旧字面量>' # 零残留
| 编号字面量出现 | 8271 处 |
| **可判定比例基线** | **82.6%**(6840 / 8271 = 82.70%,批 1 改名后重打,存进 `id_registry.json` 时**下取整到 0.1pp**——用 `round()` 会让 82.34 进位成 82.3 再反过来把自己判死,实测踩过;比较容差 0.1pp) |
| 校验 1 未登记前缀 | 0 处 |
-| 校验 2 形态不合规 | 396 处(**批 1 已从 417 降到 396**:裸形 `S`/`T` 类 71 → 50。剩余大头:真无模块码 `TC-nnn` 181 处 / 5 文件、数字模块码 `TC-104-nnn` 23 处(§6 表里模块码是 `I104`,非数字)、`DP-0n` 22 处、`Task #nn` 33 处、`Trap 空格形`+`陷阱 中文形` 43 处、`gen/round` 36 处、大写后缀 31 处) |
+| 校验 2 形态不合规 | 396 处(**批 1 已从 417 降到 396**:裸形 `S`/`T` 类 71 → 50。剩余大头:真无模块码 `TC-nnn` 181 处 / 5 文件、数字模块码 `TC-104-nnn` 23 处(§6 表里模块码是 `I104`,非数字)、`DP-01`~`DP-04` 22 处、`Task #nn` 33 处、`Trap 空格形`+`陷阱 中文形` 43 处、`gen/round` 36 处、大写后缀 31 处) |
| 校验 3 悬空引用 | 错误 626 / 告警 223(scoped 别名收编旧号后 −16)(错误集中在 `TC-PS-*`/`TC-PE-*`/`TC-AH-*`/`TC-FR-*`/`TC-SOE-*`——**主机侧单测有码无文档**,正是 §7.2 列的"缺文档 = 追溯断链") |
| 校验 4 重复定义 | 0 处(`§4.3` 已声明的同号不同义族对 443 个字面量走 `collides_with` 白名单,不计事故) |
| 校验 5 冻结越游标 | 0 处 |
@@ -418,7 +420,7 @@ git grep -n '<旧字面量>' # 零残留
|---|---|---|
| §4.1 `E\d+`「已封闭 `E0`~`E15`」 | `docs/网络/网络自愈架构设计.md` §5.2 实验表已到 **E19** | 游标按实测 E19 收录;封闭线待修订 |
| §4.1 `FR-[A-Z0-9]+-\d{2}` | 现存 `FR-STO-1` 等全是**未补零**的 1 位序号 | 正则放宽到 `\d{1,2}`,补零归 §9 阶段 1 |
-| §4.1 `TC-[A-Z]{1,4}-\d{3,4}` | 模块码 `GD5F`/`I104` **含数字**,按原文正则会漏掉 GD5F 全族(实测 285 处) | 放宽为 `[A-Z][A-Z0-9]{0,4}`;序号暂收 2 位(`TC-STO-06` 属 §7.2 孤儿) |
+| §4.1 `TC-[A-Z]{1,4}-\d{3,4}` | 模块码 `GD5F`/`I104` **含数字**,按原文正则会漏掉 GD5F 全族(实测 285 处) | 放宽为 `[A-Z][A-Z0-9]{0,4}`;序号暂收 2 位(`TC-STORAGE-06` 属 §7.2 孤儿) |
| §4.1/§4.2 总表无 `F--` | `F-NET-2~17`/`F-DRV-*`/`F-MS-*` 定义在 `docs/网络/网络自愈架构设计.md` 且被大量代码注释引用 | 先按实测收编成族(§5.1 第 1 步:表里没有的类别先改本规范) |
| §4.1 `N-\d{2}` | 报告用 `N-03a`/`N-03c` 子项后缀;§5.5 扩位示例 `N-100` | 放宽到 `\d{1,3}[a-z]?` |
@@ -430,6 +432,7 @@ git grep -n '<旧字面量>' # 零残留
| 批 | 日期 | 族 | 旧 → 新 | 处数 / 文件 | 别名 |
|---|---|---|---|---|---|
| **批 1** | 2026-10-20 | 代码规范条款 | `S1`~`S19` → `CODE-RULE-01`~`19` | 78 处 / 2 文件 | 18 条(scoped:`scripts/check_coding_standard.py`、`docs/代码规范/pre-commit使用说明.md`) |
+| **批 2** | 2026-10-20 | 测试用例模块码 | 16 个码 → 单词化(见 §6) | 1,146 处 / 约 30 文件 | 全局别名(字面量已完全限定,无歧义) |
| **批 1** | 2026-10-20 | UI 像素回归状态 | `S0`~`S7` → `MENU-STATE-00`~`07` | 61 处 / 3 文件 | 8 条(scoped:`simulator/tests/check_menu_rows.py`、`docs/UI设计/UI_自动化测试流程.md`、`simulator/README.md`) |
⚠ **别名必须带 scope**:同一裸形字面量可同时是多族的旧号(实测 `S3` 三义)。全局别名会把另一族的真悬空洗成「已解析」——等于用工具复制 §1.2 的 `N-31`/`N-32` 撞号事故。
diff --git a/scripts/check_ids.py b/scripts/check_ids.py
index fcc7ae06..03e55e6c 100644
--- a/scripts/check_ids.py
+++ b/scripts/check_ids.py
@@ -63,7 +63,7 @@ TRACE_SCRIPT = REPO_ROOT / "scripts" / "check_test_traceability.py"
# 候选池:任何「1~4 位大写字母 + 连字符 + 数字」先进来,再判是否登记过。
# 三段式(TC-NET-1501 / TRAP-NET-18)单独一条——中段可能含数字(GD5F),
# 只用两段式正则会截出 "NET-1501" 这种假前缀。
-CAND_MOD = re.compile(r"(?(§7.1 统一为小写)"
+ "malformed": "大写后缀非法:§4.1 规定后缀只允许 -<小写字母>(§7.1 统一为小写)",
+ "module_code_note": "2026-10-20 批 2 模块码单词化后码长可达 9 位(ADCHEALTH/WATCHDOG),{0,4} 放宽到 {0,9};不放宽会让改名后的号整批从门禁眼里消失(实测漏 950 处)"
},
{
"name": "TC-NOMOD",
@@ -431,7 +433,7 @@
"name": "TM",
"class": "TM",
"title": "测试阶段(§4.1 在册保留,模块码取 §6)",
- "pattern": "\\bTM-[A-Z][A-Z0-9]{0,4}-[0-9]{2}\\b",
+ "pattern": "\\bTM-[A-Z][A-Z0-9]{0,9}-[0-9]{2}\\b",
"owner_docs_glob": [
"docs/测试说明/*.md"
],
@@ -452,7 +454,7 @@
"name": "DP",
"class": "DP",
"title": "测试设计原则(§4.1 目标形态带模块码)",
- "pattern": "\\bDP-[A-Z][A-Z0-9]{0,4}-[0-9]{2}\\b",
+ "pattern": "\\bDP-[A-Z][A-Z0-9]{0,9}-[0-9]{2}\\b",
"owner_docs_glob": [
"docs/测试说明/*.md"
],
@@ -492,7 +494,7 @@
"name": "TRAP",
"class": "TRAP",
"title": "陷阱记录(§4.2 保留原号,历史证词高频锚点)",
- "pattern": "\\bTRAP-[A-Z][A-Z0-9]{0,4}-[0-9]{2}\\b",
+ "pattern": "\\bTRAP-[A-Z][A-Z0-9]{0,9}-[0-9]{2}\\b",
"owner_docs_glob": [
"docs/问题记录/*_Trap_Records.md"
],
@@ -516,7 +518,7 @@
"name": "FEAT",
"class": "FEAT",
"title": "网络层功能/驱动改进项 F--(§4 总表缺这一族)",
- "pattern": "\\bF-[A-Z][A-Z0-9]{0,3}-[0-9]{1,2}\\b",
+ "pattern": "\\bF-[A-Z][A-Z0-9]{0,9}-[0-9]{1,2}\\b",
"owner_docs": [
"docs/网络/网络自愈架构设计.md"
],
diff --git a/scripts/rename_ids.py b/scripts/rename_ids.py
index 8619b198..58c72f22 100644
--- a/scripts/rename_ids.py
+++ b/scripts/rename_ids.py
@@ -88,12 +88,16 @@ def match_files(patterns, candidates):
def render(template, groups):
+ """按模板渲染新号。**只有模板带格式说明符时**才把数字组转 int——
+ 否则 `TC-PROTSET-011` 会被渲染成 `TC-PROTSET-11`(丢前导零,实测差点毁掉整批补零形态)。"""
vals = {}
for k, v in groups.items():
if v is None:
vals[k] = ""
+ elif v.isdigit() and re.search(r"\{%s:[^}]+\}" % re.escape(k), template):
+ vals[k] = int(v)
else:
- vals[k] = int(v) if v.isdigit() else v
+ vals[k] = v
return template.format(**vals)
@@ -149,18 +153,20 @@ def merge_aliases(new_aliases, batch):
"""把本批 `旧号 → 新号` 并进 id_aliases.json,带 scope(同字面量多义的关键)。"""
doc = json.loads(ALIASES_FILE.read_text(encoding="utf-8"))
table = doc.setdefault("aliases", {})
- scope = [norm(x) for x in batch.get("files", [])]
+ # 已**完全限定**的字面量(如 `TC-PROTSET-011`)可以全局认别名;裸形(`S3`)必须带 scope
+ scope = [] if batch.get("global_alias") else [norm(x) for x in batch.get("files", [])]
added = 0
for old, news in sorted(new_aliases.items()):
scope_txt = ("旧号仅在本批 scope 内指向新号;scope 外同字面量属其它族,不受本条影响"
- if scope else "全库生效(本批无 scope)")
+ if scope else "全库生效(本批字面量已完全限定,无歧义)")
entry = {
"to": sorted(news)[0] if len(news) == 1 else sorted(news),
"status": "renamed",
- "scope": scope,
"note": "%s(scripts/rename_ids.py 批:族 %s)|%s"
% (batch.get("note", "批量改名"), batch.get("family"), scope_txt),
}
+ if scope:
+ entry["scope"] = scope
cur = table.get(old)
if cur is None:
table[old] = entry
diff --git a/scripts/rename_maps/batch2.json b/scripts/rename_maps/batch2.json
new file mode 100644
index 00000000..94bbfbee
--- /dev/null
+++ b/scripts/rename_maps/batch2.json
@@ -0,0 +1,25 @@
+{
+ "schema": 1,
+ "batch": "批 2(模块码单词化,16 个有歧义的码)",
+ "applied_by": "scripts/rename_ids.py",
+ "record": "docs/编号规范.md §6 模块码表 + §8.3 迁移批次记录",
+ "note": "字面量已完全限定(TC-<旧码>-),故别名全局生效;裸形族才需要 scope",
+ "batches": [
+ {"family": "TC-ADCIN", "old": "\\bTC-AI-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-ADCIN-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:模块码 AI → ADCIN(App/algo/adc_input;与 AH 只差一个字母)"},
+ {"family": "TC-ADCHEALTH", "old": "\\bTC-AH-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-ADCHEALTH-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:模块码 AH → ADCHEALTH(App/algo/adc_health)"},
+ {"family": "TC-PROTSET", "old": "\\bTC-PS-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-PROTSET-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:模块码 PS → PROTSET(App/algo/prot_set 保护定值)"},
+ {"family": "TC-PROTELEM", "old": "\\bTC-PE-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-PROTELEM-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:模块码 PE → PROTELEM(App/algo/prot_elm 保护元件/判据)"},
+ {"family": "TC-PHASOR", "old": "\\bTC-PH-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-PHASOR-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:模块码 PH → PHASOR(App/algo/phasor + sample_ring)"},
+ {"family": "TC-TIMESYNC", "old": "\\bTC-TS-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-TIMESYNC-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:模块码 TS → TIMESYNC(App/sync/time_sync;TS 与 test suite / 时间戳 撞义)"},
+ {"family": "TC-VOLLOCK", "old": "\\bTC-VL-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-VOLLOCK-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:模块码 VL → VOLLOCK(App/fs/vol_lock 卷锁)"},
+ {"family": "TC-NANDPORT", "old": "\\bTC-NP-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-NANDPORT-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:模块码 NP → NANDPORT(dhara NAND 移植层;原名看不出是移植层)"},
+ {"family": "TC-CONFIG", "old": "\\bTC-CFG-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-CONFIG-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:模块码 CFG → CONFIG(App/cfg + Drivers/BSP/NETCFG)"},
+ {"family": "TC-SYSCLK", "old": "\\bTC-CLK-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-SYSCLK-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:模块码 CLK → SYSCLK(App/util/sys_clock;CLK 也泛指任何时钟信号)"},
+ {"family": "TC-WATCHDOG", "old": "\\bTC-WD-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-WATCHDOG-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:模块码 WD → WATCHDOG(App/util/task_watchdog;WD 也读作『喂狗动作』)"},
+ {"family": "TC-STORAGE", "old": "\\bTC-STO-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-STORAGE-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:模块码 STO → STORAGE(存储栈 FTL+FatFs+App/fs;STO 易读成 stop)"},
+ {"family": "TC-SHA256", "old": "\\bTC-SH-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-SHA256-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:模块码 SH → SHA256(App/util/sha256;算法名应写全)"},
+ {"family": "TC-FTPAUTH", "old": "\\bTC-FA-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-FTPAUTH-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:模块码 FA → FTPAUTH(Drivers/BSP/NET/lftpd 鉴权)"},
+ {"family": "TC-FREQ", "old": "\\bTC-FR-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-FREQ-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:模块码 FR → FREQ(App/algo/freq L2.5 测频)"},
+ {"family": "TC-IEC104", "old": "\\bTC-104-(?P[0-9]{1,4}[a-zA-Z]?)\\b", "new": "TC-IEC104-{n}", "global_alias": true, "files": ["*", "*/*", "*/*/*", "*/*/*/*", "*/*/*/*/*", "*/*/*/*/*/*"], "note": "批 2:数字模块码 104 → IEC104(§6 表里本就写 I104,代码写成纯数字 104;纯数字不是模块码)"}
+ ]
+}
diff --git a/test/board/storage_test.h b/test/board/storage_test.h
index fdf18fc2..1fa91c7e 100644
--- a/test/board/storage_test.h
+++ b/test/board/storage_test.h
@@ -31,7 +31,7 @@ extern storage_test_stats_t g_storage_stats;
void storage_test_run(void);
/* 存储套件恢复测试(默认关闭):取消注释并编译 STORAGE 套件运行一次,
- * 即可重建 BBT(清除 TC-STO-03 等注入的坏块)并重新格式化,恢复设备干净态。
+ * 即可重建 BBT(清除 TC-STORAGE-03 等注入的坏块)并重新格式化,恢复设备干净态。
* 恢复完成后建议重新注释并编译正常构建。 */
//#define ENABLE_STORAGE_RECOVERY_TESTS /* 台架已跑过一次恢复(2026-09-20 BBT 回出厂态),保持注释 */
diff --git a/test/board/storage_test_task.c b/test/board/storage_test_task.c
index dccef937..4c7bafc6 100644
--- a/test/board/storage_test_task.c
+++ b/test/board/storage_test_task.c
@@ -32,7 +32,7 @@ static FIL fil;
* L6406E 实测;2048 分块仍覆盖整页写路径,128KB 总量不变) */
static uint8_t s_perf_buf[2048];
-/* TC-STO-01: FTL 掉电恢复(journal 持久化)
+/* TC-STORAGE-01: FTL 掉电恢复(journal 持久化)
* 写文件并同步落盘,随后模拟掉电(卸载 + 复位 FTL + 重新 resume),再挂载校验内容一致。
*/
static void storage_test_powerloss(void)
@@ -44,10 +44,10 @@ static void storage_test_powerloss(void)
uint32_t i;
int ok = 0;
- DBG_INFO("=== Storage Test: TC-STO-01 Power-loss recovery ===");
+ DBG_INFO("=== Storage Test: TC-STORAGE-01 Power-loss recovery ===");
if (f_mount(&fs, "", 1) != FR_OK) {
- STORAGE_TEST_CHECK(0, "TC-STO-01 mount");
+ STORAGE_TEST_CHECK(0, "TC-STORAGE-01 mount");
return;
}
@@ -62,7 +62,7 @@ static void storage_test_powerloss(void)
f_sync(&fil);
f_close(&fil);
} else {
- STORAGE_TEST_CHECK(0, "TC-STO-01 f_open(write)");
+ STORAGE_TEST_CHECK(0, "TC-STORAGE-01 f_open(write)");
return;
}
@@ -72,7 +72,7 @@ static void storage_test_powerloss(void)
nand_ftl_init();
if (f_mount(&fs, "", 1) != FR_OK) {
- STORAGE_TEST_CHECK(0, "TC-STO-01 remount after resume");
+ STORAGE_TEST_CHECK(0, "TC-STORAGE-01 remount after resume");
return;
}
@@ -93,11 +93,11 @@ static void storage_test_powerloss(void)
} else {
ok = 0;
}
- STORAGE_TEST_CHECK(ok, "TC-STO-01 content survived power-loss (resume)");
+ STORAGE_TEST_CHECK(ok, "TC-STORAGE-01 content survived power-loss (resume)");
f_unlink("pl.dat");
}
-/* TC-STO-02: 大文件 / 多扇区 / 随机 seek
+/* TC-STORAGE-02: 大文件 / 多扇区 / 随机 seek
* 写 256KB 位置相关模式文件,顺序读回比对 + 随机偏移 seek 读比对。
* 栈预算:testTask 栈 4KB,局部缓冲 4096 必然溢出栈(8 月侥幸未爆是堆使用
* 低),改 2048 = 恰好一个 NAND 整页,覆盖度等价。
@@ -111,16 +111,16 @@ static void storage_test_largefile(void)
uint32_t off, i;
int ok = 1;
- DBG_INFO("=== Storage Test: TC-STO-02 Large file / random seek ===");
+ DBG_INFO("=== Storage Test: TC-STORAGE-02 Large file / random seek ===");
if (f_mount(&fs, "", 1) != FR_OK) {
- STORAGE_TEST_CHECK(0, "TC-STO-02 mount");
+ STORAGE_TEST_CHECK(0, "TC-STORAGE-02 mount");
return;
}
/* 写:位置相关模式 */
if (f_open(&fil, "big.dat", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) {
- STORAGE_TEST_CHECK(0, "TC-STO-02 f_open(write)");
+ STORAGE_TEST_CHECK(0, "TC-STORAGE-02 f_open(write)");
return;
}
for (off = 0; off < total; off += chunk) {
@@ -133,7 +133,7 @@ static void storage_test_largefile(void)
/* 顺序读回 */
if (f_open(&fil, "big.dat", FA_READ) != FR_OK) {
- STORAGE_TEST_CHECK(0, "TC-STO-02 f_open(read)");
+ STORAGE_TEST_CHECK(0, "TC-STORAGE-02 f_open(read)");
return;
}
for (off = 0; off < total; off += chunk) {
@@ -144,7 +144,7 @@ static void storage_test_largefile(void)
}
if (!ok) break;
}
- STORAGE_TEST_CHECK(ok, "TC-STO-02 sequential 256KB read consistent");
+ STORAGE_TEST_CHECK(ok, "TC-STORAGE-02 sequential 256KB read consistent");
/* 随机 seek 读 */
if (ok) {
@@ -160,13 +160,13 @@ static void storage_test_largefile(void)
}
if (!seek_ok) break;
}
- STORAGE_TEST_CHECK(seek_ok, "TC-STO-02 random seek read consistent");
+ STORAGE_TEST_CHECK(seek_ok, "TC-STORAGE-02 random seek read consistent");
}
f_close(&fil);
f_unlink("big.dat");
}
-/* TC-STO-03: 坏块注入下存储写入
+/* TC-STORAGE-03: 坏块注入下存储写入
* 清空旧 map → 注入若干好块为坏(持久化) → 重建文件系统 → 正常写读 → 校验坏块仍被报告。
*/
static void storage_test_badblock(void)
@@ -177,7 +177,7 @@ static void storage_test_badblock(void)
int nbad = 0;
int ok = 1;
- DBG_INFO("=== Storage Test: TC-STO-03 Bad-block injection during storage ===");
+ DBG_INFO("=== Storage Test: TC-STORAGE-03 Bad-block injection during storage ===");
/* 清空旧 dhara map,避免后续注入的坏块被旧映射引用 */
nand_ftl_format();
@@ -190,10 +190,10 @@ static void storage_test_badblock(void)
}
}
if (nbad < 3) {
- STORAGE_TEST_CHECK(0, "TC-STO-03 could not find 3 good blocks (got %d)", nbad);
+ STORAGE_TEST_CHECK(0, "TC-STORAGE-03 could not find 3 good blocks (got %d)", nbad);
return;
}
- STORAGE_TEST_CHECK(nbad == 3, "TC-STO-03 injected %d bad blocks", nbad);
+ STORAGE_TEST_CHECK(nbad == 3, "TC-STORAGE-03 injected %d bad blocks", nbad);
/* 复位 FTL 使 dhara 经 is_block_bad 看到新坏块 */
f_mount(&fs, "", 0);
@@ -205,12 +205,12 @@ static void storage_test_badblock(void)
MKFS_PARM opts = { FM_FAT32, 0, 0, 0, 0 };
uint8_t work[FF_MAX_SS];
if (f_mkfs("", &opts, work, sizeof(work)) != FR_OK) {
- STORAGE_TEST_CHECK(0, "TC-STO-03 f_mkfs");
+ STORAGE_TEST_CHECK(0, "TC-STORAGE-03 f_mkfs");
return;
}
}
if (f_mount(&fs, "", 1) != FR_OK) {
- STORAGE_TEST_CHECK(0, "TC-STO-03 mount");
+ STORAGE_TEST_CHECK(0, "TC-STORAGE-03 mount");
return;
}
@@ -222,7 +222,7 @@ static void storage_test_badblock(void)
f_write(&fil, wbuf, sizeof(wbuf), &bw);
f_close(&fil);
} else {
- STORAGE_TEST_CHECK(0, "TC-STO-03 f_open(write)");
+ STORAGE_TEST_CHECK(0, "TC-STORAGE-03 f_open(write)");
return;
}
@@ -239,24 +239,24 @@ static void storage_test_badblock(void)
} else {
ok = 0;
}
- STORAGE_TEST_CHECK(ok, "TC-STO-03 file intact with injected bad blocks");
+ STORAGE_TEST_CHECK(ok, "TC-STORAGE-03 file intact with injected bad blocks");
/* 校验注入坏块仍被报告为坏(未被 dhara 占用) */
int badok = 1;
for (int k = 0; k < nbad; k++) {
if (gd5f2gq5ue_is_block_bad(bad[k]) != 1) { badok = 0; }
}
- STORAGE_TEST_CHECK(badok, "TC-STO-03 injected blocks still reported bad");
+ STORAGE_TEST_CHECK(badok, "TC-STORAGE-03 injected blocks still reported bad");
f_unlink("bbt.dat");
/* 注意:注入的坏块已持久化,测试设备专用;如需恢复需重建 BBT / 重新格式化
- * (配套 TC-STO-04 恢复测试:storage_test.h 启用 ENABLE_STORAGE_RECOVERY_TESTS
+ * (配套 TC-STORAGE-04 恢复测试:storage_test.h 启用 ENABLE_STORAGE_RECOVERY_TESTS
* 后跑一次套件,即可清除运行时注入坏块 + 清 dhara map 回出厂态) */
}
-#endif /* ENABLE_DESTRUCTIVE_TESTS: s_perf_buf + TC-STO-01/02/03(写、擦、坏块注入) */
+#endif /* ENABLE_DESTRUCTIVE_TESTS: s_perf_buf + TC-STORAGE-01/02/03(写、擦、坏块注入) */
-/* TC-STO-05: 文件名/路径合法性校验(守护 ".fschk 无限重格式化" 真根因)
+/* TC-STORAGE-05: 文件名/路径合法性校验(守护 ".fschk 无限重格式化" 真根因)
* 本移植 FF_USE_LFN=0,只支持严格 8.3 短名(主名≤8、扩展≤3、不以点开头)。
* 非法名字 f_open 必返 FR_INVALID_NAME(纯 RAM 名字判定、不碰盘);合法但
* 不存在的名字返 FR_NO_FILE。本测试断言两类严格可区分——一旦哪天有人把
@@ -293,10 +293,10 @@ static void storage_test_name_validation(void)
"pipe|name" /* | */
};
- DBG_INFO("=== Storage Test: TC-STO-05 Filename validation ===");
+ DBG_INFO("=== Storage Test: TC-STORAGE-05 Filename validation ===");
if (f_mount(&fs, "", 1) != FR_OK) {
- STORAGE_TEST_CHECK(0, "TC-STO-05 mount");
+ STORAGE_TEST_CHECK(0, "TC-STORAGE-05 mount");
return;
}
@@ -310,7 +310,7 @@ static void storage_test_name_validation(void)
DBG_ERROR(" valid name wrongly rejected: '%s'", good[i]);
}
}
- STORAGE_TEST_CHECK(gok, "TC-STO-05 valid 8.3 names accepted");
+ STORAGE_TEST_CHECK(gok, "TC-STORAGE-05 valid 8.3 names accepted");
for (i = 0; i < (uint32_t)(sizeof(bad) / sizeof(bad[0])); i++) {
FRESULT r = f_open(&fil, bad[i], FA_READ);
@@ -325,11 +325,11 @@ static void storage_test_name_validation(void)
DBG_ERROR(" invalid name NOT rejected: '%s' -> fr=%d", bad[i], (int)r);
}
}
- STORAGE_TEST_CHECK(bok, "TC-STO-05 invalid names rejected (FR_INVALID_NAME)");
+ STORAGE_TEST_CHECK(bok, "TC-STORAGE-05 invalid names rejected (FR_INVALID_NAME)");
}
#ifdef ENABLE_DESTRUCTIVE_TESTS
-/* TC-STO-06: 打开模式与写回字节数语义(守护 FA_OPEN_APPEND / 短写陷阱)
+/* TC-STORAGE-06: 打开模式与写回字节数语义(守护 FA_OPEN_APPEND / 短写陷阱)
* 本移植 FA_OPEN_APPEND 不含 FA_WRITE → 不带写位打开 f_write 必返 FR_DENIED;
* 追加写必须 FA_WRITE|FA_OPEN_APPEND。另 f_write 簇耗尽返 FR_OK+短写(无错误
* 码),判成败必须校验写回字节数。锁定这两条移植专有语义防回归。
@@ -339,17 +339,17 @@ static void storage_test_open_modes(void)
UINT bw;
FRESULT r;
- DBG_INFO("=== Storage Test: TC-STO-06 Open-mode semantics ===");
+ DBG_INFO("=== Storage Test: TC-STORAGE-06 Open-mode semantics ===");
if (f_mount(&fs, "", 1) != FR_OK) {
- STORAGE_TEST_CHECK(0, "TC-STO-06 mount");
+ STORAGE_TEST_CHECK(0, "TC-STORAGE-06 mount");
return;
}
(void)f_unlink("mode.tmp");
/* 1) 建一个含初始内容的文件 */
r = f_open(&fil, "mode.tmp", FA_CREATE_ALWAYS | FA_WRITE);
- STORAGE_TEST_CHECK(r == FR_OK, "TC-STO-06 create base file");
+ STORAGE_TEST_CHECK(r == FR_OK, "TC-STORAGE-06 create base file");
if (r == FR_OK) {
f_write(&fil, "abc", 3, &bw);
f_close(&fil);
@@ -357,36 +357,36 @@ static void storage_test_open_modes(void)
/* 2) FA_OPEN_APPEND(无 FA_WRITE)→ 写必返 FR_DENIED */
r = f_open(&fil, "mode.tmp", FA_OPEN_APPEND);
- STORAGE_TEST_CHECK(r == FR_OK, "TC-STO-06 open append(no write)");
+ STORAGE_TEST_CHECK(r == FR_OK, "TC-STORAGE-06 open append(no write)");
if (r == FR_OK) {
FRESULT wr = f_write(&fil, "xyz", 3, &bw);
STORAGE_TEST_CHECK(wr == FR_DENIED,
- "TC-STO-06 append-no-write must DENY (fr=%d)", (int)wr);
+ "TC-STORAGE-06 append-no-write must DENY (fr=%d)", (int)wr);
f_close(&fil);
}
/* 3) FA_WRITE|FA_OPEN_APPEND → 追加成功且字节数正确 */
r = f_open(&fil, "mode.tmp", FA_WRITE | FA_OPEN_APPEND);
- STORAGE_TEST_CHECK(r == FR_OK, "TC-STO-06 open write|append");
+ STORAGE_TEST_CHECK(r == FR_OK, "TC-STORAGE-06 open write|append");
if (r == FR_OK) {
(void)f_write(&fil, "xyz", 3, &bw);
- STORAGE_TEST_CHECK(bw == 3, "TC-STO-06 append byte-count (%u)", bw);
+ STORAGE_TEST_CHECK(bw == 3, "TC-STORAGE-06 append byte-count (%u)", bw);
f_close(&fil);
}
/* 4) 只读打开后写 → 必返 FR_DENIED(读句柄不可写) */
r = f_open(&fil, "mode.tmp", FA_READ);
- STORAGE_TEST_CHECK(r == FR_OK, "TC-STO-06 open read-only");
+ STORAGE_TEST_CHECK(r == FR_OK, "TC-STORAGE-06 open read-only");
if (r == FR_OK) {
FRESULT wr = f_write(&fil, "q", 1, &bw);
STORAGE_TEST_CHECK(wr == FR_DENIED,
- "TC-STO-06 read-only write must DENY (fr=%d)", (int)wr);
+ "TC-STORAGE-06 read-only write must DENY (fr=%d)", (int)wr);
f_close(&fil);
}
(void)f_unlink("mode.tmp");
}
-#endif /* ENABLE_DESTRUCTIVE_TESTS: TC-STO-06 */
+#endif /* ENABLE_DESTRUCTIVE_TESTS: TC-STORAGE-06 */
#endif /* !ENABLE_STORAGE_RECOVERY_TESTS: 共享缓冲 + 正常测试函数 */
#ifdef ENABLE_STORAGE_RECOVERY_TESTS
@@ -506,7 +506,7 @@ static void storage_test_run_normal(void)
}
#endif /* ENABLE_DESTRUCTIVE_TESTS: 文件系统写读 + 性能压测 */
- /* ==================== 存储集成测试(TC-STO-05 契约 + 01~03 集成) ========== */
+ /* ==================== 存储集成测试(TC-STORAGE-05 契约 + 01~03 集成) ========== */
/* 纯语义契约测试(非破坏性):文件名合法性 */
storage_test_name_validation();
@@ -581,42 +581,42 @@ static void storage_test_wipe_visible(void)
DBG_INFO(" wiped %lu blocks (%lu skipped as bad, %lu visible)",
(unsigned long)done, (unsigned long)skipped, (unsigned long)usable);
- STORAGE_TEST_CHECK(done > 0U, "TC-STO-04 full wipe (%lu blocks erased)",
+ STORAGE_TEST_CHECK(done > 0U, "TC-STORAGE-04 full wipe (%lu blocks erased)",
(unsigned long)done);
}
#endif /* STORAGE_RECOVERY_FULL_WIPE */
-/* TC-STO-04: 维护模式(恢复 = 重建 BBT + 重新格式化;叠加全片擦除 = 容量恢复)
+/* TC-STORAGE-04: 维护模式(恢复 = 重建 BBT + 重新格式化;叠加全片擦除 = 容量恢复)
* 仅在启用 ENABLE_STORAGE_RECOVERY_TESTS 时编译运行;运行一次即可把设备
* 恢复到干净出厂态(清除运行时注入坏块并清空 dhara map)。
*/
static void storage_test_recover(void)
{
- DBG_INFO("=== Storage Test: TC-STO-04 maintenance (recovery / full wipe) ===");
+ DBG_INFO("=== Storage Test: TC-STORAGE-04 maintenance (recovery / full wipe) ===");
int r = gd5f2gq5ue_bbt_rebuild();
- STORAGE_TEST_CHECK(r == GD5F_OK, "TC-STO-04 bbt rebuild");
+ STORAGE_TEST_CHECK(r == GD5F_OK, "TC-STORAGE-04 bbt rebuild");
#ifdef STORAGE_RECOVERY_FULL_WIPE
storage_test_wipe_visible();
#else
nand_ftl_format();
- STORAGE_TEST_CHECK(1, "TC-STO-04 nand_ftl_format done");
+ STORAGE_TEST_CHECK(1, "TC-STORAGE-04 nand_ftl_format done");
#endif
uint8_t fb[GD5F_TOTAL_BLOCKS / 8];
uint32_t ver = 0;
if (gd5f_bbt_dump_flash(fb, &ver) == GD5F_OK) {
- STORAGE_TEST_CHECK(ver >= 1, "TC-STO-04 persisted BBT version=%lu", ver);
+ STORAGE_TEST_CHECK(ver >= 1, "TC-STORAGE-04 persisted BBT version=%lu", ver);
} else {
- STORAGE_TEST_CHECK(0, "TC-STO-04 dump_flash failed");
+ STORAGE_TEST_CHECK(0, "TC-STORAGE-04 dump_flash failed");
}
#ifdef STORAGE_RECOVERY_FULL_WIPE
- DBG_INFO("TC-STO-04 full wipe complete; power-cycle to rebuild fresh "
+ DBG_INFO("TC-STORAGE-04 full wipe complete; power-cycle to rebuild fresh "
"(capacity expected back to full)");
#else
- DBG_INFO("TC-STO-04 recovery complete; recommend power-cycle to re-init cleanly");
+ DBG_INFO("TC-STORAGE-04 recovery complete; recommend power-cycle to re-init cleanly");
#endif
}
#endif
diff --git a/test/board/test_config.h b/test/board/test_config.h
index 5d9aef92..d2123a9c 100644
--- a/test/board/test_config.h
+++ b/test/board/test_config.h
@@ -34,7 +34,7 @@ extern "C" {
/* === 破坏性测试总开关(默认关闭)===
* 破坏性用例会改变设备的**持久状态**,跑一次即有代价(2026-09-21 实测:GD5F 整轮
- * 破坏性用例跑一次即消耗一个 NAND 块,容量 95248 → 95200,且 TC-STO-04 恢复不回来):
+ * 破坏性用例跑一次即消耗一个 NAND 块,容量 95248 → 95200,且 TC-STORAGE-04 恢复不回来):
* - 向 BBT 持久化坏块标记 / 注入坏块(永久减少可用容量)
* - 写、擦 NAND 块(覆盖卷数据);格式化卷(nand_ftl_format / f_mkfs)
* - FatFS 建文件、写文件、性能压测
diff --git a/test/host/adc_health/adc_health_test.c b/test/host/adc_health/adc_health_test.c
index 724d9f90..e543d66d 100644
--- a/test/host/adc_health/adc_health_test.c
+++ b/test/host/adc_health/adc_health_test.c
@@ -14,17 +14,17 @@
* 3. 不占 MCU 的 RAM,毫秒级完成。
*
* 覆盖点(对应 docs/算法/继电保护功能复现规划.md §3.1 L1-6):
- * TC-AH-001 init + 首拍只建基线(不误报)
- * TC-AH-002 正常 1 kHz 推进 2000 拍:零故障零事件(健康不误报)
- * TC-AH-003 TPAFE 静默:99ms 不报 / 100ms 报 / 恢复清除电平位、锁存位留痕
- * TC-AH-004 STM32 静默:TPAFE 正常时只报 STM32 侧
- * TC-AH-005 TPAFE 丢帧:d=3 → tgap+=2、事件仅当拍(边沿语义)
- * TC-AH-006 STM32 gap 计数增量 → 事件(不入锁存:超拍非故障)
- * TC-AH-007 序号倒退 → SEQ_BACKWARD 锁存(前进后仍留痕)
- * TC-AH-008 FRSTDATA / STM32_ERR / HW_ERR 增量 → 事件位与锁存位编号一致
- * TC-AH-009 tick 回绕:跨 0xFFFFFFFF 的正常推进不误报静默;回绕后冻结仍报
- * TC-AH-010 NULL 守卫:in=NULL 跳过;out=NULL 只更新内部状态
- * TC-AH-011 init 幂等:故障后 re-init 全清
+ * TC-ADCHEALTH-001 init + 首拍只建基线(不误报)
+ * TC-ADCHEALTH-002 正常 1 kHz 推进 2000 拍:零故障零事件(健康不误报)
+ * TC-ADCHEALTH-003 TPAFE 静默:99ms 不报 / 100ms 报 / 恢复清除电平位、锁存位留痕
+ * TC-ADCHEALTH-004 STM32 静默:TPAFE 正常时只报 STM32 侧
+ * TC-ADCHEALTH-005 TPAFE 丢帧:d=3 → tgap+=2、事件仅当拍(边沿语义)
+ * TC-ADCHEALTH-006 STM32 gap 计数增量 → 事件(不入锁存:超拍非故障)
+ * TC-ADCHEALTH-007 序号倒退 → SEQ_BACKWARD 锁存(前进后仍留痕)
+ * TC-ADCHEALTH-008 FRSTDATA / STM32_ERR / HW_ERR 增量 → 事件位与锁存位编号一致
+ * TC-ADCHEALTH-009 tick 回绕:跨 0xFFFFFFFF 的正常推进不误报静默;回绕后冻结仍报
+ * TC-ADCHEALTH-010 NULL 守卫:in=NULL 跳过;out=NULL 只更新内部状态
+ * TC-ADCHEALTH-011 init 幂等:故障后 re-init 全清
*
* 通过:全部 TC PASS(main 返回 0)。
* 入口:int main(void),返回 0=PASS / 1=FAIL(由 run 脚本判读)。
@@ -66,7 +66,7 @@ static adc_health_in_t mk_in(uint32_t seq, uint32_t now_ms) {
/* ===================== TC ===================== */
-/* TC-AH-001:init + 首拍只建基线 */
+/* TC-ADCHEALTH-001:init + 首拍只建基线 */
static void tc_prime(void) {
adc_health_in_t in;
adc_health_status_t st;
@@ -76,14 +76,14 @@ static void tc_prime(void) {
adc_health_check(&in, &st);
CHECK((st.flags == 0u) && (st.events == 0u) && (st.sticky == 0u) &&
(st.tpafe_gaps == 0u),
- "TC-AH-001 first check only primes: no flags/events/sticky");
+ "TC-ADCHEALTH-001 first check only primes: no flags/events/sticky");
/* 第二拍序号未动但仅 1ms(< 门限)→ 仍不报 */
in.now_ms = 1001u;
adc_health_check(&in, &st);
- CHECK(st.flags == 0u, "TC-AH-001 1ms without advance is not a stall");
+ CHECK(st.flags == 0u, "TC-ADCHEALTH-001 1ms without advance is not a stall");
}
-/* TC-AH-002:正常 1 kHz 推进 2000 拍零误报 */
+/* TC-ADCHEALTH-002:正常 1 kHz 推进 2000 拍零误报 */
static void tc_healthy(void) {
adc_health_status_t st;
adc_health_in_t in;
@@ -100,10 +100,10 @@ static void tc_healthy(void) {
seq++;
now++;
}
- CHECK(ok, "TC-AH-002 healthy 1kHz sweep 2000 beats: zero flags/events");
+ CHECK(ok, "TC-ADCHEALTH-002 healthy 1kHz sweep 2000 beats: zero flags/events");
}
-/* TC-AH-003:TPAFE 静默 99/100ms 门限 + 恢复留痕 */
+/* TC-ADCHEALTH-003:TPAFE 静默 99/100ms 门限 + 恢复留痕 */
static void tc_tpafe_stall(void) {
adc_health_status_t st;
adc_health_in_t in;
@@ -127,28 +127,28 @@ static void tc_tpafe_stall(void) {
now++;
}
CHECK((st.flags & ADC_HF_TPAFE_STALL) == 0u,
- "TC-AH-003 no TPAFE stall before 100ms");
+ "TC-ADCHEALTH-003 no TPAFE stall before 100ms");
/* 第 100ms:报 */
in = mk_in(seq, now);
in.stm32_seq = seq + 100u;
adc_health_check(&in, &st);
CHECK((st.flags & ADC_HF_TPAFE_STALL) != 0u,
- "TC-AH-003 TPAFE stall at 100ms");
+ "TC-ADCHEALTH-003 TPAFE stall at 100ms");
CHECK((st.sticky & ADC_HF_TPAFE_STALL) != 0u,
- "TC-AH-003 stall latched into sticky");
+ "TC-ADCHEALTH-003 stall latched into sticky");
CHECK(st.tpafe_stall_ms >= ADC_HEALTH_STALL_MS,
- "TC-AH-003 stall_ms reported >= threshold");
+ "TC-ADCHEALTH-003 stall_ms reported >= threshold");
/* 恢复:TPAFE 序号重新前进 → 电平位清除、sticky 留痕 */
in = mk_in(seq + 1u, now + 1u);
in.stm32_seq = seq + 101u;
adc_health_check(&in, &st);
CHECK((st.flags & ADC_HF_TPAFE_STALL) == 0u,
- "TC-AH-003 stall level clears on recovery");
+ "TC-ADCHEALTH-003 stall level clears on recovery");
CHECK((adc_health_sticky() & ADC_HF_TPAFE_STALL) != 0u,
- "TC-AH-003 sticky keeps the fault trace after recovery");
+ "TC-ADCHEALTH-003 sticky keeps the fault trace after recovery");
}
-/* TC-AH-004:STM32 静默(TPAFE 正常) */
+/* TC-ADCHEALTH-004:STM32 静默(TPAFE 正常) */
static void tc_stm32_stall(void) {
adc_health_status_t st;
adc_health_in_t in;
@@ -169,12 +169,12 @@ static void tc_stm32_stall(void) {
adc_health_check(&in, &st);
}
CHECK((st.flags & ADC_HF_STM32_STALL) != 0u,
- "TC-AH-004 STM32 stall at 100ms");
+ "TC-ADCHEALTH-004 STM32 stall at 100ms");
CHECK((st.flags & ADC_HF_TPAFE_STALL) == 0u,
- "TC-AH-004 healthy TPAFE not falsely stalled");
+ "TC-ADCHEALTH-004 healthy TPAFE not falsely stalled");
}
-/* TC-AH-005:TPAFE 丢帧计数 + 边沿语义 */
+/* TC-ADCHEALTH-005:TPAFE 丢帧计数 + 边沿语义 */
static void tc_tpafe_gap(void) {
adc_health_status_t st;
adc_health_in_t in;
@@ -185,15 +185,15 @@ static void tc_tpafe_gap(void) {
in.tpafe_seq = 13u; in.stm32_seq = 11u; in.now_ms = 11u; /* TPAFE d=3 */
adc_health_check(&in, &st);
CHECK((st.events & ADC_HE_TPAFE_GAP) != 0u,
- "TC-AH-005 gap event on d>1");
- CHECK(st.tpafe_gaps == 2u, "TC-AH-005 d=3 accumulates 2 lost points");
+ "TC-ADCHEALTH-005 gap event on d>1");
+ CHECK(st.tpafe_gaps == 2u, "TC-ADCHEALTH-005 d=3 accumulates 2 lost points");
in.tpafe_seq = 14u; in.stm32_seq = 12u; in.now_ms = 12u; /* 恢复正常 d=1 */
adc_health_check(&in, &st);
- CHECK(st.events == 0u, "TC-AH-005 gap event is edge-only (next beat clean)");
- CHECK(st.tpafe_gaps == 2u, "TC-AH-005 gap counter is cumulative");
+ CHECK(st.events == 0u, "TC-ADCHEALTH-005 gap event is edge-only (next beat clean)");
+ CHECK(st.tpafe_gaps == 2u, "TC-ADCHEALTH-005 gap counter is cumulative");
}
-/* TC-AH-006:STM32 gap 计数增量 → 事件、不入锁存 */
+/* TC-ADCHEALTH-006:STM32 gap 计数增量 → 事件、不入锁存 */
static void tc_stm32_gap(void) {
adc_health_status_t st;
adc_health_in_t in;
@@ -204,13 +204,13 @@ static void tc_stm32_gap(void) {
in.stm32_gaps = 1u; in.tpafe_seq = 2u; in.stm32_seq = 2u; in.now_ms = 2u;
adc_health_check(&in, &st);
CHECK((st.events & ADC_HE_STM32_GAP) != 0u,
- "TC-AH-006 STM32 gap increment raises event");
+ "TC-ADCHEALTH-006 STM32 gap increment raises event");
CHECK((st.sticky & (ADC_HF_FRSTDATA | ADC_HF_STM32_ERR |
ADC_HF_HW_ERR)) == 0u,
- "TC-AH-006 gap does NOT latch sticky (overrun is not a fault)");
+ "TC-ADCHEALTH-006 gap does NOT latch sticky (overrun is not a fault)");
}
-/* TC-AH-007:序号倒退 → 锁存 */
+/* TC-ADCHEALTH-007:序号倒退 → 锁存 */
static void tc_backward(void) {
adc_health_status_t st;
adc_health_in_t in;
@@ -223,9 +223,9 @@ static void tc_backward(void) {
in.tpafe_seq = 995u; in.stm32_seq = 995u; in.now_ms = 101u; /* 倒退 */
adc_health_check(&in, &st);
CHECK((st.flags & ADC_HF_SEQ_BACKWARD) != 0u,
- "TC-AH-007 backward seq raises latched flag");
+ "TC-ADCHEALTH-007 backward seq raises latched flag");
CHECK((st.sticky & ADC_HF_SEQ_BACKWARD) != 0u,
- "TC-AH-007 backward latched into sticky");
+ "TC-ADCHEALTH-007 backward latched into sticky");
/* 恢复正常推进 50 拍:SEQ_BACKWARD 不清(锁存语义) */
s = 996u; t = 102u;
for (i = 0; i < 50; i++) {
@@ -234,10 +234,10 @@ static void tc_backward(void) {
s++; t++;
}
CHECK((adc_health_flags() & ADC_HF_SEQ_BACKWARD) != 0u,
- "TC-AH-007 SEQ_BACKWARD persists after normal advance");
+ "TC-ADCHEALTH-007 SEQ_BACKWARD persists after normal advance");
}
-/* TC-AH-008:三类错误计数增量 → 事件位与锁存位编号一致 */
+/* TC-ADCHEALTH-008:三类错误计数增量 → 事件位与锁存位编号一致 */
static void tc_err_counters(void) {
adc_health_status_t st;
adc_health_in_t in;
@@ -251,29 +251,29 @@ static void tc_err_counters(void) {
adc_health_check(&in, &st);
CHECK(((st.events & ADC_HE_FRSTDATA) != 0u) &&
((st.sticky & ADC_HF_FRSTDATA) != 0u),
- "TC-AH-008 FRSTDATA increment: event + sticky (same bit number)");
+ "TC-ADCHEALTH-008 FRSTDATA increment: event + sticky (same bit number)");
in.tpafe_seq = 3u; in.stm32_seq = 3u; in.now_ms = 3u;
in.stm32_errs = 1u;
adc_health_check(&in, &st);
CHECK(((st.events & ADC_HE_STM32_ERR) != 0u) &&
((st.sticky & ADC_HF_STM32_ERR) != 0u),
- "TC-AH-008 STM32 err increment: event + sticky (same bit number)");
+ "TC-ADCHEALTH-008 STM32 err increment: event + sticky (same bit number)");
in.tpafe_seq = 4u; in.stm32_seq = 4u; in.now_ms = 4u;
in.stm32_hw_errs = 1u;
adc_health_check(&in, &st);
CHECK(((st.events & ADC_HE_HW_ERR) != 0u) &&
((st.sticky & ADC_HF_HW_ERR) != 0u),
- "TC-AH-008 HAL err increment: event + sticky (same bit number)");
+ "TC-ADCHEALTH-008 HAL err increment: event + sticky (same bit number)");
/* 计数不再变化 → 事件不再重复触发 */
in.tpafe_seq = 5u; in.stm32_seq = 5u; in.now_ms = 5u;
adc_health_check(&in, &st);
- CHECK(st.events == 0u, "TC-AH-008 steady error counters raise no repeat events");
+ CHECK(st.events == 0u, "TC-ADCHEALTH-008 steady error counters raise no repeat events");
}
-/* TC-AH-009:tick 回绕安全 */
+/* TC-ADCHEALTH-009:tick 回绕安全 */
static void tc_tick_wrap(void) {
adc_health_status_t st;
adc_health_in_t in;
@@ -290,7 +290,7 @@ static void tc_tick_wrap(void) {
}
seq++; now++; /* uint32 自然回绕 */
}
- CHECK(ok, "TC-AH-009 tick wrap sweep: no false stall");
+ CHECK(ok, "TC-ADCHEALTH-009 tick wrap sweep: no false stall");
/* 回绕后两侧同时冻结。⚠ 第 1 拍消费 sweep 末尾的"未消费 +1"并重置计时起点
* → 第 i 拍 elapsed = i,需 101 拍才到 100ms */
for (i = 0; i < 101; i++) {
@@ -300,10 +300,10 @@ static void tc_tick_wrap(void) {
}
CHECK(((st.flags & ADC_HF_TPAFE_STALL) != 0u) &&
((st.flags & ADC_HF_STM32_STALL) != 0u),
- "TC-AH-009 stall still detected after tick wrap");
+ "TC-ADCHEALTH-009 stall still detected after tick wrap");
}
-/* TC-AH-010:NULL 守卫 */
+/* TC-ADCHEALTH-010:NULL 守卫 */
static void tc_null_guard(void) {
adc_health_status_t st;
adc_health_in_t in;
@@ -314,7 +314,7 @@ static void tc_null_guard(void) {
adc_health_check(&in, &st);
st.flags = 0xA5A5A5A5u;
adc_health_check(NULL, &st);
- CHECK(st.flags == 0xA5A5A5A5u, "TC-AH-010 in=NULL leaves out untouched");
+ CHECK(st.flags == 0xA5A5A5A5u, "TC-ADCHEALTH-010 in=NULL leaves out untouched");
/* out=NULL:内部状态照常更新(两侧冻结 101 拍 → 静默位应出现) */
for (i = 0; i < 101; i++) {
@@ -322,10 +322,10 @@ static void tc_null_guard(void) {
adc_health_check(&in, NULL);
}
CHECK((adc_health_flags() & ADC_HF_TPAFE_STALL) != 0u,
- "TC-AH-010 out=NULL still updates internal state");
+ "TC-ADCHEALTH-010 out=NULL still updates internal state");
}
-/* TC-AH-011:init 幂等 / 故障后全清 */
+/* TC-ADCHEALTH-011:init 幂等 / 故障后全清 */
static void tc_reinit(void) {
adc_health_status_t st;
adc_health_in_t in;
@@ -338,15 +338,15 @@ static void tc_reinit(void) {
in = mk_in(1u, (uint32_t)(2 + i));
adc_health_check(&in, &st);
}
- CHECK(st.sticky != 0u, "TC-AH-011 pre: sticky non-zero before re-init");
+ CHECK(st.sticky != 0u, "TC-ADCHEALTH-011 pre: sticky non-zero before re-init");
adc_health_init();
CHECK((adc_health_flags() == 0u) && (adc_health_sticky() == 0u) &&
(adc_health_tpafe_gaps() == 0u),
- "TC-AH-011 re-init clears flags/sticky/gaps");
+ "TC-ADCHEALTH-011 re-init clears flags/sticky/gaps");
in = mk_in(9u, 9u); /* 序号跳变也无妨:首拍只建基线 */
adc_health_check(&in, &st);
CHECK((st.flags == 0u) && (st.events == 0u),
- "TC-AH-011 re-prime after re-init is clean");
+ "TC-ADCHEALTH-011 re-prime after re-init is clean");
}
int main(void) {
diff --git a/test/host/adc_input/adc_input_test.c b/test/host/adc_input/adc_input_test.c
index d61c091a..85bf5ab8 100644
--- a/test/host/adc_input/adc_input_test.c
+++ b/test/host/adc_input/adc_input_test.c
@@ -18,51 +18,51 @@
* 3. 不占 MCU 的 RAM,毫秒级完成。
*
* 覆盖点(对应 docs/算法/继电保护功能复现规划.md §2.1 的 L1-3 / L1-4):
- * —— adc_input_init(TC-AI-001..006)——
- * TC-AI-001 poll 失败后失败计数可见(前置状态构造)
- * TC-AI-002 poll 成功后 TPAFE 侧可取数(前置状态构造)
- * TC-AI-003 init 返回 0(映射表自检通过)
- * TC-AI-004 init 后 STM32 状态码 = NOT_RUN
- * TC-AI-005 init 后失败计数归零
- * TC-AI-006 init 后 TPAFE / STM32 两侧均无有效数据(有效标志被清)
- * —— adc_input_desc(TC-AI-010..01A)——
- * TC-AI-010..018 九个语义通道 -> (来源, 下标) 与权威映射表逐项一致
- * TC-AI-019/01A 越界(ADC_SEM_COUNT)与负数语义 -> NULL
- * —— map_check(TC-AI-020)——
- * TC-AI-020 真实映射表自洽(反向路径结构上不可达,见文件末说明)
- * —— stm32_take(TC-AI-021..078,v2.0 DMA 模型)——
- * TC-AI-021..025 取到新帧:返回 0 / 状态码 / 不计失败 / DMA 只挂一次 / seq=1
- * TC-AI-026..02B **Rank -> 通道号映射**:UB->CH14(rank9) / UC->CH3(rank4) /
+ * —— adc_input_init(TC-ADCIN-001..006)——
+ * TC-ADCIN-001 poll 失败后失败计数可见(前置状态构造)
+ * TC-ADCIN-002 poll 成功后 TPAFE 侧可取数(前置状态构造)
+ * TC-ADCIN-003 init 返回 0(映射表自检通过)
+ * TC-ADCIN-004 init 后 STM32 状态码 = NOT_RUN
+ * TC-ADCIN-005 init 后失败计数归零
+ * TC-ADCIN-006 init 后 TPAFE / STM32 两侧均无有效数据(有效标志被清)
+ * —— adc_input_desc(TC-ADCIN-010..01A)——
+ * TC-ADCIN-010..018 九个语义通道 -> (来源, 下标) 与权威映射表逐项一致
+ * TC-ADCIN-019/01A 越界(ADC_SEM_COUNT)与负数语义 -> NULL
+ * —— map_check(TC-ADCIN-020)——
+ * TC-ADCIN-020 真实映射表自洽(反向路径结构上不可达,见文件末说明)
+ * —— stm32_take(TC-ADCIN-021..078,v2.0 DMA 模型)——
+ * TC-ADCIN-021..025 取到新帧:返回 0 / 状态码 / 不计失败 / DMA 只挂一次 / seq=1
+ * TC-ADCIN-026..02B **Rank -> 通道号映射**:UB->CH14(rank9) / UC->CH3(rank4) /
* IB->CH6(rank7) / IC->CH1(rank2) / IN->CH2(rank3) / TEMP->CH5(rank6)
- * TC-AI-02C stm32_take 不置 TPAFE 有效标志(两来源独立)
- * TC-AI-080..089 **乒乓双缓冲**:消费侧读"刚完成的半区",即使另一半正被 DMA
+ * TC-ADCIN-02C stm32_take 不置 TPAFE 有效标志(两来源独立)
+ * TC-ADCIN-080..089 **乒乓双缓冲**:消费侧读"刚完成的半区",即使另一半正被 DMA
* 改写也不得读到(撕裂帧防线);两拍交替半区、seq 推进;
* 超拍未消费 -> 记一次丢帧(gap),与停摆(err)分开计数
- * TC-AI-090..09A HAL 错误回调计数 + 三个回调的 `hadc == &hadc1` 句柄守卫
+ * TC-ADCIN-090..09A HAL 错误回调计数 + 三个回调的 `hadc == &hadc1` 句柄守卫
* (别的句柄不得污染本层 seq / hw_errs)
- * TC-AI-030..034 HAL_ADC_Start_DMA 失败:init 返回 -2 / 状态码 RC_START / 计数 +1
- * TC-AI-035..039 本拍无新帧:返回 RC_STALL / **单拍不计故障**(相位伪影)/ seq 不前进
- * TC-AI-03A..03E 连续两拍无新帧才计停摆;停摆与丢帧分开计数;恢复拍自愈
- * TC-AI-070..078 **停摆拍不得沿用上一拍旧值**(2026-10-10 补,真机实测发现的
+ * TC-ADCIN-030..034 HAL_ADC_Start_DMA 失败:init 返回 -2 / 状态码 RC_START / 计数 +1
+ * TC-ADCIN-035..039 本拍无新帧:返回 RC_STALL / **单拍不计故障**(相位伪影)/ seq 不前进
+ * TC-ADCIN-03A..03E 连续两拍无新帧才计停摆;停摆与丢帧分开计数;恢复拍自愈
+ * TC-ADCIN-070..078 **停摆拍不得沿用上一拍旧值**(2026-10-10 补,真机实测发现的
* 正确性缺陷;DMA 版改由"无新帧"触发同一路径):先成功一拍让
* STM32 侧进入有效态,再注入无新帧拍 -> adc_input_raw() 必须返 -2;
- * 恢复拍重新置有效。TC-AI-034 只覆盖"挂载失败即无数据",
+ * 恢复拍重新置有效。TC-ADCIN-034 只覆盖"挂载失败即无数据",
* 照不出"成功过之后停摆 → 静默沿用旧值",故单独立一组。
- * —— adc_input_raw(TC-AI-040..04B)——
- * TC-AI-040..043 参数守卫:out=NULL / 越界 / 负数 -> -1,且不写 out
- * TC-AI-044/045 无有效数据 -> -2(两来源分别)
- * TC-AI-046..048 poll 快照契约:返回码透传 / 请求 8 通道 / 目的缓冲非空
- * TC-AI-049..04B TPAFE 按**下标**取数(UA=6 / UN=5 / IA=2)且补码负值原样保留
- * —— adc_input_poll(TC-AI-050..058)——
- * TC-AI-050..052 无新帧(0):返回 0 / TPAFE 无效 / STM32 侧照常扫描
- * TC-AI-053/054 参数错(-1):返回 -1 / TPAFE 无效
- * TC-AI-055 已有有效帧后再"无新帧"**不清零**(保持上次有效值)
- * TC-AI-056..058 STM32 失败**不阻断** TPAFE、**不影响** poll 返回值,另由状态码暴露
- * —— adc_input_stm32_rc / _errs(TC-AI-060..066)——
- * TC-AI-060/061 init 后 = NOT_RUN / 计数 0
- * TC-AI-062 成功: rc=OK 且 errs 不变
- * TC-AI-063/064 两次失败累计 = 2,rc = 最近一次(TIMEOUT)
- * TC-AI-065/066 恢复成功 rc=OK,errs 单调不回退
+ * —— adc_input_raw(TC-ADCIN-040..04B)——
+ * TC-ADCIN-040..043 参数守卫:out=NULL / 越界 / 负数 -> -1,且不写 out
+ * TC-ADCIN-044/045 无有效数据 -> -2(两来源分别)
+ * TC-ADCIN-046..048 poll 快照契约:返回码透传 / 请求 8 通道 / 目的缓冲非空
+ * TC-ADCIN-049..04B TPAFE 按**下标**取数(UA=6 / UN=5 / IA=2)且补码负值原样保留
+ * —— adc_input_poll(TC-ADCIN-050..058)——
+ * TC-ADCIN-050..052 无新帧(0):返回 0 / TPAFE 无效 / STM32 侧照常扫描
+ * TC-ADCIN-053/054 参数错(-1):返回 -1 / TPAFE 无效
+ * TC-ADCIN-055 已有有效帧后再"无新帧"**不清零**(保持上次有效值)
+ * TC-ADCIN-056..058 STM32 失败**不阻断** TPAFE、**不影响** poll 返回值,另由状态码暴露
+ * —— adc_input_stm32_rc / _errs(TC-ADCIN-060..066)——
+ * TC-ADCIN-060/061 init 后 = NOT_RUN / 计数 0
+ * TC-ADCIN-062 成功: rc=OK 且 errs 不变
+ * TC-ADCIN-063/064 两次失败累计 = 2,rc = 最近一次(TIMEOUT)
+ * TC-ADCIN-065/066 恢复成功 rc=OK,errs 单调不回退
*
* 通过:全部 TC PASS(main 返回 0)。
* 入口:int main(void),返回 0=PASS / 1=FAIL(由 run 脚本判读)。
@@ -201,7 +201,7 @@ static void dma_beat(uint16_t base) {
}
}
-/* ===================== TC-AI-001..006:init ===================== */
+/* ===================== TC-ADCIN-001..006:init ===================== */
static void tc_init(void) {
int32_t v = -999;
@@ -213,69 +213,69 @@ static void tc_init(void) {
(void)adc_input_poll(); /* 单拍无新帧 = 相位伪影,不计故障 */
(void)adc_input_poll(); /* 连续第二拍无新帧 = 真停摆 */
- CHECK(adc_input_stm32_errs() == 1u, "TC-AI-001 连续两拍无新帧 -> 停摆计数 = 1");
+ CHECK(adc_input_stm32_errs() == 1u, "TC-ADCIN-001 连续两拍无新帧 -> 停摆计数 = 1");
CHECK((adc_input_raw(ADC_SEM_UA, &v) == 0) && (v == 4321),
- "TC-AI-002 poll 后 UA 可取数且值正确");
+ "TC-ADCIN-002 poll 后 UA 可取数且值正确");
- CHECK(adc_input_init() == 0, "TC-AI-003 adc_input_init 返回 0(映射自检通过)");
+ CHECK(adc_input_init() == 0, "TC-ADCIN-003 adc_input_init 返回 0(映射自检通过)");
CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_NOT_RUN,
- "TC-AI-004 init 后 STM32 状态码 = NOT_RUN");
- CHECK(s_start_dma_calls == 1, "TC-AI-003B init 挂载 DMA 恰好一次");
- CHECK(s_dma_len == (2u * ADC_INPUT_STM32_CH_NUM), "TC-AI-003C DMA 长度 = 2 x 9(乒乓双缓冲)");
- CHECK(s_dma_buf != NULL, "TC-AI-003D DMA 目的缓冲地址已交下来");
- CHECK(adc_input_stm32_seq() == 0u, "TC-AI-005B init 后 DMA 完成计数 = 0");
- CHECK(adc_input_stm32_errs() == 0u, "TC-AI-005 init 后 STM32 失败计数归零");
+ "TC-ADCIN-004 init 后 STM32 状态码 = NOT_RUN");
+ CHECK(s_start_dma_calls == 1, "TC-ADCIN-003B init 挂载 DMA 恰好一次");
+ CHECK(s_dma_len == (2u * ADC_INPUT_STM32_CH_NUM), "TC-ADCIN-003C DMA 长度 = 2 x 9(乒乓双缓冲)");
+ CHECK(s_dma_buf != NULL, "TC-ADCIN-003D DMA 目的缓冲地址已交下来");
+ CHECK(adc_input_stm32_seq() == 0u, "TC-ADCIN-005B init 后 DMA 完成计数 = 0");
+ CHECK(adc_input_stm32_errs() == 0u, "TC-ADCIN-005 init 后 STM32 失败计数归零");
CHECK((adc_input_raw(ADC_SEM_UA, &v) == -2) && (adc_input_raw(ADC_SEM_UB, &v) == -2),
- "TC-AI-006 init 后 TPAFE / STM32 两侧均无有效数据");
+ "TC-ADCIN-006 init 后 TPAFE / STM32 两侧均无有效数据");
}
-/* ===================== TC-AI-010..01A:desc 映射表 ===================== */
+/* ===================== TC-ADCIN-010..01A:desc 映射表 ===================== */
static void tc_desc(void) {
const adc_channel_desc_t *d;
d = adc_input_desc(ADC_SEM_UA);
CHECK((d != NULL) && (d->source == ADC_SRC_TPAFE) && (d->index == 6u),
- "TC-AI-010 UA -> TPAFE buf[6]");
+ "TC-ADCIN-010 UA -> TPAFE buf[6]");
d = adc_input_desc(ADC_SEM_UB);
CHECK((d != NULL) && (d->source == ADC_SRC_STM32) && (d->index == 14u),
- "TC-AI-011 UB -> STM32 CH14");
+ "TC-ADCIN-011 UB -> STM32 CH14");
d = adc_input_desc(ADC_SEM_UC);
CHECK((d != NULL) && (d->source == ADC_SRC_STM32) && (d->index == 3u),
- "TC-AI-012 UC -> STM32 CH3");
+ "TC-ADCIN-012 UC -> STM32 CH3");
d = adc_input_desc(ADC_SEM_UN);
CHECK((d != NULL) && (d->source == ADC_SRC_TPAFE) && (d->index == 5u),
- "TC-AI-013 UN -> TPAFE buf[5]");
+ "TC-ADCIN-013 UN -> TPAFE buf[5]");
d = adc_input_desc(ADC_SEM_IA);
CHECK((d != NULL) && (d->source == ADC_SRC_TPAFE) && (d->index == 2u),
- "TC-AI-014 IA -> TPAFE buf[2]");
+ "TC-ADCIN-014 IA -> TPAFE buf[2]");
d = adc_input_desc(ADC_SEM_IB);
CHECK((d != NULL) && (d->source == ADC_SRC_STM32) && (d->index == 6u),
- "TC-AI-015 IB -> STM32 CH6");
+ "TC-ADCIN-015 IB -> STM32 CH6");
d = adc_input_desc(ADC_SEM_IC);
CHECK((d != NULL) && (d->source == ADC_SRC_STM32) && (d->index == 1u),
- "TC-AI-016 IC -> STM32 CH1");
+ "TC-ADCIN-016 IC -> STM32 CH1");
d = adc_input_desc(ADC_SEM_IN);
CHECK((d != NULL) && (d->source == ADC_SRC_STM32) && (d->index == 2u),
- "TC-AI-017 IN -> STM32 CH2");
+ "TC-ADCIN-017 IN -> STM32 CH2");
d = adc_input_desc(ADC_SEM_TEMP);
CHECK((d != NULL) && (d->source == ADC_SRC_STM32) && (d->index == 5u),
- "TC-AI-018 TEMP -> STM32 CH5");
+ "TC-ADCIN-018 TEMP -> STM32 CH5");
- CHECK(adc_input_desc(ADC_SEM_COUNT) == NULL, "TC-AI-019 越界(ADC_SEM_COUNT) -> NULL");
- CHECK(adc_input_desc((adc_semantic_t)(-1)) == NULL, "TC-AI-01A 负数语义 -> NULL");
+ CHECK(adc_input_desc(ADC_SEM_COUNT) == NULL, "TC-ADCIN-019 越界(ADC_SEM_COUNT) -> NULL");
+ CHECK(adc_input_desc((adc_semantic_t)(-1)) == NULL, "TC-ADCIN-01A 负数语义 -> NULL");
}
-/* ===================== TC-AI-020:map_check ===================== */
+/* ===================== TC-ADCIN-020:map_check ===================== */
static void tc_map_check(void) {
/* 真实映射表自洽:TPAFE 下标 < 8 且每个 STM32 通道号都出现在扫描 Rank 内。
* 反向路径(表不自洽 -> -1)需在运行时改表,而 k_adc_map / k_stm32_rank_ch 均为
* 编译期 static const、无运行时输入可使其不自洽 -> 结构上不可达(见文件末说明)。 */
- CHECK(map_check() == 0, "TC-AI-020 映射表自洽(TPAFE 下标与 STM32 Rank 均在范围内)");
+ CHECK(map_check() == 0, "TC-ADCIN-020 映射表自洽(TPAFE 下标与 STM32 Rank 均在范围内)");
}
-/* ===================== TC-AI-021..02C:stm32_scan 成功路径 ===================== */
+/* ===================== TC-ADCIN-021..02C:stm32_scan 成功路径 ===================== */
static void tc_take_ok(void) {
int32_t v = 0;
@@ -284,25 +284,25 @@ static void tc_take_ok(void) {
(void)adc_input_init();
dma_beat(100); /* 前半区一帧:Rank i -> 100+i */
- CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-AI-021 stm32_take 取到新帧 -> 0");
- CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_OK, "TC-AI-022 状态码 = RC_OK");
- CHECK(adc_input_stm32_errs() == 0u, "TC-AI-023 成功不计入失败");
- CHECK(s_start_dma_calls == 1, "TC-AI-024 DMA 只在 init 挂一次(每拍不重启)");
- CHECK(adc_input_stm32_seq() == 1u, "TC-AI-025 DMA 完成计数 = 1");
+ CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-021 stm32_take 取到新帧 -> 0");
+ CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_OK, "TC-ADCIN-022 状态码 = RC_OK");
+ CHECK(adc_input_stm32_errs() == 0u, "TC-ADCIN-023 成功不计入失败");
+ CHECK(s_start_dma_calls == 1, "TC-ADCIN-024 DMA 只在 init 挂一次(每拍不重启)");
+ CHECK(adc_input_stm32_seq() == 1u, "TC-ADCIN-025 DMA 完成计数 = 1");
/* Rank -> 通道号映射:第 i 个 Rank = 100+i。
* k_stm32_rank_ch = [CH0..CH7, CH14],故 CH3->103 / CH5->105 / CH6->106 / CH14->108。 */
- CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 108), "TC-AI-026 UB 取到 CH14(rank9)=108");
- CHECK((adc_input_raw(ADC_SEM_UC, &v) == 0) && (v == 103), "TC-AI-027 UC 取到 CH3(rank4)=103");
- CHECK((adc_input_raw(ADC_SEM_IB, &v) == 0) && (v == 106), "TC-AI-028 IB 取到 CH6(rank7)=106");
- CHECK((adc_input_raw(ADC_SEM_IC, &v) == 0) && (v == 101), "TC-AI-029 IC 取到 CH1(rank2)=101");
- CHECK((adc_input_raw(ADC_SEM_IN, &v) == 0) && (v == 102), "TC-AI-02A IN 取到 CH2(rank3)=102");
- CHECK((adc_input_raw(ADC_SEM_TEMP, &v) == 0) && (v == 105), "TC-AI-02B TEMP 取到 CH5(rank6)=105");
+ CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 108), "TC-ADCIN-026 UB 取到 CH14(rank9)=108");
+ CHECK((adc_input_raw(ADC_SEM_UC, &v) == 0) && (v == 103), "TC-ADCIN-027 UC 取到 CH3(rank4)=103");
+ CHECK((adc_input_raw(ADC_SEM_IB, &v) == 0) && (v == 106), "TC-ADCIN-028 IB 取到 CH6(rank7)=106");
+ CHECK((adc_input_raw(ADC_SEM_IC, &v) == 0) && (v == 101), "TC-ADCIN-029 IC 取到 CH1(rank2)=101");
+ CHECK((adc_input_raw(ADC_SEM_IN, &v) == 0) && (v == 102), "TC-ADCIN-02A IN 取到 CH2(rank3)=102");
+ CHECK((adc_input_raw(ADC_SEM_TEMP, &v) == 0) && (v == 105), "TC-ADCIN-02B TEMP 取到 CH5(rank6)=105");
- CHECK(adc_input_raw(ADC_SEM_UA, &v) == -2, "TC-AI-02C stm32_take 不置 TPAFE 有效标志");
+ CHECK(adc_input_raw(ADC_SEM_UA, &v) == -2, "TC-ADCIN-02C stm32_take 不置 TPAFE 有效标志");
}
-/* ============ TC-AI-080..085:乒乓双缓冲(读刚完成半区,不读正在写的半区) ============
+/* ============ TC-ADCIN-080..085:乒乓双缓冲(读刚完成半区,不读正在写的半区) ============
* 这是 DMA 方案最关键的一条:消费侧必须读"上一拍刚完成的那一半",而 DMA 此刻正在
* 写另一半。若读错半区,取到的是**正在被改写**的数据 → 半新半旧的撕裂帧。 */
@@ -314,30 +314,30 @@ static void tc_dma_pingpong(void) {
dma_beat(100); /* 第 1 帧 -> 前半区(半传输回调) */
dma_fill(1u, 900u); /* 模拟 DMA 正在写后半区(值 900 系) */
- CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-AI-080 第一拍取帧成功");
+ CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-080 第一拍取帧成功");
CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 108),
- "TC-AI-081 读的是刚完成的前半区(108),不是正在写的后半区");
+ "TC-ADCIN-081 读的是刚完成的前半区(108),不是正在写的后半区");
dma_beat(200); /* 第 2 帧 -> 后半区(传输完成回调) */
dma_fill(0u, 800u); /* 模拟 DMA 正在写前半区(值 800 系) */
- CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-AI-082 第二拍取帧成功");
+ CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-082 第二拍取帧成功");
CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 208),
- "TC-AI-083 第二拍读到后半区(208)");
- CHECK(adc_input_stm32_seq() == 2u, "TC-AI-084 DMA 完成计数 = 2");
+ "TC-ADCIN-083 第二拍读到后半区(208)");
+ CHECK(adc_input_stm32_seq() == 2u, "TC-ADCIN-084 DMA 完成计数 = 2");
/* 半区奇偶口径:seq=1 -> 前半区,seq=2 -> 后半区(与 dma_beat 独立推导,互相证伪) */
- CHECK(((adc_input_raw(ADC_SEM_UC, &v) == 0) && (v == 203)), "TC-AI-085 UC 同帧内一致(203)");
+ CHECK(((adc_input_raw(ADC_SEM_UC, &v) == 0) && (v == 203)), "TC-ADCIN-085 UC 同帧内一致(203)");
/* 消费者超拍:两拍都没取 -> 中间那帧已被乒乓缓冲覆盖 -> 记一次丢帧 */
dma_beat(300);
dma_beat(400);
- CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-AI-086 超拍后仍取到最新帧");
- CHECK(adc_input_stm32_gaps() == 1u, "TC-AI-087 seq 前进 2 -> 记一次丢帧");
- CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 408), "TC-AI-088 取到的是最新帧(408)");
- CHECK(adc_input_stm32_errs() == 0u, "TC-AI-089 丢帧不计入停摆(两类故障分开)");
+ CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-086 超拍后仍取到最新帧");
+ CHECK(adc_input_stm32_gaps() == 1u, "TC-ADCIN-087 seq 前进 2 -> 记一次丢帧");
+ CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 408), "TC-ADCIN-088 取到的是最新帧(408)");
+ CHECK(adc_input_stm32_errs() == 0u, "TC-ADCIN-089 丢帧不计入停摆(两类故障分开)");
}
-/* ============ TC-AI-090..093:HAL 错误回调与句柄守卫 ============ */
+/* ============ TC-ADCIN-090..093:HAL 错误回调与句柄守卫 ============ */
static void tc_hw_errs(void) {
fakes_reset();
@@ -345,21 +345,21 @@ static void tc_hw_errs(void) {
HAL_ADC_ErrorCallback(&hadc1);
HAL_ADC_ErrorCallback(&hadc1);
- CHECK(adc_input_stm32_hw_errs() == 2u, "TC-AI-090 错误回调累计 = 2");
+ CHECK(adc_input_stm32_hw_errs() == 2u, "TC-ADCIN-090 错误回调累计 = 2");
HAL_ADC_ErrorCallback(&hadc_other);
- CHECK(adc_input_stm32_hw_errs() == 2u, "TC-AI-091 别的 ADC 句柄不得计入(hadc 守卫)");
+ CHECK(adc_input_stm32_hw_errs() == 2u, "TC-ADCIN-091 别的 ADC 句柄不得计入(hadc 守卫)");
HAL_ADC_ConvHalfCpltCallback(&hadc_other);
HAL_ADC_ConvCpltCallback(&hadc_other);
- CHECK(adc_input_stm32_seq() == 0u, "TC-AI-092 别的句柄的完成回调不得推进 seq");
+ CHECK(adc_input_stm32_seq() == 0u, "TC-ADCIN-092 别的句柄的完成回调不得推进 seq");
HAL_ADC_ErrorCallback(&hadc1);
- CHECK(adc_input_stm32_hw_errs() == 3u, "TC-AI-093 hw_errs 与 errs 分开计数、互不干扰");
- CHECK(adc_input_stm32_errs() == 0u, "TC-AI-09A hw_errs 不污染 errs");
+ CHECK(adc_input_stm32_hw_errs() == 3u, "TC-ADCIN-093 hw_errs 与 errs 分开计数、互不干扰");
+ CHECK(adc_input_stm32_errs() == 0u, "TC-ADCIN-09A hw_errs 不污染 errs");
}
-/* ===================== TC-AI-030..034:DMA 挂载失败 ===================== */
+/* ===================== TC-ADCIN-030..034:DMA 挂载失败 ===================== */
static void tc_init_dma_fail(void) {
int32_t v = 0;
@@ -367,13 +367,13 @@ static void tc_init_dma_fail(void) {
fakes_reset();
s_start_dma_rc = HAL_ERROR;
- CHECK(adc_input_init() == -2, "TC-AI-030 HAL_ADC_Start_DMA 失败 -> init 返回 -2");
- CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_START, "TC-AI-031 状态码 = RC_START");
- CHECK(adc_input_stm32_errs() == 1u, "TC-AI-032 失败计数 +1");
- CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-AI-034 挂载失败后 STM32 侧无有效数据");
+ CHECK(adc_input_init() == -2, "TC-ADCIN-030 HAL_ADC_Start_DMA 失败 -> init 返回 -2");
+ CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_START, "TC-ADCIN-031 状态码 = RC_START");
+ CHECK(adc_input_stm32_errs() == 1u, "TC-ADCIN-032 失败计数 +1");
+ CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-ADCIN-034 挂载失败后 STM32 侧无有效数据");
}
-/* ===================== TC-AI-035..03A:本拍无新帧(停摆) ===================== */
+/* ===================== TC-ADCIN-035..03A:本拍无新帧(停摆) ===================== */
static void tc_take_stall(void) {
int32_t v = 0;
@@ -382,29 +382,29 @@ static void tc_take_stall(void) {
(void)adc_input_init();
/* 没有任何 DMA 完成回调 = TIM3 未启动 / ADC 停摆 / DMA 出错 */
- CHECK(stm32_take() == ADC_INPUT_RC_STALL, "TC-AI-035 无新帧 -> RC_STALL(-2)");
- CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_STALL, "TC-AI-036 状态码 = RC_STALL");
- CHECK(adc_input_stm32_errs() == 0u, "TC-AI-037 单拍无新帧不计故障(相位伪影)");
- CHECK(adc_input_stm32_seq() == 0u, "TC-AI-038 停摆期间 seq 不前进");
- CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-AI-039 停摆拍 STM32 侧无有效数据");
+ CHECK(stm32_take() == ADC_INPUT_RC_STALL, "TC-ADCIN-035 无新帧 -> RC_STALL(-2)");
+ CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_STALL, "TC-ADCIN-036 状态码 = RC_STALL");
+ CHECK(adc_input_stm32_errs() == 0u, "TC-ADCIN-037 单拍无新帧不计故障(相位伪影)");
+ CHECK(adc_input_stm32_seq() == 0u, "TC-ADCIN-038 停摆期间 seq 不前进");
+ CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-ADCIN-039 停摆拍 STM32 侧无有效数据");
(void)stm32_take(); /* 连续第二拍无新帧 = 真停摆 */
- CHECK(adc_input_stm32_errs() == 1u, "TC-AI-03A 连续两拍无新帧 -> 停摆计数 = 1");
+ CHECK(adc_input_stm32_errs() == 1u, "TC-ADCIN-03A 连续两拍无新帧 -> 停摆计数 = 1");
(void)stm32_take(); /* 第三拍仍无新帧 */
- CHECK(adc_input_stm32_errs() == 2u, "TC-AI-03B 停摆持续 -> 每拍累计 = 2");
- CHECK(adc_input_stm32_gaps() == 0u, "TC-AI-03C 停摆不计入丢帧(两类故障分开)");
+ CHECK(adc_input_stm32_errs() == 2u, "TC-ADCIN-03B 停摆持续 -> 每拍累计 = 2");
+ CHECK(adc_input_stm32_gaps() == 0u, "TC-ADCIN-03C 停摆不计入丢帧(两类故障分开)");
dma_beat(100); /* 恢复 */
- CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-AI-03D 恢复后取帧成功");
- CHECK(adc_input_stm32_gaps() == 0u, "TC-AI-03E 恢复拍前进 1 -> 不算丢帧");
+ CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-03D 恢复后取帧成功");
+ CHECK(adc_input_stm32_gaps() == 0u, "TC-ADCIN-03E 恢复拍前进 1 -> 不算丢帧");
}
-/* ============ TC-AI-070..078:停摆拍不得沿用上一拍旧值(陈旧帧) ============
+/* ============ TC-ADCIN-070..078:停摆拍不得沿用上一拍旧值(陈旧帧) ============
* 背景(2026-10-10 真机实测发现):本层只有一份 s_stm32_raw[],而 s_stm32_valid
* 此前只在成功时置 1、失败时**从不清零** → 消费侧照样取数、照样压入采样环,
* s_frames_skip 抓不到。轮询版的触发路径是"超时拍半新半旧",DMA 版(v2.0)改成
* "本拍无新帧仍沿用上一拍"——**同一条缺陷、同一个防线**,故本组用例保留。
- * TC-AI-034 是"挂载失败后本就无数据"(valid 一直是 0),照不出这条路径——
+ * TC-ADCIN-034 是"挂载失败后本就无数据"(valid 一直是 0),照不出这条路径——
* 必须先成功一拍。 */
static void tc_take_stale(void) {
@@ -414,27 +414,27 @@ static void tc_take_stale(void) {
fakes_reset();
(void)adc_input_init();
dma_beat(100);
- CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-AI-070 前置:首拍成功");
- CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 108), "TC-AI-071 前置:UB 取到 108(有效态)");
+ CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-070 前置:首拍成功");
+ CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 108), "TC-ADCIN-071 前置:UB 取到 108(有效态)");
/* 第二拍没有任何 DMA 完成(TIM3 停 / ADC 停摆 / DMA 出错) */
- CHECK(stm32_take() == ADC_INPUT_RC_STALL, "TC-AI-072 第二拍无新帧");
- CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-AI-073 停摆拍不得沿用上一拍值 -> -2");
- CHECK(adc_input_raw(ADC_SEM_UC, &v) == -2, "TC-AI-074 停摆拍连其它 STM32 通道也不得出数");
- CHECK(adc_input_raw(ADC_SEM_TEMP, &v) == -2, "TC-AI-074B 同上(TEMP 亦 -2)");
+ CHECK(stm32_take() == ADC_INPUT_RC_STALL, "TC-ADCIN-072 第二拍无新帧");
+ CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-ADCIN-073 停摆拍不得沿用上一拍值 -> -2");
+ CHECK(adc_input_raw(ADC_SEM_UC, &v) == -2, "TC-ADCIN-074 停摆拍连其它 STM32 通道也不得出数");
+ CHECK(adc_input_raw(ADC_SEM_TEMP, &v) == -2, "TC-ADCIN-074B 同上(TEMP 亦 -2)");
dma_beat(200);
- CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-AI-075 第三拍恢复成功");
- CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 208), "TC-AI-076 恢复拍重新可取数(自愈)");
+ CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-075 第三拍恢复成功");
+ CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 208), "TC-ADCIN-076 恢复拍重新可取数(自愈)");
/* --- 挂载失败支路:同样不得沿用(init 失败后整层无有效数据) --- */
fakes_reset();
s_start_dma_rc = HAL_ERROR;
(void)adc_input_init();
- CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-AI-078 挂载失败后不得取到任何值 -> -2");
+ CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-ADCIN-078 挂载失败后不得取到任何值 -> -2");
}
-/* ===================== TC-AI-040..045:raw 参数守卫与无数据 ===================== */
+/* ===================== TC-ADCIN-040..045:raw 参数守卫与无数据 ===================== */
static void tc_raw_guards(void) {
int32_t v = 0;
@@ -442,15 +442,15 @@ static void tc_raw_guards(void) {
fakes_reset();
(void)adc_input_init();
- CHECK(adc_input_raw(ADC_SEM_UA, NULL) == -1, "TC-AI-040 out=NULL -> -1");
- CHECK(adc_input_raw(ADC_SEM_COUNT, &v) == -1, "TC-AI-041 ch 越界 -> -1");
- CHECK(adc_input_raw((adc_semantic_t)(-1), &v) == -1, "TC-AI-042 ch 负数 -> -1");
- CHECK(v == 0, "TC-AI-043 参数错时不写 out");
- CHECK(adc_input_raw(ADC_SEM_UA, &v) == -2, "TC-AI-044 TPAFE 无有效帧 -> -2");
- CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-AI-045 STM32 无有效扫描 -> -2");
+ CHECK(adc_input_raw(ADC_SEM_UA, NULL) == -1, "TC-ADCIN-040 out=NULL -> -1");
+ CHECK(adc_input_raw(ADC_SEM_COUNT, &v) == -1, "TC-ADCIN-041 ch 越界 -> -1");
+ CHECK(adc_input_raw((adc_semantic_t)(-1), &v) == -1, "TC-ADCIN-042 ch 负数 -> -1");
+ CHECK(v == 0, "TC-ADCIN-043 参数错时不写 out");
+ CHECK(adc_input_raw(ADC_SEM_UA, &v) == -2, "TC-ADCIN-044 TPAFE 无有效帧 -> -2");
+ CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-ADCIN-045 STM32 无有效扫描 -> -2");
}
-/* ===================== TC-AI-046..04B:raw TPAFE 取数与补码 ===================== */
+/* ===================== TC-ADCIN-046..04B:raw TPAFE 取数与补码 ===================== */
static void tc_raw_tpafe(void) {
int32_t v = 0;
@@ -468,16 +468,16 @@ static void tc_raw_tpafe(void) {
s_fake_tpafe[7] = 1007;
s_snapshot_rc = 1;
- CHECK(adc_input_poll() == 1, "TC-AI-046 poll 透传 TPAFE 快照码 1");
- CHECK(s_snapshot_count == (uint8_t)ADC_INPUT_TPAFE_CH_NUM, "TC-AI-047 快照请求 8 通道");
- CHECK(s_snapshot_dst != NULL, "TC-AI-048 快照目的缓冲非空");
- CHECK((adc_input_raw(ADC_SEM_UA, &v) == 0) && (v == 3006), "TC-AI-049 UA -> buf[6]=3006");
- CHECK((adc_input_raw(ADC_SEM_UN, &v) == 0) && (v == 2005), "TC-AI-04A UN -> buf[5]=2005");
+ CHECK(adc_input_poll() == 1, "TC-ADCIN-046 poll 透传 TPAFE 快照码 1");
+ CHECK(s_snapshot_count == (uint8_t)ADC_INPUT_TPAFE_CH_NUM, "TC-ADCIN-047 快照请求 8 通道");
+ CHECK(s_snapshot_dst != NULL, "TC-ADCIN-048 快照目的缓冲非空");
+ CHECK((adc_input_raw(ADC_SEM_UA, &v) == 0) && (v == 3006), "TC-ADCIN-049 UA -> buf[6]=3006");
+ CHECK((adc_input_raw(ADC_SEM_UN, &v) == 0) && (v == 2005), "TC-ADCIN-04A UN -> buf[5]=2005");
CHECK((adc_input_raw(ADC_SEM_IA, &v) == 0) && (v == -1234),
- "TC-AI-04B IA -> buf[2]=-1234(补码负值原样保留)");
+ "TC-ADCIN-04B IA -> buf[2]=-1234(补码负值原样保留)");
}
-/* ===================== TC-AI-050..058:poll 契约 ===================== */
+/* ===================== TC-ADCIN-050..058:poll 契约 ===================== */
static void tc_poll(void) {
int32_t v = 0;
@@ -487,16 +487,16 @@ static void tc_poll(void) {
(void)adc_input_init();
s_snapshot_rc = 0;
dma_beat(100);
- CHECK(adc_input_poll() == 0, "TC-AI-050 快照无新帧 -> poll 返回 0");
- CHECK(adc_input_raw(ADC_SEM_UA, &v) == -2, "TC-AI-051 无新帧时 TPAFE 侧无效");
- CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_OK, "TC-AI-052 同拍 STM32 取帧照常执行");
+ CHECK(adc_input_poll() == 0, "TC-ADCIN-050 快照无新帧 -> poll 返回 0");
+ CHECK(adc_input_raw(ADC_SEM_UA, &v) == -2, "TC-ADCIN-051 无新帧时 TPAFE 侧无效");
+ CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_OK, "TC-ADCIN-052 同拍 STM32 取帧照常执行");
/* --- 参数错(-1):返回 -1,TPAFE 无效 --- */
fakes_reset();
(void)adc_input_init();
s_snapshot_rc = -1;
- CHECK(adc_input_poll() == -1, "TC-AI-053 快照参数错 -> poll 返回 -1");
- CHECK(adc_input_raw(ADC_SEM_UA, &v) == -2, "TC-AI-054 参数错时 TPAFE 侧无效");
+ CHECK(adc_input_poll() == -1, "TC-ADCIN-053 快照参数错 -> poll 返回 -1");
+ CHECK(adc_input_raw(ADC_SEM_UA, &v) == -2, "TC-ADCIN-054 参数错时 TPAFE 侧无效");
/* --- 已有有效帧后再"无新帧":保持上次有效值(不清零) --- */
fakes_reset();
@@ -507,7 +507,7 @@ static void tc_poll(void) {
s_snapshot_rc = 0;
(void)adc_input_poll();
CHECK((adc_input_raw(ADC_SEM_UA, &v) == 0) && (v == 777),
- "TC-AI-055 已有有效帧后无新帧不清零");
+ "TC-ADCIN-055 已有有效帧后无新帧不清零");
/* --- STM32 失败不阻断 TPAFE、不影响 poll 返回值 --- */
fakes_reset();
@@ -515,36 +515,36 @@ static void tc_poll(void) {
s_fake_tpafe[2] = 55;
s_snapshot_rc = 1;
/* 不注入任何 DMA 完成 = STM32 侧停摆 */
- CHECK(adc_input_poll() == 1, "TC-AI-056 STM32 停摆不影响 poll 返回值(仍为 1)");
+ CHECK(adc_input_poll() == 1, "TC-ADCIN-056 STM32 停摆不影响 poll 返回值(仍为 1)");
CHECK((adc_input_raw(ADC_SEM_IA, &v) == 0) && (v == 55),
- "TC-AI-057 STM32 停摆不影响 TPAFE 取数");
- CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_STALL, "TC-AI-058 STM32 停摆另由状态码暴露");
+ "TC-ADCIN-057 STM32 停摆不影响 TPAFE 取数");
+ CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_STALL, "TC-ADCIN-058 STM32 停摆另由状态码暴露");
}
-/* ===================== TC-AI-060..066:rc / errs 观测 ===================== */
+/* ===================== TC-ADCIN-060..066:rc / errs 观测 ===================== */
static void tc_rc_errs(void) {
fakes_reset();
(void)adc_input_init();
- CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_NOT_RUN, "TC-AI-060 init 后未扫描 = NOT_RUN(-3)");
- CHECK(adc_input_stm32_errs() == 0u, "TC-AI-061 init 后失败计数 = 0");
+ CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_NOT_RUN, "TC-ADCIN-060 init 后未扫描 = NOT_RUN(-3)");
+ CHECK(adc_input_stm32_errs() == 0u, "TC-ADCIN-061 init 后失败计数 = 0");
dma_beat(100);
(void)stm32_take(); /* 成功 */
CHECK((adc_input_stm32_rc() == ADC_INPUT_RC_OK) && (adc_input_stm32_errs() == 0u),
- "TC-AI-062 成功: rc=OK 且 errs 不变");
+ "TC-ADCIN-062 成功: rc=OK 且 errs 不变");
(void)stm32_take(); /* 停摆 1(单拍 = 相位伪影,不计) */
(void)stm32_take(); /* 停摆 2 -> 计 1 */
- CHECK(adc_input_stm32_errs() == 1u, "TC-AI-063 连续两拍停摆累计 = 1");
- CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_STALL, "TC-AI-064 rc = 最近一次(STALL)");
+ CHECK(adc_input_stm32_errs() == 1u, "TC-ADCIN-063 连续两拍停摆累计 = 1");
+ CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_STALL, "TC-ADCIN-064 rc = 最近一次(STALL)");
dma_beat(200);
(void)stm32_take(); /* 恢复成功 */
- CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_OK, "TC-AI-065 恢复成功后 rc=OK");
- CHECK(adc_input_stm32_errs() == 1u, "TC-AI-066 errs 单调递增(不因成功回落)");
- CHECK(adc_input_stm32_seq() == 2u, "TC-AI-067 seq 只由 DMA 完成回调推进");
+ CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_OK, "TC-ADCIN-065 恢复成功后 rc=OK");
+ CHECK(adc_input_stm32_errs() == 1u, "TC-ADCIN-066 errs 单调递增(不因成功回落)");
+ CHECK(adc_input_stm32_seq() == 2u, "TC-ADCIN-067 seq 只由 DMA 完成回调推进");
}
/* ===================== main ===================== */
diff --git a/test/host/cfg_file/cfg_file_test.c b/test/host/cfg_file/cfg_file_test.c
index 25e587e6..d2212b0c 100644
--- a/test/host/cfg_file/cfg_file_test.c
+++ b/test/host/cfg_file/cfg_file_test.c
@@ -16,43 +16,43 @@
*
* 覆盖点(对应 docs/测试说明/配置文件单元测试说明.md 的 TC-CFG-xxx):
* —— 值类型编解码(s_encode / s_decode 经公开 load/save 间接验证 + 直接白盒)——
- * TC-CFG-001 UINT 1/2/4 字节小端往返(含 0 / 最大值)
- * TC-CFG-002 UINT 非法:空 / 非数字 / 带后缀 / 超范围
- * TC-CFG-003 IP4 正常与非法(段数不足、>255、前导非数字、多余后缀)
- * TC-CFG-004 MAC 三种分隔符 + 大小写 + 非法
- * TC-CFG-005 STR 正常 / 超长拒绝 / 边界(恰好放下)
+ * TC-CONFIG-001 UINT 1/2/4 字节小端往返(含 0 / 最大值)
+ * TC-CONFIG-002 UINT 非法:空 / 非数字 / 带后缀 / 超范围
+ * TC-CONFIG-003 IP4 正常与非法(段数不足、>255、前导非数字、多余后缀)
+ * TC-CONFIG-004 MAC 三种分隔符 + 大小写 + 非法
+ * TC-CONFIG-005 STR 正常 / 超长拒绝 / 边界(恰好放下)
* —— INI 解析(s_split_line / s_match_section / s_key_value / s_parse)——
- * TC-CFG-010 注释(; 与 #)与空行忽略
- * TC-CFG-011 CRLF / LF 混排
- * TC-CFG-012 段名大小写无关匹配、前后空白修剪
- * TC-CFG-013 键名大小写无关、值前后空白修剪
- * TC-CFG-014 未知段 / 未知键留默认(不崩溃)
- * TC-CFG-015 键值行出现在段头之前 = 忽略
+ * TC-CONFIG-010 注释(; 与 #)与空行忽略
+ * TC-CONFIG-011 CRLF / LF 混排
+ * TC-CONFIG-012 段名大小写无关匹配、前后空白修剪
+ * TC-CONFIG-013 键名大小写无关、值前后空白修剪
+ * TC-CONFIG-014 未知段 / 未知键留默认(不崩溃)
+ * TC-CONFIG-015 键值行出现在段头之前 = 忽略
* —— 注册校验(cfg_file_register)——
- * TC-CFG-020 正常注册 / 重复段名拒绝 / NULL 参数拒绝
- * TC-CFG-021 非法键定义拒绝(UINT len 非 1/2/4、MAC len≠6、STR len>79)
- * TC-CFG-022 段名超长拒绝(≥ CFG_NAME_MAX)
- * TC-CFG-023 挂回调段 data_size > CFG_SNAP_MAX 拒绝
- * TC-CFG-024 键名超长拒绝(≥ CFG_NAME_MAX);恰好 15 字符(= CFG_FILE_MAX_NAME_LEN)接受
+ * TC-CONFIG-020 正常注册 / 重复段名拒绝 / NULL 参数拒绝
+ * TC-CONFIG-021 非法键定义拒绝(UINT len 非 1/2/4、MAC len≠6、STR len>79)
+ * TC-CONFIG-022 段名超长拒绝(≥ CFG_NAME_MAX)
+ * TC-CONFIG-023 挂回调段 data_size > CFG_SNAP_MAX 拒绝
+ * TC-CONFIG-024 键名超长拒绝(≥ CFG_NAME_MAX);恰好 15 字符(= CFG_FILE_MAX_NAME_LEN)接受
* —— load 契约(cfg_file_load)——
- * TC-CFG-030 文件缺失 -> 生成出厂模板写盘 + 返回 0
- * TC-CFG-031 文件存在 -> 解析有效键进 RAM 副本
- * TC-CFG-032 超长文件(> CFG_FILE_MAX_LEN)-> 工厂默认 + 重建模板 + 自检留痕
- * TC-CFG-033 读取失败 -> 返回 -1(RAM 保持工厂默认)
- * TC-CFG-034 未注册任何段 -> 返回 -1
+ * TC-CONFIG-030 文件缺失 -> 生成出厂模板写盘 + 返回 0
+ * TC-CONFIG-031 文件存在 -> 解析有效键进 RAM 副本
+ * TC-CONFIG-032 超长文件(> CFG_FILE_MAX_LEN)-> 工厂默认 + 重建模板 + 自检留痕
+ * TC-CONFIG-033 读取失败 -> 返回 -1(RAM 保持工厂默认)
+ * TC-CONFIG-034 未注册任何段 -> 返回 -1
* —— save 契约(cfg_file_save)——
- * TC-CFG-040 文件缺失 -> 重建完整文档
- * TC-CFG-041 外科手术:保留注释/未知段/未知键,受管键原位改写
- * TC-CFG-042 缺失受管段/键补写
- * TC-CFG-043 输出超长 -> 拒绝保存(-1) 且原文件不动
- * TC-CFG-044 受管键行超 CFG_LINE_TEST_MAX -> 拒绝保存(-1) 原文件不动(P2-1);
+ * TC-CONFIG-040 文件缺失 -> 重建完整文档
+ * TC-CONFIG-041 外科手术:保留注释/未知段/未知键,受管键原位改写
+ * TC-CONFIG-042 缺失受管段/键补写
+ * TC-CONFIG-043 输出超长 -> 拒绝保存(-1) 且原文件不动
+ * TC-CONFIG-044 受管键行超 CFG_LINE_TEST_MAX -> 拒绝保存(-1) 原文件不动(P2-1);
* 非受管键的超长行照旧放过(原样保留)
* —— poll 契约(cfg_file_poll)——
- * TC-CFG-050 首轮建立基线(不重载)
- * TC-CFG-051 沉降去抖:连续 2 次稳定才重载
- * TC-CFG-052 与基线一致不重载
- * TC-CFG-053 变更后重载 + 挂回调段差异触发回调
- * TC-CFG-054 溢出到文件超长 -> 工厂默认 + 重建模板 + 自检留痕(不触发回调)
+ * TC-CONFIG-050 首轮建立基线(不重载)
+ * TC-CONFIG-051 沉降去抖:连续 2 次稳定才重载
+ * TC-CONFIG-052 与基线一致不重载
+ * TC-CONFIG-053 变更后重载 + 挂回调段差异触发回调
+ * TC-CONFIG-054 溢出到文件超长 -> 工厂默认 + 重建模板 + 自检留痕(不触发回调)
*
* 通过:全部 TC PASS(main 返回 0)。
* 入口:int main(void),返回 0=PASS / 1=FAIL(由 run 脚本判读)。
@@ -333,9 +333,9 @@ static void register_std(void) {
/* ===================== 用例 ===================== */
-/* TC-CFG-001/002:UINT 往返与非法值 */
+/* TC-CONFIG-001/002:UINT 往返与非法值 */
static void tc_uint(void) {
- printf("[TC-CFG-001] UINT encode/decode round-trip\n");
+ printf("[TC-CONFIG-001] UINT encode/decode round-trip\n");
{
uint8_t d1[1]; uint8_t d2[2]; uint8_t d4[4];
CHECK(s_decode_uint(d1, 1u, "255") == 0 && d1[0] == 0xFFu, "u8 max 255");
@@ -349,7 +349,7 @@ static void tc_uint(void) {
"u16 0x1234 little-endian order");
}
- printf("[TC-CFG-002] UINT illegal values rejected\n");
+ printf("[TC-CONFIG-002] UINT illegal values rejected\n");
{
uint8_t d[4];
CHECK(s_decode_uint(d, 1u, "") == -1, "empty rejected");
@@ -362,11 +362,11 @@ static void tc_uint(void) {
}
}
-/* TC-CFG-003:IP4 */
+/* TC-CONFIG-003:IP4 */
static void tc_ip4(void) {
uint8_t d[4];
- printf("[TC-CFG-003] IPv4 decode\n");
+ printf("[TC-CONFIG-003] IPv4 decode\n");
CHECK(s_decode_ip4(d, "0.0.0.0") == 0 && d[0] == 0u && d[3] == 0u, "all-zero");
CHECK(s_decode_ip4(d, "255.255.255.255") == 0 &&
d[0] == 255u && d[3] == 255u, "all-255");
@@ -380,11 +380,11 @@ static void tc_ip4(void) {
CHECK(s_decode_ip4(d, "") == -1, "empty rejected");
}
-/* TC-CFG-004:MAC */
+/* TC-CONFIG-004:MAC */
static void tc_mac(void) {
uint8_t d[6];
- printf("[TC-CFG-004] MAC decode (separators/case)\n");
+ printf("[TC-CONFIG-004] MAC decode (separators/case)\n");
CHECK(s_decode_mac(d, "00:11:22:33:44:55") == 0 &&
d[0] == 0x00u && d[5] == 0x55u, "colon separator");
CHECK(s_decode_mac(d, "00-11-22-33-44-55") == 0 &&
@@ -404,11 +404,11 @@ static void tc_mac(void) {
CHECK(s_decode_mac(d, "") == -1, "empty rejected");
}
-/* TC-CFG-005:STR */
+/* TC-CONFIG-005:STR */
static void tc_str(void) {
uint8_t d[8];
- printf("[TC-CFG-005] STR decode (length boundary)\n");
+ printf("[TC-CONFIG-005] STR decode (length boundary)\n");
CHECK(s_decode_str(d, 8u, "hello") == 0 && d[0] == 'h' && d[5] == '\0',
"normal string + NUL");
CHECK(s_decode_str(d, 8u, "1234567") == 0 && d[6] == '7' && d[7] == '\0',
@@ -417,9 +417,9 @@ static void tc_str(void) {
CHECK(s_decode_str(d, 8u, "") == 0 && d[0] == '\0', "empty string ok");
}
-/* TC-CFG-010~015:INI 解析 */
+/* TC-CONFIG-010~015:INI 解析 */
static void tc_parse(void) {
- printf("[TC-CFG-010..015] INI parsing via load\n");
+ printf("[TC-CONFIG-010..015] INI parsing via load\n");
{
vfs_reset();
register_std();
@@ -446,7 +446,7 @@ static void tc_parse(void) {
CHECK(s_sys_data.baud == 9600u, "multi-section: sys parsed");
}
- printf("[TC-CFG-012] section/key name case-insensitive + value whitespace trim\n");
+ printf("[TC-CONFIG-012] section/key name case-insensitive + value whitespace trim\n");
{
vfs_reset();
register_std();
@@ -462,7 +462,7 @@ static void tc_parse(void) {
CHECK(s_net_data.ip[0] == 1u && s_net_data.ip[3] == 4u, "value whitespace trimmed");
}
- printf("[TC-CFG-011] LF-only line endings\n");
+ printf("[TC-CONFIG-011] LF-only line endings\n");
{
vfs_reset();
register_std();
@@ -472,7 +472,7 @@ static void tc_parse(void) {
CHECK(s_net_data.ip[3] == 8u, "LF: ip parsed");
}
- printf("[TC-CFG-015] key-value before any section ignored\n");
+ printf("[TC-CONFIG-015] key-value before any section ignored\n");
{
vfs_reset();
register_std();
@@ -482,7 +482,7 @@ static void tc_parse(void) {
CHECK(s_net_data.ip[0] == 5u, "valid key after section parsed");
}
- printf("[TC-CFG-014b] invalid value keeps factory default + logs\n");
+ printf("[TC-CONFIG-014b] invalid value keeps factory default + logs\n");
{
vfs_reset();
register_std();
@@ -495,9 +495,9 @@ static void tc_parse(void) {
}
}
-/* TC-CFG-020~023:register 校验 */
+/* TC-CONFIG-020~023:register 校验 */
static void tc_register(void) {
- printf("[TC-CFG-020] register validation\n");
+ printf("[TC-CONFIG-020] register validation\n");
{
cfg_section_reg_t r;
vfs_reset();
@@ -518,7 +518,7 @@ static void tc_register(void) {
CHECK(cfg_file_register(&r) == -1, "NULL p_data rejected");
}
- printf("[TC-CFG-021] invalid key definitions rejected\n");
+ printf("[TC-CONFIG-021] invalid key definitions rejected\n");
{
cfg_section_reg_t r;
static const cfg_key_def_t bad_uint[] = { { "k", CFG_VAL_UINT, 0u, 3u } };
@@ -544,7 +544,7 @@ static void tc_register(void) {
CHECK(cfg_file_register(&r) == -1, "key len=0 rejected");
}
- printf("[TC-CFG-022] section name length limit\n");
+ printf("[TC-CONFIG-022] section name length limit\n");
{
cfg_section_reg_t r;
vfs_reset();
@@ -558,7 +558,7 @@ static void tc_register(void) {
CHECK(cfg_file_register(&r) == -1, "section name >= 16 chars rejected");
}
- printf("[TC-CFG-023] callback section data_size limit\n");
+ printf("[TC-CONFIG-023] callback section data_size limit\n");
{
cfg_section_reg_t r;
vfs_reset();
@@ -576,7 +576,7 @@ static void tc_register(void) {
CHECK(cfg_file_register(&r) == 0, "same section without callback accepted");
}
- printf("[TC-CFG-024] key name length limit\n");
+ printf("[TC-CONFIG-024] key name length limit\n");
{
cfg_section_reg_t r;
static const cfg_key_def_t long_key[] = {
@@ -602,9 +602,9 @@ static void tc_register(void) {
}
}
-/* TC-CFG-030~034:load 契约 */
+/* TC-CONFIG-030~034:load 契约 */
static void tc_load(void) {
- printf("[TC-CFG-030] missing file -> factory template written\n");
+ printf("[TC-CONFIG-030] missing file -> factory template written\n");
{
vfs_reset();
register_std();
@@ -618,7 +618,7 @@ static void tc_load(void) {
CHECK(strstr(vfs_get(), "u8=7") != NULL, "template has default u8=7");
}
- printf("[TC-CFG-032] oversized file -> factory default + regenerate + syslog\n");
+ printf("[TC-CONFIG-032] oversized file -> factory default + regenerate + syslog\n");
{
size_t i;
vfs_reset();
@@ -637,7 +637,7 @@ static void tc_load(void) {
CHECK(s_vfs_len <= CFG_FILE_MAX_LEN, "file regenerated within limit");
}
- printf("[TC-CFG-033] read failure -> -1, RAM keeps factory default\n");
+ printf("[TC-CONFIG-033] read failure -> -1, RAM keeps factory default\n");
{
vfs_reset();
register_std();
@@ -647,16 +647,16 @@ static void tc_load(void) {
CHECK(s_net_data.u8 == s_net_def.u8, "RAM stays factory default");
}
- printf("[TC-CFG-034] load with no registered section -> -1\n");
+ printf("[TC-CONFIG-034] load with no registered section -> -1\n");
{
vfs_reset();
CHECK(cfg_file_load() == -1, "no section registered returns -1");
}
}
-/* TC-CFG-040~043:save 契约 */
+/* TC-CONFIG-040~043:save 契约 */
static void tc_save(void) {
- printf("[TC-CFG-040] save with missing file -> full document\n");
+ printf("[TC-CONFIG-040] save with missing file -> full document\n");
{
vfs_reset();
register_std();
@@ -668,7 +668,7 @@ static void tc_save(void) {
CHECK(strstr(vfs_get(), "baud=38400") != NULL, "second section written");
}
- printf("[TC-CFG-041] surgical save preserves comments/unknown\n");
+ printf("[TC-CONFIG-041] surgical save preserves comments/unknown\n");
{
vfs_reset();
register_std();
@@ -689,7 +689,7 @@ static void tc_save(void) {
CHECK(strstr(vfs_get(), "u8=200") != NULL, "managed key rewritten in place");
}
- printf("[TC-CFG-042] surgical save appends missing managed section/key\n");
+ printf("[TC-CONFIG-042] surgical save appends missing managed section/key\n");
{
vfs_reset();
register_std();
@@ -703,7 +703,7 @@ static void tc_save(void) {
CHECK(strstr(vfs_get(), "baud=57600") != NULL, "missing key written");
}
- printf("[TC-CFG-043] output overflow -> reject, original untouched\n");
+ printf("[TC-CONFIG-043] output overflow -> reject, original untouched\n");
{
size_t i;
vfs_reset();
@@ -725,7 +725,7 @@ static void tc_save(void) {
}
}
- printf("[TC-CFG-044] over-long managed key line -> reject (P2-1)\n");
+ printf("[TC-CONFIG-044] over-long managed key line -> reject (P2-1)\n");
{
char buf[512];
size_t n;
@@ -772,9 +772,9 @@ static void tc_save(void) {
}
}
-/* TC-CFG-050~054:poll 契约 */
+/* TC-CONFIG-050~054:poll 契约 */
static void tc_poll(void) {
- printf("[TC-CFG-050] poll first round establishes baseline\n");
+ printf("[TC-CONFIG-050] poll first round establishes baseline\n");
{
vfs_reset();
register_std();
@@ -784,7 +784,7 @@ static void tc_poll(void) {
CHECK(s_base_valid == 1u, "baseline established");
}
- printf("[TC-CFG-051/052] settle debounce + no-change skip\n");
+ printf("[TC-CONFIG-051/052] settle debounce + no-change skip\n");
{
vfs_reset();
register_std();
@@ -801,7 +801,7 @@ static void tc_poll(void) {
CHECK(s_net_data.u8 == 88u, "reloaded after settle");
}
- printf("[TC-CFG-053] change triggers reload + callback\n");
+ printf("[TC-CONFIG-053] change triggers reload + callback\n");
{
vfs_reset();
register_std();
@@ -815,7 +815,7 @@ static void tc_poll(void) {
CHECK(s_net_cb_count >= 1, "callback fired on section change");
}
- printf("[TC-CFG-055] content change without size/mtime token change -> not detected\n");
+ printf("[TC-CONFIG-055] content change without size/mtime token change -> not detected\n");
{
vfs_reset();
register_std();
@@ -830,7 +830,7 @@ static void tc_poll(void) {
"same-token change ignored (size+mtime is the change signal)");
}
- printf("[TC-CFG-054] poll detects oversized file -> factory + regenerate + syslog\n");
+ printf("[TC-CONFIG-054] poll detects oversized file -> factory + regenerate + syslog\n");
{
size_t i;
vfs_reset();
diff --git a/test/host/freq/freq_test.c b/test/host/freq/freq_test.c
index 75232ab9..344be2ec 100644
--- a/test/host/freq/freq_test.c
+++ b/test/host/freq/freq_test.c
@@ -22,17 +22,17 @@
* 读数在跳变后 60 ms 内回到 ±0.05 Hz
*
* 覆盖点:
- * TC-FR-001 50 Hz 收敛时序(J3)+ 稳态精度(J1 子集)
- * TC-FR-002 扫频 45~55 Hz @0.5 Hz(J1,逐点判 + 最坏值打印)
- * TC-FR-003 噪声鲁棒(J2,最坏值打印)
- * TC-FR-004 频率阶跃 50->51(J4)
- * TC-FR-005 零幅浮空不发散(J5)+ 恢复后重新收敛
- * TC-FR-006 直流偏置抑制(全周傅氏滤直流 -> 测频不受影响)
- * TC-FR-007 3/5 次谐波污染抑制(相量基波选择性)
- * TC-FR-008 相位跳变假值钳制(J6)
- * TC-FR-009 UA 无幅值 -> 自动落 IA 源
- * TC-FR-010 init 幂等 / get 参数守卫 / 未收敛 -2
- * TC-FR-011 幅值门中途失效 -> valid 清零 + 读数保持(J5 中途版)
+ * TC-FREQ-001 50 Hz 收敛时序(J3)+ 稳态精度(J1 子集)
+ * TC-FREQ-002 扫频 45~55 Hz @0.5 Hz(J1,逐点判 + 最坏值打印)
+ * TC-FREQ-003 噪声鲁棒(J2,最坏值打印)
+ * TC-FREQ-004 频率阶跃 50->51(J4)
+ * TC-FREQ-005 零幅浮空不发散(J5)+ 恢复后重新收敛
+ * TC-FREQ-006 直流偏置抑制(全周傅氏滤直流 -> 测频不受影响)
+ * TC-FREQ-007 3/5 次谐波污染抑制(相量基波选择性)
+ * TC-FREQ-008 相位跳变假值钳制(J6)
+ * TC-FREQ-009 UA 无幅值 -> 自动落 IA 源
+ * TC-FREQ-010 init 幂等 / get 参数守卫 / 未收敛 -2
+ * TC-FREQ-011 幅值门中途失效 -> valid 清零 + 读数保持(J5 中途版)
*
* 通过:全部 TC PASS(main 返回 0)。
* 创建日期:2026-10-12(B8)
@@ -134,7 +134,7 @@ static void chain_reset(void) {
(void)freq_init();
}
-/* ===================== TC-FR-001:50 Hz 收敛时序 + 稳态精度 ===================== */
+/* ===================== TC-FREQ-001:50 Hz 收敛时序 + 稳态精度 ===================== */
static void tc_converge_50(void) {
float f = 0.0f;
uint32_t first_valid_t = 0u, phasor_ready_t = 0u;
@@ -155,17 +155,17 @@ static void tc_converge_50(void) {
got = 1;
}
}
- CHECK(got, "TC-FR-001 freq becomes valid at 50 Hz");
+ CHECK(got, "TC-FREQ-001 freq becomes valid at 50 Hz");
CHECK((first_valid_t >= phasor_ready_t)
&& ((first_valid_t - phasor_ready_t) <= 40u),
- "TC-FR-001 J3: first valid reading <= 40 ms after first phasor");
+ "TC-FREQ-001 J3: first valid reading <= 40 ms after first phasor");
(void)freq_get(&f);
printf(" [DATA] 50 Hz steady: f=%.4f err=%.4f Hz (first valid @%u ms, phasor @%u ms)\n",
(double)f, (double)f - 50.0, (unsigned)first_valid_t, (unsigned)phasor_ready_t);
- CHECK(fabsf(f - 50.0f) <= 0.01f, "TC-FR-001 J1(50Hz): |err| <= 0.01 Hz");
+ CHECK(fabsf(f - 50.0f) <= 0.01f, "TC-FREQ-001 J1(50Hz): |err| <= 0.01 Hz");
}
-/* ===================== TC-FR-002:扫频 45~55 Hz @0.5 Hz(J1) ===================== */
+/* ===================== TC-FREQ-002:扫频 45~55 Hz @0.5 Hz(J1) ===================== */
static void tc_sweep(void) {
double worst = 0.0, worst_f = 0.0;
int ok = 1;
@@ -178,17 +178,17 @@ static void tc_sweep(void) {
chain_reset();
drive_n(150u, f_true, 1000.0, 0.0, 0.0, 0.0, 0.0, 1u);
- CHECK(freq_get(&f_meas) == 0, "TC-FR-002 freq valid at each sweep point");
+ CHECK(freq_get(&f_meas) == 0, "TC-FREQ-002 freq valid at each sweep point");
err = fabs((double)f_meas - f_true);
if (err > worst) { worst = err; worst_f = f_true; }
if (err > 0.02) { ok = 0; }
}
printf(" [DATA] sweep 45.00~55.00 Hz step 0.5: worst |err| = %.4f Hz @ %.1f Hz (J1 <= 0.02)\n",
worst, worst_f);
- CHECK(ok, "TC-FR-002 J1: |f_meas - f_true| <= 0.02 Hz over 45~55 Hz");
+ CHECK(ok, "TC-FREQ-002 J1: |f_meas - f_true| <= 0.02 Hz over 45~55 Hz");
}
-/* ===================== TC-FR-003:噪声鲁棒(J2) ===================== */
+/* ===================== TC-FREQ-003:噪声鲁棒(J2) ===================== */
static void tc_noise(void) {
double worst = 0.0;
int ok = 1;
@@ -207,10 +207,10 @@ static void tc_noise(void) {
if (err > 0.10) { ok = 0; }
}
printf(" [DATA] noise rms=1%% amp: worst |err| = %.4f Hz (J2 <= 0.10)\n", worst);
- CHECK(ok, "TC-FR-003 J2: |err| <= 0.10 Hz with 1% noise");
+ CHECK(ok, "TC-FREQ-003 J2: |err| <= 0.10 Hz with 1% noise");
}
-/* ===================== TC-FR-004:频率阶跃 50->51(J4) ===================== */
+/* ===================== TC-FREQ-004:频率阶跃 50->51(J4) ===================== */
static void tc_step(void) {
float f = 0.0f;
uint32_t settle = 0u;
@@ -236,12 +236,12 @@ static void tc_step(void) {
}
printf(" [DATA] step 50->51: settle = %u ms, final f=%.4f err=%.4f\n",
(unsigned)settle, (double)f, (double)f - 51.0);
- CHECK((settle != 0u) && (settle <= 120u), "TC-FR-004 J4: settle <= 120 ms");
- CHECK(ok, "TC-FR-004 J4: stays within +/-0.05 Hz after settle");
- CHECK(fabsf(f - 51.0f) <= 0.01f, "TC-FR-004 J1(51Hz): steady |err| <= 0.01 Hz");
+ CHECK((settle != 0u) && (settle <= 120u), "TC-FREQ-004 J4: settle <= 120 ms");
+ CHECK(ok, "TC-FREQ-004 J4: stays within +/-0.05 Hz after settle");
+ CHECK(fabsf(f - 51.0f) <= 0.01f, "TC-FREQ-004 J1(51Hz): steady |err| <= 0.01 Hz");
}
-/* ===================== TC-FR-005:零幅浮空不发散(J5) ===================== */
+/* ===================== TC-FREQ-005:零幅浮空不发散(J5) ===================== */
static void tc_zero_amp(void) {
float f = 123.0f;
uint32_t i;
@@ -254,17 +254,17 @@ static void tc_zero_amp(void) {
(void)freq_get(&f);
if (!(f == f)) { no_nan = 0; } /* NaN 自比较为假 */
}
- CHECK(never_valid, "TC-FR-005 J5: zero-amplitude never asserts valid");
- CHECK(no_nan && (f == 0.0f), "TC-FR-005 J5: reading stays 0, no divergence/NaN");
+ CHECK(never_valid, "TC-FREQ-005 J5: zero-amplitude never asserts valid");
+ CHECK(no_nan && (f == 0.0f), "TC-FREQ-005 J5: reading stays 0, no divergence/NaN");
/* 恢复:重新注入波形后应再次收敛 */
drive_n(150u, 49.0, 1000.0, 0.0, 0.0, 0.0, 0.0, 1u);
(void)freq_get(&f);
printf(" [DATA] recover after float: f=%.4f err=%.4f\n", (double)f, (double)f - 49.0);
CHECK((freq_valid() != 0u) && (fabsf(f - 49.0f) <= 0.01f),
- "TC-FR-005 recovers and meets J1 after waveform returns");
+ "TC-FREQ-005 recovers and meets J1 after waveform returns");
}
-/* ===================== TC-FR-006:直流偏置抑制 ===================== */
+/* ===================== TC-FREQ-006:直流偏置抑制 ===================== */
static void tc_dc_offset(void) {
float f = 0.0f;
@@ -272,10 +272,10 @@ static void tc_dc_offset(void) {
drive_n(150u, 50.3, 1000.0, 8000.0, 0.0, 0.0, 0.0, 1u); /* DC = 8000 码 */
(void)freq_get(&f);
printf(" [DATA] DC=8000: f=%.4f err=%.4f\n", (double)f, (double)f - 50.3);
- CHECK(fabsf(f - 50.3f) <= 0.01f, "TC-FR-006 DC offset rejected: |err| <= 0.01 Hz");
+ CHECK(fabsf(f - 50.3f) <= 0.01f, "TC-FREQ-006 DC offset rejected: |err| <= 0.01 Hz");
}
-/* ===================== TC-FR-007:3/5 次谐波污染 ===================== */
+/* ===================== TC-FREQ-007:3/5 次谐波污染 ===================== */
static void tc_harmonics(void) {
float f = 0.0f;
@@ -283,10 +283,10 @@ static void tc_harmonics(void) {
drive_n(150u, 48.0, 1000.0, 0.0, 200.0, 100.0, 0.0, 1u); /* 20%/10% 谐波 */
(void)freq_get(&f);
printf(" [DATA] h3=20%% h5=10%%: f=%.4f err=%.4f\n", (double)f, (double)f - 48.0);
- CHECK(fabsf(f - 48.0f) <= 0.01f, "TC-FR-007 harmonics rejected: |err| <= 0.01 Hz");
+ CHECK(fabsf(f - 48.0f) <= 0.01f, "TC-FREQ-007 harmonics rejected: |err| <= 0.01 Hz");
}
-/* ===================== TC-FR-008:相位跳变假值钳制(J6) ===================== */
+/* ===================== TC-FREQ-008:相位跳变假值钳制(J6) ===================== */
static void tc_phase_jump(void) {
float f = 0.0f;
uint32_t i;
@@ -306,11 +306,11 @@ static void tc_phase_jump(void) {
}
printf(" [DATA] after jump: f=%.4f err=%.4f (recover window 60 ms)\n",
(double)f, (double)f - 50.0);
- CHECK(ok, "TC-FR-008 J6: recovers to +/-0.05 Hz within 60 ms after jump");
- CHECK(freq_valid() != 0u, "TC-FR-008 J6: still valid after clamp path");
+ CHECK(ok, "TC-FREQ-008 J6: recovers to +/-0.05 Hz within 60 ms after jump");
+ CHECK(freq_valid() != 0u, "TC-FREQ-008 J6: still valid after clamp path");
}
-/* ===================== TC-FR-009:UA 无幅值 -> IA 回退 ===================== */
+/* ===================== TC-FREQ-009:UA 无幅值 -> IA 回退 ===================== */
static void tc_src_fallback(void) {
float f = 0.0f;
@@ -319,39 +319,39 @@ static void tc_src_fallback(void) {
(void)freq_get(&f);
printf(" [DATA] UA=0 IA=1000: f=%.4f err=%.4f\n", (double)f, (double)f - 52.0);
CHECK((freq_valid() != 0u) && (fabsf(f - 52.0f) <= 0.01f),
- "TC-FR-009 falls back to IA source when UA below amplitude gate");
+ "TC-FREQ-009 falls back to IA source when UA below amplitude gate");
}
-/* ===================== TC-FR-010:init 幂等 / 参数守卫 ===================== */
+/* ===================== TC-FREQ-010:init 幂等 / 参数守卫 ===================== */
static void tc_init_guards(void) {
float f = 5.0f;
chain_reset();
- CHECK(freq_get(&f) == -2, "TC-FR-010 get before convergence -> -2");
- CHECK((f == 0.0f), "TC-FR-010 get -2 writes 0 to out");
- CHECK(freq_get(NULL) == -1, "TC-FR-010 NULL out -> -1");
- CHECK(freq_valid() == 0u, "TC-FR-010 valid=0 before convergence");
- CHECK(freq_last() == 0.0f, "TC-FR-010 last=0 before convergence");
+ CHECK(freq_get(&f) == -2, "TC-FREQ-010 get before convergence -> -2");
+ CHECK((f == 0.0f), "TC-FREQ-010 get -2 writes 0 to out");
+ CHECK(freq_get(NULL) == -1, "TC-FREQ-010 NULL out -> -1");
+ CHECK(freq_valid() == 0u, "TC-FREQ-010 valid=0 before convergence");
+ CHECK(freq_last() == 0.0f, "TC-FREQ-010 last=0 before convergence");
(void)freq_init();
- CHECK(freq_get(&f) == -2, "TC-FR-010 freq_init idempotent (still -2)");
+ CHECK(freq_get(&f) == -2, "TC-FREQ-010 freq_init idempotent (still -2)");
}
-/* ===================== TC-FR-011:幅值门中途失效 -> 保持 ===================== */
+/* ===================== TC-FREQ-011:幅值门中途失效 -> 保持 ===================== */
static void tc_gate_hold(void) {
float f_before = 0.0f, f_after = 0.0f;
chain_reset();
drive_n(150u, 50.0, 1000.0, 0.0, 0.0, 0.0, 0.0, 1u);
(void)freq_get(&f_before);
- CHECK(freq_valid() == 1u, "TC-FR-011 valid before gate loss");
+ CHECK(freq_valid() == 1u, "TC-FREQ-011 valid before gate loss");
drive_n(50u, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1u); /* 波形消失 */
- CHECK(freq_valid() == 0u, "TC-FR-011 J5: valid cleared on gate loss");
+ CHECK(freq_valid() == 0u, "TC-FREQ-011 J5: valid cleared on gate loss");
(void)freq_get(&f_after);
printf(" [DATA] hold: before=%.4f held=%.4f delta=%.4f\n",
(double)f_before, (double)f_after, (double)(f_after - f_before));
CHECK(fabsf(f_after - f_before) <= 0.3f,
- "TC-FR-011 J5: reading bounded (|delta| <= 0.3 Hz) during gate loss");
+ "TC-FREQ-011 J5: reading bounded (|delta| <= 0.3 Hz) during gate loss");
}
int main(void) {
diff --git a/test/host/ftp_auth/ftp_auth_test.c b/test/host/ftp_auth/ftp_auth_test.c
index 4938e2ac..0f91f267 100644
--- a/test/host/ftp_auth/ftp_auth_test.c
+++ b/test/host/ftp_auth/ftp_auth_test.c
@@ -13,16 +13,16 @@
* 毫秒级穷举。用户名侧信道路径(错用户名也走哈希)同属纯逻辑。
*
* 覆盖点:
- * TC-FA-001 user_match:相等 / 大小写不敏感 / 不等 / NULL
- * TC-FA-002 正确用户名+正确口令 → OK,计数 0
- * TC-FA-003 错口令 → FAIL,计数 1
- * TC-FA-004 错用户名+对口令 → FAIL(哈希路径已走,时间拉平)
- * TC-FA-005 连续 5 次失败 → 第 6 次(锁定期内)LOCKED,对口令也拒
- * TC-FA-006 锁定期满(+60000 tick)→ 对口令 OK,计数清零
- * TC-FA-007 成功清零计数:3 败 + 1 成 → 再 4 败不触发锁定(第 5 败才锁)
- * TC-FA-008 tick 32 位回绕:锁定期内回绕点仍 LOCKED,期满回绕点放行
- * TC-FA-009 配置 pwd_hash 非法 hex → 恒 FAIL(fail-closed)
- * TC-FA-010 空口令 / NULL 口令 → FAIL;NULL creds/state → FAIL
+ * TC-FTPAUTH-001 user_match:相等 / 大小写不敏感 / 不等 / NULL
+ * TC-FTPAUTH-002 正确用户名+正确口令 → OK,计数 0
+ * TC-FTPAUTH-003 错口令 → FAIL,计数 1
+ * TC-FTPAUTH-004 错用户名+对口令 → FAIL(哈希路径已走,时间拉平)
+ * TC-FTPAUTH-005 连续 5 次失败 → 第 6 次(锁定期内)LOCKED,对口令也拒
+ * TC-FTPAUTH-006 锁定期满(+60000 tick)→ 对口令 OK,计数清零
+ * TC-FTPAUTH-007 成功清零计数:3 败 + 1 成 → 再 4 败不触发锁定(第 5 败才锁)
+ * TC-FTPAUTH-008 tick 32 位回绕:锁定期内回绕点仍 LOCKED,期满回绕点放行
+ * TC-FTPAUTH-009 配置 pwd_hash 非法 hex → 恒 FAIL(fail-closed)
+ * TC-FTPAUTH-010 空口令 / NULL 口令 → FAIL;NULL creds/state → FAIL
*
* 通过:全部 TC PASS(main 返回 0)。
* 入口:int main(void),返回 0=PASS / 1=FAIL(由 run 脚本判读)。
@@ -54,18 +54,18 @@ static int s_failed;
static const ftp_auth_creds_t s_creds = { "admin", DEF_HASH, 1u };
-/* ===================== TC-FA-001:user_match ===================== */
+/* ===================== TC-FTPAUTH-001:user_match ===================== */
static void tc_user_match(void)
{
- CHECK(ftp_auth_user_match("admin", "admin") == 1, "TC-FA-001a 相等匹配");
- CHECK(ftp_auth_user_match("admin", "ADMIN") == 1, "TC-FA-001b 大小写不敏感");
- CHECK(ftp_auth_user_match("admin", "root") == 0, "TC-FA-001c 不等拒绝");
- CHECK(ftp_auth_user_match("admin", "admin2") == 0, "TC-FA-001d 前缀不算匹配");
- CHECK(ftp_auth_user_match("admin", NULL) == 0, "TC-FA-001e NULL 拒绝");
+ CHECK(ftp_auth_user_match("admin", "admin") == 1, "TC-FTPAUTH-001a 相等匹配");
+ CHECK(ftp_auth_user_match("admin", "ADMIN") == 1, "TC-FTPAUTH-001b 大小写不敏感");
+ CHECK(ftp_auth_user_match("admin", "root") == 0, "TC-FTPAUTH-001c 不等拒绝");
+ CHECK(ftp_auth_user_match("admin", "admin2") == 0, "TC-FTPAUTH-001d 前缀不算匹配");
+ CHECK(ftp_auth_user_match("admin", NULL) == 0, "TC-FTPAUTH-001e NULL 拒绝");
}
-/* ===================== TC-FA-002..004:基本判定 ===================== */
+/* ===================== TC-FTPAUTH-002..004:基本判定 ===================== */
static void tc_basic(void)
{
@@ -73,20 +73,20 @@ static void tc_basic(void)
(void)memset(&st, 0, sizeof(st));
CHECK(ftp_auth_check(&s_creds, 1u, "admin", &st, 1000u) == FTP_AUTH_OK,
- "TC-FA-002 对用户名+对口令 → OK");
- CHECK(st.fail_count == 0u, "TC-FA-002b 成功后计数为 0");
+ "TC-FTPAUTH-002 对用户名+对口令 → OK");
+ CHECK(st.fail_count == 0u, "TC-FTPAUTH-002b 成功后计数为 0");
(void)memset(&st, 0, sizeof(st));
CHECK(ftp_auth_check(&s_creds, 1u, "wrong", &st, 1000u) == FTP_AUTH_FAIL,
- "TC-FA-003 错口令 → FAIL");
- CHECK(st.fail_count == 1u, "TC-FA-003b 失败计数 1");
+ "TC-FTPAUTH-003 错口令 → FAIL");
+ CHECK(st.fail_count == 1u, "TC-FTPAUTH-003b 失败计数 1");
(void)memset(&st, 0, sizeof(st));
CHECK(ftp_auth_check(&s_creds, 0u, "admin", &st, 1000u) == FTP_AUTH_FAIL,
- "TC-FA-004 错用户名+对口令 → FAIL(哈希路径已走)");
+ "TC-FTPAUTH-004 错用户名+对口令 → FAIL(哈希路径已走)");
}
-/* ===================== TC-FA-005..006:锁定与解锁 ===================== */
+/* ===================== TC-FTPAUTH-005..006:锁定与解锁 ===================== */
static void tc_lock(void)
{
@@ -96,25 +96,25 @@ static void tc_lock(void)
(void)memset(&st, 0, sizeof(st));
for (int i = 0; i < 5; i++) {
CHECK(ftp_auth_check(&s_creds, 1u, "wrong", &st, t) == FTP_AUTH_FAIL,
- "TC-FA-005 第 1..5 次失败 → FAIL");
+ "TC-FTPAUTH-005 第 1..5 次失败 → FAIL");
}
- CHECK(st.fail_count == 5u, "TC-FA-005b 计数到达 FAIL_MAX");
+ CHECK(st.fail_count == 5u, "TC-FTPAUTH-005b 计数到达 FAIL_MAX");
/* 锁定期内:对口令也 LOCKED,且不再计数 */
CHECK(ftp_auth_check(&s_creds, 1u, "admin", &st, t + 1u) == FTP_AUTH_LOCKED,
- "TC-FA-005c 锁定期内对口令 → LOCKED");
- CHECK(st.fail_count == 5u, "TC-FA-005d LOCKED 不改变计数");
+ "TC-FTPAUTH-005c 锁定期内对口令 → LOCKED");
+ CHECK(st.fail_count == 5u, "TC-FTPAUTH-005d LOCKED 不改变计数");
/* 59999 tick:仍在窗内(差值 < 60000) */
CHECK(ftp_auth_check(&s_creds, 1u, "admin", &st,
st.lock_until_tick - 1u) == FTP_AUTH_LOCKED,
- "TC-FA-005e 窗内最后 1 tick 仍 LOCKED");
+ "TC-FTPAUTH-005e 窗内最后 1 tick 仍 LOCKED");
/* 期满:恰好到达 lock_until → 放行 */
CHECK(ftp_auth_check(&s_creds, 1u, "admin", &st,
st.lock_until_tick) == FTP_AUTH_OK,
- "TC-FA-006 期满对口令 → OK");
- CHECK(st.fail_count == 0u, "TC-FA-006b 解锁成功后计数清零");
+ "TC-FTPAUTH-006 期满对口令 → OK");
+ CHECK(st.fail_count == 0u, "TC-FTPAUTH-006b 解锁成功后计数清零");
}
-/* ===================== TC-FA-007:成功清零计数 ===================== */
+/* ===================== TC-FTPAUTH-007:成功清零计数 ===================== */
static void tc_reset(void)
{
@@ -126,19 +126,19 @@ static void tc_reset(void)
(void)ftp_auth_check(&s_creds, 1u, "wrong", &st, t);
}
CHECK(ftp_auth_check(&s_creds, 1u, "admin", &st, t) == FTP_AUTH_OK,
- "TC-FA-007a 3 败后成功 → OK");
- CHECK(st.fail_count == 0u, "TC-FA-007b 成功清零");
+ "TC-FTPAUTH-007a 3 败后成功 → OK");
+ CHECK(st.fail_count == 0u, "TC-FTPAUTH-007b 成功清零");
for (int i = 0; i < 4; i++) {
CHECK(ftp_auth_check(&s_creds, 1u, "wrong", &st, t) == FTP_AUTH_FAIL,
- "TC-FA-007c 清零后再 4 败仍 FAIL(未锁)");
+ "TC-FTPAUTH-007c 清零后再 4 败仍 FAIL(未锁)");
}
CHECK(ftp_auth_check(&s_creds, 1u, "wrong", &st, t) == FTP_AUTH_FAIL,
- "TC-FA-007d 第 5 败 FAIL 并上锁");
+ "TC-FTPAUTH-007d 第 5 败 FAIL 并上锁");
CHECK(ftp_auth_check(&s_creds, 1u, "admin", &st, t + 1u) == FTP_AUTH_LOCKED,
- "TC-FA-007e 连续 5 败后 LOCKED");
+ "TC-FTPAUTH-007e 连续 5 败后 LOCKED");
}
-/* ===================== TC-FA-008:tick 32 位回绕 ===================== */
+/* ===================== TC-FTPAUTH-008:tick 32 位回绕 ===================== */
static void tc_wraparound(void)
{
@@ -150,13 +150,13 @@ static void tc_wraparound(void)
st.lock_until_tick = 0xFFFFFFF0u;
/* 回绕前 240 tick:仍在窗内 */
CHECK(ftp_auth_check(&s_creds, 1u, "admin", &st, 0xFFFFFF00u) == FTP_AUTH_LOCKED,
- "TC-FA-008a 回绕前窗内 → LOCKED");
+ "TC-FTPAUTH-008a 回绕前窗内 → LOCKED");
/* 回绕后 32 tick:now=0x10,(int32_t)(0x10-0xFFFFFFF0)=+32 → 期满 */
CHECK(ftp_auth_check(&s_creds, 1u, "admin", &st, 0x00000010u) == FTP_AUTH_OK,
- "TC-FA-008b 回绕后期满 → OK(有符号差抗回绕)");
+ "TC-FTPAUTH-008b 回绕后期满 → OK(有符号差抗回绕)");
}
-/* ===================== TC-FA-009..010:fail-closed 边界 ===================== */
+/* ===================== TC-FTPAUTH-009..010:fail-closed 边界 ===================== */
static void tc_fail_closed(void)
{
@@ -165,17 +165,17 @@ static void tc_fail_closed(void)
(void)memset(&st, 0, sizeof(st));
CHECK(ftp_auth_check(&bad_creds, 1u, "admin", &st, 1000u) == FTP_AUTH_FAIL,
- "TC-FA-009 非法 hex 配置 → 恒 FAIL(无人能登录,fail-closed)");
+ "TC-FTPAUTH-009 非法 hex 配置 → 恒 FAIL(无人能登录,fail-closed)");
(void)memset(&st, 0, sizeof(st));
CHECK(ftp_auth_check(&s_creds, 1u, "", &st, 1000u) == FTP_AUTH_FAIL,
- "TC-FA-010a 空口令 → FAIL");
+ "TC-FTPAUTH-010a 空口令 → FAIL");
CHECK(ftp_auth_check(&s_creds, 1u, NULL, &st, 1000u) == FTP_AUTH_FAIL,
- "TC-FA-010b NULL 口令 → FAIL");
+ "TC-FTPAUTH-010b NULL 口令 → FAIL");
CHECK(ftp_auth_check(NULL, 1u, "admin", &st, 1000u) == FTP_AUTH_FAIL,
- "TC-FA-010c NULL creds → FAIL");
+ "TC-FTPAUTH-010c NULL creds → FAIL");
CHECK(ftp_auth_check(&s_creds, 1u, "admin", NULL, 1000u) == FTP_AUTH_FAIL,
- "TC-FA-010d NULL state → FAIL");
+ "TC-FTPAUTH-010d NULL state → FAIL");
}
/* ===================== main ===================== */
diff --git a/test/host/iec104/iec104_test.c b/test/host/iec104/iec104_test.c
index 3464e93b..f162a1b3 100644
--- a/test/host/iec104/iec104_test.c
+++ b/test/host/iec104/iec104_test.c
@@ -10,29 +10,29 @@
* 发送经 send_apdu 回调全量捕获,时基由测试注入。
*
* 覆盖点(docs/子系统设计/IEC104上行设计说明.md §7):
- * TC-104-001 CP56Time2a 往返 / 闰年 / IV / 钳位
- * TC-104-002 IOA 3B 与短浮点小端往返
- * TC-104-003 APCI 重组:半帧 / 粘帧 / 坏起始符 / 坏长度
- * TC-104-004 STARTDT 握手 → RUN
- * TC-104-005 OPEN 态 I 帧忽略(序号不消费)
- * TC-104-006 总召全流程:actcon→4 分片(首召 COT=4)→actterm;二召 COT=2;RBT→COT=4
- * TC-104-007 遥信变位 COV(COT=3);无效位不触发
- * TC-104-008 遥测死区 COV:死区内不发 / 越死区发
- * TC-104-009 k 窗:12 未确认停发;S 确认后恢复
- * TC-104-010 w 阈:收满 8 发 S
- * TC-104-011 t2 到期发 S
- * TC-104-012 t3 空闲发 TESTFR act;未答 t1 超时 → IDLE;con 清挂起不误杀
- * TC-104-013 遥控两段式:选择/执行成功;失配 PN;拒绝类选择段即 PN
- * TC-104-014 定值两段写(真实 prot_set):越界 PN;执行后 get_f + selfcheck
- * TC-104-015 C_RD:YC 命中 / 定值命中 / 未知 IOA COT14+EVI
- * TC-104-016 C_CS:clock_sync 收正确 epoch;IV → PN;clock_sync 失败 → PN
- * TC-104-017 未知类型 COT12+EVI;错公共地址 COT13+EVI
- * TC-104-018 STOPDT:数据停发,TESTFR 仍应答
- * TC-104-019 序号错 → IDLE(链路故障)
- * TC-104-020 pts:无效通道 IV / 未就绪 NT / 无效遥信 IV / is_dp / 表尺寸
- * TC-104-021 C_TS / C_RP actcon
- * TC-104-022 周期上送 COT=1(YC 组 + 频率)
- * TC-104-023 k 窗满 COV 不丢事件(pend 暂存,窗开后补发)
+ * TC-IEC104-001 CP56Time2a 往返 / 闰年 / IV / 钳位
+ * TC-IEC104-002 IOA 3B 与短浮点小端往返
+ * TC-IEC104-003 APCI 重组:半帧 / 粘帧 / 坏起始符 / 坏长度
+ * TC-IEC104-004 STARTDT 握手 → RUN
+ * TC-IEC104-005 OPEN 态 I 帧忽略(序号不消费)
+ * TC-IEC104-006 总召全流程:actcon→4 分片(首召 COT=4)→actterm;二召 COT=2;RBT→COT=4
+ * TC-IEC104-007 遥信变位 COV(COT=3);无效位不触发
+ * TC-IEC104-008 遥测死区 COV:死区内不发 / 越死区发
+ * TC-IEC104-009 k 窗:12 未确认停发;S 确认后恢复
+ * TC-IEC104-010 w 阈:收满 8 发 S
+ * TC-IEC104-011 t2 到期发 S
+ * TC-IEC104-012 t3 空闲发 TESTFR act;未答 t1 超时 → IDLE;con 清挂起不误杀
+ * TC-IEC104-013 遥控两段式:选择/执行成功;失配 PN;拒绝类选择段即 PN
+ * TC-IEC104-014 定值两段写(真实 prot_set):越界 PN;执行后 get_f + selfcheck
+ * TC-IEC104-015 C_RD:YC 命中 / 定值命中 / 未知 IOA COT14+EVI
+ * TC-IEC104-016 C_CS:clock_sync 收正确 epoch;IV → PN;clock_sync 失败 → PN
+ * TC-IEC104-017 未知类型 COT12+EVI;错公共地址 COT13+EVI
+ * TC-IEC104-018 STOPDT:数据停发,TESTFR 仍应答
+ * TC-IEC104-019 序号错 → IDLE(链路故障)
+ * TC-IEC104-020 pts:无效通道 IV / 未就绪 NT / 无效遥信 IV / is_dp / 表尺寸
+ * TC-IEC104-021 C_TS / C_RP actcon
+ * TC-IEC104-022 周期上送 COT=1(YC 组 + 频率)
+ * TC-IEC104-023 k 窗满 COV 不丢事件(pend 暂存,窗开后补发)
*
* 通过:全部 TC PASS(main 返回 0)。
* 创建日期:2026-10-12(B4)
diff --git a/test/host/nand_port/nand_port_test.c b/test/host/nand_port/nand_port_test.c
index fb22635c..93e08593 100644
--- a/test/host/nand_port/nand_port_test.c
+++ b/test/host/nand_port/nand_port_test.c
@@ -21,15 +21,15 @@
* 主机侧由 harness 的 /utf-8 保证注释里的中文被正确解码。
*
* 用例前缀:TC-NP-NNN(NP = NAND Port);分组:
- * TC-NP-000 假芯片自洽(几何 / 上电态)
- * TC-NP-100..108 dhara_nand_is_free 整页扫描(N-12)
- * TC-NP-110..112 dhara_nand_is_free 越界守卫(N-13)
- * TC-NP-200..207 dhara_nand_prog(越界 / NULL / 往返 / 双编程探针 / 失败注入)
- * TC-NP-300..307 dhara_nand_read(越界 / 越窗 offset+length / 部分读 / ECC / E-42)
- * TC-NP-400..405 dhara_nand_copy(src 与 dst 双端守卫 / 正常搬页)
- * TC-NP-500..504 dhara_nand_erase(越界块零标坏块 / 整块回 0xFF / 失败注入)
- * TC-NP-600..605 dhara_nand_is_bad / dhara_nand_mark_bad(越界保守判坏、BBT 不变)
- * TC-NP-700 dhara map 级场景(写入 -> 重新 resume,双编程计数为 0)
+ * TC-NANDPORT-000 假芯片自洽(几何 / 上电态)
+ * TC-NANDPORT-100..108 dhara_nand_is_free 整页扫描(N-12)
+ * TC-NANDPORT-110..112 dhara_nand_is_free 越界守卫(N-13)
+ * TC-NANDPORT-200..207 dhara_nand_prog(越界 / NULL / 往返 / 双编程探针 / 失败注入)
+ * TC-NANDPORT-300..307 dhara_nand_read(越界 / 越窗 offset+length / 部分读 / ECC / E-42)
+ * TC-NANDPORT-400..405 dhara_nand_copy(src 与 dst 双端守卫 / 正常搬页)
+ * TC-NANDPORT-500..504 dhara_nand_erase(越界块零标坏块 / 整块回 0xFF / 失败注入)
+ * TC-NANDPORT-600..605 dhara_nand_is_bad / dhara_nand_mark_bad(越界保守判坏、BBT 不变)
+ * TC-NANDPORT-700 dhara map 级场景(写入 -> 重新 resume,双编程计数为 0)
*
* 通过:全部 CHECK 通过(main 返回 0)。
* 入口:int main(void),返回 0=PASS / 1=FAIL(由 run 脚本判读)。
@@ -402,7 +402,7 @@ static int s_failed;
/* dhara 核心(真实源,非桩):nand_ftl.c 引用 dhara_map_*,必须一并纳入才能链接。
* 纳入后本编译单元 = 移植层 + 它服务的 FTL 本体,故 dhara map 级场景
- * (TC-NP-700 写入 -> 重新 resume)测的是真链路。顺序:journal 在 map 之前。 */
+ * (TC-NANDPORT-700 写入 -> 重新 resume)测的是真链路。顺序:journal 在 map 之前。 */
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4100 4244 4334 4701)
@@ -428,7 +428,7 @@ static struct dhara_nand s_ut_nand;
* N-12 修复**之前**的 dhara_nand_is_free:只读页首 64 B 就回答"空闲"。
* 本函数按当时的形状内联一份(同样经假芯片的两段式读),用来证明本套件**有牙**:
* 对同一页,旧算法答 1(误判空闲)、新实现答 0。将来有人把 is_free 改回只看
- * 页首,TC-NP-105 立刻变红——而不是"测试跟着实现一起改回去"。
+ * 页首,TC-NANDPORT-105 立刻变红——而不是"测试跟着实现一起改回去"。
*/
static int old_is_free_first64(const struct dhara_nand *n, dhara_page_t p) {
uint8_t buf[64];
@@ -449,18 +449,18 @@ static int old_is_free_first64(const struct dhara_nand *n, dhara_page_t p) {
return 1;
}
-/* ===================== TC-NP-100..108:dhara_nand_is_free(整页扫描) =====================
+/* ===================== TC-NANDPORT-100..108:dhara_nand_is_free(整页扫描) =====================
*
* N-12:旧实现只看页首 64 B,会把"页首 0xFF、后段有数据"的已编程页误判空闲
* -> dhara 往已编程页再编程 = 数据丢失。本组把"必须扫完整页"钉死,
- * 并用 TC-NP-105 的旧算法对照证明这组断言真的能咬人。
+ * 并用 TC-NANDPORT-105 的旧算法对照证明这组断言真的能咬人。
*/
static void tc_is_free(void) {
static uint8_t page_buf[FAKE_PAGE_SIZE];
struct dhara_nand zeroed;
- /* TC-NP-100:整页擦除 -> 1 */
- printf("[TC-NP-100] erased page is free\n");
+ /* TC-NANDPORT-100:整页擦除 -> 1 */
+ printf("[TC-NANDPORT-100] erased page is free\n");
fake_chip_reset();
CHECK(dhara_nand_is_free(&s_ut_nand, 0u) == 1, "erased page -> is_free = 1");
CHECK(g_fake_page_read_cnt == 1u, "one page_read only (no per-byte commands)");
@@ -469,8 +469,8 @@ static void tc_is_free(void) {
CHECK(g_fake_isfree_scan_cnt == (FAKE_PAGE_SIZE / 64u),
"64B column-read fingerprint calibrated (proves scenario really calls is_free)");
- /* TC-NP-101:第 0 字节有数据 -> 0(快路径) */
- printf("[TC-NP-101] byte 0 programmed -> not free\n");
+ /* TC-NANDPORT-101:第 0 字节有数据 -> 0(快路径) */
+ printf("[TC-NANDPORT-101] byte 0 programmed -> not free\n");
fake_chip_reset();
(void)memset(page_buf, 0xFF, sizeof(page_buf));
page_buf[0] = 0x00u;
@@ -479,10 +479,10 @@ static void tc_is_free(void) {
CHECK(g_fake_read_cache_cnt == 1u,
"early exit on first chunk = fast path (same cost as the old impl)");
- /* TC-NP-102:N-12 回归用例
+ /* TC-NANDPORT-102:N-12 回归用例
* 页首 64 B 全 0xFF、第 1000 字节 = 0x00 -> 必须答"非空"。
* 旧实现只看页首 64 B 会误判空闲,dhara 遂往这一页再编程。 */
- printf("[TC-NP-102] N-12 regression: hole in first 64B, data at byte 1000\n");
+ printf("[TC-NANDPORT-102] N-12 regression: hole in first 64B, data at byte 1000\n");
fake_chip_reset();
(void)memset(page_buf, 0xFF, sizeof(page_buf));
page_buf[1000] = 0x00u;
@@ -492,8 +492,8 @@ static void tc_is_free(void) {
CHECK(g_fake_read_cache_cnt > 1u,
"scan continues past the first 64B (old impl stopped here = root cause)");
- /* TC-NP-103:只有最后一个字节非 0xFF -> 0 */
- printf("[TC-NP-103] only last byte programmed -> not free\n");
+ /* TC-NANDPORT-103:只有最后一个字节非 0xFF -> 0 */
+ printf("[TC-NANDPORT-103] only last byte programmed -> not free\n");
fake_chip_reset();
(void)memset(page_buf, 0xFF, sizeof(page_buf));
page_buf[FAKE_PAGE_SIZE - 1u] = 0x5Au;
@@ -503,8 +503,8 @@ static void tc_is_free(void) {
CHECK(g_fake_read_cache_cnt == (FAKE_PAGE_SIZE / 64u),
"full scan to the page tail before answering (32 column reads)");
- /* TC-NP-104:只有第 64 字节非 0xFF -> 0(旧窗口右边界外的第一个字节) */
- printf("[TC-NP-104] only byte 64 programmed -> not free\n");
+ /* TC-NANDPORT-104:只有第 64 字节非 0xFF -> 0(旧窗口右边界外的第一个字节) */
+ printf("[TC-NANDPORT-104] only byte 64 programmed -> not free\n");
fake_chip_reset();
(void)memset(page_buf, 0xFF, sizeof(page_buf));
page_buf[64u] = 0x00u;
@@ -512,10 +512,10 @@ static void tc_is_free(void) {
CHECK(dhara_nand_is_free(&s_ut_nand, 4u) == 0,
"only byte 64 (first byte outside the old window) -> is_free = 0");
- /* TC-NP-105:旧算法对照(证明本套件有牙)
+ /* TC-NANDPORT-105:旧算法对照(证明本套件有牙)
* 同一页形态:旧算法答 1 = 误判空闲,新实现答 0。
* 任何人把 is_free 改回"只看页首",这条立刻红。 */
- printf("[TC-NP-105] old-algorithm contrast (test has teeth)\n");
+ printf("[TC-NANDPORT-105] old-algorithm contrast (test has teeth)\n");
fake_chip_reset();
(void)memset(page_buf, 0xFF, sizeof(page_buf));
page_buf[1000] = 0x00u;
@@ -525,8 +525,8 @@ static void tc_is_free(void) {
CHECK(dhara_nand_is_free(&s_ut_nand, 5u) == 0,
"new implementation answers not-free -> 0 (opposite verdict = teeth)");
- /* TC-NP-106:读失败保守判非空(E-42 同族) */
- printf("[TC-NP-106] read failure is answered conservatively\n");
+ /* TC-NANDPORT-106:读失败保守判非空(E-42 同族) */
+ printf("[TC-NANDPORT-106] read failure is answered conservatively\n");
fake_chip_reset();
s_fail_page_read = 1;
CHECK(dhara_nand_is_free(&s_ut_nand, 6u) == 0,
@@ -536,8 +536,8 @@ static void tc_is_free(void) {
CHECK(dhara_nand_is_free(&s_ut_nand, 7u) == 0,
"read_from_cache failure -> not free (E-42 family)");
- /* TC-NP-107:NULL / num_blocks = 0 的几何守卫 */
- printf("[TC-NP-107] NULL geometry / zero blocks guard\n");
+ /* TC-NANDPORT-107:NULL / num_blocks = 0 的几何守卫 */
+ printf("[TC-NANDPORT-107] NULL geometry / zero blocks guard\n");
fake_chip_reset();
CHECK(dhara_nand_is_free(NULL, 0u) == 0, "n = NULL -> not free, no crash");
CHECK(fake_chip_access_total() == 0u, "n = NULL causes zero chip access");
@@ -547,8 +547,8 @@ static void tc_is_free(void) {
CHECK(dhara_nand_is_free(&zeroed, 0u) == 0, "num_blocks = 0 -> not free");
CHECK(fake_chip_access_total() == 0u, "num_blocks = 0 causes zero chip access");
- /* TC-NP-108:擦除后重新判空(假芯片语义自洽,防"擦除没生效"假绿) */
- printf("[TC-NP-108] fake chip erase really clears the array\n");
+ /* TC-NANDPORT-108:擦除后重新判空(假芯片语义自洽,防"擦除没生效"假绿) */
+ printf("[TC-NANDPORT-108] fake chip erase really clears the array\n");
fake_chip_reset();
fake_fill_pattern(page_buf, FAKE_PAGE_SIZE, 7u);
fake_poke_page(8u, page_buf, FAKE_PAGE_SIZE);
@@ -557,9 +557,9 @@ static void tc_is_free(void) {
CHECK(dhara_nand_is_free(&s_ut_nand, 8u) == 1, "after erase -> free (fake chip sane)");
}
-/* ===================== TC-NP-110..112:is_free 越界守卫(N-13) ===================== */
+/* ===================== TC-NANDPORT-110..112:is_free 越界守卫(N-13) ===================== */
static void tc_is_free_oob(void) {
- printf("[TC-NP-110] is_free out-of-range pages (N-13)\n");
+ printf("[TC-NANDPORT-110] is_free out-of-range pages (N-13)\n");
fake_chip_reset();
CHECK(dhara_nand_is_free(&s_ut_nand, DHARA_PAGE_NONE) == 0,
@@ -567,13 +567,13 @@ static void tc_is_free_oob(void) {
CHECK(fake_chip_access_total() == 0u,
"DHARA_PAGE_NONE causes zero chip access (no truncated address)");
- printf("[TC-NP-111] is_free at total_pages boundary\n");
+ printf("[TC-NANDPORT-111] is_free at total_pages boundary\n");
fake_chip_reset();
CHECK(dhara_nand_is_free(&s_ut_nand, UT_OOB_PAGE) == 0,
"page == total_pages -> is_free = 0");
CHECK(fake_chip_access_total() == 0u, "page == total_pages -> zero chip access");
- printf("[TC-NP-112] is_free beyond total_pages\n");
+ printf("[TC-NANDPORT-112] is_free beyond total_pages\n");
fake_chip_reset();
CHECK(dhara_nand_is_free(&s_ut_nand, UT_OOB_PAGE + 1u) == 0,
"page == total_pages + 1 -> is_free = 0");
@@ -586,13 +586,13 @@ static int fake_no_write_access(void) {
(g_fake_program_exec_cnt == 0u) && (g_fake_block_erase_cnt == 0u);
}
-/* ===================== TC-NP-200..205:dhara_nand_prog ===================== */
+/* ===================== TC-NANDPORT-200..205:dhara_nand_prog ===================== */
static void tc_prog(void) {
static uint8_t page_buf[FAKE_PAGE_SIZE];
dhara_error_t err;
- /* TC-NP-200:越界页 -> -1 + CORRUPT_MAP + 零写入 */
- printf("[TC-NP-200] prog out-of-range page -> -1, zero write\n");
+ /* TC-NANDPORT-200:越界页 -> -1 + CORRUPT_MAP + 零写入 */
+ printf("[TC-NANDPORT-200] prog out-of-range page -> -1, zero write\n");
fake_chip_reset();
fake_fill_pattern(page_buf, FAKE_PAGE_SIZE, 11u);
err = DHARA_E_NONE;
@@ -602,10 +602,10 @@ static void tc_prog(void) {
CHECK(fake_no_write_access(), "prog out-of-range -> zero write access");
CHECK(g_fake_mark_bad_cnt == 0u, "prog out-of-range -> no block marked bad");
- /* TC-NP-201:DHARA_PAGE_NONE -> -1 + CORRUPT_MAP + 零写入
+ /* TC-NANDPORT-201:DHARA_PAGE_NONE -> -1 + CORRUPT_MAP + 零写入
* 旧实现会把 0xffffffff 加偏移送进 SPI 命令,被地址位截断成某个真实页
* -> 静默写坏无辜数据;现在必须在守卫处就挡住。 */
- printf("[TC-NP-201] prog DHARA_PAGE_NONE -> -1, zero write (N-13)\n");
+ printf("[TC-NANDPORT-201] prog DHARA_PAGE_NONE -> -1, zero write (N-13)\n");
fake_chip_reset();
err = DHARA_E_NONE;
CHECK(dhara_nand_prog(&s_ut_nand, DHARA_PAGE_NONE, page_buf, &err) == -1,
@@ -613,16 +613,16 @@ static void tc_prog(void) {
CHECK(err == DHARA_E_CORRUPT_MAP, "prog DHARA_PAGE_NONE -> DHARA_E_CORRUPT_MAP");
CHECK(fake_chip_access_total() == 0u, "prog DHARA_PAGE_NONE -> zero chip access");
- /* TC-NP-202:data == NULL -> -1(守卫顺带挡住空指针) */
- printf("[TC-NP-202] prog with NULL data -> -1\n");
+ /* TC-NANDPORT-202:data == NULL -> -1(守卫顺带挡住空指针) */
+ printf("[TC-NANDPORT-202] prog with NULL data -> -1\n");
fake_chip_reset();
err = DHARA_E_NONE;
CHECK(dhara_nand_prog(&s_ut_nand, 0u, NULL, &err) == -1, "prog data = NULL -> -1");
CHECK(err == DHARA_E_CORRUPT_MAP, "prog data = NULL -> DHARA_E_CORRUPT_MAP");
CHECK(fake_no_write_access(), "prog data = NULL -> zero write access");
- /* TC-NP-203:正常页 -> 0 且回读一致 */
- printf("[TC-NP-203] prog a valid page -> 0, read-back matches\n");
+ /* TC-NANDPORT-203:正常页 -> 0 且回读一致 */
+ printf("[TC-NANDPORT-203] prog a valid page -> 0, read-back matches\n");
fake_chip_reset();
err = DHARA_E_NONE;
CHECK(dhara_nand_prog(&s_ut_nand, 64u, page_buf, &err) == 0, "prog page 64 -> 0");
@@ -630,8 +630,8 @@ static void tc_prog(void) {
CHECK(fake_page_equals(64u, page_buf, FAKE_PAGE_SIZE), "prog page 64 content on chip");
CHECK(g_fake_double_program_cnt == 0u, "prog onto an erased page -> no violation");
- /* TC-NP-204:最后一个合法页(上界内边界) */
- printf("[TC-NP-204] prog last valid page (boundary inside)\n");
+ /* TC-NANDPORT-204:最后一个合法页(上界内边界) */
+ printf("[TC-NANDPORT-204] prog last valid page (boundary inside)\n");
fake_chip_reset();
err = DHARA_E_NONE;
CHECK(dhara_nand_prog(&s_ut_nand, UT_TOTAL_PAGES - 1u, page_buf, &err) == 0,
@@ -639,8 +639,8 @@ static void tc_prog(void) {
CHECK(fake_page_equals(UT_TOTAL_PAGES - 1u, page_buf, FAKE_PAGE_SIZE),
"last valid page content on chip");
- /* TC-NP-205:双编程探针自检——同一页再编程必须被记违规(防探针是死码) */
- printf("[TC-NP-205] double-program probe really fires\n");
+ /* TC-NANDPORT-205:双编程探针自检——同一页再编程必须被记违规(防探针是死码) */
+ printf("[TC-NANDPORT-205] double-program probe really fires\n");
fake_chip_reset();
err = DHARA_E_NONE;
(void)dhara_nand_prog(&s_ut_nand, 128u, page_buf, &err);
@@ -648,8 +648,8 @@ static void tc_prog(void) {
CHECK(g_fake_double_program_cnt == 1u, "reprogramming a programmed page -> 1 violation");
CHECK(g_fake_last_double_program_page == 128u, "violation records the offending page");
- /* TC-NP-206:编程失败 -> BAD_BLOCK + 标坏该块(错误分类不被守卫改动破坏) */
- printf("[TC-NP-206] program failure -> BAD_BLOCK + mark bad\n");
+ /* TC-NANDPORT-206:编程失败 -> BAD_BLOCK + 标坏该块(错误分类不被守卫改动破坏) */
+ printf("[TC-NANDPORT-206] program failure -> BAD_BLOCK + mark bad\n");
fake_chip_reset();
s_fail_program_exec = 1;
err = DHARA_E_NONE;
@@ -659,9 +659,9 @@ static void tc_prog(void) {
CHECK(g_fake_mark_bad_cnt == 1u, "program failure marks exactly one block bad");
CHECK(g_fake_mark_bad_log[0] == 2u, "the block marked bad is the page's own block");
- /* TC-NP-207:program_load 失败(装载阶段)-> 同样 BAD_BLOCK + 标坏该块,
+ /* TC-NANDPORT-207:program_load 失败(装载阶段)-> 同样 BAD_BLOCK + 标坏该块,
* 且在 exec 之前就短路(真实芯片:02h 都没成,10h 自然不发) */
- printf("[TC-NP-207] program_load failure -> BAD_BLOCK + mark bad\n");
+ printf("[TC-NANDPORT-207] program_load failure -> BAD_BLOCK + mark bad\n");
fake_chip_reset();
s_fail_program_load = 1;
err = DHARA_E_NONE;
@@ -673,14 +673,14 @@ static void tc_prog(void) {
CHECK(g_fake_mark_bad_log[0] == 3u, "the block marked bad is the page's own block");
}
-/* ===================== TC-NP-300..307:dhara_nand_read ===================== */
+/* ===================== TC-NANDPORT-300..307:dhara_nand_read ===================== */
static void tc_read(void) {
static uint8_t page_buf[FAKE_PAGE_SIZE];
static uint8_t rd[FAKE_PAGE_SIZE];
dhara_error_t err;
- /* TC-NP-300/301:越界页 -> -1 + CORRUPT_MAP + 零访问 */
- printf("[TC-NP-300] read out-of-range page -> -1, zero access\n");
+ /* TC-NANDPORT-300/301:越界页 -> -1 + CORRUPT_MAP + 零访问 */
+ printf("[TC-NANDPORT-300] read out-of-range page -> -1, zero access\n");
fake_chip_reset();
err = DHARA_E_NONE;
CHECK(dhara_nand_read(&s_ut_nand, UT_OOB_PAGE, 0u, 512u, rd, &err) == -1,
@@ -688,7 +688,7 @@ static void tc_read(void) {
CHECK(err == DHARA_E_CORRUPT_MAP, "read out-of-range -> DHARA_E_CORRUPT_MAP");
CHECK(fake_chip_access_total() == 0u, "read out-of-range -> zero chip access");
- printf("[TC-NP-301] read DHARA_PAGE_NONE -> -1, zero access\n");
+ printf("[TC-NANDPORT-301] read DHARA_PAGE_NONE -> -1, zero access\n");
fake_chip_reset();
err = DHARA_E_NONE;
CHECK(dhara_nand_read(&s_ut_nand, DHARA_PAGE_NONE, 0u, 512u, rd, &err) == -1,
@@ -696,8 +696,8 @@ static void tc_read(void) {
CHECK(err == DHARA_E_CORRUPT_MAP, "read DHARA_PAGE_NONE -> DHARA_E_CORRUPT_MAP");
CHECK(fake_chip_access_total() == 0u, "read DHARA_PAGE_NONE -> zero chip access");
- /* TC-NP-302:offset + length 越过 2048 -> -1 */
- printf("[TC-NP-302] read spanning past the page end -> -1\n");
+ /* TC-NANDPORT-302:offset + length 越过 2048 -> -1 */
+ printf("[TC-NANDPORT-302] read spanning past the page end -> -1\n");
fake_chip_reset();
err = DHARA_E_NONE;
CHECK(dhara_nand_read(&s_ut_nand, 0u, 2000u, 100u, rd, &err) == -1,
@@ -712,16 +712,16 @@ static void tc_read(void) {
CHECK(dhara_nand_read(&s_ut_nand, 0u, 0u, FAKE_PAGE_SIZE + 1u, rd, &err) == -1,
"read length 2049 -> -1");
- /* TC-NP-303:NULL data -> -1 */
- printf("[TC-NP-303] read with NULL data -> -1\n");
+ /* TC-NANDPORT-303:NULL data -> -1 */
+ printf("[TC-NANDPORT-303] read with NULL data -> -1\n");
fake_chip_reset();
err = DHARA_E_NONE;
CHECK(dhara_nand_read(&s_ut_nand, 0u, 0u, 512u, NULL, &err) == -1,
"read data = NULL -> -1");
CHECK(fake_chip_access_total() == 0u, "read data = NULL -> zero chip access");
- /* TC-NP-304:正常部分读 -> 0 且内容正确 */
- printf("[TC-NP-304] partial read returns the right slice\n");
+ /* TC-NANDPORT-304:正常部分读 -> 0 且内容正确 */
+ printf("[TC-NANDPORT-304] partial read returns the right slice\n");
prep_content_page(page_buf, 21u);
err = DHARA_E_NONE;
CHECK(dhara_nand_read(&s_ut_nand, UT_SRC_PAGE, 1024u, 512u, rd, &err) == 0,
@@ -729,16 +729,16 @@ static void tc_read(void) {
CHECK(memcmp(rd, &page_buf[1024], 512u) == 0, "partial read returns the right bytes");
CHECK(g_fake_page_read_cnt == 1u, "partial read issues one page_read");
- /* TC-NP-305:整页读 -> 0 且内容正确(边界 length == 2048) */
- printf("[TC-NP-305] full page read\n");
+ /* TC-NANDPORT-305:整页读 -> 0 且内容正确(边界 length == 2048) */
+ printf("[TC-NANDPORT-305] full page read\n");
prep_content_page(page_buf, 21u);
err = DHARA_E_NONE;
CHECK(dhara_nand_read(&s_ut_nand, UT_SRC_PAGE, 0u, FAKE_PAGE_SIZE, rd, &err) == 0,
"full page read (length == 2048) -> 0");
CHECK(memcmp(rd, page_buf, FAKE_PAGE_SIZE) == 0, "full page read matches the chip");
- /* TC-NP-306:ECC 不可纠正 -> -1 + DHARA_E_ECC */
- printf("[TC-NP-306] uncorrectable ECC -> -1 + DHARA_E_ECC\n");
+ /* TC-NANDPORT-306:ECC 不可纠正 -> -1 + DHARA_E_ECC */
+ printf("[TC-NANDPORT-306] uncorrectable ECC -> -1 + DHARA_E_ECC\n");
prep_content_page(page_buf, 21u);
s_fail_check_ecc = 1;
err = DHARA_E_NONE;
@@ -746,8 +746,8 @@ static void tc_read(void) {
"check_ecc failure -> -1");
CHECK(err == DHARA_E_ECC, "check_ecc failure -> DHARA_E_ECC");
- /* TC-NP-307:E-42 同族——read_from_cache 失败必须 -1(旧实现返回 0 交垃圾) */
- printf("[TC-NP-307] E-42: read_from_cache failure must not report success\n");
+ /* TC-NANDPORT-307:E-42 同族——read_from_cache 失败必须 -1(旧实现返回 0 交垃圾) */
+ printf("[TC-NANDPORT-307] E-42: read_from_cache failure must not report success\n");
prep_content_page(page_buf, 21u);
s_fail_read_cache = 1;
err = DHARA_E_NONE;
@@ -756,13 +756,13 @@ static void tc_read(void) {
CHECK(err == DHARA_E_ECC, "read_from_cache failure -> DHARA_E_ECC");
}
-/* ===================== TC-NP-400..405:dhara_nand_copy ===================== */
+/* ===================== TC-NANDPORT-400..405:dhara_nand_copy ===================== */
static void tc_copy(void) {
static uint8_t page_buf[FAKE_PAGE_SIZE];
dhara_error_t err;
- /* TC-NP-400:src 越界 -> -1 + CORRUPT_MAP + 零写入 */
- printf("[TC-NP-400] copy with out-of-range src -> -1, zero write\n");
+ /* TC-NANDPORT-400:src 越界 -> -1 + CORRUPT_MAP + 零写入 */
+ printf("[TC-NANDPORT-400] copy with out-of-range src -> -1, zero write\n");
fake_chip_reset();
err = DHARA_E_NONE;
CHECK(dhara_nand_copy(&s_ut_nand, UT_OOB_PAGE, 100u, &err) == -1,
@@ -771,8 +771,8 @@ static void tc_copy(void) {
CHECK(fake_no_write_access(), "copy bad src -> zero write access");
CHECK(fake_chip_access_total() == 0u, "copy bad src -> zero chip access at all");
- /* TC-NP-401:src = DHARA_PAGE_NONE -> -1 + CORRUPT_MAP */
- printf("[TC-NP-401] copy with DHARA_PAGE_NONE src -> -1\n");
+ /* TC-NANDPORT-401:src = DHARA_PAGE_NONE -> -1 + CORRUPT_MAP */
+ printf("[TC-NANDPORT-401] copy with DHARA_PAGE_NONE src -> -1\n");
fake_chip_reset();
err = DHARA_E_NONE;
CHECK(dhara_nand_copy(&s_ut_nand, DHARA_PAGE_NONE, 100u, &err) == -1,
@@ -780,9 +780,9 @@ static void tc_copy(void) {
CHECK(err == DHARA_E_CORRUPT_MAP, "copy DHARA_PAGE_NONE src -> DHARA_E_CORRUPT_MAP");
CHECK(fake_chip_access_total() == 0u, "copy DHARA_PAGE_NONE src -> zero chip access");
- /* TC-NP-402:dst 越界 -> -1 + CORRUPT_MAP + 零写入 + 零标坏块
+ /* TC-NANDPORT-402:dst 越界 -> -1 + CORRUPT_MAP + 零写入 + 零标坏块
* dst 越界最致命:那是一次写入,旧实现会静默写进被截断出来的无辜页。 */
- printf("[TC-NP-402] copy with out-of-range dst -> -1, zero write, zero mark-bad\n");
+ printf("[TC-NANDPORT-402] copy with out-of-range dst -> -1, zero write, zero mark-bad\n");
prep_content_page(page_buf, 31u);
err = DHARA_E_NONE;
CHECK(dhara_nand_copy(&s_ut_nand, UT_SRC_PAGE, UT_OOB_PAGE, &err) == -1,
@@ -791,8 +791,8 @@ static void tc_copy(void) {
CHECK(fake_no_write_access(), "copy bad dst -> zero write access");
CHECK(g_fake_mark_bad_cnt == 0u, "copy bad dst -> no block marked bad");
- /* TC-NP-403:dst = DHARA_PAGE_NONE(哨兵漏进来的真实形态) */
- printf("[TC-NP-403] copy with DHARA_PAGE_NONE dst -> -1, zero write\n");
+ /* TC-NANDPORT-403:dst = DHARA_PAGE_NONE(哨兵漏进来的真实形态) */
+ printf("[TC-NANDPORT-403] copy with DHARA_PAGE_NONE dst -> -1, zero write\n");
prep_content_page(page_buf, 31u);
err = DHARA_E_NONE;
CHECK(dhara_nand_copy(&s_ut_nand, UT_SRC_PAGE, DHARA_PAGE_NONE, &err) == -1,
@@ -801,8 +801,8 @@ static void tc_copy(void) {
CHECK(fake_no_write_access(), "copy DHARA_PAGE_NONE dst -> zero write access");
CHECK(g_fake_mark_bad_cnt == 0u, "copy DHARA_PAGE_NONE dst -> zero mark_bad");
- /* TC-NP-404:正常 copy -> 0 且目标页与源一致 */
- printf("[TC-NP-404] normal copy moves the page content\n");
+ /* TC-NANDPORT-404:正常 copy -> 0 且目标页与源一致 */
+ printf("[TC-NANDPORT-404] normal copy moves the page content\n");
prep_content_page(page_buf, 31u);
err = DHARA_E_NONE;
CHECK(dhara_nand_copy(&s_ut_nand, UT_SRC_PAGE, 128u, &err) == 0,
@@ -811,8 +811,8 @@ static void tc_copy(void) {
CHECK(fake_page_equals(128u, page_buf, FAKE_PAGE_SIZE), "dst page equals src content");
CHECK(g_fake_double_program_cnt == 0u, "copy onto an erased page -> no violation");
- /* TC-NP-405:copy 到已编程页 -> 探针记下双编程(场景层的判据基础) */
- printf("[TC-NP-405] copy onto a programmed page is recorded as a violation\n");
+ /* TC-NANDPORT-405:copy 到已编程页 -> 探针记下双编程(场景层的判据基础) */
+ printf("[TC-NANDPORT-405] copy onto a programmed page is recorded as a violation\n");
prep_content_page(page_buf, 31u);
err = DHARA_E_NONE;
(void)dhara_nand_copy(&s_ut_nand, UT_SRC_PAGE, 128u, &err);
@@ -820,14 +820,14 @@ static void tc_copy(void) {
CHECK(g_fake_double_program_cnt == 1u, "second copy onto the same dst -> 1 violation");
}
-/* ===================== TC-NP-500..504:dhara_nand_erase ===================== */
+/* ===================== TC-NANDPORT-500..504:dhara_nand_erase ===================== */
static void tc_erase(void) {
static uint8_t page_buf[FAKE_PAGE_SIZE];
dhara_error_t err;
uint32_t i;
- /* TC-NP-500:越界块 -> -1 + CORRUPT_MAP + 零标坏块 */
- printf("[TC-NP-500] erase out-of-range block -> -1, zero mark-bad\n");
+ /* TC-NANDPORT-500:越界块 -> -1 + CORRUPT_MAP + 零标坏块 */
+ printf("[TC-NANDPORT-500] erase out-of-range block -> -1, zero mark-bad\n");
fake_chip_reset();
err = DHARA_E_NONE;
CHECK(dhara_nand_erase(&s_ut_nand, UT_OOB_BLOCK, &err) == -1,
@@ -836,8 +836,8 @@ static void tc_erase(void) {
CHECK(g_fake_mark_bad_cnt == 0u, "erase out-of-range -> no block marked bad");
CHECK(fake_chip_access_total() == 0u, "erase out-of-range -> zero chip access");
- /* TC-NP-501:块号 = 0xffffffff(哨兵当块号用) */
- printf("[TC-NP-501] erase block 0xffffffff -> -1\n");
+ /* TC-NANDPORT-501:块号 = 0xffffffff(哨兵当块号用) */
+ printf("[TC-NANDPORT-501] erase block 0xffffffff -> -1\n");
fake_chip_reset();
err = DHARA_E_NONE;
CHECK(dhara_nand_erase(&s_ut_nand, 0xFFFFFFFFu, &err) == -1,
@@ -846,8 +846,8 @@ static void tc_erase(void) {
CHECK(g_fake_mark_bad_cnt == 0u, "erase block 0xffffffff -> zero mark_bad");
CHECK(fake_chip_access_total() == 0u, "erase block 0xffffffff -> zero chip access");
- /* TC-NP-502:正常擦除 -> 0 且该块全页回 0xFF */
- printf("[TC-NP-502] erase a valid block clears every page\n");
+ /* TC-NANDPORT-502:正常擦除 -> 0 且该块全页回 0xFF */
+ printf("[TC-NANDPORT-502] erase a valid block clears every page\n");
fake_chip_reset();
fake_fill_pattern(page_buf, FAKE_PAGE_SIZE, 41u);
for (i = 0; i < FAKE_PAGES_PER_BLOCK; i++) {
@@ -860,15 +860,15 @@ static void tc_erase(void) {
CHECK(fake_block_all_ff(2u), "after erase every page of block 2 reads 0xFF");
CHECK(g_fake_block_erase_cnt == 1u, "erase issues one block-erase command");
- /* TC-NP-503:最后一个合法块(上界内边界) */
- printf("[TC-NP-503] erase last valid block (boundary inside)\n");
+ /* TC-NANDPORT-503:最后一个合法块(上界内边界) */
+ printf("[TC-NANDPORT-503] erase last valid block (boundary inside)\n");
fake_chip_reset();
err = DHARA_E_NONE;
CHECK(dhara_nand_erase(&s_ut_nand, UT_OOB_BLOCK - 1u, &err) == 0,
"erase block == num_blocks - 1 -> 0");
- /* TC-NP-504:擦除失败 -> BAD_BLOCK + 标坏该块 */
- printf("[TC-NP-504] erase failure -> BAD_BLOCK + mark bad\n");
+ /* TC-NANDPORT-504:擦除失败 -> BAD_BLOCK + 标坏该块 */
+ printf("[TC-NANDPORT-504] erase failure -> BAD_BLOCK + mark bad\n");
fake_chip_reset();
s_fail_block_erase = 1;
err = DHARA_E_NONE;
@@ -878,10 +878,10 @@ static void tc_erase(void) {
CHECK(g_fake_mark_bad_log[0] == 3u, "the block marked bad is the one that failed");
}
-/* ===================== TC-NP-600..605:is_bad / mark_bad ===================== */
+/* ===================== TC-NANDPORT-600..605:is_bad / mark_bad ===================== */
static void tc_bad_block(void) {
- /* TC-NP-600:越界块 is_bad -> 1 且不碰驱动 */
- printf("[TC-NP-600] is_bad out-of-range block -> 1, zero access\n");
+ /* TC-NANDPORT-600:越界块 is_bad -> 1 且不碰驱动 */
+ printf("[TC-NANDPORT-600] is_bad out-of-range block -> 1, zero access\n");
fake_chip_reset();
CHECK(dhara_nand_is_bad(&s_ut_nand, UT_OOB_BLOCK) == 1,
"is_bad block == num_blocks -> 1 (conservative)");
@@ -889,20 +889,20 @@ static void tc_bad_block(void) {
"is_bad block = 0xffffffff -> 1 (conservative)");
CHECK(g_fake_is_bad_cnt == 0u, "is_bad out-of-range never reaches the driver");
- /* TC-NP-601:NULL 几何 is_bad -> 1 */
- printf("[TC-NP-601] is_bad with NULL geometry -> 1\n");
+ /* TC-NANDPORT-601:NULL 几何 is_bad -> 1 */
+ printf("[TC-NANDPORT-601] is_bad with NULL geometry -> 1\n");
fake_chip_reset();
CHECK(dhara_nand_is_bad(NULL, 0u) == 1, "is_bad n = NULL -> 1, no crash");
CHECK(g_fake_is_bad_cnt == 0u, "is_bad n = NULL -> zero driver access");
- /* TC-NP-602:合法好块 -> 0(透传驱动) */
- printf("[TC-NP-602] is_bad on a valid block passes through\n");
+ /* TC-NANDPORT-602:合法好块 -> 0(透传驱动) */
+ printf("[TC-NANDPORT-602] is_bad on a valid block passes through\n");
fake_chip_reset();
CHECK(dhara_nand_is_bad(&s_ut_nand, 5u) == 0, "good block -> is_bad = 0");
CHECK(g_fake_is_bad_cnt == 1u, "valid block reaches the driver once");
- /* TC-NP-603/604:越界 mark_bad -> 坏块表不变、计数为 0 */
- printf("[TC-NP-603] mark_bad out-of-range leaves the BBT untouched\n");
+ /* TC-NANDPORT-603/604:越界 mark_bad -> 坏块表不变、计数为 0 */
+ printf("[TC-NANDPORT-603] mark_bad out-of-range leaves the BBT untouched\n");
fake_chip_reset();
fake_bad_snapshot();
dhara_nand_mark_bad(&s_ut_nand, UT_OOB_BLOCK);
@@ -910,7 +910,7 @@ static void tc_bad_block(void) {
CHECK(fake_bad_unchanged(), "mark_bad out-of-range -> BBT unchanged");
CHECK(fake_chip_access_total() == 0u, "mark_bad out-of-range -> zero chip access");
- printf("[TC-NP-604] mark_bad with 0xffffffff leaves the BBT untouched\n");
+ printf("[TC-NANDPORT-604] mark_bad with 0xffffffff leaves the BBT untouched\n");
fake_chip_reset();
fake_bad_snapshot();
dhara_nand_mark_bad(&s_ut_nand, 0xFFFFFFFFu);
@@ -919,8 +919,8 @@ static void tc_bad_block(void) {
dhara_nand_mark_bad(NULL, 0u);
CHECK(g_fake_mark_bad_cnt == 0u, "mark_bad n = NULL -> driver not called, no crash");
- /* TC-NP-605:合法块 mark_bad -> 驱动收到一次、块号正确、随后 is_bad = 1 */
- printf("[TC-NP-605] mark_bad on a valid block really marks it\n");
+ /* TC-NANDPORT-605:合法块 mark_bad -> 驱动收到一次、块号正确、随后 is_bad = 1 */
+ printf("[TC-NANDPORT-605] mark_bad on a valid block really marks it\n");
fake_chip_reset();
dhara_nand_mark_bad(&s_ut_nand, 7u);
CHECK(g_fake_mark_bad_cnt == 1u, "valid mark_bad reaches the driver once");
@@ -928,7 +928,7 @@ static void tc_bad_block(void) {
CHECK(dhara_nand_is_bad(&s_ut_nand, 7u) == 1, "marked block now reports bad");
}
-/* ===================== TC-NP-700:dhara map 级场景(真链路) =====================
+/* ===================== TC-NANDPORT-700:dhara map 级场景(真链路) =====================
*
* 用真实 dhara_map_* 跑一轮"写入 -> sync -> 重新 resume -> 读回",断言:
* - 数据往返一致;
@@ -941,7 +941,7 @@ static void tc_dhara_scenario(void) {
dhara_error_t err;
int rc;
- printf("[TC-NP-700] dhara map write -> resume -> read round-trip\n");
+ printf("[TC-NANDPORT-700] dhara map write -> resume -> read round-trip\n");
fake_chip_reset();
s_initialized = 0;
CHECK(nand_ftl_init() == 0, "first init on a blank chip creates the volume");
@@ -994,10 +994,10 @@ int main(void) {
s_ut_nand.num_blocks, (unsigned long)UT_TOTAL_PAGES);
fake_chip_reset();
- CHECK(FAKE_TOTAL_PAGES == 2048u, "TC-NP-000 fake chip geometry (32 x 64 pages)");
- CHECK(fake_page_all_ff(0u), "TC-NP-000b power-on state is all 0xFF");
+ CHECK(FAKE_TOTAL_PAGES == 2048u, "TC-NANDPORT-000 fake chip geometry (32 x 64 pages)");
+ CHECK(fake_page_all_ff(0u), "TC-NANDPORT-000b power-on state is all 0xFF");
CHECK(UT_TOTAL_PAGES == ((dhara_page_t)FAKE_USABLE_BLOCKS * FAKE_PAGES_PER_BLOCK),
- "TC-NP-000c guard bound = num_blocks << log2_ppb");
+ "TC-NANDPORT-000c guard bound = num_blocks << log2_ppb");
printf("-- dhara_nand_is_free: whole-page scan (N-12) --\n");
tc_is_free();
diff --git a/test/host/phasor/phasor_test.c b/test/host/phasor/phasor_test.c
index 0a14e669..cfdc51a2 100644
--- a/test/host/phasor/phasor_test.c
+++ b/test/host/phasor/phasor_test.c
@@ -15,18 +15,18 @@
* 3. 不占 MCU 的 RAM,毫秒级完成。
*
* 覆盖点(对应 docs/算法/继电保护功能复现规划.md §3.2):
- * TC-PH-001 L2-1 系数表逐项等于 sin(2πk/N)·(√2/N) / cos(2πk/N)·(√2/N)(防转录错)
- * TC-PH-002 L2-1 系数表精确零点(sin@0,10 / cos@5,15)与归一化 Σcoe² = 1/N
- * TC-PH-003 L2-3 纯基波:fAmSQ = A/√2(有效值),fAm = √2·fAmSQ(幅值)
- * TC-PH-004 L2-3/L2-4 实部虚部与相位:atan2(fIm,fRe) = 注入相角
- * TC-PH-005 直流 + 2/3/5 次谐波被完全滤除(基波读数不变)
- * TC-PH-006 任意次谐波提取(索引步进 = 谐波次数):k=2 / k=5
- * TC-PH-007 频率偏离 50 Hz 的幅值误差(±1 Hz ≤ 1.5%,±2 Hz ≤ 3%,见 §9 Q3)
- * TC-PH-010 采样环:入环/取窗时序、回绕、饱和、帧计数、参数守卫
- * TC-PH-020 L2-2 实例层:实例数/实例表/未攒满一周波不产出
- * TC-PH-021 L2-6 滑动窗:连续滑动 20 拍基波读数恒定
- * TC-PH-022 L2-7 双区交换:使用区交替 + get 返回**最后一次** run 的结果(非陈旧)
- * TC-PH-030..034 phasor_zero 四字段清零 / phasor_init 双区清零 + 使用区与就绪标志复位 + 幂等
+ * TC-PHASOR-001 L2-1 系数表逐项等于 sin(2πk/N)·(√2/N) / cos(2πk/N)·(√2/N)(防转录错)
+ * TC-PHASOR-002 L2-1 系数表精确零点(sin@0,10 / cos@5,15)与归一化 Σcoe² = 1/N
+ * TC-PHASOR-003 L2-3 纯基波:fAmSQ = A/√2(有效值),fAm = √2·fAmSQ(幅值)
+ * TC-PHASOR-004 L2-3/L2-4 实部虚部与相位:atan2(fIm,fRe) = 注入相角
+ * TC-PHASOR-005 直流 + 2/3/5 次谐波被完全滤除(基波读数不变)
+ * TC-PHASOR-006 任意次谐波提取(索引步进 = 谐波次数):k=2 / k=5
+ * TC-PHASOR-007 频率偏离 50 Hz 的幅值误差(±1 Hz ≤ 1.5%,±2 Hz ≤ 3%,见 §9 Q3)
+ * TC-PHASOR-010 采样环:入环/取窗时序、回绕、饱和、帧计数、参数守卫
+ * TC-PHASOR-020 L2-2 实例层:实例数/实例表/未攒满一周波不产出
+ * TC-PHASOR-021 L2-6 滑动窗:连续滑动 20 拍基波读数恒定
+ * TC-PHASOR-022 L2-7 双区交换:使用区交替 + get 返回**最后一次** run 的结果(非陈旧)
+ * TC-PHASOR-030..034 phasor_zero 四字段清零 / phasor_init 双区清零 + 使用区与就绪标志复位 + 幂等
*
* 通过:全部 TC PASS(main 返回 0)。
* 入口:int main(void),返回 0=PASS / 1=FAIL(由 run 脚本判读)。
@@ -98,7 +98,7 @@ static void frame_at(float *f, uint32_t t, double amp, double phase) {
}
}
-/* ===================== TC-PH-001/002:L2-1 系数表 ===================== */
+/* ===================== TC-PHASOR-001/002:L2-1 系数表 ===================== */
static void tc_table(void) {
const double scale = sqrt(2.0) / (double)PHASOR_N;
@@ -136,7 +136,7 @@ static void tc_table(void) {
"L2-1 sin[5] == sqrt(2)/N (peak coefficient)");
}
-/* ===================== TC-PH-003/004:基波幅值 / 有效值 / 相位 ===================== */
+/* ===================== TC-PHASOR-003/004:基波幅值 / 有效值 / 相位 ===================== */
static void tc_fundamental(void) {
static const struct { double amp; double ph; } k_case[] = {
@@ -176,7 +176,7 @@ static void tc_fundamental(void) {
CHECK(ok_ph, "L2-4/L2-3 atan2(fIm,fRe) == injected phase (6 amp/phase cases)");
}
-/* ===================== TC-PH-005:直流与谐波被滤除 ===================== */
+/* ===================== TC-PHASOR-005:直流与谐波被滤除 ===================== */
static void tc_filtering(void) {
const double amp = 57.7, exp_rms = amp / sqrt(2.0);
@@ -218,7 +218,7 @@ static void tc_filtering(void) {
CHECK(ok, "L2-3 DC + 2nd/3rd/5th harmonics fully rejected (5 cases, err <= 1%)");
}
-/* ===================== TC-PH-006:任意次谐波提取 ===================== */
+/* ===================== TC-PHASOR-006:任意次谐波提取 ===================== */
static void tc_harmonic(void) {
/* 基波 100 + 二次 25 + 五次 12(峰值);三根谱线应各自独立读出 */
@@ -263,7 +263,7 @@ static void tc_harmonic(void) {
}
}
-/* ===================== TC-PH-007:频率敏感性 ===================== */
+/* ===================== TC-PHASOR-007:频率敏感性 ===================== */
static void tc_freqdev(void) {
const double amp = 57.7, exp_rms = amp / sqrt(2.0);
@@ -302,7 +302,7 @@ static void tc_freqdev(void) {
CHECK(ok, "L2-3 frequency sensitivity: 50Hz<=0.1%, +-1Hz<=1.5%, +-2Hz<=3% (worst phase)");
}
-/* ===================== TC-PH-010:采样环 ===================== */
+/* ===================== TC-PHASOR-010:采样环 ===================== */
static void tc_ring(void) {
float f[ADC_SEM_COUNT];
@@ -360,7 +360,7 @@ static void tc_ring(void) {
CHECK(sample_ring_push_frame(f, 3u) == -1, "L2-in ring: wrong frame length rejected");
}
-/* ===================== TC-PH-020/021/022:实例层 + 滑动窗 + 双区 ===================== */
+/* ===================== TC-PHASOR-020/021/022:实例层 + 滑动窗 + 双区 ===================== */
static void tc_instances(void) {
const double amp = 100.0, exp_rms = amp / sqrt(2.0);
@@ -433,7 +433,7 @@ static void tc_instances(void) {
CHECK(ok, "L2-2/L2-6 instance results == phasor_calc() on the same ring window");
}
-/* ===================== TC-PH-030..034:phasor_zero / init 清零 ===================== */
+/* ===================== TC-PHASOR-030..034:phasor_zero / init 清零 ===================== */
static void tc_zero(void) {
phasor_t p;
@@ -444,7 +444,7 @@ static void tc_zero(void) {
p.fRe = 1.0f; p.fIm = -2.0f; p.fAm = 3.0f; p.fAmSQ = 4.0f;
phasor_zero(&p);
CHECK((p.fRe == 0.0f) && (p.fIm == 0.0f) && (p.fAm == 0.0f) && (p.fAmSQ == 0.0f),
- "TC-PH-030 phasor_zero clears all four fields");
+ "TC-PHASOR-030 phasor_zero clears all four fields");
/* 2) 经 phasor_init:先把双区写成脏值,init 后必须全零,使用区复位、就绪标志清 */
for (i = 0u; i < (uint8_t)PHASOR_INST_N; i++) {
@@ -463,16 +463,16 @@ static void tc_zero(void) {
zones_dirty = 1;
}
}
- CHECK(zones_dirty == 0, "TC-PH-031 phasor_init zeroes both result zones");
- CHECK(s_use_zone == 0u, "TC-PH-032 phasor_init resets use zone to 0");
- CHECK(phasor_get(0u, &p) == -2, "TC-PH-033 phasor_init clears ready (get -> -2)");
+ CHECK(zones_dirty == 0, "TC-PHASOR-031 phasor_init zeroes both result zones");
+ CHECK(s_use_zone == 0u, "TC-PHASOR-032 phasor_init resets use zone to 0");
+ CHECK(phasor_get(0u, &p) == -2, "TC-PHASOR-033 phasor_init clears ready (get -> -2)");
/* 3) 幂等:重复 init 不改变结果 */
(void)phasor_init();
- CHECK((s_use_zone == 0u) && (phasor_get(0u, &p) == -2), "TC-PH-034 phasor_init is idempotent");
+ CHECK((s_use_zone == 0u) && (phasor_get(0u, &p) == -2), "TC-PHASOR-034 phasor_init is idempotent");
}
-/* ===================== TC-PH-022:L2-7 双区指针原子交换 ===================== */
+/* ===================== TC-PHASOR-022:L2-7 双区指针原子交换 ===================== */
static void tc_dualzone(void) {
const double amp = 100.0;
diff --git a/test/host/prot_elm/prot_elm_test.c b/test/host/prot_elm/prot_elm_test.c
index 325e7432..ab1cdba5 100644
--- a/test/host/prot_elm/prot_elm_test.c
+++ b/test/host/prot_elm/prot_elm_test.c
@@ -5,24 +5,24 @@
* 被测对象:真实源文件(#include 原样纳入):
* prot_elm.c + prot_set.c(判据吃定值 RAM)
* phasor.c + sample_ring.c + freq.c(prot_elm.c 链接依赖;
- * TC-PE-001~010 走 prot_elm_eval 纯判据路径,TC-PE-013 走
+ * TC-PROTELEM-001~010 走 prot_elm_eval 纯判据路径,TC-PROTELEM-013 走
* run() 适配层 = 合成波形跑真实 L2+测频链)
*
* 覆盖点(docs/算法/继电保护功能复现规划.md §3.3 L3-1/3/4/6、§8 验收):
- * TC-PE-001 init:全状态清零、动作位图 0
- * TC-PE-002 过量滞回 + 定时限:1.01× 定值启动、延时到点动作、
+ * TC-PROTELEM-001 init:全状态清零、动作位图 0
+ * TC-PROTELEM-002 过量滞回 + 定时限:1.01× 定值启动、延时到点动作、
* 返回系数内保持、跌破返回门槛释放(1.2×/0.9× 验收口径的核)
- * TC-PE-003 延时 0:启动同拍即动作
- * TC-PE-004 欠量方向(UV):低于定值启动、高于返回门槛释放
- * TC-PE-005 投退=0:不判据、状态复位
- * TC-PE-006 定值闭锁(L5-1 联动):locked → 全元件复位;解锁后恢复
- * TC-PE-007 时基回绕:跨 0xFFFFFFFF 的延时判定仍正确
- * TC-PE-008 动作位图聚合
- * TC-PE-009 守卫:state(NULL)/越界编号、name 越界
- * TC-PE-010 跨上下文复归请求(B5):request 不当拍生效、下一拍 eval 头部消费
- * TC-PE-011 过频 OF(B8/L3-5):越限 + RET_OF 滞回 + 定时限
- * TC-PE-012 低频 UF(B8/L3-5):欠量方向 + RET_UF 滞回 + 方向隔离
- * TC-PE-013 run() 接线(B8):测频驱动 OF 动作;幅值门失效 OF 复位且
+ * TC-PROTELEM-003 延时 0:启动同拍即动作
+ * TC-PROTELEM-004 欠量方向(UV):低于定值启动、高于返回门槛释放
+ * TC-PROTELEM-005 投退=0:不判据、状态复位
+ * TC-PROTELEM-006 定值闭锁(L5-1 联动):locked → 全元件复位;解锁后恢复
+ * TC-PROTELEM-007 时基回绕:跨 0xFFFFFFFF 的延时判定仍正确
+ * TC-PROTELEM-008 动作位图聚合
+ * TC-PROTELEM-009 守卫:state(NULL)/越界编号、name 越界
+ * TC-PROTELEM-010 跨上下文复归请求(B5):request 不当拍生效、下一拍 eval 头部消费
+ * TC-PROTELEM-011 过频 OF(B8/L3-5):越限 + RET_OF 滞回 + 定时限
+ * TC-PROTELEM-012 低频 UF(B8/L3-5):欠量方向 + RET_UF 滞回 + 方向隔离
+ * TC-PROTELEM-013 run() 接线(B8):测频驱动 OF 动作;幅值门失效 OF 复位且
* 相量类元件仍被评估(不整拍跳过)
*
* 通过:全部 TC PASS(main 返回 0)。
@@ -65,7 +65,7 @@ static void mk_base(float m[PE_COUNT]) {
static void tc_init_clear(void) {
prot_set_init();
prot_elm_init();
- CHECK(prot_elm_active_mask() == 0u, "TC-PE-001 init: active mask 0");
+ CHECK(prot_elm_active_mask() == 0u, "TC-PROTELEM-001 init: active mask 0");
{
prot_elm_state_t st;
uint32_t i;
@@ -77,7 +77,7 @@ static void tc_init_clear(void) {
clean = 0;
}
}
- CHECK(clean, "TC-PE-001 init: all element states clear");
+ CHECK(clean, "TC-PROTELEM-001 init: all element states clear");
}
}
@@ -95,33 +95,33 @@ static void tc_over_hysteresis(void) {
prot_elm_eval(1000u, m);
prot_elm_state(PE_OC1, &st);
CHECK((st.picked == 0u) && (st.enabled != 0u),
- "TC-PE-002 0.99x set: no pickup");
+ "TC-PROTELEM-002 0.99x set: no pickup");
m[PE_OC1] = 10.1f;
prot_elm_eval(1001u, m);
prot_elm_state(PE_OC1, &st);
CHECK((st.picked != 0u) && (st.asserted == 0u),
- "TC-PE-002 1.01x set: pickup before delay");
+ "TC-PROTELEM-002 1.01x set: pickup before delay");
prot_elm_eval(1100u, m); /* 1100-1001 = 99 ms */
prot_elm_state(PE_OC1, &st);
- CHECK(st.asserted == 0u, "TC-PE-002 not asserted at 99ms");
+ CHECK(st.asserted == 0u, "TC-PROTELEM-002 not asserted at 99ms");
prot_elm_eval(1101u, m); /* 100 ms 整 */
prot_elm_state(PE_OC1, &st);
- CHECK(st.asserted != 0u, "TC-PE-002 asserted at 100ms");
+ CHECK(st.asserted != 0u, "TC-PROTELEM-002 asserted at 100ms");
m[PE_OC1] = 9.7f; /* 返回门槛(9.492)与动作门槛(10)之间 */
prot_elm_eval(1200u, m);
prot_elm_state(PE_OC1, &st);
CHECK((st.picked != 0u) && (st.asserted != 0u),
- "TC-PE-002 hysteresis: holds between return and pickup threshold");
+ "TC-PROTELEM-002 hysteresis: holds between return and pickup threshold");
m[PE_OC1] = 9.4f; /* 跌破返回门槛 */
prot_elm_eval(1300u, m);
prot_elm_state(PE_OC1, &st);
CHECK((st.picked == 0u) && (st.asserted == 0u),
- "TC-PE-002 below return threshold: drops out");
+ "TC-PROTELEM-002 below return threshold: drops out");
}
static void tc_zero_delay(void) {
@@ -136,7 +136,7 @@ static void tc_zero_delay(void) {
prot_elm_eval(5000u, m);
prot_elm_state(PE_OC3, &st);
CHECK((st.picked != 0u) && (st.asserted != 0u),
- "TC-PE-003 dly=0: asserted on the same beat as pickup");
+ "TC-PROTELEM-003 dly=0: asserted on the same beat as pickup");
}
static void tc_under_direction(void) {
@@ -152,27 +152,27 @@ static void tc_under_direction(void) {
m[PE_UV] = 25.0f;
prot_elm_eval(2000u, m);
prot_elm_state(PE_UV, &st);
- CHECK(st.picked == 0u, "TC-PE-004 UV above set: no pickup");
+ CHECK(st.picked == 0u, "TC-PROTELEM-004 UV above set: no pickup");
m[PE_UV] = 19.0f;
prot_elm_eval(2001u, m);
prot_elm_state(PE_UV, &st);
- CHECK(st.picked != 0u, "TC-PE-004 UV below set: pickup");
+ CHECK(st.picked != 0u, "TC-PROTELEM-004 UV below set: pickup");
prot_elm_eval(2051u, m); /* 50 ms */
prot_elm_state(PE_UV, &st);
- CHECK(st.asserted != 0u, "TC-PE-004 UV asserted after delay");
+ CHECK(st.asserted != 0u, "TC-PROTELEM-004 UV asserted after delay");
m[PE_UV] = 20.5f; /* 20 与 20.996 之间:保持 */
prot_elm_eval(2100u, m);
prot_elm_state(PE_UV, &st);
- CHECK(st.asserted != 0u, "TC-PE-004 UV holds below return threshold");
+ CHECK(st.asserted != 0u, "TC-PROTELEM-004 UV holds below return threshold");
m[PE_UV] = 21.5f; /* 高于返回门槛:释放 */
prot_elm_eval(2200u, m);
prot_elm_state(PE_UV, &st);
CHECK((st.picked == 0u) && (st.asserted == 0u),
- "TC-PE-004 UV above return threshold: drops out");
+ "TC-PROTELEM-004 UV above return threshold: drops out");
}
static void tc_disabled(void) {
@@ -187,7 +187,7 @@ static void tc_disabled(void) {
prot_elm_eval(3000u, m);
prot_elm_state(PE_OC2, &st);
CHECK((st.enabled == 0u) && (st.picked == 0u) && (st.asserted == 0u),
- "TC-PE-005 enable=0: no judgement even at 999x");
+ "TC-PROTELEM-005 enable=0: no judgement even at 999x");
}
static void tc_set_lock(void) {
@@ -201,20 +201,20 @@ static void tc_set_lock(void) {
(void)prot_set_set(PS_OC1_DLY, PROT_SET_Q10(0.0));
prot_elm_eval(4000u, m);
prot_elm_state(PE_OC1, &st);
- CHECK(st.asserted != 0u, "TC-PE-006 pre: element operates while settings valid");
+ CHECK(st.asserted != 0u, "TC-PROTELEM-006 pre: element operates while settings valid");
(void)prot_set_set(PS_OC1_CUR, PROT_SET_Q10(9.0)); /* 改值不封存 */
- CHECK(prot_set_selfcheck() == -1, "TC-PE-006 tamper detected by selfcheck");
+ CHECK(prot_set_selfcheck() == -1, "TC-PROTELEM-006 tamper detected by selfcheck");
prot_elm_eval(4100u, m);
prot_elm_state(PE_OC1, &st);
CHECK((st.enabled == 0u) && (st.asserted == 0u),
- "TC-PE-006 settings lock resets all elements (L5-1 gating)");
+ "TC-PROTELEM-006 settings lock resets all elements (L5-1 gating)");
prot_set_seal();
prot_elm_eval(4200u, m);
prot_elm_state(PE_OC1, &st);
CHECK((st.enabled != 0u) && (st.asserted != 0u),
- "TC-PE-006 unlock restores judgement");
+ "TC-PROTELEM-006 unlock restores judgement");
}
static void tc_tick_wrap(void) {
@@ -228,15 +228,15 @@ static void tc_tick_wrap(void) {
m[PE_OC2] = 5.1f; /* OC2 定值 5.0 */
prot_elm_eval(0xFFFFFFF0u, m); /* 启动点贴近回绕 */
prot_elm_state(PE_OC2, &st);
- CHECK(st.picked != 0u, "TC-PE-007 pickup near tick wrap");
+ CHECK(st.picked != 0u, "TC-PROTELEM-007 pickup near tick wrap");
prot_elm_eval(0x00000010u, m); /* 回绕后 32 ms */
prot_elm_state(PE_OC2, &st);
- CHECK(st.asserted == 0u, "TC-PE-007 not asserted at 32ms after wrap");
+ CHECK(st.asserted == 0u, "TC-PROTELEM-007 not asserted at 32ms after wrap");
prot_elm_eval(0x00000060u, m); /* 回绕后 112 ms */
prot_elm_state(PE_OC2, &st);
- CHECK(st.asserted != 0u, "TC-PE-007 asserted at 112ms across wrap");
+ CHECK(st.asserted != 0u, "TC-PROTELEM-007 asserted at 112ms across wrap");
}
static void tc_active_mask(void) {
@@ -251,7 +251,7 @@ static void tc_active_mask(void) {
m[PE_OV] = 130.0f; /* OV 定值 120 */
prot_elm_eval(6000u, m);
CHECK(prot_elm_active_mask() == ((1uL << PE_OC1) | (1uL << PE_OV)),
- "TC-PE-008 active mask aggregates OC1+OV only");
+ "TC-PROTELEM-008 active mask aggregates OC1+OV only");
}
static void tc_guards(void) {
@@ -261,12 +261,12 @@ static void tc_guards(void) {
prot_elm_init();
prot_elm_state(PE_COUNT, &st);
CHECK((st.enabled == 0u) && (st.picked == 0u) && (st.asserted == 0u),
- "TC-PE-009 out-of-range id -> zero state");
+ "TC-PROTELEM-009 out-of-range id -> zero state");
prot_elm_state(PE_OC1, NULL); /* 不得崩溃 */
- CHECK(prot_elm_name(PE_COUNT) != NULL, "TC-PE-009 name out-of-range -> fallback");
- CHECK(prot_elm_name(PE_3U0) != NULL, "TC-PE-009 name valid id -> non-NULL");
+ CHECK(prot_elm_name(PE_COUNT) != NULL, "TC-PROTELEM-009 name out-of-range -> fallback");
+ CHECK(prot_elm_name(PE_3U0) != NULL, "TC-PROTELEM-009 name valid id -> non-NULL");
prot_elm_eval(7000u, NULL); /* NULL 测量:按 0 处理,不得崩溃 */
- CHECK(1, "TC-PE-009 eval(NULL meas) survives");
+ CHECK(1, "TC-PROTELEM-009 eval(NULL meas) survives");
}
static void tc_request_reset(void) {
@@ -279,11 +279,11 @@ static void tc_request_reset(void) {
m[PE_OC1] = 999.0f; /* OC1 默认 dly=0 → 启动同拍动作 */
prot_elm_eval(1000u, m);
prot_elm_state(PE_OC1, &st);
- CHECK(st.asserted != 0u, "TC-PE-010 pre: OC1 asserted (default dly=0)");
+ CHECK(st.asserted != 0u, "TC-PROTELEM-010 pre: OC1 asserted (default dly=0)");
prot_elm_request_reset(); /* 跨上下文请求:不当拍生效 */
prot_elm_state(PE_OC1, &st);
- CHECK(st.asserted != 0u, "TC-PE-010 request alone does not reset");
+ CHECK(st.asserted != 0u, "TC-PROTELEM-010 request alone does not reset");
/* 下一拍头部消费请求 → 复位;测量落在滞回保持区(9.6 ∈ [返回9.5, 动作10))
* ——不复位则 picked/asserted 保持,复位后保持清零,可区分 */
@@ -291,12 +291,12 @@ static void tc_request_reset(void) {
prot_elm_eval(1100u, m);
prot_elm_state(PE_OC1, &st);
CHECK((st.picked == 0u) && (st.asserted == 0u),
- "TC-PE-010 next eval consumes request -> cleared in hysteresis band");
+ "TC-PROTELEM-010 next eval consumes request -> cleared in hysteresis band");
}
/* ===================== OF/UF(L3-5,B8)===================== */
-/* TC-PE-011:过频——越限 + RET_OF 滞回 + 定时限(判据核级) */
+/* TC-PROTELEM-011:过频——越限 + RET_OF 滞回 + 定时限(判据核级) */
static void tc_of_hysteresis(void) {
float m[PE_COUNT];
prot_elm_state_t st;
@@ -311,36 +311,36 @@ static void tc_of_hysteresis(void) {
prot_elm_eval(1000u, m);
prot_elm_state(PE_OF, &st);
CHECK((st.picked == 0u) && (st.enabled != 0u),
- "TC-PE-011 OF 50.9 (<51): no pickup");
+ "TC-PROTELEM-011 OF 50.9 (<51): no pickup");
m[PE_OF] = 51.1f;
prot_elm_eval(1001u, m);
prot_elm_state(PE_OF, &st);
CHECK((st.picked != 0u) && (st.asserted == 0u),
- "TC-PE-011 OF 51.1: pickup before delay");
+ "TC-PROTELEM-011 OF 51.1: pickup before delay");
prot_elm_eval(1100u, m);
prot_elm_state(PE_OF, &st);
- CHECK(st.asserted == 0u, "TC-PE-011 OF not asserted at 99ms");
+ CHECK(st.asserted == 0u, "TC-PROTELEM-011 OF not asserted at 99ms");
prot_elm_eval(1101u, m);
prot_elm_state(PE_OF, &st);
- CHECK(st.asserted != 0u, "TC-PE-011 OF asserted at 100ms");
+ CHECK(st.asserted != 0u, "TC-PROTELEM-011 OF asserted at 100ms");
m[PE_OF] = 50.7f; /* 50.49 与 51 之间:滞回保持 */
prot_elm_eval(1200u, m);
prot_elm_state(PE_OF, &st);
CHECK((st.picked != 0u) && (st.asserted != 0u),
- "TC-PE-011 OF holds between return(50.49) and pickup(51)");
+ "TC-PROTELEM-011 OF holds between return(50.49) and pickup(51)");
m[PE_OF] = 50.4f; /* 跌破返回门槛 */
prot_elm_eval(1300u, m);
prot_elm_state(PE_OF, &st);
CHECK((st.picked == 0u) && (st.asserted == 0u),
- "TC-PE-011 OF below return threshold: drops out");
+ "TC-PROTELEM-011 OF below return threshold: drops out");
}
-/* TC-PE-012:低频——欠量方向 + RET_UF 滞回(与 OF 系数独立,勿混 0.95/1.05) */
+/* TC-PROTELEM-012:低频——欠量方向 + RET_UF 滞回(与 OF 系数独立,勿混 0.95/1.05) */
static void tc_uf_direction(void) {
float m[PE_COUNT];
prot_elm_state_t st;
@@ -354,36 +354,36 @@ static void tc_uf_direction(void) {
m[PE_UF] = 49.1f;
prot_elm_eval(2000u, m);
prot_elm_state(PE_UF, &st);
- CHECK(st.picked == 0u, "TC-PE-012 UF 49.1 (>49): no pickup");
+ CHECK(st.picked == 0u, "TC-PROTELEM-012 UF 49.1 (>49): no pickup");
m[PE_UF] = 48.9f;
prot_elm_eval(2001u, m);
prot_elm_state(PE_UF, &st);
- CHECK(st.picked != 0u, "TC-PE-012 UF 48.9 (<49): pickup");
+ CHECK(st.picked != 0u, "TC-PROTELEM-012 UF 48.9 (<49): pickup");
prot_elm_eval(2051u, m);
prot_elm_state(PE_UF, &st);
- CHECK(st.asserted != 0u, "TC-PE-012 UF asserted after 50ms");
+ CHECK(st.asserted != 0u, "TC-PROTELEM-012 UF asserted after 50ms");
m[PE_UF] = 49.3f; /* 49 与 49.49 之间:保持 */
prot_elm_eval(2100u, m);
prot_elm_state(PE_UF, &st);
- CHECK(st.asserted != 0u, "TC-PE-012 UF holds below return threshold");
+ CHECK(st.asserted != 0u, "TC-PROTELEM-012 UF holds below return threshold");
m[PE_UF] = 49.6f; /* 高于返回门槛:释放 */
prot_elm_eval(2200u, m);
prot_elm_state(PE_UF, &st);
CHECK((st.picked == 0u) && (st.asserted == 0u),
- "TC-PE-012 UF above return threshold: drops out");
+ "TC-PROTELEM-012 UF above return threshold: drops out");
/* OF 不得被低频误启动(方向隔离);UF 不得被过频误启动 */
m[PE_OF] = 52.0f;
m[PE_UF] = 52.0f;
prot_elm_eval(2300u, m);
prot_elm_state(PE_OF, &st);
- CHECK(st.picked != 0u, "TC-PE-012 OF picks at 52 (over direction)");
+ CHECK(st.picked != 0u, "TC-PROTELEM-012 OF picks at 52 (over direction)");
prot_elm_state(PE_UF, &st);
- CHECK(st.picked == 0u, "TC-PE-012 UF NOT picked at 52 (direction isolation)");
+ CHECK(st.picked == 0u, "TC-PROTELEM-012 UF NOT picked at 52 (direction isolation)");
}
/* ---- run() 适配层驱动:合成波形跑真实 L2+测频链(同 freq_test 口径) ---- */
@@ -403,7 +403,7 @@ static void drive_beat(double f, double amp) {
s_t++;
}
-/* TC-PE-013:run() 级——freq 有效读数驱动 OF 动作;幅值门失效后 OF 复位
+/* TC-PROTELEM-013:run() 级——freq 有效读数驱动 OF 动作;幅值门失效后 OF 复位
* 且相量类元件仍被评估(不整拍跳过,B5 行为不回归) */
static void tc_run_freq_wiring(void) {
prot_elm_state_t st;
@@ -424,9 +424,9 @@ static void tc_run_freq_wiring(void) {
}
prot_elm_state(PE_OF, &st);
CHECK((st.picked != 0u) && (st.asserted != 0u),
- "TC-PE-013 run(): OF asserted from measured 52.5 Hz");
+ "TC-PROTELEM-013 run(): OF asserted from measured 52.5 Hz");
prot_elm_state(PE_UF, &st);
- CHECK(st.picked == 0u, "TC-PE-013 run(): UF clear at 52.5 Hz");
+ CHECK(st.picked == 0u, "TC-PROTELEM-013 run(): UF clear at 52.5 Hz");
/* 波形消失(浮空):freq 幅值门失效 -> OF 按方向填充复位;
* 同时相量 rms=0 -> UV(定值 20,dly=0)启动 = 证明未整拍跳过 */
@@ -436,10 +436,10 @@ static void tc_run_freq_wiring(void) {
}
prot_elm_state(PE_OF, &st);
CHECK((st.picked == 0u) && (st.asserted == 0u),
- "TC-PE-013 run(): OF resets when freq source loses amplitude");
+ "TC-PROTELEM-013 run(): OF resets when freq source loses amplitude");
prot_elm_state(PE_UV, &st);
CHECK(st.picked != 0u,
- "TC-PE-013 run(): UV still evaluated with zero-amplitude (no whole-beat skip)");
+ "TC-PROTELEM-013 run(): UV still evaluated with zero-amplitude (no whole-beat skip)");
}
int main(void) {
diff --git a/test/host/prot_set/prot_set_test.c b/test/host/prot_set/prot_set_test.c
index 2b85509e..9c64dc2e 100644
--- a/test/host/prot_set/prot_set_test.c
+++ b/test/host/prot_set/prot_set_test.c
@@ -5,22 +5,22 @@
* 被测对象:真实源文件(#include 原样纳入)。纯逻辑,无需桩。
*
* 覆盖点(docs/算法/继电保护功能复现规划.md §5.2 / §3.4 L5-1):
- * TC-PS-001 init:默认值装载、越界位图 0、selfcheck 通过、未闭锁
- * TC-PS-002 set:范围内写入生效;越界拒写且原值不动
- * TC-PS-003 校验和封存语义:set 后未 seal → selfcheck 失败并闭锁;
+ * TC-PROTSET-001 init:默认值装载、越界位图 0、selfcheck 通过、未闭锁
+ * TC-PROTSET-002 set:范围内写入生效;越界拒写且原值不动
+ * TC-PROTSET-003 校验和封存语义:set 后未 seal → selfcheck 失败并闭锁;
* seal → 通过并解锁(L5-1 核心闭环)
- * TC-PS-004 load_raw:合法整表装载并封存;含越界项 → 整表不装载 +
+ * TC-PROTSET-004 load_raw:合法整表装载并封存;含越界项 → 整表不装载 +
* bad_mask 指认越界项(定值一致性:宁可全旧不可半新)
- * TC-PS-005 Q10 往返精度(±1 LSB)
- * TC-PS-006 元数据表自检:min<=max、投退项 0..1、非零通讯地址不重复
- * TC-PS-007 越界编号守卫(get/set)
- * TC-PS-008 全局软压板 PS_GLOBAL_EN(B7):默认投入、set_sealed 原子写
+ * TC-PROTSET-005 Q10 往返精度(±1 LSB)
+ * TC-PROTSET-006 元数据表自检:min<=max、投退项 0..1、非零通讯地址不重复
+ * TC-PROTSET-007 越界编号守卫(get/set)
+ * TC-PROTSET-008 全局软压板 PS_GLOBAL_EN(B7):默认投入、set_sealed 原子写
* 不破坏 selfcheck、脏标志三件套(peek/take/mark)
- * TC-PS-009 持久化 blob 往返:serialize → init 清场 → parse 恢复
+ * TC-PROTSET-009 持久化 blob 往返:serialize → init 清场 → parse 恢复
* (位精确 + 封存自洽 + parse 不置脏)
- * TC-PS-010 损坏 blob 整表拒绝(all-or-nothing):值区位翻转/坏 magic/
+ * TC-PROTSET-010 损坏 blob 整表拒绝(all-or-nothing):值区位翻转/坏 magic/
* 截断/超长/坏版本/伪造自洽越界 → 全部拒绝且活跃值区一字不动
- * TC-PS-011 OF/UF 定值行(B8):40 项 / blob 版本 2 / 本地项地址 0 /
+ * TC-PROTSET-011 OF/UF 定值行(B8):40 项 / blob 版本 2 / 本地项地址 0 /
* 默认值与范围 / 返回系数独立性 / 64 位 bad_mask(bit 39)/
* B7 旧档(32 项)换代拒绝
*
@@ -40,46 +40,46 @@ static int s_total = 0, s_passed = 0, s_failed = 0;
#include "prot_set.c"
-/* TC-PS-001 */
+/* TC-PROTSET-001 */
static void tc_init(void) {
prot_set_init();
- CHECK(prot_set_bad_mask() == 0u, "TC-PS-001 init: no bad items");
- CHECK(prot_set_selfcheck() == 0, "TC-PS-001 init: selfcheck pass");
- CHECK(prot_set_locked() == 0u, "TC-PS-001 init: not locked");
+ CHECK(prot_set_bad_mask() == 0u, "TC-PROTSET-001 init: no bad items");
+ CHECK(prot_set_selfcheck() == 0, "TC-PROTSET-001 init: selfcheck pass");
+ CHECK(prot_set_locked() == 0u, "TC-PROTSET-001 init: not locked");
CHECK(prot_set_get_f(PS_OC1_CUR) > 9.99f && prot_set_get_f(PS_OC1_CUR) < 10.01f,
- "TC-PS-001 default OC1 current = 10.0 A");
+ "TC-PROTSET-001 default OC1 current = 10.0 A");
CHECK(prot_set_get_ctl(PS_OC3_TRIP) == 0u,
- "TC-PS-001 default OC3 = alarm (trip off)");
+ "TC-PROTSET-001 default OC3 = alarm (trip off)");
}
-/* TC-PS-002 */
+/* TC-PROTSET-002 */
static void tc_set_range(void) {
prot_set_init();
CHECK(prot_set_set(PS_OC2_CUR, PROT_SET_Q10(7.5)) == 0,
- "TC-PS-002 in-range set accepted");
+ "TC-PROTSET-002 in-range set accepted");
CHECK(prot_set_get_f(PS_OC2_CUR) > 7.49f && prot_set_get_f(PS_OC2_CUR) < 7.51f,
- "TC-PS-002 value readable after set");
+ "TC-PROTSET-002 value readable after set");
CHECK(prot_set_set(PS_OC2_CUR, PROT_SET_Q10(101.0)) == -1,
- "TC-PS-002 over-max set rejected");
+ "TC-PROTSET-002 over-max set rejected");
CHECK(prot_set_get_f(PS_OC2_CUR) > 7.49f && prot_set_get_f(PS_OC2_CUR) < 7.51f,
- "TC-PS-002 rejected set leaves value unchanged");
+ "TC-PROTSET-002 rejected set leaves value unchanged");
CHECK(prot_set_set(PS_OC1_EN, PROT_SET_Q10(2)) == -1,
- "TC-PS-002 ctl item rejects value 2");
+ "TC-PROTSET-002 ctl item rejects value 2");
}
-/* TC-PS-003 */
+/* TC-PROTSET-003 */
static void tc_seal_selfcheck(void) {
prot_set_init();
- CHECK(prot_set_set(PS_OC1_CUR, PROT_SET_Q10(8.0)) == 0, "TC-PS-003 set ok");
+ CHECK(prot_set_set(PS_OC1_CUR, PROT_SET_Q10(8.0)) == 0, "TC-PROTSET-003 set ok");
CHECK(prot_set_selfcheck() == -1,
- "TC-PS-003 set-without-seal => selfcheck FAIL (tamper detect)");
- CHECK(prot_set_locked() == 1u, "TC-PS-003 selfcheck failure latches lock");
+ "TC-PROTSET-003 set-without-seal => selfcheck FAIL (tamper detect)");
+ CHECK(prot_set_locked() == 1u, "TC-PROTSET-003 selfcheck failure latches lock");
prot_set_seal();
- CHECK(prot_set_selfcheck() == 0, "TC-PS-003 seal => selfcheck pass");
- CHECK(prot_set_locked() == 0u, "TC-PS-003 seal clears lock");
+ CHECK(prot_set_selfcheck() == 0, "TC-PROTSET-003 seal => selfcheck pass");
+ CHECK(prot_set_locked() == 0u, "TC-PROTSET-003 seal clears lock");
}
-/* TC-PS-004 */
+/* TC-PROTSET-004 */
static void tc_load_raw(void) {
int32_t tbl[PS_ID_COUNT];
uint32_t i;
@@ -89,38 +89,38 @@ static void tc_load_raw(void) {
tbl[i] = prot_set_get((prot_set_id_t)i);
}
tbl[PS_OL_CUR] = PROT_SET_Q10(1.5);
- CHECK(prot_set_load_raw(tbl) == 0, "TC-PS-004 valid table loads");
+ CHECK(prot_set_load_raw(tbl) == 0, "TC-PROTSET-004 valid table loads");
CHECK(prot_set_get_f(PS_OL_CUR) > 1.49f && prot_set_get_f(PS_OL_CUR) < 1.51f,
- "TC-PS-004 loaded value visible");
- CHECK(prot_set_selfcheck() == 0, "TC-PS-004 load_raw auto-seals");
+ "TC-PROTSET-004 loaded value visible");
+ CHECK(prot_set_selfcheck() == 0, "TC-PROTSET-004 load_raw auto-seals");
tbl[PS_OC3_DLY] = PROT_SET_Q10(60001.0); /* 越上限 */
tbl[PS_OL_CUR] = PROT_SET_Q10(2.5); /* 合法改动 */
- CHECK(prot_set_load_raw(tbl) == -1, "TC-PS-004 bad table rejected");
+ CHECK(prot_set_load_raw(tbl) == -1, "TC-PROTSET-004 bad table rejected");
CHECK(prot_set_bad_mask() == (1uLL << PS_OC3_DLY),
- "TC-PS-004 bad_mask points at the offending item");
+ "TC-PROTSET-004 bad_mask points at the offending item");
CHECK(prot_set_get_f(PS_OL_CUR) > 1.49f && prot_set_get_f(PS_OL_CUR) < 1.51f,
- "TC-PS-004 rejected load keeps OLD table (all-or-nothing)");
- CHECK(prot_set_load_raw(0) == -1, "TC-PS-004 NULL table rejected");
+ "TC-PROTSET-004 rejected load keeps OLD table (all-or-nothing)");
+ CHECK(prot_set_load_raw(0) == -1, "TC-PROTSET-004 NULL table rejected");
}
-/* TC-PS-005 */
+/* TC-PROTSET-005 */
static void tc_q10_roundtrip(void) {
float v = 12.345f;
int32_t q;
prot_set_init();
q = PROT_SET_Q10(v);
- CHECK(prot_set_set(PS_OC1_CUR, q) == 0, "TC-PS-005 set ok");
+ CHECK(prot_set_set(PS_OC1_CUR, q) == 0, "TC-PROTSET-005 set ok");
{
float back = prot_set_get_f(PS_OC1_CUR);
float err = back - v;
if (err < 0.0f) { err = -err; }
- CHECK(err < 0.001f, "TC-PS-005 Q10 roundtrip error < 1 LSB");
+ CHECK(err < 0.001f, "TC-PROTSET-005 Q10 roundtrip error < 1 LSB");
}
}
-/* TC-PS-006 */
+/* TC-PROTSET-006 */
static void tc_meta_sanity(void) {
uint32_t i, j;
int ok_range = 1, ok_ctl = 1, ok_addr = 1;
@@ -136,40 +136,40 @@ static void tc_meta_sanity(void) {
if (g_prot_set_meta[j].comm_addr == m->comm_addr) { ok_addr = 0; }
}
}
- CHECK(ok_range, "TC-PS-006 meta: min<=def<=max for all items");
- CHECK(ok_ctl, "TC-PS-006 meta: ctl items are 0..1");
- CHECK(ok_addr, "TC-PS-006 meta: comm addresses unique");
- CHECK((uint32_t)PS_ID_COUNT <= 64u, "TC-PS-006 item count fits 64-bit bad_mask (B8: 40)");
+ CHECK(ok_range, "TC-PROTSET-006 meta: min<=def<=max for all items");
+ CHECK(ok_ctl, "TC-PROTSET-006 meta: ctl items are 0..1");
+ CHECK(ok_addr, "TC-PROTSET-006 meta: comm addresses unique");
+ CHECK((uint32_t)PS_ID_COUNT <= 64u, "TC-PROTSET-006 item count fits 64-bit bad_mask (B8: 40)");
}
-/* TC-PS-007 */
+/* TC-PROTSET-007 */
static void tc_id_guard(void) {
prot_set_init();
- CHECK(prot_set_get(PS_ID_COUNT) == 0, "TC-PS-007 get out-of-range id -> 0");
- CHECK(prot_set_set(PS_ID_COUNT, 0) == -1, "TC-PS-007 set out-of-range id -> -1");
- CHECK(prot_set_set_sealed(PS_ID_COUNT, 0) == -1, "TC-PS-007 set_sealed id guard");
+ CHECK(prot_set_get(PS_ID_COUNT) == 0, "TC-PROTSET-007 get out-of-range id -> 0");
+ CHECK(prot_set_set(PS_ID_COUNT, 0) == -1, "TC-PROTSET-007 set out-of-range id -> -1");
+ CHECK(prot_set_set_sealed(PS_ID_COUNT, 0) == -1, "TC-PROTSET-007 set_sealed id guard");
}
-/* TC-PS-008(B7:全局软压板 + 原子写 + 脏标志) */
+/* TC-PROTSET-008(B7:全局软压板 + 原子写 + 脏标志) */
static void tc_global_plate_dirty(void) {
prot_set_init();
- CHECK(prot_set_dirty_peek() == 0u, "TC-PS-008 init not dirty");
- CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 1u, "TC-PS-008 global plate default IN");
- CHECK(prot_set_set(PS_GLOBAL_EN, PROT_SET_Q10(2)) == -1, "TC-PS-008 plate rejects 2");
- CHECK(prot_set_set_sealed(PS_GLOBAL_EN, 0) == 0, "TC-PS-008 plate OUT via set_sealed");
- CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 0u, "TC-PS-008 plate OUT readable");
- CHECK(prot_set_selfcheck() == 0, "TC-PS-008 set_sealed leaves selfcheck PASS (no unsealed window)");
- CHECK(prot_set_locked() == 0u, "TC-PS-008 set_sealed no lock");
- CHECK(prot_set_dirty_peek() == 1u, "TC-PS-008 set_sealed marks dirty");
- CHECK(prot_set_dirty_take() == 1u, "TC-PS-008 dirty take consumes");
- CHECK(prot_set_dirty_peek() == 0u, "TC-PS-008 dirty cleared after take");
+ CHECK(prot_set_dirty_peek() == 0u, "TC-PROTSET-008 init not dirty");
+ CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 1u, "TC-PROTSET-008 global plate default IN");
+ CHECK(prot_set_set(PS_GLOBAL_EN, PROT_SET_Q10(2)) == -1, "TC-PROTSET-008 plate rejects 2");
+ CHECK(prot_set_set_sealed(PS_GLOBAL_EN, 0) == 0, "TC-PROTSET-008 plate OUT via set_sealed");
+ CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 0u, "TC-PROTSET-008 plate OUT readable");
+ CHECK(prot_set_selfcheck() == 0, "TC-PROTSET-008 set_sealed leaves selfcheck PASS (no unsealed window)");
+ CHECK(prot_set_locked() == 0u, "TC-PROTSET-008 set_sealed no lock");
+ CHECK(prot_set_dirty_peek() == 1u, "TC-PROTSET-008 set_sealed marks dirty");
+ CHECK(prot_set_dirty_take() == 1u, "TC-PROTSET-008 dirty take consumes");
+ CHECK(prot_set_dirty_peek() == 0u, "TC-PROTSET-008 dirty cleared after take");
prot_set_dirty_mark();
- CHECK(prot_set_dirty_peek() == 1u, "TC-PS-008 dirty mark re-arms (write-fail retry)");
- CHECK(prot_set_set_sealed(PS_GLOBAL_EN, PROT_SET_Q10(2)) == -1, "TC-PS-008 set_sealed range check");
- CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 0u, "TC-PS-008 rejected set_sealed keeps value");
+ CHECK(prot_set_dirty_peek() == 1u, "TC-PROTSET-008 dirty mark re-arms (write-fail retry)");
+ CHECK(prot_set_set_sealed(PS_GLOBAL_EN, PROT_SET_Q10(2)) == -1, "TC-PROTSET-008 set_sealed range check");
+ CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 0u, "TC-PROTSET-008 rejected set_sealed keeps value");
}
-/* TC-PS-009(B7:blob 往返) */
+/* TC-PROTSET-009(B7:blob 往返) */
static void tc_store_roundtrip(void) {
uint8_t blob[PROT_SET_BLOB_SZ];
uint32_t len = 0u;
@@ -180,15 +180,15 @@ static void tc_store_roundtrip(void) {
(void)prot_set_set_sealed(PS_GLOBAL_EN, 0);
(void)prot_set_dirty_take();
cur = prot_set_get(PS_OC1_CUR);
- CHECK(prot_set_store_serialize(blob, sizeof(blob), &len) == 0, "TC-PS-009 serialize ok");
- CHECK(len == (uint32_t)PROT_SET_BLOB_SZ, "TC-PS-009 blob exact size");
+ CHECK(prot_set_store_serialize(blob, sizeof(blob), &len) == 0, "TC-PROTSET-009 serialize ok");
+ CHECK(len == (uint32_t)PROT_SET_BLOB_SZ, "TC-PROTSET-009 blob exact size");
prot_set_init();
- CHECK(prot_set_get(PS_OC1_CUR) != cur, "TC-PS-009 init wiped to defaults");
- CHECK(prot_set_store_parse(blob, len) == 0, "TC-PS-009 parse ok");
- CHECK(prot_set_get(PS_OC1_CUR) == cur, "TC-PS-009 value round-trip bit-exact");
- CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 0u, "TC-PS-009 plate state round-trip");
- CHECK(prot_set_selfcheck() == 0, "TC-PS-009 parsed table sealed");
- CHECK(prot_set_dirty_peek() == 0u, "TC-PS-009 parse does not mark dirty");
+ CHECK(prot_set_get(PS_OC1_CUR) != cur, "TC-PROTSET-009 init wiped to defaults");
+ CHECK(prot_set_store_parse(blob, len) == 0, "TC-PROTSET-009 parse ok");
+ CHECK(prot_set_get(PS_OC1_CUR) == cur, "TC-PROTSET-009 value round-trip bit-exact");
+ CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 0u, "TC-PROTSET-009 plate state round-trip");
+ CHECK(prot_set_selfcheck() == 0, "TC-PROTSET-009 parsed table sealed");
+ CHECK(prot_set_dirty_peek() == 0u, "TC-PROTSET-009 parse does not mark dirty");
}
/* 伪造辅助:按 blob 值区重算尾部 sum/sumn(构造"自洽但越界"的对抗样本) */
@@ -205,7 +205,7 @@ static void s_forge_tail(uint8_t *b, uint32_t len) {
s_put32(b + len - 4u, inv);
}
-/* TC-PS-010(B7:损坏 blob 整表拒绝,all-or-nothing) */
+/* TC-PROTSET-010(B7:损坏 blob 整表拒绝,all-or-nothing) */
static void tc_store_corrupt(void) {
uint8_t blob[PROT_SET_BLOB_SZ];
uint32_t len = 0u;
@@ -214,36 +214,36 @@ static void tc_store_corrupt(void) {
prot_set_init();
(void)prot_set_set_sealed(PS_OC2_CUR, PROT_SET_Q10(6.0));
keep = prot_set_get(PS_OC2_CUR);
- CHECK(prot_set_store_serialize(blob, sizeof(blob), &len) == 0, "TC-PS-010 serialize ok");
+ CHECK(prot_set_store_serialize(blob, sizeof(blob), &len) == 0, "TC-PROTSET-010 serialize ok");
blob[PROT_SET_BLOB_HDR_SZ] ^= 0x01u; /* 值区一位翻转:sum 对不符 */
- CHECK(prot_set_store_parse(blob, len) == -1, "TC-PS-010 flipped value byte rejected (sum pair)");
- CHECK(prot_set_get(PS_OC2_CUR) == keep, "TC-PS-010 reject leaves values untouched");
+ CHECK(prot_set_store_parse(blob, len) == -1, "TC-PROTSET-010 flipped value byte rejected (sum pair)");
+ CHECK(prot_set_get(PS_OC2_CUR) == keep, "TC-PROTSET-010 reject leaves values untouched");
(void)prot_set_store_serialize(blob, sizeof(blob), &len);
blob[0] ^= 0xFFu; /* magic 破坏 */
- CHECK(prot_set_store_parse(blob, len) == -1, "TC-PS-010 bad magic rejected");
+ CHECK(prot_set_store_parse(blob, len) == -1, "TC-PROTSET-010 bad magic rejected");
(void)prot_set_store_serialize(blob, sizeof(blob), &len);
- CHECK(prot_set_store_parse(blob, len - 4u) == -1, "TC-PS-010 truncated blob rejected");
- CHECK(prot_set_store_parse(blob, len + 4u) == -1, "TC-PS-010 oversized blob rejected");
+ CHECK(prot_set_store_parse(blob, len - 4u) == -1, "TC-PROTSET-010 truncated blob rejected");
+ CHECK(prot_set_store_parse(blob, len + 4u) == -1, "TC-PROTSET-010 oversized blob rejected");
(void)prot_set_store_serialize(blob, sizeof(blob), &len);
blob[5] ^= 0x02u; /* version 高字节:1 -> 0x200 */
- CHECK(prot_set_store_parse(blob, len) == -1, "TC-PS-010 version mismatch rejected");
+ CHECK(prot_set_store_parse(blob, len) == -1, "TC-PROTSET-010 version mismatch rejected");
/* 对抗样本:越限定值 + 重算 sum 对(校验全过、范围必拦) */
(void)prot_set_store_serialize(blob, sizeof(blob), &len);
s_put32(blob + PROT_SET_BLOB_HDR_SZ + 4u * (uint32_t)PS_OC1_CUR,
(uint32_t)(g_prot_set_meta[PS_OC1_CUR].max + 1));
s_forge_tail(blob, len);
- CHECK(prot_set_store_parse(blob, len) == -1, "TC-PS-010 forged consistent out-of-range rejected");
- CHECK(prot_set_bad_mask() == (1uLL << PS_OC1_CUR), "TC-PS-010 bad_mask points at item");
- CHECK(prot_set_get(PS_OC1_CUR) == PROT_SET_Q10(10.0), "TC-PS-010 defaults still intact");
- CHECK(prot_set_selfcheck() == 0, "TC-PS-010 active table still self-consistent after all rejects");
+ CHECK(prot_set_store_parse(blob, len) == -1, "TC-PROTSET-010 forged consistent out-of-range rejected");
+ CHECK(prot_set_bad_mask() == (1uLL << PS_OC1_CUR), "TC-PROTSET-010 bad_mask points at item");
+ CHECK(prot_set_get(PS_OC1_CUR) == PROT_SET_Q10(10.0), "TC-PROTSET-010 defaults still intact");
+ CHECK(prot_set_selfcheck() == 0, "TC-PROTSET-010 active table still self-consistent after all rejects");
}
-/* TC-PS-011(B8:OF/UF 定值行 + 40 项 + 64 位 bad_mask + 换代拒绝) */
+/* TC-PROTSET-011(B8:OF/UF 定值行 + 40 项 + 64 位 bad_mask + 换代拒绝) */
static void tc_of_uf_meta(void) {
uint8_t blob[PROT_SET_BLOB_SZ];
uint32_t len = 0u;
@@ -251,10 +251,10 @@ static void tc_of_uf_meta(void) {
prot_set_init();
/* 结构:40 项、blob 版本 2、尺寸随项数自适应 */
- CHECK((uint32_t)PS_ID_COUNT == 40u, "TC-PS-011 PS_ID_COUNT == 40 (32 + 8 OF/UF)");
- CHECK(PROT_SET_BLOB_VER == 2u, "TC-PS-011 blob version bumped to 2 (B8)");
+ CHECK((uint32_t)PS_ID_COUNT == 40u, "TC-PROTSET-011 PS_ID_COUNT == 40 (32 + 8 OF/UF)");
+ CHECK(PROT_SET_BLOB_VER == 2u, "TC-PROTSET-011 blob version bumped to 2 (B8)");
CHECK((uint32_t)PROT_SET_BLOB_SZ == (PROT_SET_BLOB_HDR_SZ + 4u * 40u + 8u),
- "TC-PS-011 blob size = hdr + 4*40 + tail");
+ "TC-PROTSET-011 blob size = hdr + 4*40 + tail");
/* 地址:参考逐项地址不在本仓库 -> 8 项全部本地项(comm_addr=0,104 不可寻址) */
CHECK((g_prot_set_meta[PS_OF_EN].comm_addr == 0u)
@@ -265,60 +265,60 @@ static void tc_of_uf_meta(void) {
&& (g_prot_set_meta[PS_UF_DLY].comm_addr == 0u)
&& (g_prot_set_meta[PS_RET_OF].comm_addr == 0u)
&& (g_prot_set_meta[PS_RET_UF].comm_addr == 0u),
- "TC-PS-011 OF/UF items all local (comm_addr=0, pending reference table)");
+ "TC-PROTSET-011 OF/UF items all local (comm_addr=0, pending reference table)");
/* 投退 = ctl 项(0/1),其余 = 模拟量 Q10 */
CHECK((g_prot_set_meta[PS_OF_EN].is_ctl == 1u) && (g_prot_set_meta[PS_UF_EN].is_ctl == 1u)
&& (g_prot_set_meta[PS_OF_HZ].is_ctl == 0u) && (g_prot_set_meta[PS_RET_UF].is_ctl == 0u),
- "TC-PS-011 EN items are ctl, HZ/DLY/RET are Q10 analog");
+ "TC-PROTSET-011 EN items are ctl, HZ/DLY/RET are Q10 analog");
/* 出厂默认(拟定值)与范围 */
- CHECK(prot_set_get(PS_OF_EN) == PROT_SET_Q10(1.0), "TC-PS-011 OF EN default 1");
- CHECK(prot_set_get(PS_UF_EN) == PROT_SET_Q10(1.0), "TC-PS-011 UF EN default 1");
- CHECK(prot_set_get(PS_OF_HZ) == PROT_SET_Q10(51.0), "TC-PS-011 OF default 51.0 Hz");
- CHECK(prot_set_get(PS_UF_HZ) == PROT_SET_Q10(49.0), "TC-PS-011 UF default 49.0 Hz");
- CHECK(prot_set_get(PS_OF_DLY) == PROT_SET_Q10(1000.0), "TC-PS-011 OF default 1000 ms");
- CHECK(prot_set_get(PS_UF_DLY) == PROT_SET_Q10(1000.0), "TC-PS-011 UF default 1000 ms");
- CHECK(prot_set_get(PS_RET_OF) == PROT_SET_Q10(0.99), "TC-PS-011 RET_OF default 0.99");
- CHECK(prot_set_get(PS_RET_UF) == PROT_SET_Q10(1.01), "TC-PS-011 RET_UF default 1.01");
+ CHECK(prot_set_get(PS_OF_EN) == PROT_SET_Q10(1.0), "TC-PROTSET-011 OF EN default 1");
+ CHECK(prot_set_get(PS_UF_EN) == PROT_SET_Q10(1.0), "TC-PROTSET-011 UF EN default 1");
+ CHECK(prot_set_get(PS_OF_HZ) == PROT_SET_Q10(51.0), "TC-PROTSET-011 OF default 51.0 Hz");
+ CHECK(prot_set_get(PS_UF_HZ) == PROT_SET_Q10(49.0), "TC-PROTSET-011 UF default 49.0 Hz");
+ CHECK(prot_set_get(PS_OF_DLY) == PROT_SET_Q10(1000.0), "TC-PROTSET-011 OF default 1000 ms");
+ CHECK(prot_set_get(PS_UF_DLY) == PROT_SET_Q10(1000.0), "TC-PROTSET-011 UF default 1000 ms");
+ CHECK(prot_set_get(PS_RET_OF) == PROT_SET_Q10(0.99), "TC-PROTSET-011 RET_OF default 0.99");
+ CHECK(prot_set_get(PS_RET_UF) == PROT_SET_Q10(1.01), "TC-PROTSET-011 RET_UF default 1.01");
CHECK((g_prot_set_meta[PS_OF_HZ].min == PROT_SET_Q10(50.0))
&& (g_prot_set_meta[PS_OF_HZ].max == PROT_SET_Q10(55.0)),
- "TC-PS-011 OF range 50.0~55.0 Hz");
+ "TC-PROTSET-011 OF range 50.0~55.0 Hz");
CHECK((g_prot_set_meta[PS_UF_HZ].min == PROT_SET_Q10(45.0))
&& (g_prot_set_meta[PS_UF_HZ].max == PROT_SET_Q10(50.0)),
- "TC-PS-011 UF range 45.0~50.0 Hz");
+ "TC-PROTSET-011 UF range 45.0~50.0 Hz");
/* 频率返回系数与电气量系数独立:返回**门槛** = 定值×系数(Q10 乘积
* /1024)——OF 门槛 < 动作门槛、UF 门槛 > 动作门槛(方向相反) */
CHECK(((int64_t)prot_set_get(PS_OF_HZ) * (int64_t)prot_set_get(PS_RET_OF)) / 1024
< (int64_t)prot_set_get(PS_OF_HZ),
- "TC-PS-011 OF return threshold (set x 0.99) below pickup");
+ "TC-PROTSET-011 OF return threshold (set x 0.99) below pickup");
CHECK(((int64_t)prot_set_get(PS_UF_HZ) * (int64_t)prot_set_get(PS_RET_UF)) / 1024
> (int64_t)prot_set_get(PS_UF_HZ),
- "TC-PS-011 UF return threshold (set x 1.01) above pickup");
+ "TC-PROTSET-011 UF return threshold (set x 1.01) above pickup");
/* 投退可经 set_sealed 投/退(YK 口径同 GLOBAL_EN;Q10(2)=2048 越界拒) */
- CHECK(prot_set_set_sealed(PS_OF_EN, 0) == 0, "TC-PS-011 OF EN set_sealed OK");
- CHECK(prot_set_get_ctl(PS_OF_EN) == 0u, "TC-PS-011 OF EN readable after seal");
- CHECK(prot_set_set_sealed(PS_OF_EN, PROT_SET_Q10(2)) == -1, "TC-PS-011 OF EN rejects Q10(2)");
- CHECK(prot_set_selfcheck() == 0, "TC-PS-011 no lock after OF/UF seal ops");
+ CHECK(prot_set_set_sealed(PS_OF_EN, 0) == 0, "TC-PROTSET-011 OF EN set_sealed OK");
+ CHECK(prot_set_get_ctl(PS_OF_EN) == 0u, "TC-PROTSET-011 OF EN readable after seal");
+ CHECK(prot_set_set_sealed(PS_OF_EN, PROT_SET_Q10(2)) == -1, "TC-PROTSET-011 OF EN rejects Q10(2)");
+ CHECK(prot_set_selfcheck() == 0, "TC-PROTSET-011 no lock after OF/UF seal ops");
/* 64 位 bad_mask:末项(bit 39 > 31)越界可指认 */
(void)prot_set_set_sealed(PS_OC1_CUR, PROT_SET_Q10(11.0));
(void)prot_set_dirty_take();
- CHECK(prot_set_store_serialize(blob, sizeof(blob), &len) == 0, "TC-PS-011 serialize ok");
+ CHECK(prot_set_store_serialize(blob, sizeof(blob), &len) == 0, "TC-PROTSET-011 serialize ok");
s_put32(blob + PROT_SET_BLOB_HDR_SZ + 4u * (uint32_t)PS_RET_UF,
(uint32_t)(g_prot_set_meta[PS_RET_UF].max + 1));
s_forge_tail(blob, len);
- CHECK(prot_set_store_parse(blob, len) == -1, "TC-PS-011 out-of-range RET_UF rejected");
+ CHECK(prot_set_store_parse(blob, len) == -1, "TC-PROTSET-011 out-of-range RET_UF rejected");
CHECK(prot_set_bad_mask() == (1uLL << PS_RET_UF),
- "TC-PS-011 bad_mask bit 39 addressable (64-bit mask, B8)");
- CHECK(prot_set_get(PS_RET_UF) == PROT_SET_Q10(1.01), "TC-PS-011 default RET_UF intact");
+ "TC-PROTSET-011 bad_mask bit 39 addressable (64-bit mask, B8)");
+ CHECK(prot_set_get(PS_RET_UF) == PROT_SET_Q10(1.01), "TC-PROTSET-011 default RET_UF intact");
/* 换代语义:B7 旧档(ver=1 / 32 项 = 144 B)在新固件必被拒 -> 出厂默认 */
CHECK(prot_set_store_parse(blob, 8u + 4u * 32u + 8u) == -1,
- "TC-PS-011 legacy 32-item blob length rejected");
- CHECK(prot_set_selfcheck() == 0, "TC-PS-011 active table intact after legacy reject");
+ "TC-PROTSET-011 legacy 32-item blob length rejected");
+ CHECK(prot_set_selfcheck() == 0, "TC-PROTSET-011 active table intact after legacy reject");
}
int main(void) {
diff --git a/test/host/sha256/sha256_test.c b/test/host/sha256/sha256_test.c
index 160d91c0..590c43bf 100644
--- a/test/host/sha256/sha256_test.c
+++ b/test/host/sha256/sha256_test.c
@@ -12,14 +12,14 @@
* 看不出哪一步坏;标准向量在主机侧毫秒级钉死。
*
* 覆盖点:
- * TC-SH-001 FIPS 180-4 向量:空串
- * TC-SH-002 FIPS 180-4 向量:"abc"
- * TC-SH-003 FIPS 180-4 向量:56 字节(补位跨分组边界)
- * TC-SH-004 FIPS 180-4 向量:1,000,000 × 'a'(流式,长度字段进第二分组)
- * TC-SH-005 流式任意切分与一次性计算等价(逐字节喂入)
- * TC-SH-006 hex_eq:小写匹配 / 大写匹配
- * TC-SH-007 hex_eq:内容不等 / 非法字符 / 长度 63/65 / NULL → 全 0
- * TC-SH-008 默认口令哈希钉值:SHA256("adminadmin") = FTP_CFG_DEF_HASH 同源值
+ * TC-SHA256-001 FIPS 180-4 向量:空串
+ * TC-SHA256-002 FIPS 180-4 向量:"abc"
+ * TC-SHA256-003 FIPS 180-4 向量:56 字节(补位跨分组边界)
+ * TC-SHA256-004 FIPS 180-4 向量:1,000,000 × 'a'(流式,长度字段进第二分组)
+ * TC-SHA256-005 流式任意切分与一次性计算等价(逐字节喂入)
+ * TC-SHA256-006 hex_eq:小写匹配 / 大写匹配
+ * TC-SHA256-007 hex_eq:内容不等 / 非法字符 / 长度 63/65 / NULL → 全 0
+ * TC-SHA256-008 默认口令哈希钉值:SHA256("adminadmin") = FTP_CFG_DEF_HASH 同源值
*
* 通过:全部 TC PASS(main 返回 0)。
* 入口:int main(void),返回 0=PASS / 1=FAIL(由 run 脚本判读)。
@@ -65,7 +65,7 @@ static int hex_eq_vector(const uint8_t d[SHA256_DIGEST_SIZE], const char *want)
return strcmp(got, want) == 0;
}
-/* ===================== TC-SH-001..004:标准向量 ===================== */
+/* ===================== TC-SHA256-001..004:标准向量 ===================== */
static void tc_vectors(void)
{
@@ -73,15 +73,15 @@ static void tc_vectors(void)
sha256_calc("", 0u, d);
CHECK(hex_eq_vector(d, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"),
- "TC-SH-001 空串向量");
+ "TC-SHA256-001 空串向量");
sha256_calc("abc", 3u, d);
CHECK(hex_eq_vector(d, "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"),
- "TC-SH-002 \"abc\" 向量");
+ "TC-SHA256-002 \"abc\" 向量");
sha256_calc("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56u, d);
CHECK(hex_eq_vector(d, "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"),
- "TC-SH-003 56 字节向量(补位跨分组)");
+ "TC-SHA256-003 56 字节向量(补位跨分组)");
{
sha256_ctx_t ctx;
@@ -93,10 +93,10 @@ static void tc_vectors(void)
sha256_final(&ctx, d);
}
CHECK(hex_eq_vector(d, "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"),
- "TC-SH-004 1e6 × 'a' 向量(流式)");
+ "TC-SHA256-004 1e6 × 'a' 向量(流式)");
}
-/* ===================== TC-SH-005:流式等价 ===================== */
+/* ===================== TC-SHA256-005:流式等价 ===================== */
static void tc_stream_equiv(void)
{
@@ -111,10 +111,10 @@ static void tc_stream_equiv(void)
sha256_update(&ctx, &msg[i], 1u);
}
sha256_final(&ctx, d2);
- CHECK(memcmp(d1, d2, sizeof(d1)) == 0, "TC-SH-005 逐字节喂入与一次性等价");
+ CHECK(memcmp(d1, d2, sizeof(d1)) == 0, "TC-SHA256-005 逐字节喂入与一次性等价");
}
-/* ===================== TC-SH-006..007:hex_eq ===================== */
+/* ===================== TC-SHA256-006..007:hex_eq ===================== */
static void tc_hex_eq(void)
{
@@ -131,11 +131,11 @@ static void tc_hex_eq(void)
}
upper[64] = '\0';
- CHECK(sha256_hex_eq(d, lower) == 1, "TC-SH-006a 小写 hex 匹配");
- CHECK(sha256_hex_eq(d, upper) == 1, "TC-SH-006b 大写 hex 匹配(大小写不敏感)");
+ CHECK(sha256_hex_eq(d, lower) == 1, "TC-SHA256-006a 小写 hex 匹配");
+ CHECK(sha256_hex_eq(d, upper) == 1, "TC-SHA256-006b 大写 hex 匹配(大小写不敏感)");
lower[63] = (char)((lower[63] == '0') ? '1' : '0');
- CHECK(sha256_hex_eq(d, lower) == 0, "TC-SH-007a 内容不等 → 0");
+ CHECK(sha256_hex_eq(d, lower) == 0, "TC-SHA256-007a 内容不等 → 0");
lower[63] = (char)((lower[63] == '0') ? '1' : '0'); /* 还原 */
{
@@ -144,22 +144,22 @@ static void tc_hex_eq(void)
memcpy(bad, lower, 64);
bad[64] = '\0';
bad[10] = 'g';
- CHECK(sha256_hex_eq(d, bad) == 0, "TC-SH-007b 非法 hex 字符 → 0");
+ CHECK(sha256_hex_eq(d, bad) == 0, "TC-SHA256-007b 非法 hex 字符 → 0");
}
memcpy(shortv, lower, 63);
shortv[63] = '\0';
- CHECK(sha256_hex_eq(d, shortv) == 0, "TC-SH-007c 长度 63 → 0");
+ CHECK(sha256_hex_eq(d, shortv) == 0, "TC-SHA256-007c 长度 63 → 0");
memcpy(longv, lower, 64);
longv[64] = 'a';
longv[65] = '\0';
- CHECK(sha256_hex_eq(d, longv) == 0, "TC-SH-007d 长度 65 → 0");
+ CHECK(sha256_hex_eq(d, longv) == 0, "TC-SHA256-007d 长度 65 → 0");
- CHECK(sha256_hex_eq(d, NULL) == 0, "TC-SH-007e NULL → 0");
+ CHECK(sha256_hex_eq(d, NULL) == 0, "TC-SHA256-007e NULL → 0");
}
-/* ===================== TC-SH-008:默认口令哈希钉值 ===================== */
+/* ===================== TC-SHA256-008:默认口令哈希钉值 ===================== */
static void tc_default_hash(void)
{
@@ -168,7 +168,7 @@ static void tc_default_hash(void)
/* 与 ftp_cfg.h FTP_CFG_DEF_HASH 同源钉值(两处若漂移本测试立刻红) */
sha256_calc("adminadmin", 10u, d);
CHECK(sha256_hex_eq(d, "d82494f05d6917ba02f7aaa29689ccb444bb73f20380876cb05d1f37537b7892") == 1,
- "TC-SH-008 SHA256(\"adminadmin\") = 出厂默认 pwd_hash");
+ "TC-SHA256-008 SHA256(\"adminadmin\") = 出厂默认 pwd_hash");
}
/* ===================== main ===================== */
diff --git a/test/host/sys_clock/sys_clock_test.c b/test/host/sys_clock/sys_clock_test.c
index 4d6e0caf..899fbf93 100644
--- a/test/host/sys_clock/sys_clock_test.c
+++ b/test/host/sys_clock/sys_clock_test.c
@@ -14,27 +14,27 @@
* - 其余用例用 sys_clock_set(unix, NULL) 建立确定基准(无 RTC 副作用)。
*
* 覆盖点(对应 docs/测试说明/系统时钟单元测试说明.md 的 TC-CLK-xxx):
- * TC-CLK-000 未初始化:sys_clock_get / get_time / get_str 的无效语义
- * TC-CLK-001 init 正常:RTC 合法 → 返回 0,基准 = 换算 Unix 秒
- * TC-CLK-002 init 闰年换算:2024-02-29 / 2000-02-29(世纪闰)/ 2/29→3/1 间隔
- * TC-CLK-003 init 月末边界:1/31、2/28、4/30 的 Unix 秒精确值
- * TC-CLK-004 init 世纪边界:2000-01-01、2038 上限(0x7FFFFFFF)、Unix 0 经 set
- * TC-CLK-005 init RTC 读失败 → 降级默认时间,返回 -1 + 打错误日志
- * TC-CLK-006 init RTC 越界(年份/月/日非法)→ 自愈写回默认时间(返回 0)
- * TC-CLK-020 init 越界且写回失败 → 降级默认时间 + 返回 -1
- * TC-CLK-007 init 越界 → 自动写回默认时间并复验(rtc 被修正)
- * TC-CLK-008 get 正常推进:tick +1000 → +1 秒(含亚秒截断)
- * TC-CLK-009 get 未跨阈值不回绕:tick + 29 天仍线性
- * TC-CLK-010 get 30 天再基准化:窗口清零、墙钟值无损、含亚秒余数结转
- * TC-CLK-011 get tick 回绕(无符号差)安全
- * TC-CLK-012 get 再基准化后长期不漂移(多轮 30 天)
- * TC-CLK-013 get_str 格式化 + 未初始化占位串
- * TC-CLK-014 get_time 日历字段(年/月/日/时/分/秒/星期)与已知日期对照
- * TC-CLK-015 get_time NULL 参数被拒
- * TC-CLK-016 set 更新基准 + 写回 RTC(观察 sd2506_set_time 被调)
- * TC-CLK-017 set sd_time=NULL 不碰 RTC
- * TC-CLK-018 set_unix 写回 RTC 且日历字段正确(含星期)
- * TC-CLK-019 星期(Zeller)与已知日期对照穷举(跨世纪/闰/月末)
+ * TC-SYSCLK-000 未初始化:sys_clock_get / get_time / get_str 的无效语义
+ * TC-SYSCLK-001 init 正常:RTC 合法 → 返回 0,基准 = 换算 Unix 秒
+ * TC-SYSCLK-002 init 闰年换算:2024-02-29 / 2000-02-29(世纪闰)/ 2/29→3/1 间隔
+ * TC-SYSCLK-003 init 月末边界:1/31、2/28、4/30 的 Unix 秒精确值
+ * TC-SYSCLK-004 init 世纪边界:2000-01-01、2038 上限(0x7FFFFFFF)、Unix 0 经 set
+ * TC-SYSCLK-005 init RTC 读失败 → 降级默认时间,返回 -1 + 打错误日志
+ * TC-SYSCLK-006 init RTC 越界(年份/月/日非法)→ 自愈写回默认时间(返回 0)
+ * TC-SYSCLK-020 init 越界且写回失败 → 降级默认时间 + 返回 -1
+ * TC-SYSCLK-007 init 越界 → 自动写回默认时间并复验(rtc 被修正)
+ * TC-SYSCLK-008 get 正常推进:tick +1000 → +1 秒(含亚秒截断)
+ * TC-SYSCLK-009 get 未跨阈值不回绕:tick + 29 天仍线性
+ * TC-SYSCLK-010 get 30 天再基准化:窗口清零、墙钟值无损、含亚秒余数结转
+ * TC-SYSCLK-011 get tick 回绕(无符号差)安全
+ * TC-SYSCLK-012 get 再基准化后长期不漂移(多轮 30 天)
+ * TC-SYSCLK-013 get_str 格式化 + 未初始化占位串
+ * TC-SYSCLK-014 get_time 日历字段(年/月/日/时/分/秒/星期)与已知日期对照
+ * TC-SYSCLK-015 get_time NULL 参数被拒
+ * TC-SYSCLK-016 set 更新基准 + 写回 RTC(观察 sd2506_set_time 被调)
+ * TC-SYSCLK-017 set sd_time=NULL 不碰 RTC
+ * TC-SYSCLK-018 set_unix 写回 RTC 且日历字段正确(含星期)
+ * TC-SYSCLK-019 星期(Zeller)与已知日期对照穷举(跨世纪/闰/月末)
*
* 通过:全部 TC PASS(main 返回 0)。
* 入口:int main(void),返回 0=PASS / 1=FAIL(由 run 脚本判读)。
@@ -189,7 +189,7 @@ static void tc_000_uninitialized(void) {
sd2506_time_t t;
char buf[32];
- printf("TC-CLK-000 未初始化语义\n");
+ printf("TC-SYSCLK-000 未初始化语义\n");
/* 注意:本用例不做 sys_clock_init / sys_clock_set */
CHECK_EQ_U32(sys_clock_get(), UINT32_MAX, "未初始化 get 返回 UINT32_MAX");
CHECK(sys_clock_get_time(&t) == -1, "未初始化 get_time 返回 -1");
@@ -201,7 +201,7 @@ static void tc_000_uninitialized(void) {
static void tc_001_init_ok(void) {
int rc;
- printf("TC-CLK-001 init 正常(RTC 合法)\n");
+ printf("TC-SYSCLK-001 init 正常(RTC 合法)\n");
rtc_set(2026, 8, 24, 0, 0, 0);
s_rtc_read_rc = SD2506_OK;
s_rtc_write_rc = SD2506_OK;
@@ -216,7 +216,7 @@ static void tc_001_init_ok(void) {
}
static void tc_002_init_leap(void) {
- printf("TC-CLK-002 init 闰年换算\n");
+ printf("TC-SYSCLK-002 init 闰年换算\n");
/* 2024 是闰年:2/29 存在 */
rtc_set(2024, 2, 29, 12, 0, 0);
s_rtc_read_rc = SD2506_OK;
@@ -240,7 +240,7 @@ static void tc_002_init_leap(void) {
}
static void tc_003_init_month_end(void) {
- printf("TC-CLK-003 init 月末边界\n");
+ printf("TC-SYSCLK-003 init 月末边界\n");
rtc_set(2026, 1, 31, 0, 0, 0); s_rtc_read_rc = SD2506_OK;
CHECK(sys_clock_init() == 0, "1/31 合法");
CHECK_EQ_U32(sys_clock_get(), ref_unix(2026, 1, 31, 0, 0, 0), "1/31 换算");
@@ -262,7 +262,7 @@ static void tc_003_init_month_end(void) {
}
static void tc_004_init_epoch_bounds(void) {
- printf("TC-CLK-004 init 世纪边界(Unix 下限 / 2038 上限)\n");
+ printf("TC-SYSCLK-004 init 世纪边界(Unix 下限 / 2038 上限)\n");
/*
* 注意:init 接受的 RTC 年份范围是 2000~2099(越界即判故障并自愈),
* 故"Unix 0(1970-01-01)"**不可能经 init 建立**——1970 会被判越界。
@@ -291,7 +291,7 @@ static void tc_004_init_epoch_bounds(void) {
}
static void tc_005_init_rtc_read_fail(void) {
- printf("TC-CLK-005 init RTC 读失败 → 降级默认时间并返回 -1\n");
+ printf("TC-SYSCLK-005 init RTC 读失败 → 降级默认时间并返回 -1\n");
s_rtc_read_rc = SD2506_ERROR; /* 注入读故障 */
s_rtc_write_rc = SD2506_OK;
clear_obs();
@@ -309,7 +309,7 @@ static void tc_005_init_rtc_read_fail(void) {
}
static void tc_006_init_out_of_range_selfheal(void) {
- printf("TC-CLK-006 init RTC 越界 → 自愈写回默认时间(返回 0)\n");
+ printf("TC-SYSCLK-006 init RTC 越界 → 自愈写回默认时间(返回 0)\n");
/*
* RTC_DEFAULT_INIT_ENABLE=1 且 FORCE=0 时:越界值触发"写回默认时间",
* 写成功且复读合法 → rtc_ok 恢复为 1 → **返回 0**(自愈,非降级)。
@@ -335,7 +335,7 @@ static void tc_006_init_out_of_range_selfheal(void) {
}
static void tc_020_init_selfheal_fail_degrades(void) {
- printf("TC-CLK-020 init 越界且写回失败 → 降级默认时间并返回 -1\n");
+ printf("TC-SYSCLK-020 init 越界且写回失败 → 降级默认时间并返回 -1\n");
/*
* 组合故障:读成功但值越界(触发写回),写回失败 → 复读仍越界 →
* rtc_ok 清 0 → 走降级分支(启用默认值时建基准 + 返回 -1)。
@@ -356,7 +356,7 @@ static void tc_020_init_selfheal_fail_degrades(void) {
}
static void tc_007_init_corrects_rtc(void) {
- printf("TC-CLK-007 init 越界 → 自动写回默认时间并复验\n");
+ printf("TC-SYSCLK-007 init 越界 → 自动写回默认时间并复验\n");
rtc_set(1999, 1, 1, 0, 0, 0); /* 越界,触发校时写回 */
s_rtc_read_rc = SD2506_OK;
s_rtc_write_rc = SD2506_OK;
@@ -372,7 +372,7 @@ static void tc_007_init_corrects_rtc(void) {
}
static void tc_008_get_advance(void) {
- printf("TC-CLK-008 get 正常推进(含亚秒截断)\n");
+ printf("TC-SYSCLK-008 get 正常推进(含亚秒截断)\n");
base_at(1000000u, 5000u);
CHECK_EQ_U32(sys_clock_get(), 1000000u, "基准时刻 = 基准值");
tick_advance(999u);
@@ -384,7 +384,7 @@ static void tc_008_get_advance(void) {
}
static void tc_009_get_no_rebase_below_threshold(void) {
- printf("TC-CLK-009 未达 30 天阈值不触发再基准化\n");
+ printf("TC-SYSCLK-009 未达 30 天阈值不触发再基准化\n");
base_at(2000000u, 0u);
/* 29 天 < 30 天阈值:线性推进,基准不动 */
tick_advance(29u * 24u * 3600u * 1000u);
@@ -393,7 +393,7 @@ static void tc_009_get_no_rebase_below_threshold(void) {
}
static void tc_010_get_rebase_at_threshold(void) {
- printf("TC-CLK-010 30 天惰性再基准化(窗口清零、值无损、余数结转)\n");
+ printf("TC-SYSCLK-010 30 天惰性再基准化(窗口清零、值无损、余数结转)\n");
base_at(3000000u, 0u);
/* 推进恰好 30 天 + 1500ms(余数 500ms 应结转到新窗) */
@@ -411,7 +411,7 @@ static void tc_010_get_rebase_at_threshold(void) {
}
static void tc_011_get_tick_wrap(void) {
- printf("TC-CLK-011 tick 回绕(无符号差)安全\n");
+ printf("TC-SYSCLK-011 tick 回绕(无符号差)安全\n");
/* 基准设在接近 2^32 处 */
base_at(4000000u, 0xFFFFF000u);
/* 推进 0x2000 ms(跨越 2^32 回绕):差 = 0x2000 = 8192ms → +8s */
@@ -420,7 +420,7 @@ static void tc_011_get_tick_wrap(void) {
}
static void tc_012_get_long_run_no_drift(void) {
- printf("TC-CLK-012 多轮再基准化长期不漂移\n");
+ printf("TC-SYSCLK-012 多轮再基准化长期不漂移\n");
base_at(5000000u, 0u);
/*
* 惰性再基准化的**正确用法**:周期性调用 get() 让差值窗口始终 < 30 天。
@@ -439,7 +439,7 @@ static void tc_012_get_long_run_no_drift(void) {
}
static void tc_013_get_str(void) {
- printf("TC-CLK-013 get_str 格式化\n");
+ printf("TC-SYSCLK-013 get_str 格式化\n");
char buf[32];
base_at(ref_unix(2026, 10, 2, 13, 4, 5), 0u);
memset(buf, 0, sizeof(buf));
@@ -453,7 +453,7 @@ static void tc_013_get_str(void) {
}
static void tc_014_get_time_fields(void) {
- printf("TC-CLK-014 get_time 日历字段\n");
+ printf("TC-SYSCLK-014 get_time 日历字段\n");
sd2506_time_t t;
/* 2026-10-02 是周五(已知) */
base_at(ref_unix(2026, 10, 2, 8, 9, 10), 0u);
@@ -465,13 +465,13 @@ static void tc_014_get_time_fields(void) {
}
static void tc_015_get_time_null(void) {
- printf("TC-CLK-015 get_time NULL 参数被拒\n");
+ printf("TC-SYSCLK-015 get_time NULL 参数被拒\n");
base_at(6000000u, 0u);
CHECK(sys_clock_get_time(NULL) == -1, "p_time == NULL → 返回 -1");
}
static void tc_016_set_writes_rtc(void) {
- printf("TC-CLK-016 set 更新基准 + 写回 RTC\n");
+ printf("TC-SYSCLK-016 set 更新基准 + 写回 RTC\n");
sd2506_time_t sd;
memset(&sd, 0, sizeof(sd));
sd.year = 2027; sd.month = 3; sd.day = 15;
@@ -497,7 +497,7 @@ static void tc_016_set_writes_rtc(void) {
}
static void tc_017_set_no_rtc(void) {
- printf("TC-CLK-017 set sd_time=NULL 不碰 RTC\n");
+ printf("TC-SYSCLK-017 set sd_time=NULL 不碰 RTC\n");
clear_obs();
CHECK(sys_clock_set(8000000u, NULL) == 0, "set(NULL) 返回 0");
CHECK(s_rtc_set_calls == 0, "sd_time == NULL → 不写 RTC");
@@ -505,7 +505,7 @@ static void tc_017_set_no_rtc(void) {
}
static void tc_018_set_unix_fields(void) {
- printf("TC-CLK-018 set_unix 写回 RTC 且字段正确\n");
+ printf("TC-SYSCLK-018 set_unix 写回 RTC 且字段正确\n");
sd2506_time_t expect_week;
uint32_t u = ref_unix(2026, 10, 2, 15, 30, 45);
clear_obs();
@@ -521,7 +521,7 @@ static void tc_018_set_unix_fields(void) {
}
static void tc_019_week_known_dates(void) {
- printf("TC-CLK-019 星期(Zeller)已知日期穷举\n");
+ printf("TC-SYSCLK-019 星期(Zeller)已知日期穷举\n");
/* 期望值经 Python datetime 独立核对(0=周日);
* 覆盖 1/2 月(Zeller 需上调为上年 13/14 月的分支)与 3~12 月(2026-10-02
* 修正前全部错误),以及世纪闰年、非闰世纪、范围首尾。*/
diff --git a/test/host/time_sync/time_sync_test.c b/test/host/time_sync/time_sync_test.c
index 48d7747f..32a3fbfb 100644
--- a/test/host/time_sync/time_sync_test.c
+++ b/test/host/time_sync/time_sync_test.c
@@ -27,36 +27,36 @@
*
* 覆盖点(TC-TS-xxx):
* —— time_sync_delay_fed(可喂心跳的分片延时)——
- * TC-TS-001 0ms 不睡眠不喂狗
- * TC-TS-002 恰好一片(50ms)
- * TC-TS-003 非整片(120ms)切成 50/50/20,每片喂心跳
- * TC-TS-004 长延时(2000ms)= 40 片 × 50ms,每片喂心跳
- * TC-TS-005 不足一片(49ms)单片处理
- * TC-TS-006 总预算 30s = 600 片(片长上限恒 50ms)
+ * TC-TIMESYNC-001 0ms 不睡眠不喂狗
+ * TC-TIMESYNC-002 恰好一片(50ms)
+ * TC-TIMESYNC-003 非整片(120ms)切成 50/50/20,每片喂心跳
+ * TC-TIMESYNC-004 长延时(2000ms)= 40 片 × 50ms,每片喂心跳
+ * TC-TIMESYNC-005 不足一片(49ms)单片处理
+ * TC-TIMESYNC-006 总预算 30s = 600 片(片长上限恒 50ms)
* —— time_sync_open_listener(监听建立与重试)——
- * TC-TS-010 首次成功:socket/bind/listen 各一次,端口经 net_htons,无退避
- * TC-TS-011 bind 失败 -> 关 socket + 退避 2000ms + 留痕,随后重试成功
- * TC-TS-012 listen 失败 -> 关 socket + 退避 2000ms,随后重试成功
- * TC-TS-013 socket 连续失败 -> 5 次后返回 -1(5 条 ERROR,5×500ms 退避)
- * TC-TS-014 第 3 次重试成功并返回新描述符
- * TC-TS-015 每次重试前 + 每片延时各喂一次心跳,且心跳位恒为 TIMESYNC
+ * TC-TIMESYNC-010 首次成功:socket/bind/listen 各一次,端口经 net_htons,无退避
+ * TC-TIMESYNC-011 bind 失败 -> 关 socket + 退避 2000ms + 留痕,随后重试成功
+ * TC-TIMESYNC-012 listen 失败 -> 关 socket + 退避 2000ms,随后重试成功
+ * TC-TIMESYNC-013 socket 连续失败 -> 5 次后返回 -1(5 条 ERROR,5×500ms 退避)
+ * TC-TIMESYNC-014 第 3 次重试成功并返回新描述符
+ * TC-TIMESYNC-015 每次重试前 + 每片延时各喂一次心跳,且心跳位恒为 TIMESYNC
* —— time_sync_handle_conn(时间包重组状态机)——
- * TC-TS-020 8 字节一次收齐 -> 大端解析 epoch + 更新墙钟 + 关连接
- * TC-TS-021 分段送达(4+4)-> 累积后解析;第二次只请求剩余 12 字节
- * TC-TS-022 一次到达 16 字节 -> 只取前 8 字节
- * TC-TS-023 前缀非 "TIME" -> 不更新墙钟,但仍关连接
- * TC-TS-024 对端关闭(n==0)-> 立即退出、不解析
- * TC-TS-025 真错误(n==-1)-> 立即退出、不解析
- * TC-TS-026 只收到 4 字节后 EOF -> 不足 8 字节不解析
- * TC-TS-027 30s 预算耗尽 -> 留痕 "no TIME packet in 30s, drop conn"
- * TC-TS-028 剩余预算不足一片 -> 末片按剩余(20ms)切分
- * TC-TS-029 32 位 tick 回绕 -> 预算计算仍正确
+ * TC-TIMESYNC-020 8 字节一次收齐 -> 大端解析 epoch + 更新墙钟 + 关连接
+ * TC-TIMESYNC-021 分段送达(4+4)-> 累积后解析;第二次只请求剩余 12 字节
+ * TC-TIMESYNC-022 一次到达 16 字节 -> 只取前 8 字节
+ * TC-TIMESYNC-023 前缀非 "TIME" -> 不更新墙钟,但仍关连接
+ * TC-TIMESYNC-024 对端关闭(n==0)-> 立即退出、不解析
+ * TC-TIMESYNC-025 真错误(n==-1)-> 立即退出、不解析
+ * TC-TIMESYNC-026 只收到 4 字节后 EOF -> 不足 8 字节不解析
+ * TC-TIMESYNC-027 30s 预算耗尽 -> 留痕 "no TIME packet in 30s, drop conn"
+ * TC-TIMESYNC-028 剩余预算不足一片 -> 末片按剩余(20ms)切分
+ * TC-TIMESYNC-029 32 位 tick 回绕 -> 预算计算仍正确
* —— time_sync_task(任务主循环)——
- * TC-TS-040 sys_evtHandle==NULL:跳过就绪屏障;accept 轮询->成功->处理->收尾
- * TC-TS-041 就绪屏障:100ms 分片等待 NET_READY(osFlagsNoClear 不消费就绪位)
- * TC-TS-042 屏障未就绪期间持续喂心跳(2026-10-02 台架根因的回归防线)
- * TC-TS-043 网络代次变化 -> 关闭旧监听并重监听
- * TC-TS-044 监听建立失败 -> 5 次重试后放弃并退避 2000ms
+ * TC-TIMESYNC-040 sys_evtHandle==NULL:跳过就绪屏障;accept 轮询->成功->处理->收尾
+ * TC-TIMESYNC-041 就绪屏障:100ms 分片等待 NET_READY(osFlagsNoClear 不消费就绪位)
+ * TC-TIMESYNC-042 屏障未就绪期间持续喂心跳(2026-10-02 台架根因的回归防线)
+ * TC-TIMESYNC-043 网络代次变化 -> 关闭旧监听并重监听
+ * TC-TIMESYNC-044 监听建立失败 -> 5 次重试后放弃并退避 2000ms
*
* 通过:全部 TC PASS(main 返回 0)。
* 入口:int main(void),返回 0=PASS / 1=FAIL(由 run 脚本判读)。
@@ -413,51 +413,51 @@ static int delays_all(uint32_t v, int n) {
return 1;
}
-/* ===================== TC-TS-001..006:delay_fed ===================== */
+/* ===================== TC-TIMESYNC-001..006:delay_fed ===================== */
static void tc_delay_fed(void) {
fakes_reset();
time_sync_delay_fed(0U);
- CHECK((s_beat_calls == 0) && (s_delay_calls == 0), "TC-TS-001 delay_fed(0) 不睡眠不喂狗");
+ CHECK((s_beat_calls == 0) && (s_delay_calls == 0), "TC-TIMESYNC-001 delay_fed(0) 不睡眠不喂狗");
fakes_reset();
time_sync_delay_fed(50U);
CHECK((s_beat_calls == 1) && (s_delay_calls == 1) && (s_delays[0] == 50U),
- "TC-TS-002 delay_fed(50) = 1 片 50ms + 1 次心跳");
+ "TC-TIMESYNC-002 delay_fed(50) = 1 片 50ms + 1 次心跳");
fakes_reset();
time_sync_delay_fed(120U);
- CHECK((s_beat_calls == 3) && (s_delay_calls == 3), "TC-TS-003 delay_fed(120) 切成 3 片");
+ CHECK((s_beat_calls == 3) && (s_delay_calls == 3), "TC-TIMESYNC-003 delay_fed(120) 切成 3 片");
CHECK((s_delays[0] == 50U) && (s_delays[1] == 50U) && (s_delays[2] == 20U),
- "TC-TS-003b 片长 50/50/20(末片为余数)");
+ "TC-TIMESYNC-003b 片长 50/50/20(末片为余数)");
fakes_reset();
time_sync_delay_fed(2000U);
CHECK((s_delay_calls == 40) && (s_beat_calls == 40) && delays_all(50U, 40),
- "TC-TS-004 delay_fed(2000) = 40 片 × 50ms,每片喂一次心跳");
+ "TC-TIMESYNC-004 delay_fed(2000) = 40 片 × 50ms,每片喂一次心跳");
fakes_reset();
time_sync_delay_fed(49U);
- CHECK((s_beat_calls == 1) && (s_delays[0] == 49U), "TC-TS-005 不足一片(49ms)单片处理");
+ CHECK((s_beat_calls == 1) && (s_delays[0] == 49U), "TC-TIMESYNC-005 不足一片(49ms)单片处理");
fakes_reset();
time_sync_delay_fed(30000U);
- CHECK(s_delay_calls == 600, "TC-TS-006 总预算 30s = 600 片(片长上限恒 50ms)");
+ CHECK(s_delay_calls == 600, "TC-TIMESYNC-006 总预算 30s = 600 片(片长上限恒 50ms)");
}
-/* ===================== TC-TS-010..015:open_listener ===================== */
+/* ===================== TC-TIMESYNC-010..015:open_listener ===================== */
static void tc_open_listener(void) {
fakes_reset();
{
int s = time_sync_open_listener();
- CHECK(s == 5, "TC-TS-010 open_listener 成功返回 socket 描述符");
+ CHECK(s == 5, "TC-TIMESYNC-010 open_listener 成功返回 socket 描述符");
CHECK((s_socket_calls == 1) && (s_bind_calls == 1) && (s_listen_calls == 1),
- "TC-TS-010b socket / bind / listen 各一次");
- CHECK(s_htons_last == (uint16_t)TIME_SYNC_PORT, "TC-TS-010c 端口经 net_htons(8888)");
- CHECK(s_bind_port == net_htons((uint16_t)TIME_SYNC_PORT), "TC-TS-010d sin_port 为网络序");
- CHECK(s_bind_family == (uint16_t)NET_AF_INET, "TC-TS-010e sin_family = NET_AF_INET");
- CHECK(s_delay_calls == 0, "TC-TS-010f 成功路径无退避延时");
+ "TC-TIMESYNC-010b socket / bind / listen 各一次");
+ CHECK(s_htons_last == (uint16_t)TIME_SYNC_PORT, "TC-TIMESYNC-010c 端口经 net_htons(8888)");
+ CHECK(s_bind_port == net_htons((uint16_t)TIME_SYNC_PORT), "TC-TIMESYNC-010d sin_port 为网络序");
+ CHECK(s_bind_family == (uint16_t)NET_AF_INET, "TC-TIMESYNC-010e sin_family = NET_AF_INET");
+ CHECK(s_delay_calls == 0, "TC-TIMESYNC-010f 成功路径无退避延时");
}
fakes_reset();
@@ -465,10 +465,10 @@ static void tc_open_listener(void) {
s_bind_seq_n = 1;
{
int s = time_sync_open_listener();
- CHECK(s == 5, "TC-TS-011 bind 失败一次后重试成功");
- CHECK((s_close_calls == 1) && (s_close_socks[0] == 5), "TC-TS-011b bind 失败关闭该 socket");
- CHECK(s_delay_calls == 40, "TC-TS-011c bind 失败退避 2000ms(40 片)");
- CHECK(g_tstest_err_count == 1, "TC-TS-011d bind 失败留痕 DBG_ERROR");
+ CHECK(s == 5, "TC-TIMESYNC-011 bind 失败一次后重试成功");
+ CHECK((s_close_calls == 1) && (s_close_socks[0] == 5), "TC-TIMESYNC-011b bind 失败关闭该 socket");
+ CHECK(s_delay_calls == 40, "TC-TIMESYNC-011c bind 失败退避 2000ms(40 片)");
+ CHECK(g_tstest_err_count == 1, "TC-TIMESYNC-011d bind 失败留痕 DBG_ERROR");
}
fakes_reset();
@@ -476,19 +476,19 @@ static void tc_open_listener(void) {
s_listen_seq_n = 1;
{
int s = time_sync_open_listener();
- CHECK(s == 5, "TC-TS-012 listen 失败一次后重试成功");
- CHECK((s_close_calls == 1) && (s_close_socks[0] == 5), "TC-TS-012b listen 失败关闭该 socket");
- CHECK(s_delay_calls == 40, "TC-TS-012c listen 失败退避 2000ms");
+ CHECK(s == 5, "TC-TIMESYNC-012 listen 失败一次后重试成功");
+ CHECK((s_close_calls == 1) && (s_close_socks[0] == 5), "TC-TIMESYNC-012b listen 失败关闭该 socket");
+ CHECK(s_delay_calls == 40, "TC-TIMESYNC-012c listen 失败退避 2000ms");
}
fakes_reset();
s_socket_default = -1;
{
int s = time_sync_open_listener();
- CHECK(s == -1, "TC-TS-013 socket 连续失败 -> 返回 -1");
- CHECK(s_socket_calls == 5, "TC-TS-013b 重试上限 5 次");
- CHECK(g_tstest_err_count == 5, "TC-TS-013c 每次失败各留痕一条(5 条 DBG_ERROR)");
- CHECK(s_delay_calls == 50, "TC-TS-013d 每次失败退避 500ms(5 × 10 片)");
+ CHECK(s == -1, "TC-TIMESYNC-013 socket 连续失败 -> 返回 -1");
+ CHECK(s_socket_calls == 5, "TC-TIMESYNC-013b 重试上限 5 次");
+ CHECK(g_tstest_err_count == 5, "TC-TIMESYNC-013c 每次失败各留痕一条(5 条 DBG_ERROR)");
+ CHECK(s_delay_calls == 50, "TC-TIMESYNC-013d 每次失败退避 500ms(5 × 10 片)");
}
fakes_reset();
@@ -498,23 +498,23 @@ static void tc_open_listener(void) {
s_socket_seq_n = 3;
{
int s = time_sync_open_listener();
- CHECK(s == 9, "TC-TS-014 第 3 次重试成功并返回新描述符");
- CHECK(s_socket_calls == 3, "TC-TS-014b 恰好尝试 3 次");
- CHECK(s_delay_calls == 20, "TC-TS-014c 两次失败退避 500ms × 2");
+ CHECK(s == 9, "TC-TIMESYNC-014 第 3 次重试成功并返回新描述符");
+ CHECK(s_socket_calls == 3, "TC-TIMESYNC-014b 恰好尝试 3 次");
+ CHECK(s_delay_calls == 20, "TC-TIMESYNC-014c 两次失败退避 500ms × 2");
}
fakes_reset();
s_socket_default = -1;
(void)time_sync_open_listener();
- CHECK(s_beat_calls == 55, "TC-TS-015 每轮重试(5) + 每片延时(50) 各喂一次心跳");
- CHECK(s_beat_id_bad == 0, "TC-TS-015b 心跳位恒为 TASK_WD_TIMESYNC");
+ CHECK(s_beat_calls == 55, "TC-TIMESYNC-015 每轮重试(5) + 每片延时(50) 各喂一次心跳");
+ CHECK(s_beat_id_bad == 0, "TC-TIMESYNC-015b 心跳位恒为 TASK_WD_TIMESYNC");
}
-/* ===================== TC-TS-020..029:handle_conn =====================
+/* ===================== TC-TIMESYNC-020..029:handle_conn =====================
* ⚠ 契约变更:handle_conn **不再** net_close
* (单连接模式下 conn==listen,close 会连监听一起毁);会话收尾只返回外层,
* 由 time_sync_task 在 `conn != ls`(模拟器多连接后端)时才关数据 fd。
- * 故本组断言一律为 s_close_calls == 0;任务级关闭见 TC-TS-040e。 */
+ * 故本组断言一律为 s_close_calls == 0;任务级关闭见 TC-TIMESYNC-040e。 */
static void tc_handle_conn(void) {
uint8_t pkt[16];
@@ -526,13 +526,13 @@ static void tc_handle_conn(void) {
s_recv_seq_n = 1;
s_tick = 100U;
time_sync_handle_conn(7);
- CHECK(s_set_unix_calls == 1, "TC-TS-020 TIME 包一次收齐 -> 更新墙钟一次");
- CHECK(s_set_unix_last == 0x12345678u, "TC-TS-020b epoch 按大端解析");
- CHECK((s_recv_calls == 1) && (s_recv_len_log[0] == 16), "TC-TS-020c 首次请求 16 字节");
- CHECK(s_recv_to_log[0] == 50U, "TC-TS-020d 单次等待片长 = 50ms");
- CHECK(s_close_calls == 0, "TC-TS-020e 处理完**不**关闭连接(close 交外层 conn!=ls 分支)");
- CHECK(s_drop_calls == 0, "TC-TS-020g 成功会话不拆(drop 只用于放弃路径)");
- CHECK(g_tstest_info_count == 1, "TC-TS-020f 留痕 wall clock updated");
+ CHECK(s_set_unix_calls == 1, "TC-TIMESYNC-020 TIME 包一次收齐 -> 更新墙钟一次");
+ CHECK(s_set_unix_last == 0x12345678u, "TC-TIMESYNC-020b epoch 按大端解析");
+ CHECK((s_recv_calls == 1) && (s_recv_len_log[0] == 16), "TC-TIMESYNC-020c 首次请求 16 字节");
+ CHECK(s_recv_to_log[0] == 50U, "TC-TIMESYNC-020d 单次等待片长 = 50ms");
+ CHECK(s_close_calls == 0, "TC-TIMESYNC-020e 处理完**不**关闭连接(close 交外层 conn!=ls 分支)");
+ CHECK(s_drop_calls == 0, "TC-TIMESYNC-020g 成功会话不拆(drop 只用于放弃路径)");
+ CHECK(g_tstest_info_count == 1, "TC-TIMESYNC-020f 留痕 wall clock updated");
/* 2) 分段送达:4 + 4 */
fakes_reset();
@@ -541,11 +541,11 @@ static void tc_handle_conn(void) {
recv_set(1, 4, pkt + 4, 4, 10U);
s_recv_seq_n = 2;
time_sync_handle_conn(3);
- CHECK((s_set_unix_calls == 1) && (s_set_unix_last == 10u), "TC-TS-021 分段送达累积后解析正确");
- CHECK(s_recv_calls == 2, "TC-TS-021b 读了两次");
+ CHECK((s_set_unix_calls == 1) && (s_set_unix_last == 10u), "TC-TIMESYNC-021 分段送达累积后解析正确");
+ CHECK(s_recv_calls == 2, "TC-TIMESYNC-021b 读了两次");
CHECK((s_recv_len_log[0] == 16) && (s_recv_len_log[1] == 12),
- "TC-TS-021c 第二次只请求剩余 12 字节");
- CHECK((s_recv_to_log[0] == 50U) && (s_recv_to_log[1] == 50U), "TC-TS-021d 每片 50ms(预算充裕)");
+ "TC-TIMESYNC-021c 第二次只请求剩余 12 字节");
+ CHECK((s_recv_to_log[0] == 50U) && (s_recv_to_log[1] == 50U), "TC-TIMESYNC-021d 每片 50ms(预算充裕)");
/* 3) 16 字节一次到达(只取前 8) */
fakes_reset();
@@ -553,8 +553,8 @@ static void tc_handle_conn(void) {
recv_set(0, 16, pkt, 16, 0U);
s_recv_seq_n = 1;
time_sync_handle_conn(4);
- CHECK((s_set_unix_calls == 1) && (s_set_unix_last == 5u), "TC-TS-022 超长包只取前 8 字节");
- CHECK(s_recv_calls == 1, "TC-TS-022b 一次读够即停");
+ CHECK((s_set_unix_calls == 1) && (s_set_unix_last == 5u), "TC-TIMESYNC-022 超长包只取前 8 字节");
+ CHECK(s_recv_calls == 1, "TC-TIMESYNC-022b 一次读够即停");
/* 4) 前缀不是 TIME */
fakes_reset();
@@ -569,23 +569,23 @@ static void tc_handle_conn(void) {
recv_set(0, 8, pkt, 8, 0U);
s_recv_seq_n = 1;
time_sync_handle_conn(4);
- CHECK(s_set_unix_calls == 0, "TC-TS-023 非 TIME 前缀不更新墙钟");
- CHECK(s_close_calls == 0, "TC-TS-023b 非 TIME 前缀也不关闭连接");
+ CHECK(s_set_unix_calls == 0, "TC-TIMESYNC-023 非 TIME 前缀不更新墙钟");
+ CHECK(s_close_calls == 0, "TC-TIMESYNC-023b 非 TIME 前缀也不关闭连接");
/* 5) 对端关闭(EOF) */
fakes_reset();
recv_set(0, 0, NULL, 0, 0U);
s_recv_seq_n = 1;
time_sync_handle_conn(6);
- CHECK((s_set_unix_calls == 0) && (s_recv_calls == 1), "TC-TS-024 对端关闭(EOF)立即退出不解析");
- CHECK(s_close_calls == 0, "TC-TS-024b EOF 也不关闭连接(net 层 auto_relisten 收口监听)");
+ CHECK((s_set_unix_calls == 0) && (s_recv_calls == 1), "TC-TIMESYNC-024 对端关闭(EOF)立即退出不解析");
+ CHECK(s_close_calls == 0, "TC-TIMESYNC-024b EOF 也不关闭连接(net 层 auto_relisten 收口监听)");
/* 6) 真错误 */
fakes_reset();
recv_set(0, -1, NULL, 0, 0U);
s_recv_seq_n = 1;
time_sync_handle_conn(6);
- CHECK((s_recv_calls == 1) && (s_set_unix_calls == 0), "TC-TS-025 真错误立即退出不解析");
+ CHECK((s_recv_calls == 1) && (s_set_unix_calls == 0), "TC-TIMESYNC-025 真错误立即退出不解析");
/* 7) 4 字节后 EOF */
fakes_reset();
@@ -594,27 +594,27 @@ static void tc_handle_conn(void) {
recv_set(1, 0, NULL, 0, 0U);
s_recv_seq_n = 2;
time_sync_handle_conn(6);
- CHECK(s_set_unix_calls == 0, "TC-TS-026 不足 8 字节不解析");
- CHECK(s_recv_calls == 2, "TC-TS-026b 继续等待后续字节");
+ CHECK(s_set_unix_calls == 0, "TC-TIMESYNC-026 不足 8 字节不解析");
+ CHECK(s_recv_calls == 2, "TC-TIMESYNC-026b 继续等待后续字节");
/* 8) 30s 预算耗尽 */
fakes_reset();
recv_set(0, -2, NULL, 0, 30000U);
s_recv_seq_n = 1;
time_sync_handle_conn(6);
- CHECK(s_recv_calls == 1, "TC-TS-027 预算耗尽后不再读(只读 1 次)");
- CHECK(g_tstest_info_count == 1, "TC-TS-027b 留痕 no TIME packet in 30s, drop conn");
- CHECK(s_close_calls == 0, "TC-TS-027c 预算耗尽也不关闭连接");
- CHECK(s_drop_calls == 1, "TC-TS-027d 预算耗尽主动拆会话(E-02 收口:net_drop_conn 拆连接保监听)");
+ CHECK(s_recv_calls == 1, "TC-TIMESYNC-027 预算耗尽后不再读(只读 1 次)");
+ CHECK(g_tstest_info_count == 1, "TC-TIMESYNC-027b 留痕 no TIME packet in 30s, drop conn");
+ CHECK(s_close_calls == 0, "TC-TIMESYNC-027c 预算耗尽也不关闭连接");
+ CHECK(s_drop_calls == 1, "TC-TIMESYNC-027d 预算耗尽主动拆会话(E-02 收口:net_drop_conn 拆连接保监听)");
/* 9) 剩余预算不足一片 */
fakes_reset();
recv_set(0, -2, NULL, 0, 29980U);
s_recv_seq_n = 1;
time_sync_handle_conn(6);
- CHECK(s_recv_calls == 2, "TC-TS-028 两次等待后结束");
+ CHECK(s_recv_calls == 2, "TC-TIMESYNC-028 两次等待后结束");
CHECK((s_recv_to_log[0] == 50U) && (s_recv_to_log[1] == 20U),
- "TC-TS-028b 第二次片长 = 剩余 20ms");
+ "TC-TIMESYNC-028b 第二次片长 = 剩余 20ms");
/* 10) 32 位 tick 回绕 */
fakes_reset();
@@ -623,10 +623,10 @@ static void tc_handle_conn(void) {
s_recv_seq_n = 1;
time_sync_handle_conn(6);
CHECK((s_recv_calls == 2) && (s_recv_to_log[0] == 50U) && (s_recv_to_log[1] == 50U),
- "TC-TS-029 32 位 tick 回绕后预算计算仍正确");
+ "TC-TIMESYNC-029 32 位 tick 回绕后预算计算仍正确");
}
-/* ===================== TC-TS-040..044:time_sync_task ===================== */
+/* ===================== TC-TIMESYNC-040..044:time_sync_task ===================== */
static void tc_task(void) {
uint8_t pkt[16];
@@ -646,15 +646,15 @@ static void tc_task(void) {
time_sync_task(NULL);
}
CHECK((s_wd_bind_calls == 1) && (s_wd_bind_id_bad == 0),
- "TC-TS-040 任务入口登记心跳位(task_wd_bind 一次)");
- CHECK(s_evt_calls == 0, "TC-TS-040b sys_evtHandle==NULL 时跳过就绪屏障");
- CHECK(s_accept_calls == 3, "TC-TS-040c accept 轮询 3 次(2 次无连接 + 1 次成功)");
- CHECK((s_set_unix_calls == 1) && (s_set_unix_last == 9u), "TC-TS-040d 收到时间包并更新墙钟");
- CHECK(s_close_calls == 1, "TC-TS-040e 连接被关闭一次");
- CHECK(s_delay_calls == 9, "TC-TS-040f 延时片数 = 4+4+1(200+200+50ms)");
- CHECK(delays_all(50U, 9), "TC-TS-040g 所有延时均按 50ms 分片");
- CHECK(s_beat_calls == 13, "TC-TS-040h 心跳次数 = 主循环1 + 退避8 + 收连接1 + 收尾1 + 次轮1");
- CHECK(s_beat_id_bad == 0, "TC-TS-040i 所有心跳均打 TIMESYNC 位");
+ "TC-TIMESYNC-040 任务入口登记心跳位(task_wd_bind 一次)");
+ CHECK(s_evt_calls == 0, "TC-TIMESYNC-040b sys_evtHandle==NULL 时跳过就绪屏障");
+ CHECK(s_accept_calls == 3, "TC-TIMESYNC-040c accept 轮询 3 次(2 次无连接 + 1 次成功)");
+ CHECK((s_set_unix_calls == 1) && (s_set_unix_last == 9u), "TC-TIMESYNC-040d 收到时间包并更新墙钟");
+ CHECK(s_close_calls == 1, "TC-TIMESYNC-040e 连接被关闭一次");
+ CHECK(s_delay_calls == 9, "TC-TIMESYNC-040f 延时片数 = 4+4+1(200+200+50ms)");
+ CHECK(delays_all(50U, 9), "TC-TIMESYNC-040g 所有延时均按 50ms 分片");
+ CHECK(s_beat_calls == 13, "TC-TIMESYNC-040h 心跳次数 = 主循环1 + 退避8 + 收连接1 + 收尾1 + 次轮1");
+ CHECK(s_beat_id_bad == 0, "TC-TIMESYNC-040i 所有心跳均打 TIMESYNC 位");
/* B) 就绪屏障:2 次未就绪 + 1 次就绪 */
fakes_reset();
@@ -667,12 +667,12 @@ static void tc_task(void) {
if (setjmp(s_jmp) == 0) {
time_sync_task(NULL);
}
- CHECK(s_evt_calls == 3, "TC-TS-041 就绪屏障轮询 3 次(2 次未就绪 + 1 次就绪)");
- CHECK(s_evt_last_timeout == 100U, "TC-TS-041b 屏障等待按 100ms 分片");
- CHECK(s_evt_last_flags == SYS_EVT_NET_READY, "TC-TS-041c 等待 NET_READY 位");
- CHECK(s_evt_last_options == (osFlagsWaitAny | osFlagsNoClear), "TC-TS-041d 就绪位不被消费");
- CHECK(s_beat_calls == 3, "TC-TS-041e 未就绪的两次各喂一次心跳(+主循环 1 次)");
- CHECK(s_wd_bind_calls == 1, "TC-TS-041f 仍先登记心跳路由");
+ CHECK(s_evt_calls == 3, "TC-TIMESYNC-041 就绪屏障轮询 3 次(2 次未就绪 + 1 次就绪)");
+ CHECK(s_evt_last_timeout == 100U, "TC-TIMESYNC-041b 屏障等待按 100ms 分片");
+ CHECK(s_evt_last_flags == SYS_EVT_NET_READY, "TC-TIMESYNC-041c 等待 NET_READY 位");
+ CHECK(s_evt_last_options == (osFlagsWaitAny | osFlagsNoClear), "TC-TIMESYNC-041d 就绪位不被消费");
+ CHECK(s_beat_calls == 3, "TC-TIMESYNC-041e 未就绪的两次各喂一次心跳(+主循环 1 次)");
+ CHECK(s_wd_bind_calls == 1, "TC-TIMESYNC-041f 仍先登记心跳路由");
/* C) 屏障期间持续喂心跳(就绪位长期不置位) */
fakes_reset();
@@ -682,8 +682,8 @@ static void tc_task(void) {
if (setjmp(s_jmp) == 0) {
time_sync_task(NULL);
}
- CHECK(s_evt_calls == 4, "TC-TS-042 屏障等待 4 次均未就绪(循环未挂死)");
- CHECK(s_beat_calls == 3, "TC-TS-042b 每次未就绪后各喂一次心跳(第 4 次跳出前)");
+ CHECK(s_evt_calls == 4, "TC-TIMESYNC-042 屏障等待 4 次均未就绪(循环未挂死)");
+ CHECK(s_beat_calls == 3, "TC-TIMESYNC-042b 每次未就绪后各喂一次心跳(第 4 次跳出前)");
/* D) 网络代次变化 -> 关闭旧监听并重监听 */
fakes_reset();
@@ -695,12 +695,12 @@ static void tc_task(void) {
if (setjmp(s_jmp) == 0) {
time_sync_task(NULL);
}
- CHECK((s_close_calls == 1) && (s_close_socks[0] == 5), "TC-TS-043 代次变化时关闭旧监听");
+ CHECK((s_close_calls == 1) && (s_close_socks[0] == 5), "TC-TIMESYNC-043 代次变化时关闭旧监听");
/* INFO 三条:两次 open_listener 成功各一条 "TCP listen on" + 一条 "network re-init, relisten" */
- CHECK(g_tstest_info_count == 3, "TC-TS-043b 留痕 network re-init, relisten(另含 2 条 listen 成功)");
- CHECK(s_accept_calls == 2, "TC-TS-043c 每次循环只轮询一次 accept 即放弃");
+ CHECK(g_tstest_info_count == 3, "TC-TIMESYNC-043b 留痕 network re-init, relisten(另含 2 条 listen 成功)");
+ CHECK(s_accept_calls == 2, "TC-TIMESYNC-043c 每次循环只轮询一次 accept 即放弃");
CHECK((s_socket_calls == 2) && (s_bind_calls == 2) && (s_listen_calls == 2),
- "TC-TS-043d 第二次循环重建了监听");
+ "TC-TIMESYNC-043d 第二次循环重建了监听");
/* E) 监听建立失败 -> 5 次重试后放弃并退避 2000ms */
fakes_reset();
@@ -709,11 +709,11 @@ static void tc_task(void) {
if (setjmp(s_jmp) == 0) {
time_sync_task(NULL);
}
- CHECK(s_socket_calls == 5, "TC-TS-044 open_listener 内部重试 5 次后放弃");
- CHECK(g_tstest_err_count == 6, "TC-TS-044b 5 条 net_socket FAIL + 1 条 retry later");
- CHECK(s_delay_calls == 90, "TC-TS-044c 退避 5×500ms + 2000ms = 90 片");
- CHECK(s_beat_calls == 97, "TC-TS-044d 心跳次数 = 2 + 5 + 50 + 40");
- CHECK(s_beat_id_bad == 0, "TC-TS-044e 所有心跳均打 TIMESYNC 位");
+ CHECK(s_socket_calls == 5, "TC-TIMESYNC-044 open_listener 内部重试 5 次后放弃");
+ CHECK(g_tstest_err_count == 6, "TC-TIMESYNC-044b 5 条 net_socket FAIL + 1 条 retry later");
+ CHECK(s_delay_calls == 90, "TC-TIMESYNC-044c 退避 5×500ms + 2000ms = 90 片");
+ CHECK(s_beat_calls == 97, "TC-TIMESYNC-044d 心跳次数 = 2 + 5 + 50 + 40");
+ CHECK(s_beat_id_bad == 0, "TC-TIMESYNC-044e 所有心跳均打 TIMESYNC 位");
}
/* ===================== main ===================== */
diff --git a/test/host/vol_lock/vol_lock_test.c b/test/host/vol_lock/vol_lock_test.c
index 5c48416d..d2f74c3a 100644
--- a/test/host/vol_lock/vol_lock_test.c
+++ b/test/host/vol_lock/vol_lock_test.c
@@ -16,20 +16,20 @@
* 3. 不占 MCU 的 RAM,毫秒级完成。
*
* 覆盖点:
- * TC-VL-001 init 首次调用创建互斥量并返回 0
- * TC-VL-002 init 幂等(重复调用不再创建)
- * TC-VL-003 init 在 osMutexNew 失败时返回 -1
- * TC-VL-004 init 失败后可重试成功(s_lock 未被污染)
- * TC-VL-005 wait 成功后返回 1,且把 timeout 原样透传给 osMutexWait
- * TC-VL-006 wait 超时(osMutexWait != osOK)返回 0
- * TC-VL-007 wait 在锁未创建时自动 init,再正常获取
- * TC-VL-008 ⭐ fail-open:锁未创建且创建失败 -> 返回 1 且**不调用** osMutexWait
- * TC-VL-009 fail-open 之后 release 无害(s_lock 仍为 NULL,不调用 osMutexRelease)
- * TC-VL-010 已创建时 wait 不再调用 osMutexNew
- * TC-VL-011 release 在已持锁时调用 osMutexRelease 一次
- * TC-VL-012 release 在锁未创建时静默返回(不崩溃、不调用)
- * TC-VL-013 完整周期 init -> wait -> release -> wait -> release
- * TC-VL-014 wait(0) 的 timeout 透传为 0(defaultTask 的 try 语义)
+ * TC-VOLLOCK-001 init 首次调用创建互斥量并返回 0
+ * TC-VOLLOCK-002 init 幂等(重复调用不再创建)
+ * TC-VOLLOCK-003 init 在 osMutexNew 失败时返回 -1
+ * TC-VOLLOCK-004 init 失败后可重试成功(s_lock 未被污染)
+ * TC-VOLLOCK-005 wait 成功后返回 1,且把 timeout 原样透传给 osMutexWait
+ * TC-VOLLOCK-006 wait 超时(osMutexWait != osOK)返回 0
+ * TC-VOLLOCK-007 wait 在锁未创建时自动 init,再正常获取
+ * TC-VOLLOCK-008 ⭐ fail-open:锁未创建且创建失败 -> 返回 1 且**不调用** osMutexWait
+ * TC-VOLLOCK-009 fail-open 之后 release 无害(s_lock 仍为 NULL,不调用 osMutexRelease)
+ * TC-VOLLOCK-010 已创建时 wait 不再调用 osMutexNew
+ * TC-VOLLOCK-011 release 在已持锁时调用 osMutexRelease 一次
+ * TC-VOLLOCK-012 release 在锁未创建时静默返回(不崩溃、不调用)
+ * TC-VOLLOCK-013 完整周期 init -> wait -> release -> wait -> release
+ * TC-VOLLOCK-014 wait(0) 的 timeout 透传为 0(defaultTask 的 try 语义)
*
* 通过:全部 TC PASS(main 返回 0)。
* 入口:int main(void),返回 0=PASS / 1=FAIL(由 run 脚本判读)。
@@ -110,76 +110,76 @@ static void fakes_reset(void) {
s_lock = NULL;
}
-/* ===================== TC-VL-001..004:vol_lock_init ===================== */
+/* ===================== TC-VOLLOCK-001..004:vol_lock_init ===================== */
static void tc_init(void) {
fakes_reset();
- CHECK(vol_lock_init() == 0, "TC-VL-001 init 首次调用返回 0");
- CHECK(s_new_calls == 1, "TC-VL-001b init 创建互斥量一次(osMutexNew)");
- CHECK(s_lock != NULL, "TC-VL-001c 模块静态态已持有句柄");
+ CHECK(vol_lock_init() == 0, "TC-VOLLOCK-001 init 首次调用返回 0");
+ CHECK(s_new_calls == 1, "TC-VOLLOCK-001b init 创建互斥量一次(osMutexNew)");
+ CHECK(s_lock != NULL, "TC-VOLLOCK-001c 模块静态态已持有句柄");
- CHECK(vol_lock_init() == 0, "TC-VL-002 init 重复调用仍返回 0(幂等)");
- CHECK(s_new_calls == 1, "TC-VL-002b 幂等:不再创建第二个互斥量");
+ CHECK(vol_lock_init() == 0, "TC-VOLLOCK-002 init 重复调用仍返回 0(幂等)");
+ CHECK(s_new_calls == 1, "TC-VOLLOCK-002b 幂等:不再创建第二个互斥量");
fakes_reset();
s_new_fail = 1;
- CHECK(vol_lock_init() == -1, "TC-VL-003 osMutexNew 失败 -> init 返回 -1");
- CHECK(s_lock == NULL, "TC-VL-003b 失败时不留下半初始化句柄");
+ CHECK(vol_lock_init() == -1, "TC-VOLLOCK-003 osMutexNew 失败 -> init 返回 -1");
+ CHECK(s_lock == NULL, "TC-VOLLOCK-003b 失败时不留下半初始化句柄");
s_new_fail = 0;
- CHECK(vol_lock_init() == 0, "TC-VL-004 失败后重试可成功(返回 0)");
- CHECK(s_new_calls == 2, "TC-VL-004b 重试确实再次调用 osMutexNew");
+ CHECK(vol_lock_init() == 0, "TC-VOLLOCK-004 失败后重试可成功(返回 0)");
+ CHECK(s_new_calls == 2, "TC-VOLLOCK-004b 重试确实再次调用 osMutexNew");
}
-/* ===================== TC-VL-005..010:vol_lock_wait ===================== */
+/* ===================== TC-VOLLOCK-005..010:vol_lock_wait ===================== */
static void tc_wait(void) {
/* --- 已创建:超时值原样透传 --- */
fakes_reset();
(void)vol_lock_init();
- CHECK(vol_lock_wait(100U) == 1, "TC-VL-005 wait 获取成功返回 1");
- CHECK(s_wait_calls == 1, "TC-VL-005b osMutexWait 被调用一次");
- CHECK(s_last_timeout == 100U, "TC-VL-005c timeout 原样透传给 osMutexWait");
+ CHECK(vol_lock_wait(100U) == 1, "TC-VOLLOCK-005 wait 获取成功返回 1");
+ CHECK(s_wait_calls == 1, "TC-VOLLOCK-005b osMutexWait 被调用一次");
+ CHECK(s_last_timeout == 100U, "TC-VOLLOCK-005c timeout 原样透传给 osMutexWait");
fakes_reset();
(void)vol_lock_init();
- CHECK(vol_lock_wait(0U) == 1, "TC-VL-014 wait(0) 获取成功返回 1(try 语义)");
- CHECK(s_last_timeout == 0U, "TC-VL-014b wait(0) 的 timeout 透传为 0");
+ CHECK(vol_lock_wait(0U) == 1, "TC-VOLLOCK-014 wait(0) 获取成功返回 1(try 语义)");
+ CHECK(s_last_timeout == 0U, "TC-VOLLOCK-014b wait(0) 的 timeout 透传为 0");
/* --- 超时:osMutexWait != osOK -> 返回 0 --- */
fakes_reset();
(void)vol_lock_init();
s_wait_ok = 0;
- CHECK(vol_lock_wait(50U) == 0, "TC-VL-006 osMutexWait 非 osOK -> wait 返回 0");
- CHECK(s_wait_calls == 1, "TC-VL-006b 超时路径确实尝试过等待");
+ CHECK(vol_lock_wait(50U) == 0, "TC-VOLLOCK-006 osMutexWait 非 osOK -> wait 返回 0");
+ CHECK(s_wait_calls == 1, "TC-VOLLOCK-006b 超时路径确实尝试过等待");
/* --- 锁未创建:自动 init 后正常获取 --- */
fakes_reset();
- CHECK(vol_lock_wait(10U) == 1, "TC-VL-007 锁未创建时 wait 自动 init 并获取");
- CHECK(s_new_calls == 1, "TC-VL-007b 自动 init 创建了互斥量");
- CHECK(s_wait_calls == 1, "TC-VL-007c 随后执行了一次等待");
+ CHECK(vol_lock_wait(10U) == 1, "TC-VOLLOCK-007 锁未创建时 wait 自动 init 并获取");
+ CHECK(s_new_calls == 1, "TC-VOLLOCK-007b 自动 init 创建了互斥量");
+ CHECK(s_wait_calls == 1, "TC-VOLLOCK-007c 随后执行了一次等待");
/* --- ⭐ fail-open:创建失败必须返回 1 且绝不阻塞 --- */
fakes_reset();
s_new_fail = 1;
- CHECK(vol_lock_wait(0U) == 1, "TC-VL-008 fail-open:锁创建失败仍返回 1(不阻塞喂狗点)");
- CHECK(s_wait_calls == 0, "TC-VL-008b fail-open 时**不调用** osMutexWait(零阻塞)");
- CHECK(s_lock == NULL, "TC-VL-008c fail-open 后仍无句柄");
+ CHECK(vol_lock_wait(0U) == 1, "TC-VOLLOCK-008 fail-open:锁创建失败仍返回 1(不阻塞喂狗点)");
+ CHECK(s_wait_calls == 0, "TC-VOLLOCK-008b fail-open 时**不调用** osMutexWait(零阻塞)");
+ CHECK(s_lock == NULL, "TC-VOLLOCK-008c fail-open 后仍无句柄");
/* --- fail-open 之后 release 无害 --- */
vol_lock_release();
- CHECK(s_release_calls == 0, "TC-VL-009 fail-open 后 release 不调用 osMutexRelease(判空静默)");
+ CHECK(s_release_calls == 0, "TC-VOLLOCK-009 fail-open 后 release 不调用 osMutexRelease(判空静默)");
/* --- 已创建时 wait 不再创建 --- */
fakes_reset();
(void)vol_lock_init();
(void)vol_lock_wait(0U);
(void)vol_lock_wait(0U);
- CHECK(s_new_calls == 1, "TC-VL-010 多次 wait 不重复创建互斥量");
- CHECK(s_wait_calls == 2, "TC-VL-010b 每次 wait 各等待一次");
+ CHECK(s_new_calls == 1, "TC-VOLLOCK-010 多次 wait 不重复创建互斥量");
+ CHECK(s_wait_calls == 2, "TC-VOLLOCK-010b 每次 wait 各等待一次");
}
-/* ===================== TC-VL-011..013:vol_lock_release ===================== */
+/* ===================== TC-VOLLOCK-011..013:vol_lock_release ===================== */
static void tc_release(void) {
/* --- 已持锁:释放一次 --- */
@@ -187,23 +187,23 @@ static void tc_release(void) {
(void)vol_lock_init();
(void)vol_lock_wait(0U);
vol_lock_release();
- CHECK(s_release_calls == 1, "TC-VL-011 已持锁时 release 调用 osMutexRelease 一次");
+ CHECK(s_release_calls == 1, "TC-VOLLOCK-011 已持锁时 release 调用 osMutexRelease 一次");
/* --- 锁未创建:静默返回 --- */
fakes_reset();
vol_lock_release();
- CHECK(s_release_calls == 0, "TC-VL-012 锁未创建时 release 静默返回(不调用、不崩溃)");
+ CHECK(s_release_calls == 0, "TC-VOLLOCK-012 锁未创建时 release 静默返回(不调用、不崩溃)");
/* --- 完整周期 --- */
fakes_reset();
- CHECK(vol_lock_init() == 0, "TC-VL-013 周期:init -> 0");
- CHECK(vol_lock_wait(0U) == 1, "TC-VL-013b 周期:wait -> 1");
+ CHECK(vol_lock_init() == 0, "TC-VOLLOCK-013 周期:init -> 0");
+ CHECK(vol_lock_wait(0U) == 1, "TC-VOLLOCK-013b 周期:wait -> 1");
vol_lock_release();
- CHECK(vol_lock_wait(100U) == 1, "TC-VL-013c 周期:再 wait -> 1(可重复获取)");
+ CHECK(vol_lock_wait(100U) == 1, "TC-VOLLOCK-013c 周期:再 wait -> 1(可重复获取)");
vol_lock_release();
- CHECK(s_new_calls == 1, "TC-VL-013d 周期:全程只创建一次互斥量");
- CHECK(s_release_calls == 2, "TC-VL-013e 周期:释放两次");
- CHECK(s_last_timeout == 100U, "TC-VL-013f 周期:第二次 wait 的 timeout 透传正确");
+ CHECK(s_new_calls == 1, "TC-VOLLOCK-013d 周期:全程只创建一次互斥量");
+ CHECK(s_release_calls == 2, "TC-VOLLOCK-013e 周期:释放两次");
+ CHECK(s_last_timeout == 100U, "TC-VOLLOCK-013f 周期:第二次 wait 的 timeout 透传正确");
}
/* ===================== main ===================== */
diff --git a/test/host/watchdog/watchdog_test.c b/test/host/watchdog/watchdog_test.c
index 4df4bd3a..5755408b 100644
--- a/test/host/watchdog/watchdog_test.c
+++ b/test/host/watchdog/watchdog_test.c
@@ -11,19 +11,19 @@
* 把模块静态态恢复到"刚上电"。
*
* 覆盖点(对应 docs/测试说明/看门狗单元测试说明.md 的 TC-WD-xxx):
- * TC-WD-001 未启动时 poll 不做任何判定(也不喂狗)
- * TC-WD-002 节流:< 100ms 的 poll 直接返回
- * TC-WD-003 全员到位置位 → 喂狗一次,且位图取走清零
- * TC-WD-004 取走清零语义:旧位不残留(下一轮必须重新置位)
- * TC-WD-005 掩码判定:缺任一位不喂,last_mask 精确记录
- * TC-WD-006 连续 1..7 次缺席不喂不报;第 8 次打 [WD] task stall
- * TC-WD-007 停喂后 stall 日志持续复报(现状行为,见用例内说明)
- * TC-WD-008 恢复:重新全员到位 → 喂狗 + streak 归零
- * TC-WD-009 节流窗口边界 99/100/199/200
- * TC-WD-010 tick 回绕安全(无符号差)
- * TC-WD-011 观测接口:last_mask / is_armed
- * TC-WD-013 非法任务 ID 被忽略(防位图越界)
- * TC-WD-014 start 幂等
+ * TC-WATCHDOG-001 未启动时 poll 不做任何判定(也不喂狗)
+ * TC-WATCHDOG-002 节流:< 100ms 的 poll 直接返回
+ * TC-WATCHDOG-003 全员到位置位 → 喂狗一次,且位图取走清零
+ * TC-WATCHDOG-004 取走清零语义:旧位不残留(下一轮必须重新置位)
+ * TC-WATCHDOG-005 掩码判定:缺任一位不喂,last_mask 精确记录
+ * TC-WATCHDOG-006 连续 1..7 次缺席不喂不报;第 8 次打 [WD] task stall
+ * TC-WATCHDOG-007 停喂后 stall 日志持续复报(现状行为,见用例内说明)
+ * TC-WATCHDOG-008 恢复:重新全员到位 → 喂狗 + streak 归零
+ * TC-WATCHDOG-009 节流窗口边界 99/100/199/200
+ * TC-WATCHDOG-010 tick 回绕安全(无符号差)
+ * TC-WATCHDOG-011 观测接口:last_mask / is_armed
+ * TC-WATCHDOG-013 非法任务 ID 被忽略(防位图越界)
+ * TC-WATCHDOG-014 start 幂等
*
* 通过:全部 TC PASS(main 返回 0)。
* 入口:int main(void),返回 0=PASS / 1=FAIL(由 run 脚本判读)。
@@ -108,7 +108,7 @@ static void poll_advance(uint32_t ms) {
/*
* 启动并清空喂狗计数:task_wd_start() 内部会先喂一次(让首个抽样窗口从启动
- * 时刻起算,见生产代码注释),该次喂狗由 TC-WD-015 单独断言;其余用例只关心
+ * 时刻起算,见生产代码注释),该次喂狗由 TC-WATCHDOG-015 单独断言;其余用例只关心
* "启动之后 poll 的喂狗行为",故此处把计数归零。
*/
static void start_and_clear(void) {
@@ -131,7 +131,7 @@ static void beat_all(void) {
/* ===================== 用例 ===================== */
static void tc_001_not_armed(void) {
- printf("TC-WD-001 未启动时 poll 不做判定\n");
+ printf("TC-WATCHDOG-001 未启动时 poll 不做判定\n");
beat_all();
poll_advance(1000);
CHECK(s_feed_count == 0, "未启动时 poll 不喂狗");
@@ -139,7 +139,7 @@ static void tc_001_not_armed(void) {
}
static void tc_002_throttle(void) {
- printf("TC-WD-002 节流:< 100ms 直接返回\n");
+ printf("TC-WATCHDOG-002 节流:< 100ms 直接返回\n");
start_and_clear();
beat_all();
poll_advance(50); /* 50ms < 100ms → 不抽样 */
@@ -149,7 +149,7 @@ static void tc_002_throttle(void) {
}
static void tc_003_all_beat_feeds(void) {
- printf("TC-WD-003 全员到位 → 喂狗一次\n");
+ printf("TC-WATCHDOG-003 全员到位 → 喂狗一次\n");
start_and_clear();
beat_all();
poll_advance(100);
@@ -158,7 +158,7 @@ static void tc_003_all_beat_feeds(void) {
}
static void tc_004_take_and_clear(void) {
- printf("TC-WD-004 取走清零:旧位不残留\n");
+ printf("TC-WATCHDOG-004 取走清零:旧位不残留\n");
start_and_clear();
beat_all();
poll_advance(100); /* 消费位图并喂狗 */
@@ -168,7 +168,7 @@ static void tc_004_take_and_clear(void) {
}
static void tc_005_mask_required(void) {
- printf("TC-WD-005 掩码判定:缺任一位不喂\n");
+ printf("TC-WATCHDOG-005 掩码判定:缺任一位不喂\n");
start_and_clear();
/* 故意缺 UI(bit4) */
task_wd_beat(TASK_WD_DEFAULT);
@@ -185,7 +185,7 @@ static void tc_005_mask_required(void) {
}
static void tc_006_stall_8(void) {
- printf("TC-WD-006 连续 8 次缺席 → 打 stall 并停喂\n");
+ printf("TC-WATCHDOG-006 连续 8 次缺席 → 打 stall 并停喂\n");
start_and_clear();
beat_all(); poll_advance(100); /* streak 清零 */
int err0 = g_wdtest_err_count;
@@ -199,7 +199,7 @@ static void tc_006_stall_8(void) {
}
static void tc_007_stall_repeats_until_reset(void) {
- printf("TC-WD-007 停喂后 stall 日志持续复报(当前设计:每 100ms 一条)\n");
+ printf("TC-WATCHDOG-007 停喂后 stall 日志持续复报(当前设计:每 100ms 一条)\n");
start_and_clear();
for (int i = 0; i < 8; i++) poll_advance(100); /* 第 8 次触发 */
int err8 = g_wdtest_err_count;
@@ -217,7 +217,7 @@ static void tc_007_stall_repeats_until_reset(void) {
}
static void tc_008_recover(void) {
- printf("TC-WD-008 恢复:重新全员到位 → 喂狗 + streak 归零\n");
+ printf("TC-WATCHDOG-008 恢复:重新全员到位 → 喂狗 + streak 归零\n");
start_and_clear();
for (int i = 0; i < 8; i++) poll_advance(100); /* 触发 stall */
beat_all();
@@ -229,7 +229,7 @@ static void tc_008_recover(void) {
}
static void tc_009_throttle_boundary(void) {
- printf("TC-WD-009 节流窗口边界 99/100/199/200\n");
+ printf("TC-WATCHDOG-009 节流窗口边界 99/100/199/200\n");
start_and_clear();
beat_all();
poll_advance(99); CHECK(s_feed_count == 0, "99ms 不判");
@@ -240,7 +240,7 @@ static void tc_009_throttle_boundary(void) {
}
static void tc_010_tick_wrap(void) {
- printf("TC-WD-010 tick 回绕安全\n");
+ printf("TC-WATCHDOG-010 tick 回绕安全\n");
start_and_clear();
s_tick = 0xFFFFFF00u; /* 推到接近 2^32 回绕 */
task_wd_poll(); /* 建立基线(此处可能不判,取决节流) */
@@ -251,7 +251,7 @@ static void tc_010_tick_wrap(void) {
}
static void tc_011_observers(void) {
- printf("TC-WD-011 观测接口语义\n");
+ printf("TC-WATCHDOG-011 观测接口语义\n");
start_and_clear();
CHECK(task_wd_is_armed() == 1, "is_armed == 1(已启动)");
beat_all();
@@ -261,7 +261,7 @@ static void tc_011_observers(void) {
}
static void tc_013_bad_id(void) {
- printf("TC-WD-013 非法任务 ID 被忽略\n");
+ printf("TC-WATCHDOG-013 非法任务 ID 被忽略\n");
start_and_clear();
task_wd_beat((task_wd_id_t)(TASK_WD_ID_MAX + 3)); /* 非法:应被忽略 */
poll_advance(100);
@@ -270,7 +270,7 @@ static void tc_013_bad_id(void) {
}
static void tc_014_start_idempotent(void) {
- printf("TC-WD-014 start 幂等\n");
+ printf("TC-WATCHDOG-014 start 幂等\n");
task_wd_start();
task_wd_start();
CHECK(s_start_count == 1, "重复 start 只启动 IWDG 一次");
@@ -278,14 +278,14 @@ static void tc_014_start_idempotent(void) {
}
static void tc_015_start_feeds_once(void) {
- printf("TC-WD-015 start 先喂一次(首个窗口从启动时刻起算)\n");
+ printf("TC-WATCHDOG-015 start 先喂一次(首个窗口从启动时刻起算)\n");
task_wd_start();
CHECK(s_start_count == 1, "start 启动 IWDG 一次");
CHECK(s_feed_count == 1, "start 内部先喂狗一次(避免启动即超时)");
}
static void tc_016_stall_not_armed_no_feed(void) {
- printf("TC-WD-016 未启动时即便全员到位也不喂\n");
+ printf("TC-WATCHDOG-016 未启动时即便全员到位也不喂\n");
/* 未 start:poll 直接返回 */
beat_all();
poll_advance(500);