diff --git a/docs/测试说明/主机单测覆盖率口径.md b/docs/测试说明/主机单测覆盖率口径.md index 6a858451..22615d1d 100644 --- a/docs/测试说明/主机单测覆盖率口径.md +++ b/docs/测试说明/主机单测覆盖率口径.md @@ -29,7 +29,7 @@ | gcc / gcov / clang / llvm-cov / lcov / gcovr(**Windows 原生侧**) | PATH 上没有;再全盘扫 `Program Files*`、`C:\msys64`、`scoop`、choco、`.platformio`、`%LOCALAPPDATA%\Programs` → **0 处**(OpenCppCoverage 也没有) | Windows 侧走不了 gcov 这条最主流的路(但 WSL 里有,见 §2.1) | | `cl /coverage`、`cl /fsanitize=coverage` | **MSVC 14.51 已不认**:只报 `warning D9002: 忽略未知选项`,**然后照常编译成功** | ⚠ 最阴的一种:不报错、静默没有插桩 → 覆盖率恒为 0 或假数据,绝不可用 | | `Team Tools\Dynamic Code Coverage Tools\CodeCoverage.exe`(17.0) | 文件在,但 `collect` / `analyze` / `instrument` **一律只打印"用法: CodeCoverage "** 并返回 -1 | 已 deprecated 且子命令不可用 | -| **`Microsoft.CodeCoverage.Console.exe`**(mscoverage 18.x,随 VS 装在 `Common7\IDE\Extensions\Microsoft\CodeCoverage.Console\`) | `collect -f cobertura` 直接吃 MSVC 原生 exe + PDB,产出标准 Cobertura XML;**子进程退出码原样透传**(实测子进程 `return 3` → `collect` 也返回 3) | ✅ **本脚本用它**("加载期动态插桩",不是编译期插桩) | +| **`Microsoft.CodeCoverage.Console.exe`**(mscoverage 18.x,随 VS 装在 `Common7\IDE\Extensions\Microsoft\CodeCoverage.Console`) | `collect -f cobertura` 直接吃 MSVC 原生 exe + PDB,产出标准 Cobertura XML;**子进程退出码原样透传**(实测子进程 `return 3` → `collect` 也返回 3) | ✅ **本脚本用它**("加载期动态插桩",不是编译期插桩) | ### 2.1 GCC 到底行不行:能编、能跑、**能出分支覆盖**——结论是**不用**(换编译器就是换分母) @@ -50,7 +50,7 @@ 分支这一维——不值当。代价如实记在 §7 第 1 条:本口径的绿灯**只证明行与函数被测到**。 探测顺序:环境变量 `DTU_MS_COVERAGE`(设了就必须有效,**不静默回退**,与 `DTU_MSVC_CL` 同口径) -→ 各 VS 安装根的 `Common7\IDE\Extensions\Microsoft\CodeCoverage.Console\` → PATH。 +→ 各 VS 安装根的 `Common7\IDE\Extensions\Microsoft\CodeCoverage.Console` → PATH。 找不到即以退出码 2 失败并打印上述现实,**不会**假装通过。 ## 3. 怎么跑 @@ -77,7 +77,7 @@ 退出码:`0` 全过且无回退 / `1` 有单测失败或覆盖率回退 / `2` 环境错误(无 cl、无 mscoverage、 编译失败、XML 缺失)/ `3` 用法错误。全量实测约 **25 s**(16 套 × 编译 + 插桩运行)。 -中间产物(exe / PDB / Cobertura XML)一律落 `%TEMP%\dtu_test_cov\<模块>\`,**不进仓库**, +中间产物(exe / PDB / Cobertura XML)一律落 `%TEMP%\dtu_test_cov\<模块>`,**不进仓库**, 所以本脚本不需要新增任何 `.gitignore` 规则。 ## 4. 统计面:进什么、不进什么 @@ -153,7 +153,7 @@ 7. **头文件里的代码归 `.h`。** 统计面含 `.h`(静态内联与被展开的行落在头文件上);当前 16 套 几乎没触及 `.h`,表里看不到它们——不要以为头文件"天生 100%"。 8. **依赖 `Microsoft.CodeCoverage.Console.exe`。** 探测顺序:`DTU_MS_COVERAGE`(设了就必须 - 有效、**不静默回退**)→ 各 VS 安装根的 `Common7\IDE\Extensions\Microsoft\CodeCoverage.Console\` → + 有效、**不静默回退**)→ 各 VS 安装根的 `Common7\IDE\Extensions\Microsoft\CodeCoverage.Console` → PATH;找不到即退出码 2(**不是 0**)。2026-10-24 起该结果直接红掉 `test-coverage` 钩子(用户裁定 FAIL 语义),并已合成自证:把 `DTU_MS_COVERAGE` 指到一个不存在的文件 → 钩子 Failed、脚本退出码 2、 打印可执行的 `[ENV]` 提示。 @@ -550,9 +550,92 @@ uint16_t ch395f_link_change_count(void); 7. **新增断言要用「逐条退回生产码」验一次牙**(变异自证):把四条修复逐条退回旧实现,失败集合单调增长 6 → 11 → 18 → 22 条、每步都是上一步的超集,改回即 127/127 全绿——**没有这一步,一条空转断言就要被交上去**。 8. **任务书里给的临时缺陷标签会被编号门禁当自造编号拦**——本批 Lead 在任务书里用的两个「单字母+连字符+序号」临时标签被原样抄进生产注释,一次冒出 8 类台账外错误(连本文档举这个反例时把字面量写出来,都会被同一根闸再拦一次,故此处只能描述形态、不能给样例)。纪律:**Lead 给的内部标签不得写进代码**,注释只写行为(如「两套 IP 字节序统一为 POSIX 网络序」),要指用例就指已登记的 `TC-*` 号。 +### 第 2 轮:测试字面量统一纯 ASCII(2026-10-24,单独一次提交) + +用户裁定「统一」。口径来自 AGENTS 铁律「**字符串字面量必须纯 ASCII**」(无 BOM 文件里奇数个汉字会吞掉结束引号, +偶数才侥幸通过)——**中文只写注释**。四名工人按目录分四组并行、写范围互斥,25 套 / 30 个 `.c` 全部改完。 + +**两套口径必须分清(本轮最大的方法论收获)**: + +| 口径 | 做法 | 结果 | 用途 | +|---|---|---|---| +| 粗口径(普查) | 按行切引号,跳过以 `*` / `//` / `/*` 开头的行 | 34 文件 / **1,552** 行 | 判断"谁还没动" | +| 严格口径(交付判据) | 状态机把块/行注释替换成**等宽空格**(保住行列)后再取字符串字面量判 `ord>127` | 30 文件 / **1,535** 行 | 交付与验收 | + +差值 = **4 个文件的命中全在注释里**(`net_socket/ns_peers.c`、`net_socket/stub/ns_rtos.h`、 +`common/ch395f_fake.h`、`common/fatfs_fake.c`:行尾或块注释续行里的中文 + ASCII 引号)——**一处都不该改**, +改了等于把中文从注释里搬走、正好违背口径。教训写死成纪律:**粗口径绝不能当交付判据**,否则要么白改注释、 +要么留下"这行为什么没改"的悬案(本批两名工人各自独立撞见并如实上报,没有一人硬凑数字)。 + +**Lead 独立终检(不采信自报)五条硬判据 → 30 文件漂移 0**: + +1. 每个文件的 **TC 号集合**与 HEAD 逐字相同(防"改标签顺手改号"与"批量替换串位"); +2. **断言宏调用点数**(`CHECK`/`ASSERT` 等)与 HEAD 相同; +3. **行数与 HEAD 完全相等**——这条专抓 `read` 全文回写把尾部(含 `main()`)吃掉的截断,第 1 轮真发生过两次; +4. **剥注释后代码区非 ASCII 字符 = 0**(含字符字面量),残留必须归零; +5. 字节卫生:BOM 与 HEAD 一致、无 CR、无 U+FFFD、末尾恰好一个换行。 +另用一条更硬的机械证明替代"眼看 diff":**逐行把两侧字面量整体替换成空串后,工作版与 HEAD 必须逐行相等** +(`only string literals changed`)——任何落到引号外的差异当场失败。 + +**"没手滑动逻辑"的证据 = 覆盖率复量逐字不变**:各套 `--module` 与基线一致(`net_socket` 887/889·53/53、 +`console_log` 199/200·16/16、`sys_log_mcu` 324/326·13/13、`cfg_file_store_mcu` 97/97·10/10、 +`net_listener` 125/126、`lftpd` 304/473、`iec104_link` 367/405 …);每套 runner 的断言数改前后相同 +(如 `iec104` 97/97、`sys_clock` 100/100、`adc_input` 103/103、`net_cfg` 45/45)。**基线本轮不需要重登**(生产码零改动)。 + +⚠ **`@build` 对本轮没有覆盖力**:`test/host/**` 不进 Keil 编译面也不进模拟器 CMake,字面量改动只能靠 +16 个 `*-unit-test` 钩子 + `test-cppcheck` + `test-coverage` 这三根闸验证——**别把"编译过了"当测试面改动的证据**。 + +**本轮新手法(值得抄进任何"批量改标签"作业)**: + +1. **TC 号逐字相等守卫**:从文件字节取原文(不手敲),提取原文与译文各自的 TC 号要求**逐字相等**,不等即拒绝写入。 + 它拦下的是「测试标签与被测事实错位」——断言照样绿,却永久指向错误的号位(本轮真的拦下一次 092 被写成 093)。 +2. **批量替换的键必须是内容,不能是顺序/位置**:按位置对齐 HEAD 与工作版会在字面量数量不等时**串位污染** + (本轮真实发生过:`net_inet_addr("255.255.255.255")` 被换成一条断言名)。正确做法是 HEAD 字节 + 按字面量文本精确匹配, + **凡未命中映射且含非 ASCII 的字面量直接报错终止**,其余字节一字节不动。 +3. **自查至少要有一维能发现「自己多改了东西」**:残留计数 + 改动形状(不含引号的改动行 = 0)+ 行数与 HEAD 对比,三样缺一就漏。 + 本轮暴露事故的正是"残留本该 0 却报 11"——只看 rc 与断言条数会一路放行到提交。 +4. **新串必须「不引入任何编号形态」**(本批真实翻车点):一句 `CHECK` 的英文标签里被写回了一条**已登记族之外**的「单字母+连字符+序号」编号, + 而 HEAD 那行早就在上一轮整改中把它换成了平实描述——**翻译等于把债重新引进来**。批量翻译的守卫除「原文与译文 TC 号逐字相等」之外, + 还必须断言「新串不得出现任何 已登记前缀族之外 的编号形态」(字母+连字符+数字一律拦)。 + ⚠ 同时暴露一条验收口径的教训:Lead 的自动验收器只比对了 `TC-*` 形的 id 集合,**没覆盖其它已登记族**(L 系 / E 系 / N 系 / S 系 / TRAP 系编号), + 这一条是**编号门禁闸**拦下来的,不是我的验收器——「结构不变式」只覆盖自己想到的维度时,绝不能替代真闸。 + ⚠ 写这条手法时,Lead 又把该编号的字面量当样例写进本文档、被同一根闸再拦一次(第 1 轮举临时标签反例时已中过一次)。**结论:门禁不看语境,文档举例只能描述形态、不能贴字面量。** +5. **替换说明符不变量(比「禁止裸 `%`」更强)**:新旧字面量的**转换说明符序列必须逐位相同**(个数/顺序/宽度一致)。 + 「禁止新增 `%`」只挡一半——丢了 `%` 是 UB(实参没被消费)、多了也是 UB(多消费栈垃圾),而逼人把 `%` 写成 `%%` + 等于把说明符偷偷变成字面文本,编译器最多给个 C4473 就放过。另注:断言名是当**实参**打印的,本身不会被二次解释, + 真正要防的是「标签被当格式串」的实现——批量改标签前顺手扫一眼宏定义。 +6. **生成脚本的脚本,转义层数会翻倍**:经模板字符串生成 Python 源码时正则里的 `\\s` 被吃成字面量反斜杠+s,正则永不匹配, + 于是 418 条断言名的 TC 前缀**全部静默丢失**。要么显式 `chr(92)`,要么像本 Lead 会话一样改用「JS 组装 JSON 规格 + + Python 按规格带断言应用」,把转义面收敛到一处。 + +**协作口径(并行作业的板子纪律)**: + +- **先改板再派工**:拆别人在做的范围时,必须先 `team_task_update` 收缩原任务写范围,再建新任务并派工。 + 本轮 Lead(我)建 G3a 时板上已回"write scopes overlap with task-9"却照样派工,属于用队友的规避动作补自己的疏漏—— + 工人-side 的补救是查 `mtime` 确认文件未被动过再让出,比外部检查及时,但这不该依赖个人自觉。 +- **多名 agent 共用 `%TEMP%`,通用文件名本身就是竞态**:本轮一名工人写 `r2_verify.py` 撞上队友同名脚本, + 是「文件未读不许改」的守卫阻止了覆盖;若当时改用直接 fs 写入就会**静默毁掉别人的工件**。纪律:临时文件一律带组前缀。 +- 任务书里的条数要写清是**字面量条数**还是**断言总数**(本轮 `adc_input` 89 条字面量 vs 103 条断言), + 否则工人会拿两套数互相印证出假结论。 +- **三个计数单位别混用**(本批全踩过):① **行** = 含非 ASCII 字面量的行数(Lead 终检口径,本轮 1,535); + ② **条** = 字面量出现次数(HEAD 全量 1,538;个别行含 2 条);③ **numstat 的 ± 行数** ≠ 替换条数—— + git 会在相邻改动块之间重排空行(实测 `adc_input` 出现 90 行对 / 89 条替换,多出的那对两侧皆空、净零)。 + 同一批工作因此出现过 1,552 / 1,538 / 1,535 三个「都对」的数字——**报数前先声明用的是哪一个**。 +- **分母只算 `.c`/`.h`**:`test/host` 下的 runner 与桩脚本是 `.py`,HEAD 上有 44 条中文 docstring, + 属另一套口径(不经 ARMCC 代码页,翻它没有工程收益);混进分母会直接虚高普查数。 +- 取改前原始字节一律 `git show HEAD:<路径>`:**不要**用 `git checkout` 取版本(会丢弃未提交工作,是铁律), + 也别拿工作区文件当「改前基线」——队友可能正在改它。 + + +**后续项(本轮不做)**:① 把「剥注释词法扫描」收进 `scripts/` 当门禁(需用户点头,并先定 `test/` 是否纳入 +`coding-standard` 的口径——该钩子现在 `exclude` 了 `test/`);② `test/host/iec104/` 里「`TC-` 直接接三位序号、不带模块码」这类**简写形态** +归族(属编号登记与可追溯性改动,牵 `id_registry.json`,不能顺手做);③ `runner .py` 的中文 docstring **不动** +(口径是 `.c/​.h`,且 Python 源不经 ARMCC 代码页,翻它无工程收益)。 + **给下一批的可复用手法与坑**(完整清单写在各套件 `.c` 文件头,这里只留跨模块通用的): + 1. **测试 TU 里 `#define fputc <改名符号>` 再纳入生产源**:`App/log/console_log.c`:492 的 `int fputc(int, FILE*)` 与宿主 CRT 撞符号(`libucrt.lib(fputc.obj) error LNK2005` + `LNK1169`)。 改名纳入后函数体与行覆盖一字不动;顺带实测确认**宿主 printf 不走用户 `fputc`**(测试输出不会被吞进环形缓冲)。 @@ -660,3 +743,4 @@ P2 5 个 2,226 行、P3 29 个 4,814 行明确不做**(四条对得上:13+5+ 绕过 netTask、`console_log.c` 冷却哨兵与空位判据),**生产码一行未改**,逐条登记在 §9「P2 落地」表内待裁定; §8 第 1 条同步改为「清单已吃穿」 | | 2026-10-24 | **第 1 轮修复(同日续)**:用户裁定「全部修」,11 条现状里 **10 条已处置 + 1 条撤销**(`net_recv_locked` 那条是误报:非阻塞分支已能报 EOF,`:1885` 核过)。生产码改动跨 `sys_log_mcu.c`(整批回投 / 文案与节流 / 删不可达截断支 / 新增 `s_is_selfheal_code` 收敛自愈触发集 / post 两层留痕节流)、`soe_store.c`(注释更正 + 触发集同源更保守子集)、`cfg_file_store_mcu.c`(`FR_NO_SYSTEM` 不存在)、`sys_log.h`(读侧容量契约)、`net_socket.c/.h/net_types.h`(`s_addr` 统一到 POSIX 网络序 + UDP 两入口执行任务守卫,新码 `NET_ERR_NOT_IN_NETTASK = -12`)、`net_socket_sim.c`(同步 + 有意不对称)、`console_log.c/.h`(冷却独立标志 / 空位判据收进临界区 / 未初始化分诊 / 三本账 + 新读口)。**`@build` 0 错 0 警**(`Code=213720 RO=18860 RW=1204 ZI=131500`);全量闸 **33/33 全绿**、`5605/6275(89.3%)`、`396/429(92.3%)`、逐文件比对**下降 0**。设计文档同步:`控制台单写者日志设计说明.md`(§4.1 口径 + §13-O2 销项 + v1.5)、`运行与自检记录设计说明.md`(§4.4/§4.5 四条)、`STM32F4-Base存储架构说明.md`(§10.1 第 10 条推论)、`CH395F_Trap_Records.md`(TRAP-NET-21 后续)、`BSD_Socket_API_使用指南.md`(新增 §9.0 唯一约定)。本轮新增处置表、后续项 5 条、台架复验 7 条、新踩坑 8 条见 §9 | +| 2026-10-24 | **第 2 轮:测试字面量统一纯 ASCII**(单独提交):用户裁定「统一」,口径 = AGENTS 铁律「字符串字面量必须纯 ASCII」(无 BOM 文件里奇数个汉字会吞掉结束引号),中文只写注释。四名工人四组互斥目录并行,25 套 / 30 个 `.c` 的非 ASCII 字面量全部改成等值英文。粗口径普查 34 文件/1,552 行、严格口径(剥注释后取字面量)30 文件/**1,535** 行——差值那 4 个文件的命中全在注释里(`ns_peers.c`、`net_socket/stub/ns_rtos.h`、`common/ch395f_fake.h`、`common/fatfs_fake.c`),按口径**不改**。**Lead 独立终检五条硬判据**(TC 号集合不变 / 断言宏计数不变 / **行数与 HEAD 相等** / 代码区非 ASCII=0 / 字节卫生)→ **30 文件漂移 0**;每套断言数与 `--module` 覆盖率复量逐字不变(`net_socket` 887/889·53/53、`console_log` 199/200·16/16、`sys_log_mcu` 324/326·13/13、`adc_input` 103/103、`sys_clock` 100/100…),生产码零改动故基线不需重登。⚠ `@build` 对 `test/host/**` 无覆盖力,本轮证据只能来自 `*-unit-test` + `test-cppcheck` + `test-coverage`。方法、两版事故与协作纪律见 §9「第 2 轮」小节 | diff --git a/test/host/adc_input/adc_input_test.c b/test/host/adc_input/adc_input_test.c index a1784267..8a1a9944 100644 --- a/test/host/adc_input/adc_input_test.c +++ b/test/host/adc_input/adc_input_test.c @@ -213,20 +213,20 @@ static void tc_init(void) { (void)adc_input_poll(); /* 单拍无新帧 = 相位伪影,不计故障 */ (void)adc_input_poll(); /* 连续第二拍无新帧 = 真停摆 */ - CHECK(adc_input_stm32_errs() == 1u, "TC-ADCIN-001 连续两拍无新帧 -> 停摆计数 = 1"); + CHECK(adc_input_stm32_errs() == 1u, "TC-ADCIN-001 two rounds in a row with no new frame -> stall count = 1"); CHECK((adc_input_raw(ADC_SEM_UA, &v) == 0) && (v == 4321), - "TC-ADCIN-002 poll 后 UA 可取数且值正确"); + "TC-ADCIN-002 after poll UA is readable and the value is right"); - CHECK(adc_input_init() == 0, "TC-ADCIN-003 adc_input_init 返回 0(映射自检通过)"); + CHECK(adc_input_init() == 0, "TC-ADCIN-003 adc_input_init returns 0 (mapping self-check passed)"); CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_NOT_RUN, - "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 失败计数归零"); + "TC-ADCIN-004 after init the STM32 status code = NOT_RUN"); + CHECK(s_start_dma_calls == 1, "TC-ADCIN-003B init arms DMA exactly once"); + CHECK(s_dma_len == (2u * ADC_INPUT_STM32_CH_NUM), "TC-ADCIN-003C DMA length = 2 x 9 (ping-pong double buffer)"); + CHECK(s_dma_buf != NULL, "TC-ADCIN-003D the DMA destination buffer address was handed down"); + CHECK(adc_input_stm32_seq() == 0u, "TC-ADCIN-005B after init the DMA completion counter = 0"); + CHECK(adc_input_stm32_errs() == 0u, "TC-ADCIN-005 after init the STM32 failure counter is zeroed"); CHECK((adc_input_raw(ADC_SEM_UA, &v) == -2) && (adc_input_raw(ADC_SEM_UB, &v) == -2), - "TC-ADCIN-006 init 后 TPAFE / STM32 两侧均无有效数据"); + "TC-ADCIN-006 after init neither TPAFE nor STM32 side holds valid data"); } /* ===================== TC-ADCIN-010..01A:desc 映射表 ===================== */ @@ -262,8 +262,8 @@ static void tc_desc(void) { CHECK((d != NULL) && (d->source == ADC_SRC_STM32) && (d->index == 5u), "TC-ADCIN-018 TEMP -> STM32 CH5"); - 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"); + CHECK(adc_input_desc(ADC_SEM_COUNT) == NULL, "TC-ADCIN-019 out of range (ADC_SEM_COUNT) -> NULL"); + CHECK(adc_input_desc((adc_semantic_t)(-1)) == NULL, "TC-ADCIN-01A negative index -> NULL"); } /* ===================== TC-ADCIN-020:map_check ===================== */ @@ -272,7 +272,7 @@ 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-ADCIN-020 映射表自洽(TPAFE 下标与 STM32 Rank 均在范围内)"); + CHECK(map_check() == 0, "TC-ADCIN-020 mapping table is self-consistent (TPAFE index and STM32 Rank both in range)"); } /* ===================== TC-ADCIN-021..02C:stm32_scan 成功路径 ===================== */ @@ -284,22 +284,22 @@ 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-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"); + CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-021 stm32_take got a new frame -> 0"); + CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_OK, "TC-ADCIN-022 status code = RC_OK"); + CHECK(adc_input_stm32_errs() == 0u, "TC-ADCIN-023 a success is not counted as a failure"); + CHECK(s_start_dma_calls == 1, "TC-ADCIN-024 DMA is armed once at init (never restarted per round)"); + CHECK(adc_input_stm32_seq() == 1u, "TC-ADCIN-025 DMA completion counter = 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-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_UB, &v) == 0) && (v == 108), "TC-ADCIN-026 UB reads CH14(rank9)=108"); + CHECK((adc_input_raw(ADC_SEM_UC, &v) == 0) && (v == 103), "TC-ADCIN-027 UC reads CH3(rank4)=103"); + CHECK((adc_input_raw(ADC_SEM_IB, &v) == 0) && (v == 106), "TC-ADCIN-028 IB reads CH6(rank7)=106"); + CHECK((adc_input_raw(ADC_SEM_IC, &v) == 0) && (v == 101), "TC-ADCIN-029 IC reads CH1(rank2)=101"); + CHECK((adc_input_raw(ADC_SEM_IN, &v) == 0) && (v == 102), "TC-ADCIN-02A IN reads CH2(rank3)=102"); + CHECK((adc_input_raw(ADC_SEM_TEMP, &v) == 0) && (v == 105), "TC-ADCIN-02B TEMP reads CH5(rank6)=105"); - CHECK(adc_input_raw(ADC_SEM_UA, &v) == -2, "TC-ADCIN-02C stm32_take 不置 TPAFE 有效标志"); + CHECK(adc_input_raw(ADC_SEM_UA, &v) == -2, "TC-ADCIN-02C stm32_take does not set the TPAFE valid flag"); } /* ============ TC-ADCIN-080..085:乒乓双缓冲(读刚完成半区,不读正在写的半区) ============ @@ -314,27 +314,27 @@ static void tc_dma_pingpong(void) { dma_beat(100); /* 第 1 帧 -> 前半区(半传输回调) */ dma_fill(1u, 900u); /* 模拟 DMA 正在写后半区(值 900 系) */ - CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-080 第一拍取帧成功"); + CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-080 first round fetch succeeded"); CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 108), - "TC-ADCIN-081 读的是刚完成的前半区(108),不是正在写的后半区"); + "TC-ADCIN-081 reads the just completed half (108), not the half being written"); dma_beat(200); /* 第 2 帧 -> 后半区(传输完成回调) */ dma_fill(0u, 800u); /* 模拟 DMA 正在写前半区(值 800 系) */ - CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-082 第二拍取帧成功"); + CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-082 second round fetch succeeded"); CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 208), - "TC-ADCIN-083 第二拍读到后半区(208)"); - CHECK(adc_input_stm32_seq() == 2u, "TC-ADCIN-084 DMA 完成计数 = 2"); + "TC-ADCIN-083 second round reads the later half (208)"); + CHECK(adc_input_stm32_seq() == 2u, "TC-ADCIN-084 DMA completion counter = 2"); /* 半区奇偶口径:seq=1 -> 前半区,seq=2 -> 后半区(与 dma_beat 独立推导,互相证伪) */ - CHECK(((adc_input_raw(ADC_SEM_UC, &v) == 0) && (v == 203)), "TC-ADCIN-085 UC 同帧内一致(203)"); + CHECK(((adc_input_raw(ADC_SEM_UC, &v) == 0) && (v == 203)), "TC-ADCIN-085 UC stays consistent within the frame (203)"); /* 消费者超拍:两拍都没取 -> 中间那帧已被乒乓缓冲覆盖 -> 记 1 点丢帧 */ dma_beat(300); dma_beat(400); - CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-086 超拍后仍取到最新帧"); - CHECK(adc_input_stm32_gaps() == 1u, "TC-ADCIN-087 seq 前进 2 -> 记 1 点丢帧"); - CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 408), "TC-ADCIN-088 取到的是最新帧(408)"); - CHECK(adc_input_stm32_errs() == 0u, "TC-ADCIN-089 丢帧不计入停摆(两类故障分开)"); + CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-086 after skipping rounds the newest frame is still fetched"); + CHECK(adc_input_stm32_gaps() == 1u, "TC-ADCIN-087 seq advanced by 2 -> records 1 dropped frame"); + CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 408), "TC-ADCIN-088 what came back is the newest frame (408)"); + CHECK(adc_input_stm32_errs() == 0u, "TC-ADCIN-089 a drop is not counted as a stall (two fault classes stay apart)"); /* 第二档:上面只跨了 1 帧(前进 2 记 1 点),"次数"与"点数"数值相同、钉不出单位。 * 这里连投三帧不消费 = 一次跨 2 帧,必须记 2 点(累计 1+2=3),把 2026-10-21 改的 @@ -355,18 +355,18 @@ static void tc_hw_errs(void) { HAL_ADC_ErrorCallback(&hadc1); HAL_ADC_ErrorCallback(&hadc1); - CHECK(adc_input_stm32_hw_errs() == 2u, "TC-ADCIN-090 错误回调累计 = 2"); + CHECK(adc_input_stm32_hw_errs() == 2u, "TC-ADCIN-090 error callback total = 2"); HAL_ADC_ErrorCallback(&hadc_other); - CHECK(adc_input_stm32_hw_errs() == 2u, "TC-ADCIN-091 别的 ADC 句柄不得计入(hadc 守卫)"); + CHECK(adc_input_stm32_hw_errs() == 2u, "TC-ADCIN-091 other ADC handles must not count (hadc guard)"); HAL_ADC_ConvHalfCpltCallback(&hadc_other); HAL_ADC_ConvCpltCallback(&hadc_other); - CHECK(adc_input_stm32_seq() == 0u, "TC-ADCIN-092 别的句柄的完成回调不得推进 seq"); + CHECK(adc_input_stm32_seq() == 0u, "TC-ADCIN-092 a completion callback from another handle must not advance seq"); HAL_ADC_ErrorCallback(&hadc1); - 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"); + CHECK(adc_input_stm32_hw_errs() == 3u, "TC-ADCIN-093 hw_errs and errs count separately and never interfere"); + CHECK(adc_input_stm32_errs() == 0u, "TC-ADCIN-09A hw_errs does not pollute errs"); } /* ===================== TC-ADCIN-030..034:DMA 挂载失败 ===================== */ @@ -377,10 +377,10 @@ static void tc_init_dma_fail(void) { fakes_reset(); s_start_dma_rc = HAL_ERROR; - 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 侧无有效数据"); + CHECK(adc_input_init() == -2, "TC-ADCIN-030 HAL_ADC_Start_DMA failure -> init returns -2"); + CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_START, "TC-ADCIN-031 status code = RC_START"); + CHECK(adc_input_stm32_errs() == 1u, "TC-ADCIN-032 failure counter +1"); + CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-ADCIN-034 after an arming failure the STM32 side holds no valid data"); } /* ===================== TC-ADCIN-035..03A:本拍无新帧(停摆) ===================== */ @@ -392,21 +392,21 @@ static void tc_take_stall(void) { (void)adc_input_init(); /* 没有任何 DMA 完成回调 = TIM3 未启动 / ADC 停摆 / DMA 出错 */ - 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 侧无有效数据"); + CHECK(stm32_take() == ADC_INPUT_RC_STALL, "TC-ADCIN-035 no new frame -> RC_STALL(-2)"); + CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_STALL, "TC-ADCIN-036 status code = RC_STALL"); + CHECK(adc_input_stm32_errs() == 0u, "TC-ADCIN-037 a single round without a new frame is not a fault (phase artefact)"); + CHECK(adc_input_stm32_seq() == 0u, "TC-ADCIN-038 seq does not advance while stalled"); + CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-ADCIN-039 a stalled round leaves the STM32 side without valid data"); (void)stm32_take(); /* 连续第二拍无新帧 = 真停摆 */ - CHECK(adc_input_stm32_errs() == 1u, "TC-ADCIN-03A 连续两拍无新帧 -> 停摆计数 = 1"); + CHECK(adc_input_stm32_errs() == 1u, "TC-ADCIN-03A two rounds in a row with no new frame -> stall count = 1"); (void)stm32_take(); /* 第三拍仍无新帧 */ - CHECK(adc_input_stm32_errs() == 2u, "TC-ADCIN-03B 停摆持续 -> 每拍累计 = 2"); - CHECK(adc_input_stm32_gaps() == 0u, "TC-ADCIN-03C 停摆不计入丢帧(两类故障分开)"); + CHECK(adc_input_stm32_errs() == 2u, "TC-ADCIN-03B an ongoing stall accumulates every round = 2"); + CHECK(adc_input_stm32_gaps() == 0u, "TC-ADCIN-03C a stall is not counted as a drop (two fault classes stay apart)"); dma_beat(100); /* 恢复 */ - CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-03D 恢复后取帧成功"); - CHECK(adc_input_stm32_gaps() == 0u, "TC-ADCIN-03E 恢复拍前进 1 -> 不算丢帧"); + CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-03D after recovery the fetch succeeds"); + CHECK(adc_input_stm32_gaps() == 0u, "TC-ADCIN-03E the recovery round advances by 1 -> not a drop"); } /* ============ TC-ADCIN-070..078:停摆拍不得沿用上一拍旧值(陈旧帧) ============ @@ -424,24 +424,24 @@ static void tc_take_stale(void) { fakes_reset(); (void)adc_input_init(); dma_beat(100); - 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(有效态)"); + CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-070 precondition: first round succeeded"); + CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 108), "TC-ADCIN-071 precondition: UB reads 108 (valid state)"); /* 第二拍没有任何 DMA 完成(TIM3 停 / ADC 停摆 / DMA 出错) */ - 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)"); + CHECK(stm32_take() == ADC_INPUT_RC_STALL, "TC-ADCIN-072 second round has no new frame"); + CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-ADCIN-073 a stalled round must not reuse the previous value -> -2"); + CHECK(adc_input_raw(ADC_SEM_UC, &v) == -2, "TC-ADCIN-074 a stalled round must not emit any other STM32 channel either"); + CHECK(adc_input_raw(ADC_SEM_TEMP, &v) == -2, "TC-ADCIN-074B same as above (TEMP also -2)"); dma_beat(200); - CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-075 第三拍恢复成功"); - CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 208), "TC-ADCIN-076 恢复拍重新可取数(自愈)"); + CHECK(stm32_take() == ADC_INPUT_RC_OK, "TC-ADCIN-075 third round recovers successfully"); + CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 208), "TC-ADCIN-076 the recovery round can be read again (self-healing)"); /* --- 挂载失败支路:同样不得沿用(init 失败后整层无有效数据) --- */ fakes_reset(); s_start_dma_rc = HAL_ERROR; (void)adc_input_init(); - CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-ADCIN-078 挂载失败后不得取到任何值 -> -2"); + CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-ADCIN-078 after an arming failure no value may be read -> -2"); } /* ===================== TC-ADCIN-040..045:raw 参数守卫与无数据 ===================== */ @@ -453,11 +453,11 @@ static void tc_raw_guards(void) { (void)adc_input_init(); 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"); + CHECK(adc_input_raw(ADC_SEM_COUNT, &v) == -1, "TC-ADCIN-041 ch out of range -> -1"); + CHECK(adc_input_raw((adc_semantic_t)(-1), &v) == -1, "TC-ADCIN-042 ch negative -> -1"); + CHECK(v == 0, "TC-ADCIN-043 on an argument error out is not written"); + CHECK(adc_input_raw(ADC_SEM_UA, &v) == -2, "TC-ADCIN-044 TPAFE has no valid frame -> -2"); + CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-ADCIN-045 STM32 has no valid scan -> -2"); } /* ===================== TC-ADCIN-046..04B:raw TPAFE 取数与补码 ===================== */ @@ -478,13 +478,13 @@ static void tc_raw_tpafe(void) { s_fake_tpafe[7] = 1007; s_snapshot_rc = 1; - 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_poll() == 1, "TC-ADCIN-046 poll passes through the TPAFE snapshot code 1"); + CHECK(s_snapshot_count == (uint8_t)ADC_INPUT_TPAFE_CH_NUM, "TC-ADCIN-047 snapshot requests 8 channels"); + CHECK(s_snapshot_dst != NULL, "TC-ADCIN-048 the snapshot destination buffer is not NULL"); 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-ADCIN-04B IA -> buf[2]=-1234(补码负值原样保留)"); + "TC-ADCIN-04B IA -> buf[2]=-1234 (two's-complement negative kept as is)"); } /* ===================== TC-ADCIN-050..058:poll 契约 ===================== */ @@ -497,16 +497,16 @@ static void tc_poll(void) { (void)adc_input_init(); s_snapshot_rc = 0; dma_beat(100); - 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 取帧照常执行"); + CHECK(adc_input_poll() == 0, "TC-ADCIN-050 snapshot with no new frame -> poll returns 0"); + CHECK(adc_input_raw(ADC_SEM_UA, &v) == -2, "TC-ADCIN-051 without a new frame the TPAFE side is invalid"); + CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_OK, "TC-ADCIN-052 the STM32 fetch in the same round still runs"); /* --- 参数错(-1):返回 -1,TPAFE 无效 --- */ fakes_reset(); (void)adc_input_init(); s_snapshot_rc = -1; - CHECK(adc_input_poll() == -1, "TC-ADCIN-053 快照参数错 -> poll 返回 -1"); - CHECK(adc_input_raw(ADC_SEM_UA, &v) == -2, "TC-ADCIN-054 参数错时 TPAFE 侧无效"); + CHECK(adc_input_poll() == -1, "TC-ADCIN-053 snapshot argument error -> poll returns -1"); + CHECK(adc_input_raw(ADC_SEM_UA, &v) == -2, "TC-ADCIN-054 on an argument error the TPAFE side is invalid"); /* --- 已有有效帧后再"无新帧":保持上次有效值(不清零) --- */ fakes_reset(); @@ -517,7 +517,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-ADCIN-055 已有有效帧后无新帧不清零"); + "TC-ADCIN-055 an existing valid frame is not zeroed when no new frame arrives"); /* --- STM32 失败不阻断 TPAFE、不影响 poll 返回值 --- */ fakes_reset(); @@ -525,10 +525,10 @@ static void tc_poll(void) { s_fake_tpafe[2] = 55; s_snapshot_rc = 1; /* 不注入任何 DMA 完成 = STM32 侧停摆 */ - CHECK(adc_input_poll() == 1, "TC-ADCIN-056 STM32 停摆不影响 poll 返回值(仍为 1)"); + CHECK(adc_input_poll() == 1, "TC-ADCIN-056 an STM32 stall does not change the poll return value (still 1)"); CHECK((adc_input_raw(ADC_SEM_IA, &v) == 0) && (v == 55), - "TC-ADCIN-057 STM32 停摆不影响 TPAFE 取数"); - CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_STALL, "TC-ADCIN-058 STM32 停摆另由状态码暴露"); + "TC-ADCIN-057 an STM32 stall does not affect TPAFE data"); + CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_STALL, "TC-ADCIN-058 an STM32 stall is exposed through the status code instead"); } /* ===================== TC-ADCIN-060..066:rc / errs 观测 ===================== */ @@ -537,24 +537,24 @@ static void tc_rc_errs(void) { fakes_reset(); (void)adc_input_init(); - 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"); + CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_NOT_RUN, "TC-ADCIN-060 after init, before any scan = NOT_RUN(-3)"); + CHECK(adc_input_stm32_errs() == 0u, "TC-ADCIN-061 after init the failure counter = 0"); dma_beat(100); (void)stm32_take(); /* 成功 */ CHECK((adc_input_stm32_rc() == ADC_INPUT_RC_OK) && (adc_input_stm32_errs() == 0u), - "TC-ADCIN-062 成功: rc=OK 且 errs 不变"); + "TC-ADCIN-062 success: rc=OK and errs unchanged"); (void)stm32_take(); /* 停摆 1(单拍 = 相位伪影,不计) */ (void)stm32_take(); /* 停摆 2 -> 计 1 */ - CHECK(adc_input_stm32_errs() == 1u, "TC-ADCIN-063 连续两拍停摆累计 = 1"); - CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_STALL, "TC-ADCIN-064 rc = 最近一次(STALL)"); + CHECK(adc_input_stm32_errs() == 1u, "TC-ADCIN-063 two consecutive stalled rounds accumulate = 1"); + CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_STALL, "TC-ADCIN-064 rc = the most recent result (STALL)"); dma_beat(200); (void)stm32_take(); /* 恢复成功 */ - 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 完成回调推进"); + CHECK(adc_input_stm32_rc() == ADC_INPUT_RC_OK, "TC-ADCIN-065 after a successful recovery rc=OK"); + CHECK(adc_input_stm32_errs() == 1u, "TC-ADCIN-066 errs increases monotonically (a success never lowers it)"); + CHECK(adc_input_stm32_seq() == 2u, "TC-ADCIN-067 seq is advanced only by the DMA completion callback"); } /* ===================== main ===================== */ diff --git a/test/host/cfg_file_store_mcu/cfg_file_store_mcu_test.c b/test/host/cfg_file_store_mcu/cfg_file_store_mcu_test.c index 694b0770..5259ae0f 100644 --- a/test/host/cfg_file_store_mcu/cfg_file_store_mcu_test.c +++ b/test/host/cfg_file_store_mcu/cfg_file_store_mcu_test.c @@ -260,7 +260,7 @@ static void tc_read(void) size_t n = 999u; int ok; - printf("-- TC-CFGFST-001..007 读 --\n"); + printf("-- TC-CFGFST-001..007 read path --\n"); /* 001 成功 + 只读模式 */ reset_all(); @@ -269,14 +269,14 @@ static void tc_read(void) && (memcmp(buf, "net ip=192.168.1.100\n", 20u) == 0) && (g_ff_obs.last_open_mode == (BYTE)FA_READ) && (s_lock_waits == 1) && (s_lock_releases == 1) && (s_lock_seq_err == 0); - CHECK(ok, "TC-CFGFST-001 读成功:内容与长度正确,打开模式就是 FA_READ(不带写位)"); + CHECK(ok, "TC-CFGFST-001 read ok: content and length correct, opened with FA_READ only (no write bit)"); /* 002 空指针守卫在取锁之前 */ reset_all(); ok = (cfg_store_read(P_CFG, NULL, sizeof(buf), &n) == -1) && (cfg_store_read(P_CFG, buf, sizeof(buf), NULL) == -1); CHECK(ok && (s_lock_waits == 0) && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 0), - "TC-CFGFST-002 空指针 -> -1 且不取卷锁(守卫顺序正确)"); + "TC-CFGFST-002 NULL pointer -> -1 and no volume lock taken (guard order correct)"); /* 003 卷忙 */ reset_all(); @@ -284,13 +284,13 @@ static void tc_read(void) ok = (cfg_store_read(P_CFG, buf, sizeof(buf), &n) == -1); CHECK(ok && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 0) && (s_lock_releases == 0) && (s_lock_seq_err == 0), - "TC-CFGFST-003 卷忙 -> -1:零 FatFs、不 release(没拿到锁不放锁)"); + "TC-CFGFST-003 volume busy -> -1: zero FatFs calls, no release (never release a lock we do not hold)"); /* 004 文件缺失:必须已放锁 */ reset_all(); ok = (cfg_store_read(P_CFG, buf, sizeof(buf), &n) == -1); CHECK(ok && (s_lock_releases == 1) && (s_lock_seq_err == 0), - "TC-CFGFST-004 文件缺失 -> -1 **且已释放卷锁**(漏放 = 之后所有卷操作全瘫)"); + "TC-CFGFST-004 missing file -> -1 **and the volume lock is released** (leaking it paralyses every later volume call)"); /* 005 cap > 文件大小 */ reset_all(); @@ -298,7 +298,7 @@ static void tc_read(void) n = 999u; ok = (cfg_store_read(P_CFG, buf, sizeof(buf), &n) == 0) && (n == 3u) && (g_ff_obs.last_read_btr == 64u) && (g_ff_obs.last_read_br == 3u); - CHECK(ok, "TC-CFGFST-005 要 64 只给 3 -> nread=3 且仍算成功(短读不是错误)"); + CHECK(ok, "TC-CFGFST-005 asked 64 got 3 -> nread=3 and still success (a short read is not an error)"); /* 006 f_read 失败 */ reset_all(); @@ -307,7 +307,7 @@ static void tc_read(void) ok = (cfg_store_read(P_CFG, buf, sizeof(buf), &n) == -1); CHECK(ok && (g_ff_obs.calls[FF_FAKE_OP_CLOSE] == 1) && (s_lock_releases == 1) && (s_lock_seq_err == 0), - "TC-CFGFST-006 读失败 -> -1 + close 已配对 + 放锁"); + "TC-CFGFST-006 read failure -> -1, close paired, lock released"); /* 007 介质短读:现状是"返回 0 + nread 如实变小",调用方靠 nread 定长度 */ reset_all(); @@ -315,7 +315,7 @@ static void tc_read(void) ff_fake_inject_read_short(P_CFG, 4u, 1); n = 999u; ok = (cfg_store_read(P_CFG, buf, sizeof(buf), &n) == 0) && (n == 4u); - CHECK(ok, "TC-CFGFST-007 注入短读 -> 返回 0、nread=4(上层按 nread 截断使用)"); + CHECK(ok, "TC-CFGFST-007 injected short read -> returns 0 with nread=4 (caller truncates by nread)"); } /* ===================== 原子写 ===================== */ @@ -326,7 +326,7 @@ static void tc_write_atomic(void) size_t n; int ok; - printf("-- TC-CFGFST-010..020 原子写(E-01 核心)--\n"); + printf("-- TC-CFGFST-010..020 atomic write (core of E-01) --\n"); /* 010 首启写(目标不存在) */ reset_all(); @@ -337,7 +337,7 @@ static void tc_write_atomic(void) && (strcmp(g_ff_obs.last_rename_old, "/CONFIG.TMP") == 0) && (strcmp(g_ff_obs.last_rename_new, "/CONFIG.INI") == 0) && (s_lock_releases == 1) && (s_lock_seq_err == 0), - "TC-CFGFST-010 首启写:TMP -> rename -> 目标 2 字节、TMP 不留痕"); + "TC-CFGFST-010 first write: TMP -> rename -> target 2 bytes, no TMP left behind"); /* 011 覆盖写:假卷的 f_rename 对已存在目标返回 FR_EXIST —— 这就是 E-01 */ reset_all(); @@ -349,7 +349,7 @@ static void tc_write_atomic(void) && (ff_fake_fetch(P_CFG, buf, 0u, sizeof(buf)) == 3u) && (memcmp(buf, "new", 3u) == 0) && (g_ff_obs.calls[FF_FAKE_OP_UNLINK] == unlinks_before + 1), - "TC-CFGFST-011 覆盖写:unlink 目标恰一次再 rename -> 新内容落地(E-01)"); + "TC-CFGFST-011 overwrite: unlink target exactly once then rename -> new content lands (E-01)"); } /* 同一条的"反面":直接 rename 到已存在目标必败(证明上一步的 unlink 不是多余的) */ { @@ -359,7 +359,7 @@ static void tc_write_atomic(void) (void)ff_fake_mkfile(P_TMP, (const uint8_t *)"x", 1u); fr = f_rename(P_TMP, P_CFG); CHECK(fr == FR_EXIST, - "TC-CFGFST-011b 假件保真:目标已存在时 f_rename 返回 FR_EXIST、不覆盖"); + "TC-CFGFST-011b fake fidelity: f_rename returns FR_EXIST when the target exists, no overwrite"); if (fr == FR_OK) { (void)f_close(&probe); } @@ -374,7 +374,7 @@ static void tc_write_atomic(void) * TMP 一定被清掉、锁一定释放、绝不留半成品 */ CHECK(ok && (ff_fake_exists(P_TMP) == 0) && (ff_fake_exists(P_CFG) == 0) && (s_lock_releases == 2) && (s_lock_seq_err == 0), - "TC-CFGFST-012 rename 失败 -> -1 + TMP 清理 + 放锁( unlink→rename 窗口如实存在)"); + "TC-CFGFST-012 rename failure -> -1, TMP cleaned, lock released (the unlink->rename window really exists)"); /* 013 TMP 打不开 */ reset_all(); @@ -384,7 +384,7 @@ static void tc_write_atomic(void) CHECK(ok && (ff_fake_size(P_CFG) == 4u) && (g_ff_obs.calls[FF_FAKE_OP_WRITE] == 0) && (g_ff_obs.calls[FF_FAKE_OP_RENAME] == 0) && (s_lock_releases == 1) && (s_lock_seq_err == 0), - "TC-CFGFST-013 TMP 打开失败 -> -1 且**目标原内容一个字节没动**"); + "TC-CFGFST-013 TMP open failure -> -1 and **not one byte of the target changed**"); /* 014 短写 = 失败:TMP 被删、目标不动、不 rename */ reset_all(); @@ -398,7 +398,7 @@ static void tc_write_atomic(void) && (ff_fake_fetch(P_CFG, buf, 0u, sizeof(buf)) == 11u) && (memcmp(buf, "good-config", 11u) == 0) && (s_lock_seq_err == 0), - "TC-CFGFST-014 TMP 短写判失败 -> 删 TMP、不 rename、目标仍是旧内容"); + "TC-CFGFST-014 TMP short write is a failure -> TMP deleted, no rename, target keeps old content"); /* 015 len = 0 合法(清空配置) */ reset_all(); @@ -407,7 +407,7 @@ static void tc_write_atomic(void) n = 999u; CHECK(ok && (ff_fake_size(P_CFG) == 0u) && (cfg_store_read(P_CFG, buf, sizeof(buf), &n) == 0) && (n == 0u), - "TC-CFGFST-015 写 0 字节成功(清空配置),回读 nread=0"); + "TC-CFGFST-015 writing 0 bytes succeeds (config cleared), read-back gives nread=0"); /* 016 卷忙:整条链零 I/O */ reset_all(); @@ -418,13 +418,13 @@ static void tc_write_atomic(void) && (g_ff_obs.calls[FF_FAKE_OP_RENAME] == 0) && (g_ff_obs.calls[FF_FAKE_OP_UNLINK] == 0) && (ff_fake_size(P_CFG) == 4u) && (s_lock_releases == 0), - "TC-CFGFST-016 卷忙 -> -1:不建 TMP、不动目标、不 release"); + "TC-CFGFST-016 volume busy -> -1: no TMP created, target untouched, no release"); /* 017 p_buf NULL */ reset_all(); ok = (cfg_store_write_atomic(P_CFG, NULL, 3u) == -1); CHECK(ok && (s_lock_waits == 0) && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 0), - "TC-CFGFST-017 p_buf NULL -> -1 且不取锁"); + "TC-CFGFST-017 p_buf NULL -> -1 and no lock taken"); /* 017b 目标路径本身是 NULL:s_build_tmp_path 的空指针分支(读函数有守卫, * 写函数**没有** p_path 的显式守卫,全靠推导函数把它挡在取锁之前) */ @@ -433,7 +433,7 @@ static void tc_write_atomic(void) ok = (cfg_store_write_atomic(NULL, (const uint8_t *)"x", 1u) == -1); CHECK(ok && (s_lock_waits == 0) && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 0) && (ff_fake_size(P_CFG) == 4u), - "TC-CFGFST-017b p_path NULL -> -1:不取锁、不开文件、目标不动"); + "TC-CFGFST-017b p_path NULL -> -1: no lock, no file open, target untouched"); /* 018 临时名由目标推导(同目录) */ reset_all(); @@ -443,22 +443,22 @@ static void tc_write_atomic(void) && (ff_fake_exists("/cfg/config.TMP") == 0) /* 已被 rename 走,不是留档 */ && (strcmp(g_ff_obs.last_rename_new, "/CFG/A.INI") == 0) && (ff_fake_size("/cfg/a.ini") == 1u), - "TC-CFGFST-018 目标是 /cfg/a.ini -> 临时文件落在同目录 /cfg/config.TMP"); + "TC-CFGFST-018 target /cfg/a.ini -> temp file lands in the same directory /cfg/config.TMP"); CHECK(strcmp(cfg_store_tmp_path(), P_TMP) == 0, - "TC-CFGFST-018b getter 仍是卷根 /config.TMP(与 s_path_tmp 同源)"); + "TC-CFGFST-018b getter still reports the volume root /config.TMP (same source as s_path_tmp)"); /* 019 目录太长 -> 推导失败,且发生在取锁之前 */ reset_all(); ok = (cfg_store_write_atomic("/this/is/a/very/deep/dir/name/x.ini", (const uint8_t *)"y", 1u) == -1); CHECK(ok && (s_lock_waits == 0) && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 0), - "TC-CFGFST-019 临时名缓冲放不下 -> -1 且不取锁(不拿半截路径去开文件)"); + "TC-CFGFST-019 temp name does not fit the buffer -> -1, no lock (never open a file with a truncated path)"); /* 020 陷阱一在本模块同样成立 */ reset_all(); (void)cfg_store_write_atomic(P_CFG, (const uint8_t *)"m", 1u); CHECK((g_ff_obs.last_open_mode & FA_WRITE) != 0u, - "TC-CFGFST-020 写 TMP 的句柄必带 FA_WRITE(这里用 CREATE_ALWAYS,不是 APPEND)"); + "TC-CFGFST-020 the TMP handle must carry FA_WRITE (CREATE_ALWAYS here, not APPEND)"); reset_all(); { static FIL probe; @@ -470,7 +470,7 @@ static void tc_write_atomic(void) fr2 = f_write(&probe, "abc", 3u, &bw); (void)f_close(&probe); CHECK((fr1 == FR_OK) && (fr2 == FR_DENIED) && (bw == 0u), - "TC-CFGFST-020b 只给 FA_CREATE_ALWAYS -> 打开成功但 f_write 恒 FR_DENIED"); + "TC-CFGFST-020b FA_CREATE_ALWAYS alone -> open succeeds but f_write is always FR_DENIED"); } } @@ -484,7 +484,7 @@ static void tc_stat_remove(void) int rel; int ok; - printf("-- TC-CFGFST-030..033 状态令牌与删除 --\n"); + printf("-- TC-CFGFST-030..033 stat token and remove --\n"); /* 030 size + 令牌 */ reset_all(); @@ -498,7 +498,7 @@ static void tc_stat_remove(void) ok = ok && (cfg_store_stat(P_CFG, &st) == 0) && (st.mtime == tok2) && (tok1 != tok2); CHECK(ok && (s_lock_seq_err == 0) && (s_lock_releases == s_lock_waits), - "TC-CFGFST-030 令牌 = (fdate<<16)|ftime,日期进位一定换令牌"); + "TC-CFGFST-030 token = (fdate<<16)|ftime, a date rollover must change the token"); /* 031 盲区:同一分钟、同长度重写 -> 令牌不变 */ reset_all(); @@ -510,7 +510,7 @@ static void tc_stat_remove(void) (void)cfg_store_write_atomic(P_CFG, (const uint8_t *)"bbbb", 4u); (void)cfg_store_stat(P_CFG, &st); CHECK(ok && (st.size == 4u) && (st.mtime == before), - "TC-CFGFST-031 同分钟同长度重写 -> 令牌不变(poll 检不出,设计已接受)"); + "TC-CFGFST-031 rewrite in the same minute with the same length -> token unchanged (poll cannot see it, accepted by design)"); } /* 032 stat 三种 -1 */ @@ -526,7 +526,7 @@ static void tc_stat_remove(void) ff_fake_inject_rc(P_CFG, FF_FAKE_OP_STAT, FR_DISK_ERR, 1); ok = ok && (cfg_store_stat(P_CFG, &st) == -1) && (s_lock_releases == rel + 1) && (s_lock_seq_err == 0); - CHECK(ok, "TC-CFGFST-032 stat:NULL 守卫/缺失/卷忙/读错误四种出口的放锁配对"); + CHECK(ok, "TC-CFGFST-032 stat: lock pairing on all four exits (NULL guard / missing / busy / read error)"); /* 033 remove */ reset_all(); @@ -539,7 +539,7 @@ static void tc_stat_remove(void) lock_busy_next(1); ok = ok && (cfg_store_remove(P_CFG) == -1) && (s_lock_releases == rel + 2) && (s_lock_seq_err == 0); - CHECK(ok, "TC-CFGFST-033 remove:成功 / 已不存在的 -1 / 卷忙的 -1 与放锁配对"); + CHECK(ok, "TC-CFGFST-033 remove: success / -1 when already gone / -1 when busy, each with lock pairing"); } /* ===================== 路径与 8.3(陷阱二) ===================== */ @@ -559,7 +559,7 @@ static void tc_names(void) FRESULT fr_colon; int ok; - printf("-- TC-CFGFST-040..042 路径合规与「名字错不升级成卷操作」 --\n"); + printf("-- TC-CFGFST-040..042 path legality, name errors never escalate to volume ops --\n"); /* 040 生产路径真的可用(改名即静默失败的第一道防线) */ reset_all(); @@ -568,7 +568,7 @@ static void tc_names(void) && (f_close(&probe) == FR_OK) && (f_open(&probe, cfg_store_tmp_path(), FA_WRITE | FA_CREATE_ALWAYS) == FR_OK) && (f_close(&probe) == FR_OK); - CHECK(ok, "TC-CFGFST-040 /config.ini 与 /config.TMP 都是合法 8.3,真能在卷上建出来"); + CHECK(ok, "TC-CFGFST-040 /config.ini and /config.TMP are valid 8.3 names and really get created on the volume"); /* 041 短名违规分档 */ reset_all(); @@ -585,7 +585,7 @@ static void tc_names(void) CHECK((fr_body == FR_INVALID_NAME) && (fr_ext == FR_INVALID_NAME) && (fr_bad == FR_INVALID_NAME) && (fr_dot == FR_INVALID_NAME) && (fr_colon == FR_INVALID_DRIVE), - "TC-CFGFST-041 分档:体>8 / 扩展>3 / 非法字符 / 点开头 -> FR_INVALID_NAME;':' -> FR_INVALID_DRIVE"); + "TC-CFGFST-041 classes: body>8 / ext>3 / bad char / leading dot -> FR_INVALID_NAME; ':' -> FR_INVALID_DRIVE"); /* 042 名字类错误码绝不升级成卷操作:非法目标名走一遍原子写 */ reset_all(); @@ -599,7 +599,7 @@ static void tc_names(void) CHECK(ok && ((uint32_t)ff_fake_count_entries() == ents_before) && (ff_fake_size(P_CFG) == 4u) && (s_lock_seq_err == 0) && (s_lock_releases == rel + 3), - "TC-CFGFST-042 非法名只让本次调用失败:条目数不变、已有配置不动、锁把把放过"); + "TC-CFGFST-042 an illegal name fails only this call: entry count unchanged, existing config intact, lock always released"); /* 非法目标名进原子写:推导出的 TMP 也非法 -> 第一步开文件就失败, * 绝不能把已经存在的目标删掉 */ reset_all(); @@ -608,7 +608,7 @@ static void tc_names(void) ok = (cfg_store_write_atomic("/badname-tooooo-long.ini", (const uint8_t *)"x", 1u) == -1); CHECK(ok && (ff_fake_size(P_CFG) == 4u) && ((uint32_t)ff_fake_count_entries() == ents_before), - "TC-CFGFST-042b 非法目标名的原子写整条失败,**不碰已有配置文件**"); + "TC-CFGFST-042b an atomic write to an illegal target fails whole, **never touching the live config file**"); } /* ===================== 堆 ===================== */ @@ -618,7 +618,7 @@ static void tc_heap(void) void *p; void *q; - printf("-- TC-CFGFST-050..053 分配后端(优化调研 P0 第 1 条)--\n"); + printf("-- TC-CFGFST-050..053 allocation backend (P0 item 1 of the optimisation study) --\n"); /* 050 成对归还 */ reset_all(); @@ -626,7 +626,7 @@ static void tc_heap(void) (void)cfg_store_free(p); CHECK((p != NULL) && (s_heap_alloc_calls == 1) && (s_heap_free_calls == 1) && (s_heap_used == 0u) && (s_heap_free_err == 0), - "TC-CFGFST-050 alloc/free 走 FreeRTOS 堆且成对归还(借多少还多少)"); + "TC-CFGFST-050 alloc/free go through the FreeRTOS heap and return in pairs (give back what was taken)"); /* 051 分配失败如实返回 NULL */ reset_all(); @@ -635,19 +635,19 @@ static void tc_heap(void) q = cfg_store_alloc(8u); cfg_store_free(p); /* NULL 必须安全 */ CHECK((p == NULL) && (q == NULL) && (s_heap_free_calls == 0), - "TC-CFGFST-051 堆见底 -> cfg_store_alloc 返回 NULL(MicroLIB 512B 的真形态)"); + "TC-CFGFST-051 heap exhausted -> cfg_store_alloc returns NULL (the real MicroLIB 512B shape)"); /* 052 free(NULL) 安全 + 不计数 */ reset_all(); cfg_store_free(NULL); CHECK((s_heap_free_calls == 0) && (s_heap_free_err == 0), - "TC-CFGFST-052 cfg_store_free(NULL) 不触碰分配器"); + "TC-CFGFST-052 cfg_store_free(NULL) does not touch the allocator"); /* 053 heap_free 转发 */ reset_all(); (void)cfg_store_alloc(100u); CHECK(cfg_store_heap_free() == (FAKE_HEAP_CAP - 100u), - "TC-CFGFST-053 cfg_store_heap_free 原样转发 xPortGetFreeHeapSize"); + "TC-CFGFST-053 cfg_store_heap_free forwards xPortGetFreeHeapSize verbatim"); } /* ===================== 入口 ===================== */ diff --git a/test/host/console_log/console_log_test.c b/test/host/console_log/console_log_test.c index 35a34227..47c75589 100644 --- a/test/host/console_log/console_log_test.c +++ b/test/host/console_log/console_log_test.c @@ -493,27 +493,27 @@ static void tc_params(void) { char buf[DBG_CON_LINE_MAX + 128U]; - printf("-- TC-CONLOG-000..006 参数校验与截断 --\n"); + printf("-- TC-CONLOG-000..006 argument checks and truncation --\n"); reset_all(); - printf("(probe) 这行走宿主 CRT\n"); + printf("(probe) this line goes through the host CRT\n"); fflush(stdout); CHECK(con_uart_tx_n == 0U && used_now() == 0U, - "TC-CONLOG-000 宿主 printf 不经过本模块 fputc(否则测试输出会被吞进环)"); + "TC-CONLOG-000 host printf does not pass through this module fputc (else test output would be swallowed into the ring)"); reset_all(); con_uart_txe_stuck = 1; /* 通道卡死:任何字节都不该上线 */ - CHECK(dbg_console_write_line(0, 5U) == -1, "TC-CONLOG-001 write_line(NULL) 返回 -1"); - CHECK(dbg_console_write_line("abc", 0U) == -1, "TC-CONLOG-002 write_line(len=0) 返回 -1"); + CHECK(dbg_console_write_line(0, 5U) == -1, "TC-CONLOG-001 write_line(NULL) returns -1"); + CHECK(dbg_console_write_line("abc", 0U) == -1, "TC-CONLOG-002 write_line(len=0) returns -1"); dbg_console_write_raw(0, 5U); dbg_console_write_raw("abc", 0U); - CHECK(con_uart_tx_n == 0U, "TC-CONLOG-003 两路 NULL/0 都不碰 UART"); - CHECK(dbg_console_dropped() == 0U, "TC-CONLOG-004 参数非法不计入丢弃"); + CHECK(con_uart_tx_n == 0U, "TC-CONLOG-003 both NULL and len=0 never touch the UART"); + CHECK(dbg_console_dropped() == 0U, "TC-CONLOG-004 invalid arguments are not counted as drops"); reset_all(); memset(buf, 'A', sizeof(buf)); CHECK(dbg_console_write_line(buf, sizeof(buf)) == (int)DBG_CON_LINE_MAX, - "TC-CONLOG-005 超过 DBG_CON_LINE_MAX 的行按 192 截断(返回值即交付字节数)"); - CHECK(con_uart_tx_n == DBG_CON_LINE_MAX, "TC-CONLOG-006 截断后恰好上线 192 字节"); + "TC-CONLOG-005 a line longer than DBG_CON_LINE_MAX is truncated to 192 (return value is the delivered byte count)"); + CHECK(con_uart_tx_n == DBG_CON_LINE_MAX, "TC-CONLOG-006 after truncation exactly 192 bytes reach the wire"); } /* ============ TC-CONLOG-010..018 写者未注册 = 无锁直发 ============ */ @@ -521,26 +521,26 @@ static void tc_unattached(void) { char big[DBG_CON_CHUNK_MAX + 64U]; - printf("-- TC-CONLOG-010..018 写者未注册:无锁直发 --\n"); + printf("-- TC-CONLOG-010..018 writer not attached: lock-free direct send --\n"); reset_all(); - CHECK(dbg_console_writer_ready() == 0U, "TC-CONLOG-010 attach 之前 writer_ready() == 0"); - CHECK(dbg_console_write_line("hello", 5U) == 5, "TC-CONLOG-011 未注册时整行直发,返回行长"); - CHECK(tx_is(0U, "hello"), "TC-CONLOG-012 直发内容原样上线(没经过环形缓冲)"); - CHECK(used_now() == 0U, "TC-CONLOG-013 直发不入环(head == tail)"); - CHECK(con_evt_sets == 0U, "TC-CONLOG-014 直发不置 SYS_EVT_CONSOLE_TX(还没写者可唤醒)"); + CHECK(dbg_console_writer_ready() == 0U, "TC-CONLOG-010 writer_ready() == 0 before attach"); + CHECK(dbg_console_write_line("hello", 5U) == 5, "TC-CONLOG-011 before attach the whole line is sent directly, returning its length"); + CHECK(tx_is(0U, "hello"), "TC-CONLOG-012 direct send reaches the wire verbatim (never went through the ring)"); + CHECK(used_now() == 0U, "TC-CONLOG-013 direct send does not enter the ring (head == tail)"); + CHECK(con_evt_sets == 0U, "TC-CONLOG-014 direct send does not set SYS_EVT_CONSOLE_TX (no writer to wake yet)"); CHECK(con_crit_enter == 0U, - "TC-CONLOG-015 直发零临界区 = 2026-10-10 逐字节交错的根因(不是丢整行)"); + "TC-CONLOG-015 direct send uses zero critical sections = the 2026-10-10 byte-interleaving root cause (not whole-line loss)"); reset_all(); memset(big, 'B', sizeof(big)); dbg_console_write_raw(big, sizeof(big)); - CHECK(con_uart_tx_n == DBG_CON_CHUNK_MAX, "TC-CONLOG-016 write_raw 有界:只发 256 字节"); + CHECK(con_uart_tx_n == DBG_CON_CHUNK_MAX, "TC-CONLOG-016 write_raw is bounded: only 256 bytes are sent"); reset_all(); con_uart_txe_after = 3; /* 前 3 次不就绪(TXE 抖动,未超上界) */ - CHECK(dbg_console_write_line("CD", 2U) == 2, "TC-CONLOG-017 TXE 抖动后仍发全"); + CHECK(dbg_console_write_line("CD", 2U) == 2, "TC-CONLOG-017 after TXE jitter the whole line still goes out"); CHECK(tx_is(0U, "CD") && con_delay_calls == 0U, - "TC-CONLOG-018 直发既不等 tick 也不入环(ISR/崩溃钩子可用的前提)"); + "TC-CONLOG-018 direct send neither waits on tick nor enters the ring (premise for ISR and crash hooks)"); } /* ============ TC-CONLOG-020..037 注册后走环形缓冲 ============ */ @@ -550,24 +550,24 @@ static void tc_ring(void) static char oversize[3000]; /* 超长入环的源(>= 钳位后的 2048B) */ uint32_t i; - printf("-- TC-CONLOG-020..027 注册后:生产者入环、写者发送 --\n"); + printf("-- TC-CONLOG-020..027 after attach: producers enter the ring, writer sends --\n"); reset_all(); attach_writer(); - CHECK(dbg_console_writer_ready() == 1U, "TC-CONLOG-020 attach 之后 writer_ready() == 1"); + CHECK(dbg_console_writer_ready() == 1U, "TC-CONLOG-020 writer_ready() == 1 after attach"); CHECK(s_con_writer_task == (TaskHandle_t)&s_task_writer, - "TC-CONLOG-021 attach 记下的正是调用方的任务句柄(自等保护的依据)"); - CHECK(dbg_console_write_line("netTask up\r\n", 12U) == 12, "TC-CONLOG-022 入环成功返回行长"); - CHECK(con_uart_tx_n == 0U, "TC-CONLOG-023 生产者绝不碰 UART"); - CHECK(used_now() == 12U, "TC-CONLOG-024 整行一次入环(used = 12)"); + "TC-CONLOG-021 attach records exactly the caller task handle (basis of the self-wait guard)"); + CHECK(dbg_console_write_line("netTask up\r\n", 12U) == 12, "TC-CONLOG-022 a successful ring entry returns the line length"); + CHECK(con_uart_tx_n == 0U, "TC-CONLOG-023 producers never touch the UART"); + CHECK(used_now() == 12U, "TC-CONLOG-024 the whole line enters the ring at once (used = 12)"); CHECK(con_evt_sets == 1U && con_evt_flags == SYS_EVT_CONSOLE_TX, - "TC-CONLOG-025 入环后置真实事件位 SYS_EVT_CONSOLE_TX(bit6)唤醒写者"); + "TC-CONLOG-025 after entering the ring the real event bit SYS_EVT_CONSOLE_TX (bit6) wakes the writer"); CHECK(con_crit_enter == 1U && con_crit_exit == 1U && con_crit_max_depth == 1U, - "TC-CONLOG-026 整行入环恰好一层临界区(行级原子的实现依据)"); + "TC-CONLOG-026 one line takes exactly one critical-section level (implementation basis of line atomicity)"); writer_drain(); - CHECK(tx_is(0U, "netTask up\r\n"), "TC-CONLOG-027 写者排空:上线字节与入环内容逐字节相同"); + CHECK(tx_is(0U, "netTask up\r\n"), "TC-CONLOG-027 writer drain: wire bytes are byte-identical to what entered the ring"); - printf("-- TC-CONLOG-028..032 分块 256B 与多生产者不交错 --\n"); + printf("-- TC-CONLOG-028..032 256B chunking and no interleaving between producers --\n"); reset_all(); attach_writer(); memset(line, 'C', sizeof(line)); @@ -575,12 +575,12 @@ static void tc_ring(void) (void)dbg_console_write_line(line, sizeof(line)); } writer_drain(); - CHECK(con_uart_block_n == 4U, "TC-CONLOG-028 960B 按 DBG_CON_CHUNK_MAX 切成 4 块"); + CHECK(con_uart_block_n == 4U, "TC-CONLOG-028 960B is split into 4 blocks by DBG_CON_CHUNK_MAX"); CHECK(con_uart_block_len[0] == 256U && con_uart_block_len[1] == 256U && con_uart_block_len[2] == 256U && con_uart_block_len[3] == 192U, - "TC-CONLOG-029 块长 256/256/256/192(单次发送上限真被执行)"); + "TC-CONLOG-029 block sizes 256/256/256/192 (the single-send ceiling is really enforced)"); CHECK(con_uart_tx_n == 960U && con_uart_txe_reads == 960U, - "TC-CONLOG-030 每字节恰好装载一次 DR(就绪即写,没有重复发)"); + "TC-CONLOG-030 every byte is loaded into DR exactly once (write when ready, no resend)"); reset_all(); attach_writer(); @@ -592,36 +592,36 @@ static void tc_ring(void) (void)dbg_console_write_line("[C] 33333\r\n", 11U); writer_drain(); CHECK(tx_is(0U, "[A] 11111\r\n[B] 22222\r\n[C] 33333\r\n"), - "TC-CONLOG-031 三个生产者各写一行 -> 上线仍是三行连续原文(G1 行级原子)"); + "TC-CONLOG-031 three producers, one line each -> the wire still shows three intact lines (G1 line atomicity)"); CHECK(strstr((const char *)&con_uart_tx[5], "[B] 22222") != 0, - "TC-CONLOG-032 行边界没被打断(没有任何一行被插进另一行中间)"); + "TC-CONLOG-032 no line boundary was broken (no line spliced into another)"); - printf("-- TC-CONLOG-033..037 跨环尾:两段拷贝 + 按连续段分块 --\n"); + printf("-- TC-CONLOG-033..037 ring wrap: two-segment copy + chunking by contiguous run --\n"); reset_all(); attach_writer(); s_con_head = 4090U; s_con_tail = 4090U; (void)dbg_console_write_line("0123456789ABCDEF", 16U); CHECK(s_con_head == 10U && used_now() == 16U, - "TC-CONLOG-033 跨环尾入环后 head 回绕到 10(4090+16-4096)"); + "TC-CONLOG-033 a wrapped line leaves head at 10 (4090+16-4096)"); CHECK(memcmp(&con_ring_store[4090], "012345", 6) == 0 && con_ring_store[0] == (uint8_t)'6' && con_ring_store[9] == (uint8_t)'F' && con_ring_store[10] == 0U, - "TC-CONLOG-034 回绕两段拷贝位置正确(前 6B 填到环尾、余 10B 从 0 起)"); + "TC-CONLOG-034 both wrap segments land correctly (first 6B fill to the ring end, remaining 10B start at 0)"); writer_drain(); CHECK(con_uart_block_n == 2U && con_uart_block_len[0] == 6U && con_uart_block_len[1] == 10U, - "TC-CONLOG-035 drain 按连续段分块:6 + 10(绝不把环中间当连续段读越界)"); - CHECK(tx_is(0U, "0123456789ABCDEF"), "TC-CONLOG-036 回绕行的上线内容与顺序都对"); + "TC-CONLOG-035 drain chunks by contiguous run: 6 + 10 (never reads past the ring end)"); + CHECK(tx_is(0U, "0123456789ABCDEF"), "TC-CONLOG-036 the wrapped line reaches the wire with correct content and order"); reset_all(); attach_writer(); /* 源缓冲必须给到 3000B:con_append 只钳长度,不会钳读取范围, * 拿 192B 的栈数组当 2048B 源就是越界读(插桩跑直接 0xC0000005) */ memset(oversize, 'D', sizeof(oversize)); - CHECK(con_append(oversize, (uint16_t)3000U) == 0, "TC-CONLOG-037 直调 con_append 超长仍成功"); + CHECK(con_append(oversize, (uint16_t)3000U) == 0, "TC-CONLOG-037 calling con_append directly with an over-long buffer still succeeds"); CHECK(used_now() == (DBG_CON_RING_SIZE / 2U), - "TC-CONLOG-038 入环长度钳在 RING/2=2048(保证任何一行都恒可入环)"); + "TC-CONLOG-038 ring entry length is clamped to RING/2=2048 (so any line can always eventually enter)"); } /* ============ TC-CONLOG-040..042 写者自记录 / 重入 / 未注册 drain ============ */ @@ -630,7 +630,7 @@ static void tc_writer_self(void) char line[DBG_CON_LINE_MAX]; uint32_t i; - printf("-- TC-CONLOG-040..042 写者自记录先排空 / drain 重入保护 --\n"); + printf("-- TC-CONLOG-040..042 writer self-logging drains first / drain re-entry guard --\n"); reset_all(); attach_writer(); memset(line, 'E', sizeof(line)); @@ -638,11 +638,11 @@ static void tc_writer_self(void) (void)dbg_console_write_line(line, sizeof(line)); } con_task_self = (TaskHandle_t)&s_task_writer; /* 写者自己记一行 */ - CHECK(dbg_console_write_line("F", 1U) == 1, "TC-CONLOG-040 写者自记录不丢行"); + CHECK(dbg_console_write_line("F", 1U) == 1, "TC-CONLOG-040 a writer logging about itself loses no line"); CHECK(con_delay_calls == 0U, - "TC-CONLOG-041 写者自记录先排空再入环:绝不进等待(否则就是等自己 -> 死锁)"); + "TC-CONLOG-041 writer self-logging drains before entering: it never waits (waiting for itself would deadlock)"); CHECK(con_uart_tx_n == 4032U && used_now() == 1U && dbg_console_dropped() == 0U, - "TC-CONLOG-042 老行全部上线、新行入环,零丢弃"); + "TC-CONLOG-042 old lines all reach the wire, the new line enters the ring, zero drops"); reset_all(); attach_writer(); @@ -650,56 +650,56 @@ static void tc_writer_self(void) s_con_draining = 1U; /* 模拟正处于 drain 之内 */ writer_drain(); CHECK(con_uart_tx_n == 0U && used_now() == 4U, - "TC-CONLOG-043 drain 重入保护:嵌套调用直接让位(写者自记录不触发递归 drain)"); + "TC-CONLOG-043 drain re-entry guard: a nested call yields at once (writer self-logging causes no recursive drain)"); reset_all(); (void)dbg_console_write_line("early\r\n", 7U); /* 未注册 -> 已直发 */ con_uart_tx_n = 0U; writer_drain(); - CHECK(con_uart_tx_n == 0U, "TC-CONLOG-044 写者未注册时 drain 不做任何事"); + CHECK(con_uart_tx_n == 0U, "TC-CONLOG-044 with no writer attached drain does nothing"); } /* ============ TC-CONLOG-050..062 缓冲满 / 丢弃 / 可观测 ============ */ static void tc_full_drop(void) { - printf("-- TC-CONLOG-050..053 缓冲满:DWT 硬上界丢弃且不覆盖旧行 --\n"); + printf("-- TC-CONLOG-050..053 ring full: DWT hard ceiling drops without overwriting old lines --\n"); reset_all(); attach_writer(); fill_ring(10U); /* 只剩 10B 可用 */ con_dwt_step = SystemCoreClock / 4U; /* 一次判据 = 250ms > 200ms 上界 */ CHECK(dbg_console_write_line("0123456789ABCDEFGHIJ", 20U) == -1, - "TC-CONLOG-050 环满 + DWT 上界到 -> 丢这一行(返回 -1)"); - CHECK(dbg_console_dropped() == 1U, "TC-CONLOG-051 丢弃计数 +1"); + "TC-CONLOG-050 ring full + DWT ceiling reached -> this line is dropped (returns -1)"); + CHECK(dbg_console_dropped() == 1U, "TC-CONLOG-051 drop counter +1"); CHECK(con_delay_calls == 0U, - "TC-CONLOG-052 有 DWT 时用周期判据,不必先烧 200 个 tick(K4)"); + "TC-CONLOG-052 with DWT the cycle criterion is used, no need to burn 200 ticks first (K4)"); CHECK(s_con_head == 4085U && used_now() == 4085U && con_uart_tx_n == 0U, - "TC-CONLOG-053 丢弃不推进 head、也不生产者自己发(没半写、更没覆盖未发出的旧行)"); + "TC-CONLOG-053 a drop does not advance head and the producer does not send itself (no half write, no overwrite of pending lines)"); - printf("-- TC-CONLOG-054..056 等待中出现空间 -> 入环成功 --\n"); + printf("-- TC-CONLOG-054..056 space appears while waiting -> line enters the ring --\n"); reset_all(); attach_writer(); fill_ring(10U); con_dwt_step = 0U; /* 时间静止:只能靠写者腾地方 */ con_delay_hook = bg_drain_hook; /* 每等一轮 = 写者排空一次 */ CHECK(dbg_console_write_line("0123456789ABCDEFGHIJ", 20U) == 20, - "TC-CONLOG-054 等一轮后腾出空间 -> 整行入环成功"); + "TC-CONLOG-054 after one wait round space frees up -> the whole line enters the ring"); CHECK(con_delay_calls == 1U && dbg_console_dropped() == 0U, - "TC-CONLOG-055 只等了一轮,且不算丢弃"); + "TC-CONLOG-055 only one wait round happened and it is not counted as a drop"); con_delay_hook = 0; - CHECK(con_uart_tx_n == 4085U, "TC-CONLOG-056 腾地方的正是写者(老行已上线)"); + CHECK(con_uart_tx_n == 4085U, "TC-CONLOG-056 it really was the writer that freed the space (old lines reached the wire)"); - printf("-- TC-CONLOG-057..059 无 DWT 支路:等待上界 = DBG_CON_WAIT_MS 个 tick --\n"); + printf("-- TC-CONLOG-057..059 no-DWT branch: wait ceiling = DBG_CON_WAIT_MS ticks --\n"); reset_all(); con_dwt_ctrl_sticky = 0; /* 调试单元被关 -> DWT 使能失败 */ attach_writer(); fill_ring(10U); - CHECK(s_con_dwt_up == 0U, "TC-CONLOG-057 DWT 使能失败时 s_con_dwt_up 保持 0"); + CHECK(s_con_dwt_up == 0U, "TC-CONLOG-057 s_con_dwt_up stays 0 when DWT enable fails"); CHECK(dbg_console_write_line("0123456789ABCDEFGHIJ", 20U) == -1, - "TC-CONLOG-058 无 DWT 时仍会丢(判据退回 tick 计数,不会无限等)"); + "TC-CONLOG-058 without DWT a drop still happens (criterion falls back to tick counting, never waits forever)"); CHECK(con_delay_calls == DBG_CON_WAIT_MS && dbg_console_dropped() == 1U, - "TC-CONLOG-059 无 DWT 的等待上界恰为 DBG_CON_WAIT_MS(200) 次 vTaskDelay"); + "TC-CONLOG-059 the no-DWT wait ceiling is exactly DBG_CON_WAIT_MS(200) vTaskDelay calls"); - printf("-- TC-CONLOG-060..062 丢弃可观测:[ERR] 行直发不经环 --\n"); + printf("-- TC-CONLOG-060..062 drop observability: the [ERR] line is sent raw, not through the ring --\n"); reset_all(); attach_writer(); fill_ring(10U); @@ -708,10 +708,10 @@ static void tc_full_drop(void) con_dwt_step = 0U; writer_drain(); CHECK(tx_contains("[ERR] CONSOLE dropped 1 lines"), - "TC-CONLOG-060 排空末尾刷出 [ERR] CONSOLE dropped 1 lines(丢行永不静默,@test 判 FAIL)"); - CHECK(dbg_console_dropped() == 0U, "TC-CONLOG-061 刷完即清零(下一轮不重复告警)"); + "TC-CONLOG-060 the drain tail flushes [ERR] CONSOLE dropped 1 lines (loss is never silent, @test marks FAIL)"); + CHECK(dbg_console_dropped() == 0U, "TC-CONLOG-061 the counter is cleared once flushed (next round does not repeat the warning)"); CHECK(used_now() == 0U, - "TC-CONLOG-062 告警行走裸发:不入环 -> 不会 con_append->drain 递归"); + "TC-CONLOG-062 the warning goes out raw: not through the ring -> no con_append->drain recursion"); } /* ============ TC-CONLOG-070..081 TX 僵尸通道:自愈 / 冷却 / 半块 ============ */ @@ -729,21 +729,21 @@ static void fault_setup(uint32_t tick0, int repair) static void tc_tx_fault(void) { - printf("-- TC-CONLOG-070..074 软复位没治好:故障即止 + 留痕只能靠标志 --\n"); + printf("-- TC-CONLOG-070..074 soft reset did not heal: stop at the fault + trace only via flag --\n"); reset_all(); fault_setup(5000U, 0); - CHECK(dbg_console_tx_fault() == 1U, "TC-CONLOG-070 发送超时 -> tx_fault 计数 +1"); + CHECK(dbg_console_tx_fault() == 1U, "TC-CONLOG-070 send timeout -> tx_fault counter +1"); CHECK(s_mx_init_calls == 1U && con_nvic_clears == 1U && con_rcc_disables == 1U && con_rcc_enables == 1U, - "TC-CONLOG-071 自愈完整一遍:清 pending -> 断时钟 -> 供时钟 -> 重初始化"); + "TC-CONLOG-071 full self-heal sequence: clear pending -> gate off clock -> gate on clock -> re-init"); CHECK(used_now() == (DBG_CON_RING_SIZE - 1U) - DBG_CON_CHUNK_MAX, - "TC-CONLOG-072 故障即止:只丢当前 256B 块,其余留环里等下轮(让位喂狗)"); + "TC-CONLOG-072 stop at the fault: only the current 256B block is lost, the rest waits in the ring (yields to the watchdog)"); CHECK(con_uart_tx_n == 0U, - "TC-CONLOG-073 通道没治好时连那条 WARN 也上不了线(裸发同样有界、不重试)"); + "TC-CONLOG-073 while the channel is unhealed even that WARN cannot get out (raw send is bounded too, no retry)"); CHECK(dbg_console_tx_fault_log_take() == 1U && dbg_console_tx_fault_log_take() == 0U, - "TC-CONLOG-074 留痕标志读后清:写者据此在 drain 之外补记 run.log(断调用图成环)"); + "TC-CONLOG-074 the trace flag is read-then-clear: the writer uses it to append run.log outside drain (breaks the call graph cycle)"); - printf("-- TC-CONLOG-075..077 软复位治好了:WARN 上线且只一次 --\n"); + printf("-- TC-CONLOG-075..077 soft reset healed: the WARN goes out exactly once --\n"); reset_all(); con_tick_now = 7000U; attach_writer(); @@ -752,14 +752,14 @@ static void tc_tx_fault(void) con_dwt_step = SystemCoreClock / 4U; s_mx_repair = 1; /* 重初始化把通道治好 */ writer_drain(); - CHECK(tx_contains("[WARN] CONSOLE tx fault"), "TC-CONLOG-075 首次故障的 WARN 行成功上线"); + CHECK(tx_contains("[WARN] CONSOLE tx fault"), "TC-CONLOG-075 the first fault WARN line reaches the wire"); CHECK(used_now() == 0U && s_con_cool_until == 7000U && dbg_console_tx_fault() == 1U, - "TC-CONLOG-076 故障块丢弃(行已出环不可重放)+ 冷却截止记为当时 tick"); + "TC-CONLOG-076 the faulted block is dropped (already out of the ring, not replayable) + cooldown deadline is the tick then"); con_uart_txe_ready_left = -1; con_dwt_step = 0U; writer_drain(); /* tick 未推进 -> 仍在冷却 */ CHECK(s_con_cool_until == 7000U && s_mx_init_calls == 1U, - "TC-CONLOG-077 冷却期内 drain 直接让位:不重试、不自愈第二次"); + "TC-CONLOG-077 during cooldown drain yields at once: no retry, no second self-heal"); } static void tc_tx_cool(void) @@ -768,36 +768,36 @@ static void tc_tx_cool(void) reset_all(); fault_setup(7000U, 1); /* 治好的那次故障 */ CHECK(s_con_cool_until == 7000U && used_now() == 3839U, - "TC-CONLOG-078 故障后剩 3839B 在环里(本块被丢)"); + "TC-CONLOG-078 3839B remain in the ring after the fault (this block was dropped)"); con_dwt_step = 0U; con_uart_txe_stuck = 0; con_tick_now = 7299U; /* 差 1ms */ writer_drain(); CHECK(s_con_cool_until == 7000U && used_now() == 3839U && s_mx_init_calls == 1U, - "TC-CONLOG-079 差 1ms 仍在冷却:环不动、不重复自愈(冷却即节奏保护)"); + "TC-CONLOG-079 1ms short of the deadline: the ring does not move and no repeated self-heal (cooldown is the pacing guard)"); con_tick_now = 7300U; /* 到点 */ writer_drain(); CHECK(s_con_cooling == 0U && used_now() == 0U && dbg_console_tx_fault() == 1U, - "TC-CONLOG-080 到点即清冷却标志、放行本轮排空,且没有新增故障" - "(cool_until 只存时刻,不再被拿来当哨兵清零)"); + "TC-CONLOG-080 at the deadline the flag clears, this round drains, and no new fault appears" + " (cool_until only stores a deadline and is no longer used as a clear-on-zero sentinel)"); /* 修复后的正向断言:冷却与否看独立标志,不再拿 tick 值当哨兵 */ reset_all(); fault_setup(0U, 0); /* 故障恰好落在 HAL_GetTick()==0 那一拍 */ CHECK(s_con_cooling == 1U && dbg_console_tx_fault() == 1U, - "TC-CONLOG-081 tick==0 那拍的故障照样进入冷却(独立标志,不撞 0 哨兵)"); + "TC-CONLOG-081 a fault in the tick==0 round still enters cooldown (own flag, no zero sentinel collision)"); writer_drain(); /* tick 仍是 0 */ CHECK(dbg_console_tx_fault() == 1U && s_mx_init_calls == 1U && used_now() == (DBG_CON_RING_SIZE - 1U) - DBG_CON_CHUNK_MAX, - "TC-CONLOG-082 同一 tick 上再来一轮被冷却挡住:不再白耗一次块超时"); + "TC-CONLOG-082 another round on the same tick is blocked by cooldown: no second wasted block timeout"); con_tick_now = DBG_CON_FAULT_COOL_MS - 1U; writer_drain(); - CHECK(dbg_console_tx_fault() == 1U, "TC-CONLOG-083 冷却 299ms 仍未到点"); + CHECK(dbg_console_tx_fault() == 1U, "TC-CONLOG-083 299ms is still inside the cooldown"); con_uart_txe_stuck = 0; con_tick_now = DBG_CON_FAULT_COOL_MS; /* 到点(且回绕起点正好是 0) */ writer_drain(); CHECK(s_con_cooling == 0U && used_now() == 0U && dbg_console_tx_fault() == 1U, - "TC-CONLOG-084 到点后清冷却并放行:全程没有第二次故障"); + "TC-CONLOG-084 after the deadline the cooldown clears and passes through: no second fault anywhere"); reset_all(); attach_writer(); @@ -816,16 +816,16 @@ static void tc_tx_cool(void) static void tc_tx_half(void) { - printf("-- TC-CONLOG-085..088 超时判据的真实后果:半块 / 已上线仍判失败 --\n"); + printf("-- TC-CONLOG-085..088 real consequences of the timeout criterion: half block / already sent yet failed --\n"); reset_all(); attach_writer(); (void)dbg_console_write_line("ABCDEFGH", 8U); con_uart_tc_stuck = 1; /* 字节都进了 DR,只有 TC 不置位 */ con_dwt_step = SystemCoreClock / 4U; writer_drain(); - CHECK(tx_is(0U, "ABCDEFGH"), "TC-CONLOG-085 TC 卡死:8 字节都已上线"); + CHECK(tx_is(0U, "ABCDEFGH"), "TC-CONLOG-085 TC stuck: all 8 bytes were handed to the shifter"); CHECK(dbg_console_tx_fault() == 1U && con_uart_block_n == 0U, - "TC-CONLOG-086 已上线仍整块判失败(docs §13-O2:丢弃/故障两本账没分开的现状)"); + "TC-CONLOG-086 already on the wire but the whole block still counts as failed (docs section 13-O2: drop and fault books were not separated)"); reset_all(); attach_writer(); @@ -833,50 +833,50 @@ static void tc_tx_half(void) con_uart_txe_ready_left = 3; /* 只挤得出 3 个字节 */ con_dwt_step = SystemCoreClock / 4U; writer_drain(); - CHECK(tx_is(0U, "ABC"), "TC-CONLOG-087 TXE 中途卡死 -> 只有已写进 DR 的 3 字节上线"); + CHECK(tx_is(0U, "ABC"), "TC-CONLOG-087 TXE stuck mid-block -> only the 3 bytes already written to DR reach the wire"); CHECK(dbg_console_tx_fault() == 1U && used_now() == 0U, - "TC-CONLOG-088 半块同样走自愈分支,整块出环(尾部 5 字节随块作废)"); + "TC-CONLOG-088 a half block takes the same self-heal branch and leaves the ring (trailing 5 bytes die with the block)"); } /* ============ TC-CONLOG-090..099 DWT 使能 / 指令计数上界 ============ */ static void tc_dwt(void) { - printf("-- TC-CONLOG-090..093 DWT 惰性使能与就绪即走 --\n"); + printf("-- TC-CONLOG-090..093 lazy DWT enable and skip-when-ready --\n"); reset_all(); (void)dbg_console_write_line("ok\r\n", 4U); /* 走一次直发 -> 顺带使能 DWT */ - CHECK(s_con_dwt_up == 1U, "TC-CONLOG-090 con_dwt_ensure 成功使能后置 s_con_dwt_up"); + CHECK(s_con_dwt_up == 1U, "TC-CONLOG-090 con_dwt_ensure sets s_con_dwt_up after a successful enable"); CHECK((g_con_core_debug.DEMCR & CoreDebug_DEMCR_TRCENA_Msk) != 0U, - "TC-CONLOG-091 真的写了 DEMCR.TRCENA(位号与 core_cm4.h 一致)"); + "TC-CONLOG-091 DEMCR.TRCENA really gets written (bit number matches core_cm4.h)"); CHECK((g_con_dwt.CTRL & DWT_CTRL_CYCCNTENA_Msk) != 0U, - "TC-CONLOG-092 真的写了 DWT.CTRL.CYCCNTENA"); + "TC-CONLOG-092 DWT.CTRL.CYCCNTENA really gets written"); CHECK(tx_is(0U, "ok\r\n") && con_dwt_reads == 4U, - "TC-CONLOG-093 通道就绪时发送循环没再读 CYCCNT(3 次 ensure + 1 次取基准 t0)"); + "TC-CONLOG-093 with the channel ready the send loop reads no further CYCCNT (3 from ensure + 1 for t0)"); - printf("-- TC-CONLOG-094..097 DWT 使能失败 -> con_tx_counted 计数上界 --\n"); + printf("-- TC-CONLOG-094..097 DWT enable failure -> con_tx_counted instruction ceiling --\n"); reset_all(); con_dwt_ctrl_sticky = 0; /* CYCCNTENA 写不进去 */ con_uart_txe_stuck = 1; dbg_console_write_raw("Q", 1U); - CHECK(s_con_dwt_up == 0U, "TC-CONLOG-094 DWT 使能失败 -> 走计数上界支路"); + CHECK(s_con_dwt_up == 0U, "TC-CONLOG-094 DWT enable failure -> the counted-guard branch is taken"); CHECK(con_uart_txe_reads == CON_TX_GUARD_MAX, - "TC-CONLOG-095 每字节最多自旋 CON_TX_GUARD_MAX(20000) 次即放弃(有界,非死等)"); - CHECK(con_uart_tx_n == 0U, "TC-CONLOG-096 计数上界内没发出去就整块放弃"); + "TC-CONLOG-095 each byte spins at most CON_TX_GUARD_MAX(20000) times then gives up (bounded, not a dead wait)"); + CHECK(con_uart_tx_n == 0U, "TC-CONLOG-096 if the block is not out within the counted ceiling the whole block is abandoned"); CHECK(con_dwt_reads == 3U, - "TC-CONLOG-097 计数支路一次都不读 CYCCNT(不依赖 DWT,也就不依赖时间源)"); + "TC-CONLOG-097 the counted branch never reads CYCCNT (independent of DWT, hence of any time source)"); - printf("-- TC-CONLOG-098..099 超时判据不依赖 HAL_GetTick(round 8b 的动机) --\n"); + printf("-- TC-CONLOG-098..099 the timeout criterion does not use HAL_GetTick (round 8b motivation) --\n"); reset_all(); con_uart_txe_stuck = 1; /* tick 冻结在 0,模拟 TIM7 停摆 */ con_dwt_step = SystemCoreClock / 10U; /* 一次判据正好 = 100ms 上界 */ dbg_console_write_raw("Q", 1U); CHECK(con_tick_reads == 0U && con_uart_tx_n == 0U, - "TC-CONLOG-098 tick 完全不走也能退出:裸发一次都没读 HAL_GetTick"); + "TC-CONLOG-098 it exits even when tick never advances: one raw send reads HAL_GetTick zero times"); reset_all(); con_uart_txe_stuck = 1; con_dwt_step = SystemCoreClock / 4U; dbg_console_write_raw("Z", 1U); CHECK(con_uart_txe_reads == 1U, - "TC-CONLOG-099 DWT 支路第一次自旋就判超时(上界真的起作用,不会拖满 20000 次)"); + "TC-CONLOG-099 the DWT branch declares timeout on the first spin (the ceiling really works, never burns 20000)"); } /* ============ TC-CONLOG-100..106 huart1.Instance == NULL 短路 + 未初始化分诊 ============ */ @@ -887,14 +887,14 @@ static void tc_null_uart(void) huart1.Instance = 0; dbg_console_write_raw("boom", 5U); CHECK(con_uart_tx_n == 0U && con_uart_txe_reads == 0U, - "TC-CONLOG-100 Instance==NULL 时一次寄存器都不碰(不解引用地址 0)"); + "TC-CONLOG-100 with Instance==NULL not one register is touched (no dereference of address 0)"); CHECK(con_dwt_reads == 3U, - "TC-CONLOG-101 仍然先惰性使能 DWT 再短路(ensure 在判空之前,顺序照旧)"); + "TC-CONLOG-101 DWT is still lazily enabled before the short circuit (ensure stays ahead of the NULL check)"); reset_all(); huart1.Instance = 0; CHECK(dbg_console_write_line("early", 5U) == 5, - "TC-CONLOG-102 未注册路径(内核前)撞上无串口也不崩、仍返回行长"); + "TC-CONLOG-102 the unattached path (pre-kernel) survives a missing UART and still returns the line length"); /* 修复后的正向断言:未初始化 != 僵尸通道,绝不重配外设 */ reset_all(); @@ -920,26 +920,26 @@ static void tc_null_uart(void) /* ============ TC-CONLOG-110..115 fputc 重定向 ============ */ static void tc_fputc(void) { - printf("-- TC-CONLOG-110..115 fputc 重定向(printf 遗留路径) --\n"); + printf("-- TC-CONLOG-110..115 fputc retarget (legacy printf path) --\n"); reset_all(); - CHECK(con_fputc_under_test('Q', stdout) == 'Q', "TC-CONLOG-110 fputc 原样返回字符(C 库约定)"); + CHECK(con_fputc_under_test('Q', stdout) == 'Q', "TC-CONLOG-110 fputc returns the character unchanged (C library convention)"); CHECK(tx_is(0U, "Q") && used_now() == 0U, - "TC-CONLOG-111 未注册写者:printf 的字节直发(与旧行为一致)"); + "TC-CONLOG-111 writer not attached: printf bytes go out directly (same as the old behaviour)"); reset_all(); attach_writer(); (void)con_fputc_under_test('R', stdout); CHECK(con_uart_tx_n == 0U && used_now() == 1U && con_ring_store[0] == (uint8_t)'R', - "TC-CONLOG-112 注册后 fputc 也收敛到单写者路径(逐字节入环)"); + "TC-CONLOG-112 after attach fputc also funnels into the single-writer path (byte by byte into the ring)"); writer_drain(); - CHECK(tx_is(0U, "R"), "TC-CONLOG-113 写者把 printf 字节发出"); + CHECK(tx_is(0U, "R"), "TC-CONLOG-113 the writer sends those printf bytes"); reset_all(); attach_writer(); con_ipsr = 12U; /* 假异常号:任意非 0 */ - CHECK(dbg_console_write_line("ISR", 3U) == 3, "TC-CONLOG-114 中断上下文写整行返回行长"); + CHECK(dbg_console_write_line("ISR", 3U) == 3, "TC-CONLOG-114 writing a whole line from interrupt context returns the line length"); CHECK(tx_is(0U, "ISR") && used_now() == 0U && con_delay_calls == 0U, - "TC-CONLOG-115 中断上下文一律裸发:不入环、不等待(否则在 ISR 里睡死)"); + "TC-CONLOG-115 interrupt context always sends raw: no ring entry, no waiting (else it sleeps inside the ISR)"); reset_all(); attach_writer(); @@ -947,59 +947,59 @@ static void tc_fputc(void) con_ipsr = 5U; con_dwt_step = SystemCoreClock / 4U; CHECK(dbg_console_write_line("0123456789", 10U) == 10, - "TC-CONLOG-116 环全满 + 中断上下文:仍直发成功(ISR 绝不进丢弃等待)"); + "TC-CONLOG-116 ring completely full + interrupt context: still sends directly (an ISR never enters the drop wait)"); CHECK(dbg_console_dropped() == 0U && con_delay_calls == 0U, - "TC-CONLOG-117 这条路径既不丢行也不记丢弃(K1:内核前/ISR 不依赖任何内核对象)"); + "TC-CONLOG-117 this path loses no line and records no drop (K1: pre-kernel and ISR depend on no kernel object)"); } /* ============ TC-CONLOG-120..122 drain 250ms 预算 ============ */ static void tc_budget(void) { - printf("-- TC-CONLOG-120..122 单次 drain 预算 250ms(让位喂狗轮询) --\n"); + printf("-- TC-CONLOG-120..122 single drain budget 250ms (yields to the watchdog poll) --\n"); reset_all(); attach_writer(); fill_ring(0U); /* 4095B = 16 块 */ con_tick_step = 130U; /* 每次读 tick 走 130ms */ writer_drain(); - CHECK(con_uart_block_n == 2U, "TC-CONLOG-120 一轮只发 2 块就因预算让位(不是发完)"); + CHECK(con_uart_block_n == 2U, "TC-CONLOG-120 one round sends only 2 blocks then yields on budget (not because it finished)"); CHECK(used_now() == (DBG_CON_RING_SIZE - 1U) - (2U * DBG_CON_CHUNK_MAX), - "TC-CONLOG-121 让位时余下 3583B 留在环里(下轮续排,不丢)"); + "TC-CONLOG-121 when it yields, 3583B remain in the ring (next round continues, nothing lost)"); con_tick_step = 0U; writer_drain(); /* 预算内发完余下 3583B */ CHECK(used_now() == 0U && con_uart_tx_n == (DBG_CON_RING_SIZE - 1U), - "TC-CONLOG-122 下轮把余下的 3583B 也发完:预算让位不丢字节(累计 4095)"); + "TC-CONLOG-122 the next round sends the remaining 3583B too: yielding on budget loses no bytes (4095 total)"); } /* ============ TC-CONLOG-130..135 计数支路的成功路径 / TC 抖动 / 直调 NULL ============ */ static void tc_counted_paths(void) { - printf("-- TC-CONLOG-130..132 DWT 不可用 -> con_tx_counted 也能发全(不只会超时) --\n"); + printf("-- TC-CONLOG-130..132 DWT unavailable -> con_tx_counted can also finish a block (not only time out) --\n"); reset_all(); con_dwt_ctrl_sticky = 0; /* CYCCNTENA 落不住 */ con_tick_now = 9000U; /* tick 冻结:证明与本支路无关 */ dbg_console_write_raw("AB", 2U); CHECK(s_con_dwt_up == 0U && tx_is(0U, "AB"), - "TC-CONLOG-130 计数支路把整块发完并返回成功(回退路径没退化)"); + "TC-CONLOG-130 the counted branch sends the whole block and returns success (fallback path did not regress)"); CHECK(con_uart_tc_reads == 1U && con_dwt_reads == 3U && con_tick_reads == 0U, - "TC-CONLOG-131 计数支路既不等 tick 也不再读 CYCCNT(零外部时间源依赖)"); + "TC-CONLOG-131 the counted branch waits no tick and reads no CYCCNT (zero external time source)"); reset_all(); con_dwt_ctrl_sticky = 0; con_uart_tc_stuck = 1; /* 字节能进 DR,TC 永不置位 */ dbg_console_write_raw("CD", 2U); CHECK(tx_is(0U, "CD") && con_uart_tc_reads == CON_TX_GUARD_MAX, - "TC-CONLOG-132 TC 卡死时计数支路同样最多自旋 CON_TX_GUARD_MAX 次即放弃"); + "TC-CONLOG-132 with TC stuck the counted branch also gives up after at most CON_TX_GUARD_MAX spins"); - printf("-- TC-CONLOG-133..135 DWT 支路 TC 抖动 / con_append 直调参数校验 --\n"); + printf("-- TC-CONLOG-133..135 DWT branch TC jitter / con_append direct-call argument checks --\n"); reset_all(); con_dwt_step = 1U; /* 时间走得极慢:不会误判超时 */ con_uart_tc_after = 2; /* 前两轮 TC 不就绪 */ dbg_console_write_raw("EF", 2U); CHECK(tx_is(0U, "EF") && con_uart_tc_reads == 3U, - "TC-CONLOG-133 TC 抖动(未超上界)后仍算整块成功:TC 循环能正常退出"); + "TC-CONLOG-133 TC jitter (below the ceiling) still ends as a successful block: the TC loop exits normally"); reset_all(); - CHECK(con_append(0, 3U) == -1, "TC-CONLOG-134 con_append(NULL) 自己也要挡住(不只靠上层)"); - CHECK(con_append("abc", 0U) == -1, "TC-CONLOG-135 con_append(len=0) 同样拒绝"); + CHECK(con_append(0, 3U) == -1, "TC-CONLOG-134 con_append(NULL) must block it itself (not only relying on the caller)"); + CHECK(con_append("abc", 0U) == -1, "TC-CONLOG-135 con_append(len=0) is rejected the same way"); } diff --git a/test/host/ftp_auth/ftp_auth_test.c b/test/host/ftp_auth/ftp_auth_test.c index 0f91f267..69f44c9b 100644 --- a/test/host/ftp_auth/ftp_auth_test.c +++ b/test/host/ftp_auth/ftp_auth_test.c @@ -58,11 +58,11 @@ static const ftp_auth_creds_t s_creds = { "admin", DEF_HASH, 1u }; static void tc_user_match(void) { - 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 拒绝"); + CHECK(ftp_auth_user_match("admin", "admin") == 1, "TC-FTPAUTH-001a equal strings match"); + CHECK(ftp_auth_user_match("admin", "ADMIN") == 1, "TC-FTPAUTH-001b case-insensitive"); + CHECK(ftp_auth_user_match("admin", "root") == 0, "TC-FTPAUTH-001c mismatch rejected"); + CHECK(ftp_auth_user_match("admin", "admin2") == 0, "TC-FTPAUTH-001d prefix does not count as match"); + CHECK(ftp_auth_user_match("admin", NULL) == 0, "TC-FTPAUTH-001e NULL rejected"); } /* ===================== TC-FTPAUTH-002..004:基本判定 ===================== */ @@ -73,17 +73,17 @@ 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-FTPAUTH-002 对用户名+对口令 → OK"); - CHECK(st.fail_count == 0u, "TC-FTPAUTH-002b 成功后计数为 0"); + "TC-FTPAUTH-002 right user + right password -> OK"); + CHECK(st.fail_count == 0u, "TC-FTPAUTH-002b counter is 0 after success"); (void)memset(&st, 0, sizeof(st)); CHECK(ftp_auth_check(&s_creds, 1u, "wrong", &st, 1000u) == FTP_AUTH_FAIL, - "TC-FTPAUTH-003 错口令 → FAIL"); - CHECK(st.fail_count == 1u, "TC-FTPAUTH-003b 失败计数 1"); + "TC-FTPAUTH-003 wrong password -> FAIL"); + CHECK(st.fail_count == 1u, "TC-FTPAUTH-003b fail count = 1"); (void)memset(&st, 0, sizeof(st)); CHECK(ftp_auth_check(&s_creds, 0u, "admin", &st, 1000u) == FTP_AUTH_FAIL, - "TC-FTPAUTH-004 错用户名+对口令 → FAIL(哈希路径已走)"); + "TC-FTPAUTH-004 wrong user + right password -> FAIL (hash path taken)"); } /* ===================== TC-FTPAUTH-005..006:锁定与解锁 ===================== */ @@ -96,22 +96,22 @@ 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-FTPAUTH-005 第 1..5 次失败 → FAIL"); + "TC-FTPAUTH-005 attempts 1..5 -> FAIL"); } - CHECK(st.fail_count == 5u, "TC-FTPAUTH-005b 计数到达 FAIL_MAX"); + CHECK(st.fail_count == 5u, "TC-FTPAUTH-005b counter reaches FAIL_MAX"); /* 锁定期内:对口令也 LOCKED,且不再计数 */ CHECK(ftp_auth_check(&s_creds, 1u, "admin", &st, t + 1u) == FTP_AUTH_LOCKED, - "TC-FTPAUTH-005c 锁定期内对口令 → LOCKED"); - CHECK(st.fail_count == 5u, "TC-FTPAUTH-005d LOCKED 不改变计数"); + "TC-FTPAUTH-005c right password during lock window -> LOCKED"); + CHECK(st.fail_count == 5u, "TC-FTPAUTH-005d LOCKED does not change the counter"); /* 59999 tick:仍在窗内(差值 < 60000) */ CHECK(ftp_auth_check(&s_creds, 1u, "admin", &st, st.lock_until_tick - 1u) == FTP_AUTH_LOCKED, - "TC-FTPAUTH-005e 窗内最后 1 tick 仍 LOCKED"); + "TC-FTPAUTH-005e last tick inside window still LOCKED"); /* 期满:恰好到达 lock_until → 放行 */ CHECK(ftp_auth_check(&s_creds, 1u, "admin", &st, st.lock_until_tick) == FTP_AUTH_OK, - "TC-FTPAUTH-006 期满对口令 → OK"); - CHECK(st.fail_count == 0u, "TC-FTPAUTH-006b 解锁成功后计数清零"); + "TC-FTPAUTH-006 right password after lock expiry -> OK"); + CHECK(st.fail_count == 0u, "TC-FTPAUTH-006b counter cleared after unlock then success"); } /* ===================== TC-FTPAUTH-007:成功清零计数 ===================== */ @@ -126,16 +126,16 @@ 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-FTPAUTH-007a 3 败后成功 → OK"); - CHECK(st.fail_count == 0u, "TC-FTPAUTH-007b 成功清零"); + "TC-FTPAUTH-007a success after 3 failures -> OK"); + CHECK(st.fail_count == 0u, "TC-FTPAUTH-007b success clears the counter"); for (int i = 0; i < 4; i++) { CHECK(ftp_auth_check(&s_creds, 1u, "wrong", &st, t) == FTP_AUTH_FAIL, - "TC-FTPAUTH-007c 清零后再 4 败仍 FAIL(未锁)"); + "TC-FTPAUTH-007c after clear, 4 more failures still FAIL (not locked)"); } CHECK(ftp_auth_check(&s_creds, 1u, "wrong", &st, t) == FTP_AUTH_FAIL, - "TC-FTPAUTH-007d 第 5 败 FAIL 并上锁"); + "TC-FTPAUTH-007d 5th failure FAILs and arms the lock"); CHECK(ftp_auth_check(&s_creds, 1u, "admin", &st, t + 1u) == FTP_AUTH_LOCKED, - "TC-FTPAUTH-007e 连续 5 败后 LOCKED"); + "TC-FTPAUTH-007e LOCKED after 5 consecutive failures"); } /* ===================== TC-FTPAUTH-008:tick 32 位回绕 ===================== */ @@ -150,10 +150,10 @@ 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-FTPAUTH-008a 回绕前窗内 → LOCKED"); + "TC-FTPAUTH-008a inside window before wraparound -> LOCKED"); /* 回绕后 32 tick:now=0x10,(int32_t)(0x10-0xFFFFFFF0)=+32 → 期满 */ CHECK(ftp_auth_check(&s_creds, 1u, "admin", &st, 0x00000010u) == FTP_AUTH_OK, - "TC-FTPAUTH-008b 回绕后期满 → OK(有符号差抗回绕)"); + "TC-FTPAUTH-008b after wraparound window elapsed -> OK (signed diff resists wraparound)"); } /* ===================== TC-FTPAUTH-009..010:fail-closed 边界 ===================== */ @@ -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-FTPAUTH-009 非法 hex 配置 → 恒 FAIL(无人能登录,fail-closed)"); + "TC-FTPAUTH-009 invalid hex config -> always FAIL (nobody can log in, fail-closed)"); (void)memset(&st, 0, sizeof(st)); CHECK(ftp_auth_check(&s_creds, 1u, "", &st, 1000u) == FTP_AUTH_FAIL, - "TC-FTPAUTH-010a 空口令 → FAIL"); + "TC-FTPAUTH-010a empty password -> FAIL"); CHECK(ftp_auth_check(&s_creds, 1u, NULL, &st, 1000u) == FTP_AUTH_FAIL, - "TC-FTPAUTH-010b NULL 口令 → FAIL"); + "TC-FTPAUTH-010b NULL password -> FAIL"); CHECK(ftp_auth_check(NULL, 1u, "admin", &st, 1000u) == FTP_AUTH_FAIL, - "TC-FTPAUTH-010c NULL creds → FAIL"); + "TC-FTPAUTH-010c NULL creds -> FAIL"); CHECK(ftp_auth_check(&s_creds, 1u, "admin", NULL, 1000u) == FTP_AUTH_FAIL, - "TC-FTPAUTH-010d NULL state → FAIL"); + "TC-FTPAUTH-010d NULL state -> FAIL"); } /* ===================== main ===================== */ diff --git a/test/host/ftp_cfg/ftp_cfg_test.c b/test/host/ftp_cfg/ftp_cfg_test.c index 57d369ea..0e4277bc 100644 --- a/test/host/ftp_cfg/ftp_cfg_test.c +++ b/test/host/ftp_cfg/ftp_cfg_test.c @@ -148,9 +148,9 @@ static void tc_register(void) printf("-- TC-FTPCFG-003..005 register --\n"); fake_reset(); ftp_cfg_register(); - CHECK(g_reg_n == 1, "TC-FTPCFG-003a 首次注册一次"); + CHECK(g_reg_n == 1, "TC-FTPCFG-003a first register adds exactly one entry"); ftp_cfg_register(); - CHECK(g_reg_n == 1, "TC-FTPCFG-003 重复 register 不重复登记(幂等)"); + CHECK(g_reg_n == 1, "TC-FTPCFG-003 repeated register never duplicates the entry (idempotent)"); CHECK((strcmp(g_reg.name, "ftp") == 0) && (g_reg.data_size == sizeof(ftp_cfg_t)) && @@ -158,7 +158,7 @@ static void tc_register(void) (g_reg.p_defaults != NULL) && (g_reg.p_data == (const void *)&s_cfg) && (g_reg.p_cb == NULL), - "TC-FTPCFG-004 段名/尺寸/键数/默认值/**p_cb 必须为 NULL**"); + "TC-FTPCFG-004 section name/size/key count/defaults/**p_cb must be NULL**"); CHECK((strcmp(g_reg.p_keys[0].name, "user") == 0) && (g_reg.p_keys[0].type == CFG_VAL_STR) && @@ -170,7 +170,7 @@ static void tc_register(void) (strcmp(g_reg.p_keys[2].name, "write") == 0) && (g_reg.p_keys[2].type == CFG_VAL_UINT) && (g_reg.p_keys[2].len == 1u), - "TC-FTPCFG-005 键表逐项:user(STR,16)/pwd_hash(STR,65)/write(UINT,1)"); + "TC-FTPCFG-005 key table item by item: user(STR,16)/pwd_hash(STR,65)/write(UINT,1)"); } /* ===================== 出厂默认与只读访问 ===================== */ @@ -182,17 +182,17 @@ static void tc_defaults(void) printf("-- TC-FTPCFG-001..002,014 defaults --\n"); /* 契约就是"恒非空"(静态常驻),单独一条断言;随后的显式守卫既让 * test-cppcheck 不再报"冗余或空指针二选一",也让真出问题时报在 001a 上 */ - CHECK(p != NULL, "TC-FTPCFG-001a ftp_cfg_get 恒非空(静态常驻)"); + CHECK(p != NULL, "TC-FTPCFG-001a ftp_cfg_get never NULL (statically resident)"); if (p == NULL) { return; } - CHECK(strcmp(p->user, "admin") == 0, "TC-FTPCFG-001 未注册也可 get,user = admin"); + CHECK(strcmp(p->user, "admin") == 0, "TC-FTPCFG-001 get works even unregistered, user = admin"); CHECK((strcmp(p->pwd_hash, FTP_CFG_DEF_HASH) == 0) && (p->write_en == 1u), - "TC-FTPCFG-002 初值 = 出厂哈希 + write_en=1(维护工作流依赖)"); + "TC-FTPCFG-002 initial value = factory hash + write_en=1 (maintenance workflow relies on it)"); CHECK((FTP_CFG_USER_MAX == 16u) && (FTP_CFG_HASH_MAX == 65u) && (sizeof(p->user) == FTP_CFG_USER_MAX) && (sizeof(p->pwd_hash) == FTP_CFG_HASH_MAX), - "TC-FTPCFG-014 缓冲尺寸契约:user 16 / hash 65(64 hex + NUL)"); + "TC-FTPCFG-014 buffer size contract: user 16 / hash 65 (64 hex + NUL)"); } /* ===================== 默认口令判定(启动告警的依据) ===================== */ @@ -200,17 +200,17 @@ static void tc_defaults(void) static void tc_default_pwd(void) { printf("-- TC-FTPCFG-006..009 default-password detection --\n"); - CHECK(ftp_cfg_is_default_pwd() == 1, "TC-FTPCFG-006 出厂态判为默认口令"); + CHECK(ftp_cfg_is_default_pwd() == 1, "TC-FTPCFG-006 factory state judged as default password"); set_hash("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"); - CHECK(ftp_cfg_is_default_pwd() == 0, "TC-FTPCFG-007 改了口令 → 不再默认"); + CHECK(ftp_cfg_is_default_pwd() == 0, "TC-FTPCFG-007 password changed -> no longer default"); set_hash_upper(); CHECK(ftp_cfg_is_default_pwd() == 1, - "TC-FTPCFG-008 大写 hex 仍判默认(比较必须大小写不敏感)"); + "TC-FTPCFG-008 uppercase hex still judged default (comparison must be case-insensitive)"); set_hash(""); - CHECK(ftp_cfg_is_default_pwd() == 0, "TC-FTPCFG-009 空哈希不是默认口令"); + CHECK(ftp_cfg_is_default_pwd() == 0, "TC-FTPCFG-009 empty hash is not the default password"); } /* ===================== 静态比较函数(NULL / 折叠 / 前缀) ===================== */ @@ -219,12 +219,12 @@ static void tc_ci_eq(void) { printf("-- TC-FTPCFG-010..013 case-insensitive compare --\n"); CHECK(s_str_ci_eq("A_b1!Z", "a_b1!z") == 1, - "TC-FTPCFG-010 只折叠 A-Z,数字/下划线/符号原样比较"); - CHECK(s_str_ci_eq("abc", "abcd") == 0, "TC-FTPCFG-011 前缀关系不算相等"); + "TC-FTPCFG-010 only folds A-Z; digits/underscore/symbols compared as-is"); + CHECK(s_str_ci_eq("abc", "abcd") == 0, "TC-FTPCFG-011 prefix relation is not equality"); CHECK((s_str_ci_eq(NULL, "x") == 0) && (s_str_ci_eq("x", NULL) == 0), - "TC-FTPCFG-012 任一为 NULL 判不等"); + "TC-FTPCFG-012 either side NULL -> not equal"); CHECK(s_str_ci_eq(NULL, NULL) == 0, - "TC-FTPCFG-013 两个 NULL 也判不等(fail-closed)"); + "TC-FTPCFG-013 both NULL also judged not equal (fail-closed)"); } /* ===================== 入口 ===================== */ diff --git a/test/host/iec104/iec104_test.c b/test/host/iec104/iec104_test.c index f162a1b3..bfc8b97e 100644 --- a/test/host/iec104/iec104_test.c +++ b/test/host/iec104/iec104_test.c @@ -315,17 +315,17 @@ static void tc_cp56(void) iec104_epoch_ms_to_cp56(e1, b); rc = iec104_cp56_to_epoch_ms(b, &back); - CHECK((rc == 0) && (back == e1), "TC-001 CP56 往返 2000-01-01"); + CHECK((rc == 0) && (back == e1), "TC-001 CP56 round trip on 2000-01-01"); iec104_epoch_ms_to_cp56(e2, b); back = 0u; rc = iec104_cp56_to_epoch_ms(b, &back); - CHECK((rc == 0) && (back == e2), "TC-001 CP56 往返闰日 2024-02-29"); + CHECK((rc == 0) && (back == e2), "TC-001 CP56 round trip on the leap day 2024-02-29"); b[2] |= 0x80u; - CHECK(iec104_cp56_to_epoch_ms(b, &back) == -2, "TC-001 IV → -2"); + CHECK(iec104_cp56_to_epoch_ms(b, &back) == -2, "TC-001 IV -> -2"); iec104_epoch_ms_to_cp56(0u, b); /* 早于 2000 → 钳位 */ back = 0u; (void)iec104_cp56_to_epoch_ms(b, &back); - CHECK(back == e1, "TC-001 早于 2000 钳位"); + CHECK(back == e1, "TC-001 a value before 2000 is clamped"); } static void tc_ioa_float(void) @@ -334,12 +334,12 @@ static void tc_ioa_float(void) iec104_put_ioa(b, 0x123456u); CHECK((iec104_get_ioa(b) == 0x123456u) && (b[0] == 0x56u) && (b[1] == 0x34u) - && (b[2] == 0x12u), "TC-002 IOA 3B 小端"); + && (b[2] == 0x12u), "TC-002 IOA is 3 bytes little endian"); iec104_put_float(b, 1.0f); CHECK((b[0] == 0x00u) && (b[1] == 0x00u) && (b[2] == 0x80u) - && (b[3] == 0x3Fu), "TC-002 float IEEE754 小端"); + && (b[3] == 0x3Fu), "TC-002 float in IEEE754 little endian"); iec104_put_float(b, -12.5f); - CHECK(iec104_get_float(b) == -12.5f, "TC-002 float 往返"); + CHECK(iec104_get_float(b) == -12.5f, "TC-002 float round trip"); } static void tc_apci(void) @@ -351,9 +351,9 @@ static void tc_apci(void) static const uint8_t b[6] = { 0x68u, 4u, 0x07u, 0u, 0u, 0u }; iec104_link_on_rx(&g_lk, b, 3u, now); - CHECK(cap_u_count(0x0Bu) == 0, "TC-003 半帧不触发"); + CHECK(cap_u_count(0x0Bu) == 0, "TC-003 a half frame triggers nothing"); iec104_link_on_rx(&g_lk, &b[3], 3u, now); - CHECK(cap_u_count(0x0Bu) == 1, "TC-003 半帧重组 → con"); + CHECK(cap_u_count(0x0Bu) == 1, "TC-003 a half frame is reassembled then con"); } { static const uint8_t b[12] = { @@ -364,21 +364,21 @@ static void tc_apci(void) iec104_link_on_rx(&g_lk, b, 12u, now); CHECK((cap_u_count(0x83u) == 1) && (iec104_link_state(&g_lk) == IEC104_ST_STOPPED), - "TC-003 粘帧逐处 + STOPDT 生效"); + "TC-003 a coalesced frame is handled one by one and STOPDT takes effect"); } reset_all(now); { static const uint8_t b[6] = { 0x69u, 4u, 0x07u, 0u, 0u, 0u }; iec104_link_on_rx(&g_lk, b, 6u, now); - CHECK(iec104_link_state(&g_lk) == IEC104_ST_IDLE, "TC-003 坏起始符 → IDLE"); + CHECK(iec104_link_state(&g_lk) == IEC104_ST_IDLE, "TC-003 a bad start byte -> IDLE"); } reset_all(now); { static const uint8_t b[6] = { 0x68u, 3u, 0x07u, 0u, 0u, 0u }; iec104_link_on_rx(&g_lk, b, 6u, now); - CHECK(iec104_link_state(&g_lk) == IEC104_ST_IDLE, "TC-003 坏长度 → IDLE"); + CHECK(iec104_link_state(&g_lk) == IEC104_ST_IDLE, "TC-003 a bad length -> IDLE"); } } @@ -387,10 +387,10 @@ static void tc_startdt(void) uint32_t now = 1000u; reset_all(now); - CHECK(iec104_link_state(&g_lk) == IEC104_ST_OPEN, "TC-004 open → OPEN"); + CHECK(iec104_link_state(&g_lk) == IEC104_ST_OPEN, "TC-004 open -> OPEN"); handshake(now); CHECK((cap_u_count(0x0Bu) == 1) - && (iec104_link_state(&g_lk) == IEC104_ST_RUN), "TC-004 STARTDT → RUN"); + && (iec104_link_state(&g_lk) == IEC104_ST_RUN), "TC-004 STARTDT -> RUN"); } static void tc_open_ignore(void) @@ -403,11 +403,11 @@ static void tc_open_ignore(void) n = mk_asdu(a, IEC104_T_C_RD_NA_1, 1u, IEC104_COT_REQ, 0u, 1u, 0x4011u, NULL, 0u); feed_i(a, n, now); CHECK((cap_i_count() == 0) && (iec104_link_state(&g_lk) == IEC104_ST_OPEN), - "TC-005 OPEN 态 I 帧忽略"); + "TC-005 an I frame in OPEN state is ignored"); handshake(now); m_ns = 0u; /* OPEN 忽略不消费序号 → 主站仍从 0 起 */ feed_i(a, n, now); /* ns=0 仍有效(序号未被消费) */ - CHECK(cap_i_count() == 1, "TC-005 RUN 后同 ns 正常应答"); + CHECK(cap_i_count() == 1, "TC-005 after RUN the same ns is answered normally"); } static void tc_interrogation(void) @@ -426,34 +426,34 @@ static void tc_interrogation(void) n = mk_asdu(a, IEC104_T_C_IC_NA_1, 1u, IEC104_COT_ACT, 0u, 1u, 0u, body, 1u); feed_i(a, n, now); CHECK((cap_i_count() == 1) && (cap_i(0, &c) == 0) && (c.type == 100u) - && (c.cot == IEC104_COT_ACTCON), "TC-006 actcon 即发 COT7"); + && (c.cot == IEC104_COT_ACTCON), "TC-006 actcon is sent right away, COT7"); iec104_link_poll(&g_lk, now); - CHECK(cap_i_count() == 5, "TC-006 首 poll 发满预算 4 分片"); + CHECK(cap_i_count() == 5, "TC-006 the first poll uses the whole budget of 4 frames"); CHECK((cap_i(1, &c) == 0) && (c.type == 3u) && (c.cot == IEC104_COT_INIT) && (c.vsq == (uint8_t)(IEC104_VSQ_SQ | 4u)) && (c.ioa == 1u), - "TC-006 YX 双点组 首召 COT=4"); + "TC-006 YX double-point group, first call COT=4"); CHECK((cap_i(2, &c) == 0) && (c.type == 1u) && (c.vsq == (uint8_t)(IEC104_VSQ_SQ | 29u)) && (c.ioa == 5u), - "TC-006 YX 单点组 29 点"); + "TC-006 YX single-point group with 29 points"); CHECK((cap_i(3, &c) == 0) && (c.type == 13u) && (c.vsq == (uint8_t)(IEC104_VSQ_SQ | 8u)) && (c.ioa == 0x4011u) - && (c.obj_len == 40u), "TC-006 YC 组 8 点 40B"); + && (c.obj_len == 40u), "TC-006 YC group of 8 points, 40 bytes"); if (cap_i(3, &c) == 0) { CHECK((iec104_get_float(c.obj) == 111.0f) && (c.obj[4] == 0u), - "TC-006 YC 值 111.0 QDS=0"); - CHECK(c.obj[9] == IEC104_QDS_IV, "TC-006 无效通道 QDS=IV"); + "TC-006 YC value 111.0 with QDS=0"); + CHECK(c.obj[9] == IEC104_QDS_IV, "TC-006 an invalid channel sets QDS=IV"); } CHECK((cap_i(4, &c) == 0) && (c.ioa == 0x401Du) && (c.vsq == 1u), - "TC-006 频率单点 SQ=0"); + "TC-006 frequency as a single point with SQ=0"); iec104_link_poll(&g_lk, now + 100u); CHECK((cap_i_count() == 6) && (cap_i(5, &c) == 0) && (c.type == 100u) - && (c.cot == IEC104_COT_ACTTERM), "TC-006 actterm 收尾"); + && (c.cot == IEC104_COT_ACTTERM), "TC-006 actterm closes the sequence"); /* 二召:init 已清 → COT=2 */ n = mk_asdu(a, IEC104_T_C_IC_NA_1, 1u, IEC104_COT_ACT, 0u, 1u, 0u, body, 1u); feed_i(a, n, now + 200u); iec104_link_poll(&g_lk, now + 200u); CHECK((cap_i(7, &c) == 0) && (c.type == 3u) && (c.cot == IEC104_COT_BG_SCAN), - "TC-006 二召 COT=2"); + "TC-006 second call COT=2"); /* RBT 位 → COT=4(actcon3 是第 12 个未确认帧 → 先 S 确认窗才开) */ n = mk_asdu(a, IEC104_T_C_IC_NA_1, 1u, IEC104_COT_ACT, IEC104_COT_BIT_RBT, 1u, 0u, body, 1u); @@ -461,7 +461,7 @@ static void tc_interrogation(void) feed_s(12u, now + 300u); iec104_link_poll(&g_lk, now + 300u); CHECK((cap_i(12, &c) == 0) && (c.type == 3u) && (c.cot == IEC104_COT_INIT), - "TC-006 RBT → COT=4"); + "TC-006 RBT -> COT=4"); } static void tc_cov_yx(void) @@ -473,33 +473,33 @@ static void tc_cov_yx(void) reset_all(now); handshake(now); iec104_link_poll(&g_lk, now); /* 建快照 */ - CHECK(cap_i_count() == 0, "TC-007 首 poll 无自发"); + CHECK(cap_i_count() == 0, "TC-007 the first poll sends nothing spontaneous"); s_f_bits |= (1uLL << 15); /* YX16(idx15)动作 */ iec104_link_poll(&g_lk, now + 100u); /* B9:单点 YX 自发 = M_SP_TB_1(30)带 CP56Time2a 时标(SOE 上送路径) */ CHECK((cap_i_count() == 1) && (cap_i(0, &c) == 0) && (c.type == 30u) && (c.cot == IEC104_COT_SPONT) && (c.ioa == 16u) - && (c.obj_len == 8u) && (c.obj[0] == 1u), "TC-007 YX16 变位 COT3 TB"); + && (c.obj_len == 8u) && (c.obj[0] == 1u), "TC-007 a YX16 change of state sends COT3 with TB"); if ((cap_i(0, &c) == 0) && (c.obj_len == 8u)) { CHECK(iec104_cp56_to_epoch_ms(&c.obj[1], &back) == 0, - "TC-007 CP56 可解"); - CHECK(back == s_epoch_val, "TC-007 时标 = epoch_ms 源"); + "TC-007 the CP56 time tag decodes"); + CHECK(back == s_epoch_val, "TC-007 the time tag equals the epoch_ms source"); } s_f_bits &= ~(1uLL << 15); /* 复归 */ iec104_link_poll(&g_lk, now + 200u); CHECK((cap_i_count() == 2) && (cap_i(1, &c) == 0) && (c.type == 30u) - && (c.ioa == 16u) && (c.obj[0] == 0u), "TC-007 YX16 复归再变"); + && (c.ioa == 16u) && (c.obj[0] == 0u), "TC-007 YX16 is reset and changes again"); /* B9 IV 路径:时标源无效 → CP56 IV 位如实置位 */ s_epoch_val = UINT64_MAX; s_f_bits |= (1uLL << 16); /* YX17(idx16)动作 */ iec104_link_poll(&g_lk, now + 300u); CHECK((cap_i_count() == 3) && (cap_i(2, &c) == 0) && (c.type == 30u) && (c.ioa == 17u) && ((c.obj[3] & 0x80u) != 0u), - "TC-007 时钟无效 → CP56 IV 位"); + "TC-007 an invalid clock sets the CP56 IV bit"); s_epoch_val = 1760234567000ULL; s_f_bits |= (1uLL << 0); /* idx0 无效位 → 不触发 */ iec104_link_poll(&g_lk, now + 400u); - CHECK(cap_i_count() == 3, "TC-007 无效位变位不触发"); + CHECK(cap_i_count() == 3, "TC-007 a change while the IV bit is set triggers nothing"); } static void tc_cov_yc(void) @@ -513,12 +513,12 @@ static void tc_cov_yc(void) iec104_link_poll(&g_lk, now); /* 快照 = 100 */ s_f_yc[0] = 105.0f; /* 死区 10 内 */ iec104_link_poll(&g_lk, now + 100u); - CHECK(cap_i_count() == 0, "TC-008 死区内不上送"); + CHECK(cap_i_count() == 0, "TC-008 inside the deadband nothing is uploaded"); s_f_yc[0] = 130.0f; /* 130-105=25 > 10 */ iec104_link_poll(&g_lk, now + 200u); CHECK((cap_i_count() == 1) && (cap_i(0, &c) == 0) && (c.type == 13u) && (c.cot == IEC104_COT_SPONT) && (c.ioa == 0x4011u) - && (iec104_get_float(c.obj) == 130.0f), "TC-008 越死区上送"); + && (iec104_get_float(c.obj) == 130.0f), "TC-008 crossing the deadband uploads"); } static void feed_rd(uint32_t now) @@ -540,12 +540,12 @@ static void tc_k_window(void) for (i = 0; i < 12; i++) { feed_rd(now); } - CHECK(cap_i_count() == 12, "TC-009 k=12 封顶"); + CHECK(cap_i_count() == 12, "TC-009 the k=12 window caps the outstanding frames"); feed_rd(now); - CHECK(cap_i_count() == 12, "TC-009 第 13 个被 k 窗抑制"); + CHECK(cap_i_count() == 12, "TC-009 the 13th frame is suppressed by the k window"); feed_s(12u, now); /* 全确认 → 窗开 */ feed_rd(now); - CHECK(cap_i_count() == 13, "TC-009 S 确认后恢复发送"); + CHECK(cap_i_count() == 13, "TC-009 sending resumes after the S acknowledgement"); } static void tc_w_thresh(void) @@ -559,9 +559,9 @@ static void tc_w_thresh(void) for (i = 0; i < 7; i++) { feed_rd(now); } - CHECK(cap_has_s(&nr) == 0, "TC-010 收 7 未发 S"); + CHECK(cap_has_s(&nr) == 0, "TC-010 after 7 received frames no S has been sent yet"); feed_rd(now); /* 第 8 个 → w 阈 */ - CHECK((cap_has_s(&nr) == 1) && (nr == 8u), "TC-010 w=8 → S nr=8"); + CHECK((cap_has_s(&nr) == 1) && (nr == 8u), "TC-010 w=8 -> S with nr=8"); } static void tc_t2(void) @@ -573,9 +573,9 @@ static void tc_t2(void) handshake(now); feed_rd(now); /* rx_unacked=1,t2 起爆 */ iec104_link_poll(&g_lk, now + 9999u); - CHECK(cap_has_s(&nr) == 0, "TC-011 t2 未到期不发 S"); + CHECK(cap_has_s(&nr) == 0, "TC-011 no S before t2 expires"); iec104_link_poll(&g_lk, now + 10001u); - CHECK((cap_has_s(&nr) == 1) && (nr == 1u), "TC-011 t2 到期发 S"); + CHECK((cap_has_s(&nr) == 1) && (nr == 1u), "TC-011 S is sent once t2 expires"); } static void tc_t3_t1(void) @@ -585,19 +585,19 @@ static void tc_t3_t1(void) reset_all(now); handshake(now); iec104_link_poll(&g_lk, now + 19999u); - CHECK(cap_u_count(0x43u) == 0, "TC-012 t3 未到期无 TESTFR"); + CHECK(cap_u_count(0x43u) == 0, "TC-012 no TESTFR before t3 expires"); iec104_link_poll(&g_lk, now + 20001u); - CHECK(cap_u_count(0x43u) == 1, "TC-012 t3 到期发 TESTFR act"); + CHECK(cap_u_count(0x43u) == 1, "TC-012 TESTFR act is sent once t3 expires"); iec104_link_poll(&g_lk, now + 20001u + 15001u); - CHECK(iec104_link_state(&g_lk) == IEC104_ST_IDLE, "TC-012 TESTFR 未答 t1 → IDLE"); + CHECK(iec104_link_state(&g_lk) == IEC104_ST_IDLE, "TC-012 an unanswered TESTFR hits t1 -> IDLE"); /* con 清挂起 → 不误杀 */ reset_all(now); handshake(now); iec104_link_poll(&g_lk, now + 20001u); - CHECK(cap_u_count(0x43u) == 1, "TC-012 重连 t3 再触发"); + CHECK(cap_u_count(0x43u) == 1, "TC-012 after reconnect t3 fires again"); feed_u(0x83u, now + 20100u); /* TESTFR con */ iec104_link_poll(&g_lk, now + 35000u); - CHECK(iec104_link_state(&g_lk) == IEC104_ST_RUN, "TC-012 con 清挂起后 t1 不误杀"); + CHECK(iec104_link_state(&g_lk) == IEC104_ST_RUN, "TC-012 once con clears the pending frame t1 does not kill it by mistake"); } static void tc_dc(void) @@ -614,13 +614,13 @@ static void tc_dc(void) n = mk_asdu(a, IEC104_T_C_DC_NA_1, 1u, IEC104_COT_ACT, 0u, 1u, 0x600Au, body, 1u); feed_i(a, n, now); CHECK((cap_i(0, &c) == 0) && (c.type == 52u) && (c.cot == IEC104_COT_ACTCON) - && ((c.cot_hi & IEC104_COT_BIT_PN) == 0u), "TC-013 选择段 actcon"); - CHECK((s_f_yk_sel == 1u) && (s_f_yk_ioa == 0x600Au), "TC-013 选择段转发源"); + && ((c.cot_hi & IEC104_COT_BIT_PN) == 0u), "TC-013 the select phase answers actcon"); + CHECK((s_f_yk_sel == 1u) && (s_f_yk_ioa == 0x600Au), "TC-013 the select phase forwards the source"); body[0] = 0x02u; /* 执行 ON */ n = mk_asdu(a, IEC104_T_C_DC_NA_1, 1u, IEC104_COT_ACT, 0u, 1u, 0x600Au, body, 1u); feed_i(a, n, now); CHECK((cap_i(1, &c) == 0) && ((c.cot_hi & IEC104_COT_BIT_PN) == 0u) - && (s_f_yk_sel == 0u), "TC-013 执行段 actcon"); + && (s_f_yk_sel == 0u), "TC-013 the execute phase answers actcon"); /* 失配:选 ON 执 OFF */ body[0] = 0x82u; n = mk_asdu(a, IEC104_T_C_DC_NA_1, 1u, IEC104_COT_ACT, 0u, 1u, 0x600Au, body, 1u); @@ -629,13 +629,13 @@ static void tc_dc(void) n = mk_asdu(a, IEC104_T_C_DC_NA_1, 1u, IEC104_COT_ACT, 0u, 1u, 0x600Au, body, 1u); feed_i(a, n, now); CHECK((cap_i(3, &c) == 0) && ((c.cot_hi & IEC104_COT_BIT_PN) != 0u), - "TC-013 执行失配 PN"); + "TC-013 a mismatching execute phase returns PN"); /* 拒绝类(YK1):选择段即 PN */ body[0] = 0x82u; n = mk_asdu(a, IEC104_T_C_DC_NA_1, 1u, IEC104_COT_ACT, 0u, 1u, 0x6000u, body, 1u); feed_i(a, n, now); CHECK((cap_i(4, &c) == 0) && ((c.cot_hi & IEC104_COT_BIT_PN) != 0u), - "TC-013 无出口硬件 YK 选择段 PN"); + "TC-013 a YK without output hardware returns PN in the select phase"); } /* TC-024(B7):YK12 全局软压板两段式转真(经真实板端源 + 原子封存) */ @@ -649,21 +649,21 @@ static void tc_dc_yk12(void) reset_all(now); handshake(now); - CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 1u, "TC-024 软压板默认投入"); + CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 1u, "TC-024 soft plates are engaged by default"); body[0] = 0x81u; /* S=1, DPC=OFF:选择段 */ n = mk_asdu(a, IEC104_T_C_DC_NA_1, 1u, IEC104_COT_ACT, 0u, 1u, 0x600Bu, body, 1u); feed_i(a, n, now); CHECK((cap_i(0, &c) == 0) && (c.cot == IEC104_COT_ACTCON) - && ((c.cot_hi & IEC104_COT_BIT_PN) == 0u), "TC-024 YK12 选择段 actcon"); - CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 1u, "TC-024 选择段不动作"); + && ((c.cot_hi & IEC104_COT_BIT_PN) == 0u), "TC-024 the YK12 select phase answers actcon"); + CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 1u, "TC-024 the select phase performs no action"); body[0] = 0x01u; /* 执行 OFF */ n = mk_asdu(a, IEC104_T_C_DC_NA_1, 1u, IEC104_COT_ACT, 0u, 1u, 0x600Bu, body, 1u); feed_i(a, n, now); CHECK((cap_i(1, &c) == 0) && ((c.cot_hi & IEC104_COT_BIT_PN) == 0u), - "TC-024 YK12 执行段 actcon"); - CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 0u, "TC-024 执行段软压板转真退出"); - CHECK(prot_set_selfcheck() == 0, "TC-024 set_sealed 原子封存 → selfcheck 通过"); - CHECK(prot_set_dirty_peek() == 1u, "TC-024 置脏待持久化"); + "TC-024 the YK12 execute phase answers actcon"); + CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 0u, "TC-024 the execute phase drives the soft plate to the released state"); + CHECK(prot_set_selfcheck() == 0, "TC-024 set_sealed seals atomically and selfcheck passes"); + CHECK(prot_set_dirty_peek() == 1u, "TC-024 the dirty flag is set for persistence"); body[0] = 0x82u; /* 再投入:选择 ON */ n = mk_asdu(a, IEC104_T_C_DC_NA_1, 1u, IEC104_COT_ACT, 0u, 1u, 0x600Bu, body, 1u); feed_i(a, n, now); @@ -671,13 +671,13 @@ static void tc_dc_yk12(void) n = mk_asdu(a, IEC104_T_C_DC_NA_1, 1u, IEC104_COT_ACT, 0u, 1u, 0x600Bu, body, 1u); feed_i(a, n, now); CHECK((cap_i(3, &c) == 0) && ((c.cot_hi & IEC104_COT_BIT_PN) == 0u), - "TC-024 投入执行 actcon"); - CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 1u, "TC-024 软压板转真投入"); + "TC-024 the engage command executes with actcon"); + CHECK(prot_set_get_ctl(PS_GLOBAL_EN) == 1u, "TC-024 the soft plate reaches the engaged state"); body[0] = 0x80u; /* DPC=00 非法:选择段即 PN */ n = mk_asdu(a, IEC104_T_C_DC_NA_1, 1u, IEC104_COT_ACT, 0u, 1u, 0x600Bu, body, 1u); feed_i(a, n, now); CHECK((cap_i(4, &c) == 0) && ((c.cot_hi & IEC104_COT_BIT_PN) != 0u), - "TC-024 非法 DPC 选择段 PN"); + "TC-024 an invalid DPC returns PN in the select phase"); } static void tc_se(void) @@ -691,27 +691,27 @@ static void tc_se(void) reset_all(now); handshake(now); - CHECK(addr == 0x8858u, "TC-014 OC1 电流定值通讯地址"); + CHECK(addr == 0x8858u, "TC-014 the OC1 current setting communication address"); iec104_put_float(body, 5.0f); body[4] = IEC104_QDC_S; /* 选择段 */ n = mk_asdu(a, IEC104_T_C_SE_NC_1, 1u, IEC104_COT_ACT, 0u, 1u, addr, body, 5u); feed_i(a, n, now); CHECK((cap_i(0, &c) == 0) && (c.type == 50u) - && ((c.cot_hi & IEC104_COT_BIT_PN) == 0u), "TC-014 定值选择 actcon"); + && ((c.cot_hi & IEC104_COT_BIT_PN) == 0u), "TC-014 selecting a setting answers actcon"); body[4] = 0u; /* 执行段 */ n = mk_asdu(a, IEC104_T_C_SE_NC_1, 1u, IEC104_COT_ACT, 0u, 1u, addr, body, 5u); feed_i(a, n, now); CHECK((cap_i(1, &c) == 0) && ((c.cot_hi & IEC104_COT_BIT_PN) == 0u), - "TC-014 定值执行 actcon"); - CHECK(prot_set_get_f(PS_OC1_CUR) == 5.0f, "TC-014 定值已写入(真实 prot_set)"); - CHECK(prot_set_selfcheck() == 0, "TC-014 执行后 seal → selfcheck 通过"); - CHECK(prot_set_dirty_peek() == 1u, "TC-014 执行段置脏(B7 待落盘)"); + "TC-014 executing a setting answers actcon"); + CHECK(prot_set_get_f(PS_OC1_CUR) == 5.0f, "TC-014 the setting really was written (real prot_set)"); + CHECK(prot_set_selfcheck() == 0, "TC-014 sealing after execute keeps selfcheck passing"); + CHECK(prot_set_dirty_peek() == 1u, "TC-014 the execute phase sets dirty (B7, waiting to be persisted)"); iec104_put_float(body, 100000.0f); /* 越上限 */ body[4] = IEC104_QDC_S; n = mk_asdu(a, IEC104_T_C_SE_NC_1, 1u, IEC104_COT_ACT, 0u, 1u, addr, body, 5u); feed_i(a, n, now); CHECK((cap_i(2, &c) == 0) && ((c.cot_hi & IEC104_COT_BIT_PN) != 0u), - "TC-014 越界选择段 PN"); + "TC-014 an out-of-range select phase returns PN"); } static void tc_rd(void) @@ -727,20 +727,20 @@ static void tc_rd(void) n = mk_asdu(a, IEC104_T_C_RD_NA_1, 1u, IEC104_COT_REQ, 0u, 1u, 0x4011u, NULL, 0u); feed_i(a, n, now); CHECK((cap_i(0, &c) == 0) && (c.type == 13u) && (c.cot == IEC104_COT_REQ) - && (iec104_get_float(c.obj) == 222.0f), "TC-015 C_RD YC 命中"); + && (iec104_get_float(c.obj) == 222.0f), "TC-015 C_RD hits a YC group"); n = mk_asdu(a, IEC104_T_C_RD_NA_1, 1u, IEC104_COT_REQ, 0u, 1u, 0x8858u, NULL, 0u); feed_i(a, n, now); CHECK((cap_i(1, &c) == 0) && (c.type == 13u) && (c.ioa == 0x8858u), - "TC-015 C_RD 定值命中"); + "TC-015 C_RD hits a setting"); n = mk_asdu(a, IEC104_T_C_RD_NA_1, 1u, IEC104_COT_REQ, 0u, 1u, 0x9999u, NULL, 0u); feed_i(a, n, now); CHECK((cap_i(2, &c) == 0) && (c.type == 102u) && (c.cot == IEC104_COT_UNK_IOA) && ((c.oa & 0x80u) != 0u), - "TC-015 未知 IOA COT14+EVI"); + "TC-015 an unknown IOA answers COT14 plus EVI"); n = mk_asdu(a, IEC104_T_C_RD_NA_1, 1u, IEC104_COT_REQ, 0u, 1u, 0u, NULL, 0u); feed_i(a, n, now); CHECK((cap_i(3, &c) == 0) && (c.cot == IEC104_COT_UNK_IOA), - "TC-015 本地定值项(comm_addr=0)不可寻址(B7)"); + "TC-015 a local setting item (comm_addr=0) is not addressable (B7)"); } static void tc_cs(void) @@ -759,18 +759,18 @@ static void tc_cs(void) feed_i(a, n, now); CHECK((cap_i(0, &c) == 0) && (c.type == 103u) && ((c.cot_hi & IEC104_COT_BIT_PN) == 0u) && (s_clock_ms == e), - "TC-016 C_CS 对时成功 epoch 精确"); + "TC-016 C_CS syncs the clock with an exact epoch"); cp[2] |= 0x80u; /* IV */ n = mk_asdu(a, IEC104_T_C_CS_NA_1, 1u, IEC104_COT_ACT, 0u, 1u, 0u, cp, 7u); feed_i(a, n, now); CHECK((cap_i(1, &c) == 0) && ((c.cot_hi & IEC104_COT_BIT_PN) != 0u), - "TC-016 CP56 IV → PN"); + "TC-016 CP56 IV -> PN"); (void)iec104_epoch_ms_to_cp56(e, cp); s_clock_rc = -1; /* 系统侧拒绝 */ n = mk_asdu(a, IEC104_T_C_CS_NA_1, 1u, IEC104_COT_ACT, 0u, 1u, 0u, cp, 7u); feed_i(a, n, now); CHECK((cap_i(2, &c) == 0) && ((c.cot_hi & IEC104_COT_BIT_PN) != 0u), - "TC-016 clock_sync 失败 → PN"); + "TC-016 a clock_sync failure -> PN"); } static void tc_err_resp(void) @@ -785,13 +785,13 @@ static void tc_err_resp(void) n = mk_asdu(a, 200u, 1u, IEC104_COT_ACT, 0u, 1u, 0u, NULL, 0u); feed_i(a, n, now); CHECK((cap_i(0, &c) == 0) && (c.type == 200u) && (c.cot == IEC104_COT_UNK_COT) - && ((c.oa & 0x80u) != 0u), "TC-017 未知类型 COT12+EVI"); + && ((c.oa & 0x80u) != 0u), "TC-017 an unknown type answers COT12 plus EVI"); m = iec104_asdu_put_hdr(a, IEC104_T_C_IC_NA_1, 1u, IEC104_COT_ACT, 0u, 2u); a[m] = IEC104_RQT_GROUP1; m++; feed_i(a, m, now); /* ca=2 ≠ 1 */ CHECK((cap_i(1, &c) == 0) && (c.cot == IEC104_COT_UNK_CA) - && ((c.oa & 0x80u) != 0u), "TC-017 错公共地址 COT13+EVI"); + && ((c.oa & 0x80u) != 0u), "TC-017 a wrong common address answers COT13 plus EVI"); } static void tc_stopdt(void) @@ -809,9 +809,9 @@ static void tc_stopdt(void) body[0] = IEC104_RQT_GROUP1; n = mk_asdu(a, IEC104_T_C_IC_NA_1, 1u, IEC104_COT_ACT, 0u, 1u, 0u, body, 1u); feed_i(a, n, now); - CHECK(cap_i_count() == 0, "TC-018 STOPPED 态数据服务关"); + CHECK(cap_i_count() == 0, "TC-018 in STOPPED state the data service is off"); feed_u(0x43u, now); - CHECK(cap_u_count(0x83u) == 1, "TC-018 STOPPED 态 TESTFR 仍应答"); + CHECK(cap_u_count(0x83u) == 1, "TC-018 in STOPPED state TESTFR is still answered"); } static void tc_seq_err(void) @@ -825,7 +825,7 @@ static void tc_seq_err(void) m_ns = 5u; /* 期望 0,投 5 */ n = mk_asdu(a, IEC104_T_C_RD_NA_1, 1u, IEC104_COT_REQ, 0u, 1u, 0x4011u, NULL, 0u); feed_i(a, n, now); - CHECK(iec104_link_state(&g_lk) == IEC104_ST_IDLE, "TC-019 序号错 → IDLE"); + CHECK(iec104_link_state(&g_lk) == IEC104_ST_IDLE, "TC-019 a sequence error -> IDLE"); } static void tc_pts(void) @@ -836,23 +836,23 @@ static void tc_pts(void) reset_all(1000u); CHECK((iec104_pts_yc_count() == 9u) && (iec104_pts_yx_count() == 33u) - && (iec104_pts_yc_ioa(8u) == 0x401Du), "TC-020 表尺寸/IOA"); + && (iec104_pts_yc_ioa(8u) == 0x401Du), "TC-020 table size and IOA layout"); s_f_yc[0] = 7.5f; CHECK((iec104_pts_yc_read(0u, &v, &q) == 0) && (v == 7.5f) && (q == 0u), - "TC-020 有效 YC"); + "TC-020 a valid YC"); s_f_yc_rc[1] = -1; (void)iec104_pts_yc_read(1u, &v, &q); - CHECK((v == 0.0f) && (q == IEC104_QDS_IV), "TC-020 无效通道 IV"); + CHECK((v == 0.0f) && (q == IEC104_QDS_IV), "TC-020 an invalid channel gives IV"); s_f_yc_rc[2] = -2; (void)iec104_pts_yc_read(2u, &v, &q); - CHECK(q == IEC104_QDS_NT, "TC-020 未就绪 NT"); + CHECK(q == IEC104_QDS_NT, "TC-020 not ready gives NT"); iec104_pts_yx_read(0u, &d); - CHECK(d == IEC104_DIQ_IV, "TC-020 无效遥信 IV"); + CHECK(d == IEC104_DIQ_IV, "TC-020 an invalid telemetry point gives IV"); CHECK((iec104_pts_yx_is_dp(0u) == 1u) && (iec104_pts_yx_is_dp(4u) == 0u), - "TC-020 is_dp 分界"); + "TC-020 the is_dp boundary"); s_f_bits = (1uLL << 15); iec104_pts_yx_read(15u, &d); - CHECK(d == 1u, "TC-020 有效遥信 ON"); + CHECK(d == 1u, "TC-020 a valid telemetry point gives ON"); } static void tc_ts_rp(void) @@ -884,10 +884,10 @@ static void tc_periodic(void) reset_all(now); handshake(now); iec104_link_poll(&g_lk, now + 60001u); - CHECK(cap_i_count() == 2, "TC-022 周期上送 2 分片"); + CHECK(cap_i_count() == 2, "TC-022 the cyclic upload takes 2 frames"); CHECK((cap_i(0, &c) == 0) && (c.type == 13u) && (c.cot == IEC104_COT_PERIODIC) - && (c.ioa == 0x4011u), "TC-022 周期 YC 组 COT=1"); - CHECK((cap_i(1, &c) == 0) && (c.ioa == 0x401Du), "TC-022 周期频率点"); + && (c.ioa == 0x4011u), "TC-022 the cyclic YC group uses COT=1"); + CHECK((cap_i(1, &c) == 0) && (c.ioa == 0x401Du), "TC-022 the cyclic frequency point"); } static void tc_cov_kfull(void) @@ -904,11 +904,11 @@ static void tc_cov_kfull(void) } s_f_bits |= (1uLL << 14); /* YX15 变位 */ iec104_link_poll(&g_lk, now + 100u); - CHECK(cap_i_count() == 12, "TC-023 k 满时自发发不出"); + CHECK(cap_i_count() == 12, "TC-023 with k full nothing spontaneous can go out"); feed_s(12u, now + 200u); /* 窗开 */ iec104_link_poll(&g_lk, now + 300u); CHECK((cap_i_count() == 13) && (cap_i(12, &c) == 0) && (c.ioa == 15u) - && (c.cot == IEC104_COT_SPONT), "TC-023 窗开后补发不丢事件"); + && (c.cot == IEC104_COT_SPONT), "TC-023 once the window opens the backlogged event is sent, none lost"); } int main(void) diff --git a/test/host/iec104_serv/iec104_serv_test.c b/test/host/iec104_serv/iec104_serv_test.c index 3746c0e8..b23bcc5d 100644 --- a/test/host/iec104_serv/iec104_serv_test.c +++ b/test/host/iec104_serv/iec104_serv_test.c @@ -221,7 +221,7 @@ void osDelay(uint32_t ticks) (void)ticks; g_n.delay_calls++; if (g_n.delay_calls > 500) { - printf(" ABORT 跑飞(>500 轮 osDelay)\n"); + printf(" ABORT runaway (>500 osDelay rounds)\n"); fflush(stdout); exit(2); } @@ -278,22 +278,22 @@ static void tc_bind_listen(void) (g_n.last_bind_family == NET_AF_INET) && (g_n.last_bind_port_net == net_htons(IEC104_SERV_PORT)) && (g_n.last_bind_addr == NET_INADDR_ANY), - "TC-I104SRV-001 建监听:2404 端口过 htons、绑任意地址、记下监听号"); + "TC-I104SRV-001 build the listener: port 2404 through htons, bind to any address, remember the listen handle"); reset_all(); g_n.socket_rc = -1; CHECK((s_bind_listen() == -1) && (g_n.bind_calls == 0) && (g_n.close_calls == 0), - "TC-I104SRV-002 建不出 socket 就返回,不去 bind 也不关不存在的口"); + "TC-I104SRV-002 if no socket can be created return at once: no bind and no close of a handle that does not exist"); reset_all(); g_n.bind_rc = -1; CHECK((s_bind_listen() == -1) && (g_n.close_calls == 1) && (g_n.listen_calls == 0), - "TC-I104SRV-003 bind 失败要把刚建的口关掉(否则每次重试漏一个 socket 号)"); + "TC-I104SRV-003 a bind failure must close the socket just created (otherwise every retry leaks a handle)"); reset_all(); g_n.listen_rc = -1; CHECK((s_bind_listen() == -1) && (g_n.close_calls == 1) && (s_listen == -1), - "TC-I104SRV-004 listen 失败同样关口且不留下半个监听"); + "TC-I104SRV-004 a listen failure also closes it and leaves no half-built listener"); } /* ===================== 发送与连续短写判死 ===================== */ @@ -307,25 +307,25 @@ static void tc_send(void) s_client = -1; s_send_apdu(NULL, apdu, 4u); CHECK((g_n.send_rc == 0) && (g_n.close_calls == 0) && (g_i4_error_count == 0), - "TC-I104SRV-010 没连接时直接返回(不发 net_send、不报错)"); + "TC-I104SRV-010 with no connection it returns directly (no net_send, no error)"); reset_all(); s_client = 7; g_n.send_rc = 4; s_send_apdu(NULL, apdu, 4u); CHECK((s_send_fail_run == 0u) && (s_conn_dead == 0u), - "TC-I104SRV-011 完整发出把连败计数清零"); + "TC-I104SRV-011 a fully sent frame clears the consecutive-failure counter"); reset_all(); s_client = 7; g_n.send_rc = 2; /* 短写:只发了 2/4 */ s_send_apdu(NULL, apdu, 4u); CHECK((s_send_fail_run == 1u) && (s_conn_dead == 0u) && (g_i4_error_count == 1), - "TC-I104SRV-012 第一次短写:留痕但不判死(拥塞很正常)"); + "TC-I104SRV-012 the first short write is logged but does not declare death (congestion is normal)"); s_send_apdu(NULL, apdu, 4u); s_send_apdu(NULL, apdu, 4u); CHECK((s_send_fail_run == 3u) && (s_conn_dead == 1u), - "TC-I104SRV-012b 连到 3 次才判死(IEC104_SEND_FAIL_MAX)"); + "TC-I104SRV-012b only the 3rd failure in a row declares death (IEC104_SEND_FAIL_MAX)"); reset_all(); s_client = 7; @@ -338,7 +338,7 @@ static void tc_send(void) s_send_apdu(NULL, apdu, 4u); s_send_apdu(NULL, apdu, 4u); CHECK((s_conn_dead == 0u) && (s_send_fail_run == 2u), - "TC-I104SRV-013 **成功即复位**:偶发拥塞不会被累计成误杀"); + "TC-I104SRV-013 success resets the counter: occasional congestion never adds up into a false kill"); } /* ===================== 时钟桥接边界 ===================== */ @@ -348,22 +348,22 @@ static void tc_clock(void) printf("-- TC-I104SRV-020..023 clock bridge --\n"); reset_all(); CHECK(s_clock_sync(NULL, 0x100000000ULL * 1000ULL) == -1, - "TC-I104SRV-020 秒数超过 32 位一律拒绝(截断写进 RTC 就是 2106 年后的乱值)"); - CHECK(g_clock_set_calls == 0, "TC-I104SRV-020b 拒绝时根本不该碰时钟"); + "TC-I104SRV-020 any second count beyond 32 bits is rejected (truncating it into the RTC means garbage past 2106)"); + CHECK(g_clock_set_calls == 0, "TC-I104SRV-020b when rejected the clock must not be touched at all"); reset_all(); (void)s_clock_sync(NULL, 1700000123000ULL); CHECK((g_clock_set_calls == 1) && (g_clock_last_secs == 1700000123u), - "TC-I104SRV-021 毫秒按整除换秒后写时钟"); + "TC-I104SRV-021 milliseconds become seconds by integer division before the clock is written"); reset_all(); g_clock_val = UINT32_MAX; /* 未对时的哨兵值 */ CHECK(s_epoch_ms(NULL) == UINT64_MAX, - "TC-I104SRV-022 未对时回 UINT64_MAX 哨兵(绝不能把 1970 当成设备时间)"); + "TC-I104SRV-022 without time sync return the UINT64_MAX sentinel (1970 must never pass for device time)"); reset_all(); g_clock_val = 1700000123u; - CHECK(s_epoch_ms(NULL) == 1700000123000ULL, "TC-I104SRV-023 正常时对时给出毫秒"); + CHECK(s_epoch_ms(NULL) == 1700000123000ULL, "TC-I104SRV-023 with a synced clock the answer is in milliseconds"); } /* ===================== 代次重建与 accept 门控 ===================== */ @@ -379,13 +379,13 @@ static void tc_generation(void) CHECK((g_n.close_calls == 2) && (g_n.last_closed_fd == 5) && (s_client == -1) && (s_liveness_ctr == 0u) && (s_conn_dead == 0u) && (g_lk_close == 1) && (s_gen == 101u) && (g_n.bind_calls == 1), - "TC-I104SRV-030 代次一变就拆掉旧连接与旧监听并重建(新 IP 上端口必须继续服务)"); + "TC-I104SRV-030 a generation change tears down the old connection and listener and rebuilds them (the port must keep serving on the new IP)"); reset_all(); s_listen = -1; s_serv_poll(); CHECK((g_n.bind_calls == 1) && (s_listen == 5) && (g_n.accept_calls == 0), - "TC-I104SRV-031 监听丢了就补建,这一轮不去 accept"); + "TC-I104SRV-031 a lost listener is rebuilt and this round does not accept"); reset_all(); s_listen = 5; @@ -393,7 +393,7 @@ static void tc_generation(void) g_n.sock_exists = 1; s_serv_poll(); CHECK((g_n.accept_calls == 0) && (s_listen == 5), - "TC-I104SRV-032 监听门未开时不 accept(否则对着未就绪的号空转)"); + "TC-I104SRV-032 no accept while the listener gate is down (otherwise it spins on a handle that is not ready)"); reset_all(); s_listen = 5; @@ -401,7 +401,7 @@ static void tc_generation(void) g_n.sock_exists = 0; /* 表项已不存在 */ s_serv_poll(); CHECK((s_listen == -1) && (g_n.accept_calls == 0), - "TC-I104SRV-032b 表项已失效时把监听号丢掉,下一轮重建"); + "TC-I104SRV-032b once the slot is invalid the listen handle is dropped and rebuilt next round"); reset_all(); s_listen = 5; @@ -413,7 +413,7 @@ static void tc_generation(void) CHECK((s_client == 9) && (g_lk_open == 1) && (g_lk_last_now == 5000u) && (s_send_fail_run == 0u) && (s_conn_dead == 0u) && (s_liveness_ctr == 0u) && (g_i4_info_count == 1), - "TC-I104SRV-033 新连接:打开链路、三个失败计数全部复位"); + "TC-I104SRV-033 a new connection opens the link and resets all three failure counters"); } /* ===================== 活性分频、对端 FIN、错误丢弃 ===================== */ @@ -428,7 +428,7 @@ static void tc_liveness(void) s_liveness_ctr = 0u; s_serv_poll(); CHECK((g_n.recv_calls == 0) && (g_lk_poll == 1) && (s_liveness_ctr == 1u), - "TC-I104SRV-034 无可读数据时按 32 分频探活,这一轮不收包(省 CPU 预算)"); + "TC-I104SRV-034 with nothing readable the liveness probe runs on a divide-by-32 tick and this round receives nothing (saves CPU budget)"); reset_all(); s_listen = 5; @@ -441,7 +441,7 @@ static void tc_liveness(void) s_liveness_ctr = 31u; /* 下一轮正好到分频点 */ s_serv_poll(); CHECK((g_n.recv_calls == 1) && (g_lk_poll == 1) && (s_client == 9), - "TC-I104SRV-035 分频到点才去收一次(TESTFR 等活性帧靠它发出去)"); + "TC-I104SRV-035 only when the divider fires does it receive once (liveness frames such as TESTFR depend on it going out)"); reset_all(); s_listen = 5; @@ -451,7 +451,7 @@ static void tc_liveness(void) s_serv_poll(); CHECK((g_n.last_closed_fd == 9) && (s_client == -1) && (g_lk_close == 1) && (g_n.close_calls == 1) && (s_listen == 5) && (g_n.bind_calls == 0), - "TC-I104SRV-036 对端正常断开:只关数据口、**监听必须留着**(单连接 socket 关错就是端口失联)"); + "TC-I104SRV-036 a normal peer disconnect closes only the data socket: the listener must stay (on a single-socket chip closing the wrong one kills the port)"); reset_all(); s_listen = 5; @@ -460,7 +460,7 @@ static void tc_liveness(void) g_n.recv_rc = 0; s_serv_poll(); CHECK((g_n.close_calls == 0) && (s_client == -1) && (g_lk_close == 1), - "TC-I104SRV-036b 数据号与监听号同号时**不许关**(否则把监听一起毁掉)"); + "TC-I104SRV-036b when the data handle equals the listen handle it must NOT be closed (that would destroy the listener too)"); reset_all(); s_listen = 5; @@ -470,7 +470,7 @@ static void tc_liveness(void) g_n.errno_val = NET_ERR_WOULDBLOCK; /* 空转:没数据可读 */ s_serv_poll(); CHECK((s_client == 9) && (g_lk_close == 0) && (g_i4_error_count == 0), - "TC-I104SRV-037 WOULDBLOCK 是正常空转,不能当成错误丢连接"); + "TC-I104SRV-037 WOULDBLOCK is normal idling and must not drop the connection as an error"); reset_all(); s_listen = 5; @@ -481,7 +481,7 @@ static void tc_liveness(void) s_serv_poll(); CHECK((s_client == -1) && (s_listen == 5) && (g_i4_error_count == 1) && (g_lk_close == 1) && (s_liveness_ctr == 0u), - "TC-I104SRV-038 真错误:丢连接并**当场重建监听**(不留空窗)"); + "TC-I104SRV-038 a real error drops the connection and rebuilds the listener on the spot (no gap in service)"); reset_all(); s_listen = 5; @@ -489,7 +489,7 @@ static void tc_liveness(void) s_conn_dead = 1u; s_service_link(1000u); CHECK((s_client == -1) && (g_n.close_calls == 1) && (g_i4_error_count == 1), - "TC-I104SRV-039 判死后由 service_link 收口(发送失败线索单独成一条)"); + "TC-I104SRV-039 after death is declared service_link does the teardown (the send-failure path is a separate case)"); reset_all(); s_listen = 5; @@ -497,7 +497,7 @@ static void tc_liveness(void) g_lk_state = IEC104_ST_IDLE; /* 链路层自己回到了未建立 */ s_service_link(1000u); CHECK((s_client == -1) && (g_lk_close >= 1) && (s_listen == 5), - "TC-I104SRV-040 协议状态掉回 IDLE 也要丢并重生(否则服务挂着但永不服务)"); + "TC-I104SRV-040 falling back to IDLE also drops and respawns the session (otherwise the service stays up but never serves)"); reset_all(); s_listen = 9; @@ -508,7 +508,7 @@ static void tc_liveness(void) g_n.recv_rc = 0; s_serv_poll(); CHECK((s_client == -1) && (s_listen == -1) && (g_n.close_calls == 0), - "TC-I104SRV-041 表项没了又重建失败:丢掉假监听号,下一轮继续重试(数据号与监听同号时不许关)"); + "TC-I104SRV-041 slot gone and the rebuild failed: drop the stale listen handle and retry next round (never close it while it equals the data handle)"); } int main(void) diff --git a/test/host/lftpd/lftpd_test.c b/test/host/lftpd/lftpd_test.c index c22922cd..9f94eecf 100644 --- a/test/host/lftpd/lftpd_test.c +++ b/test/host/lftpd/lftpd_test.c @@ -334,7 +334,7 @@ void vTaskDelay(TickType_t t) (void)t; g_n.delay_calls++; if (g_n.delay_calls > 200) { - printf(" ABORT 循环跑飞(>200 轮)\n"); + printf(" ABORT loop runaway (>200 rounds)\n"); fflush(stdout); exit(2); } @@ -450,46 +450,46 @@ static void tc_gates(void) (void)handle_control_channel(&g_cli); CHECK((rep_has("220 ") == 1) && (rep_has("530 ") == 3) && (g_n.accept_calls == 0), - "TC-LFTPD-001 未登录只放行 USER/PASS/QUIT/FEAT/SYST/NOOP,其它一律 530"); + "TC-LFTPD-001 before login only USER/PASS/QUIT/FEAT/SYST/NOOP pass, everything else gets 530"); reset_all(); feed("ABCDEFG", "NOOP", NULL, NULL); (void)handle_control_channel(&g_cli); CHECK((rep_has("500 ") == 1) && (rep_has("200 ") == 1), - "TC-LFTPD-002 命令名 >=5 字符先拒(command_tmp 只有 5 格,防 memcpy 越界)"); + "TC-LFTPD-002 a command name of 5 characters or more is rejected first (command_tmp has only 5 slots, this keeps memcpy in bounds)"); reset_all(); g_cli.auth_logged_in = 1; /* 否则会被认证白名单先以 530 拦掉,测不到分派 */ feed("FOO bar", NULL, NULL, NULL); (void)handle_control_channel(&g_cli); CHECK((rep_has("502 ") == 1) && (rep_has("530 ") == 0), - "TC-LFTPD-003 认不出的命令回 502 而不是断开"); + "TC-LFTPD-003 an unknown command answers 502 instead of dropping the connection"); reset_all(); feed("QUIT", "NOOP", NULL, NULL); (void)handle_control_channel(&g_cli); CHECK((rep_has("221 ") == 1) && (rep_has("200 ") == 0) && (g_n.line_i == 1), - "TC-LFTPD-004 QUIT 之后不再读下一条(会话就此结束)"); + "TC-LFTPD-004 after QUIT no further command is read (the session ends here)"); reset_all(); g_n.string_rc = -1; /* 220 都送不出去 */ feed("NOOP", NULL, NULL, NULL); (void)handle_control_channel(&g_cli); CHECK((g_n.line_i == 0) && (g_lg_info_count >= 1), - "TC-LFTPD-005 欢迎未送达(对端已走)就直接收工,不空转读命令(该留痕按真实分级算 INFO)"); + "TC-LFTPD-005 if the welcome never got through (peer already gone) finish straight away instead of spinning on reads; that trace really is INFO"); reset_all(); g_cli.data_socket = 33; /* 被动模式已开但客户端直接跑了 */ feed("QUIT", NULL, NULL, NULL); (void)handle_control_channel(&g_cli); CHECK((g_n.close_calls == 1) && (g_cli.data_socket == -1), - "TC-LFTPD-006 退出时必须释放还开着的**数据监听**(单连接 socket 不能留残口)"); + "TC-LFTPD-006 on exit the still-open data listener must be released (a single-socket chip must not be left with a dangling socket)"); reset_all(); g_cli.auth_logged_in = 1; feed("noop", NULL, NULL, NULL); (void)handle_control_channel(&g_cli); - CHECK(rep_has("200 ") == 1, "TC-LFTPD-007 命令名大小写不敏感"); + CHECK(rep_has("200 ") == 1, "TC-LFTPD-007 command names are case insensitive"); reset_all(); g_cli.auth_logged_in = 1; @@ -499,7 +499,7 @@ static void tc_gates(void) feed("LIST", NULL, NULL, NULL); (void)handle_control_channel(&g_cli); CHECK((rep_has("425 ") == 1) && (g_n.accept_calls == 0), - "TC-LFTPD-010 没先开被动模式的数据命令一律 425,且不去 accept"); + "TC-LFTPD-010 a data command without passive mode set first gets 425 and never reaches accept"); } /* ===================== 被动模式与数据通道 ===================== */ @@ -514,7 +514,7 @@ static void tc_passive(void) (void)cmd_pasv(&g_cli, NULL); CHECK((strcmp(rep(0), "227 Entering Passive Mode (192,168,1,1,19,136).\r\n") == 0) && (g_cli.data_socket == 20) && (g_n.listen_calls == 1), - "TC-LFTPD-011 227 六元组:IP 经 htonl 后按高字节到低字节(点分序)、端口高/低,并记下被动监听号"); + "TC-LFTPD-011 the 227 tuple: ip through htonl then high byte to low byte (dotted order), port high/low, and the passive listen handle is recorded"); reset_all(); g_cli.auth_logged_in = 1; @@ -523,14 +523,14 @@ static void tc_passive(void) (void)handle_control_channel(&g_cli); CHECK((rep_has("425 ") == 1) && (g_n.close_calls == 1) && (g_cli.data_socket == -1), - "TC-LFTPD-012 拿不到本机 IP 时要把刚建的监听关掉(别留半个被动模式)"); + "TC-LFTPD-012 when the local ip is unavailable the listener just created must be closed (no half-passive mode left behind)"); reset_all(); g_cli.auth_logged_in = 1; feed("EPSV", NULL, NULL, NULL); (void)handle_control_channel(&g_cli); CHECK(strcmp(rep(1), "229 Entering Extended Passive Mode (|||5000|).\r\n") == 0, - "TC-LFTPD-013 EPSV 只报端口(IPv6 客户端自己沿用控制连接地址)"); + "TC-LFTPD-013 EPSV reports only the port (an IPv6 client reuses the control connection address)"); reset_all(); g_cli.auth_logged_in = 1; @@ -540,7 +540,7 @@ static void tc_passive(void) (void)handle_control_channel(&g_cli); CHECK((rep_has("150 ") == 1) && (rep_has("425 ") == 1) && (g_cli.data_socket == -1) && (g_n.close_calls == 1), - "TC-LFTPD-014 数据 accept 失败:报 425 并**关掉监听复位**,不留给下一条命令"); + "TC-LFTPD-014 a failed data accept reports 425 and closes and resets the listener instead of leaving it to the next command"); reset_all(); g_cli.auth_logged_in = 1; @@ -550,14 +550,14 @@ static void tc_passive(void) feed("PASV", "LIST", NULL, NULL); (void)handle_control_channel(&g_cli); CHECK((rep_has("226 ") == 1) && (g_n.data_write_rc == 0), - "TC-LFTPD-015 LIST 成功:先 150、数据口写目录、再 226 收尾"); + "TC-LFTPD-015 LIST success: 150 first, the directory goes out on the data socket, then 226 closes it"); reset_all(); g_cli.auth_logged_in = 1; g_io.opendir_rc = 1; /* 目录打不开 */ feed("PASV", "LIST", NULL, NULL); (void)handle_control_channel(&g_cli); - CHECK(rep_has("550 ") == 1, "TC-LFTPD-016 目录打不开时 LIST 回 550(不是 226)"); + CHECK(rep_has("550 ") == 1, "TC-LFTPD-016 when the directory cannot be opened LIST answers 550 (not 226)"); } /* ===================== 传输与写开关 ===================== */ @@ -571,7 +571,7 @@ static void tc_transfer(void) feed("PASV", "RETR a.txt", NULL, NULL); (void)handle_control_channel(&g_cli); CHECK((rep_has("226 ") == 1) && (g_lg_info_count >= 1) && (g_wd_beats >= 1), - "TC-LFTPD-017 RETR 成功:226 收尾、留 DOWNLOAD 记录,且传输循环有喂狗"); + "TC-LFTPD-017 RETR success: 226 at the end, a DOWNLOAD record is kept and the transfer loop feeds the watchdog"); reset_all(); g_cli.auth_logged_in = 1; @@ -579,7 +579,7 @@ static void tc_transfer(void) feed("PASV", "RETR gone.txt", NULL, NULL); (void)handle_control_channel(&g_cli); CHECK((rep_has("450 ") == 1) && (g_lg_error_count >= 1), - "TC-LFTPD-018 文件打不开回 450(传输失败与命令不合法要分开报)"); + "TC-LFTPD-018 a file that cannot be opened answers 450 (a transfer failure and an invalid command must be reported apart)"); reset_all(); g_cli.auth_logged_in = 1; @@ -588,7 +588,7 @@ static void tc_transfer(void) feed("PASV", "STOR up.bin", NULL, NULL); (void)handle_control_channel(&g_cli); CHECK((g_io.unlink_calls == 1) && (rep_has("450 ") == 1), - "TC-LFTPD-019 STOR 中途失败必须**删掉半成品**(否则 Flash 上永久留个坏文件)"); + "TC-LFTPD-019 a STOR failing halfway must delete the partial file (otherwise a broken file stays on flash forever)"); reset_all(); g_cli.auth_logged_in = 1; @@ -598,27 +598,27 @@ static void tc_transfer(void) (void)handle_control_channel(&g_cli); CHECK((rep_has("550 ") == 1) && (g_n.accept_calls == 0) && (g_io.open_write_rc == 0) && (g_io.unlink_calls == 0), - "TC-LFTPD-020 写开关关闭时 STOR 在碰文件之前就拒绝,且不开数据通道"); + "TC-LFTPD-020 with writes disabled STOR is refused before the file is touched and no data channel is opened"); reset_all(); g_cli.auth_logged_in = 1; g_cfg.write_en = 0u; (void)cmd_dele(&g_cli, "a.txt"); - CHECK(rep_has("550 ") == 1, "TC-LFTPD-021 写开关同样挡住 DELE"); + CHECK(rep_has("550 ") == 1, "TC-LFTPD-021 the write switch blocks DELE as well"); reset_all(); g_cli.auth_logged_in = 1; g_io.is_dir = 1; (void)cmd_dele(&g_cli, "sub"); CHECK((rep_has("550 ") == 1) && (g_io.unlink_calls == 0), - "TC-LFTPD-022 DELE 不许删目录(本实现只支持删文件)"); + "TC-LFTPD-022 DELE must not delete directories (this implementation only deletes files)"); reset_all(); g_cli.auth_logged_in = 1; g_io.is_dir = 0; (void)cmd_dele(&g_cli, "a.txt"); CHECK((g_io.unlink_calls == 1) && (rep_has("250 ") == 1), - "TC-LFTPD-022b 删普通文件走 unlink 并回 250"); + "TC-LFTPD-022b deleting a regular file goes through unlink and answers 250"); } /* ===================== 目录与元信息 ===================== */ @@ -629,58 +629,58 @@ static void tc_meta(void) reset_all(); (void)cmd_cwd(&g_cli, ""); CHECK((rep_has("550 ") == 1) && (strcmp(g_cli.directory, "/") == 0), - "TC-LFTPD-023 CWD 空参数拒绝,当前目录不变"); + "TC-LFTPD-023 CWD with an empty argument is refused and the current directory stays"); reset_all(); g_io.is_dir = 0; (void)cmd_cwd(&g_cli, "a.txt"); - CHECK(rep_has("550 ") == 1, "TC-LFTPD-023b CWD 到普通文件被拒(is_dir 必须真为目录)"); + CHECK(rep_has("550 ") == 1, "TC-LFTPD-023b CWD onto a regular file is refused (is_dir must really be a directory)"); reset_all(); g_io.is_dir = 1; (void)cmd_cwd(&g_cli, "logs"); CHECK((rep_has("250 ") == 1) && (strcmp(g_cli.directory, "//logs") == 0) && (g_free_calls == 1), - "TC-LFTPD-024 CWD 成功后更新当前目录并释放路径缓冲(不泄漏堆)"); + "TC-LFTPD-024 a successful CWD updates the current directory and frees the path buffer (no heap leak)"); reset_all(); (void)cmd_cwd(&g_cli, "/"); CHECK((rep_has("250 ") == 1) && (g_io.stat_rc == 0), - "TC-LFTPD-024b 回到根目录免 stat 直接放行(根一定存在)"); + "TC-LFTPD-024b going back to the root skips stat and succeeds directly (the root always exists)"); reset_all(); g_io.is_dir = 0; g_io.size = 12345u; (void)cmd_size(&g_cli, "up.bin"); - CHECK(strcmp(rep(0), "213 12345\r\n") == 0, "TC-LFTPD-025 SIZE 报字节数"); + CHECK(strcmp(rep(0), "213 12345\r\n") == 0, "TC-LFTPD-025 SIZE reports the byte count"); reset_all(); g_io.stat_rc = -1; (void)cmd_size(&g_cli, "nope"); - CHECK(rep_has("550 ") == 1, "TC-LFTPD-025b 文件不存在时 SIZE 回 550"); + CHECK(rep_has("550 ") == 1, "TC-LFTPD-025b when the file is missing SIZE answers 550"); reset_all(); (void)strcpy(g_cli.directory, "/logs"); (void)cmd_pwd(&g_cli, NULL); CHECK(strcmp(rep(0), "257 \"/logs\"\r\n") == 0, - "TC-LFTPD-026 PWD 用双引号包住目录(RFC 959 要求)"); + "TC-LFTPD-026 PWD wraps the directory in double quotes (required by RFC 959)"); reset_all(); (void)cmd_syst(&g_cli, NULL); CHECK(strcmp(rep(0), "215 UNIX Type: L8\r\n") == 0, - "TC-LFTPD-027 SYST 固定报 UNIX Type: L8(客户端据此决定模式)"); + "TC-LFTPD-027 SYST always reports UNIX Type: L8 (clients pick their mode from it)"); reset_all(); (void)cmd_feat(&g_cli, NULL); CHECK((strncmp(rep(0), "211-", 4) == 0) && (strcmp(rep(1), "EPSV\r\n") == 0) && (strcmp(rep(2), "PASV\r\n") == 0) && (strncmp(rep(5), "211 ", 4) == 0) && (g_n.reply_n == 6), - "TC-LFTPD-028 FEAT 多行:首行 211-、四条能力无状态码、末行 211 结束"); + "TC-LFTPD-028 FEAT multiline: first line 211-, four capability lines without a status code, last line 211 ends it"); reset_all(); (void)cmd_type(&g_cli, "I"); (void)cmd_noop(&g_cli, NULL); - CHECK(rep_has("200 ") == 2, "TC-LFTPD-030 TYPE 与 NOOP 都回 200"); + CHECK(rep_has("200 ") == 2, "TC-LFTPD-030 both TYPE and NOOP answer 200"); } /* ===================== 登录序列 ===================== */ @@ -693,7 +693,7 @@ static void tc_login(void) (void)handle_control_channel(&g_cli); CHECK((rep_has("331 ") == 1) && (rep_has("230 ") == 1) && (g_cli.auth_logged_in == 1u) && (strcmp(g_cli.auth_user, "admin") == 0), - "TC-LFTPD-031 USER 记下用户名与匹配位,PASS 过了就转已登录"); + "TC-LFTPD-031 USER records the user name and the match bit; a passing PASS switches to logged in"); reset_all(); g_auth_res = FTP_AUTH_FAIL; @@ -701,7 +701,7 @@ static void tc_login(void) (void)handle_control_channel(&g_cli); CHECK((rep_has("530 ") == 1) && (g_cli.auth_logged_in == 0u) && (g_lg_info_count >= 1), - "TC-LFTPD-032 口令错:530 且**必须重新走 USER**(auth_user_ok 已清零)"); + "TC-LFTPD-032 a wrong password gives 530 and USER must be repeated (auth_user_ok was cleared)"); reset_all(); g_auth_res = FTP_AUTH_LOCKED; @@ -709,7 +709,7 @@ static void tc_login(void) feed("USER admin", "PASS bad", NULL, NULL); (void)handle_control_channel(&g_cli); CHECK(rep_has("530 ") == 1, - "TC-LFTPD-033 连错被锁时同样只回 530(不给攻击者区分提示)"); + "TC-LFTPD-033 while locked out after repeated failures it also answers only 530 (no distinguishing hint for an attacker)"); reset_all(); g_cfg_present = 0; /* 配置读不到 */ @@ -717,7 +717,7 @@ static void tc_login(void) (void)handle_control_channel(&g_cli); CHECK((rep_has("331 ") == 1) && (rep_has("530 ") == 1) && (g_cli.auth_user_ok == 0u), - "TC-LFTPD-034 配置缺失时 USER 无法匹配、PASS 直接 530(fail-closed)"); + "TC-LFTPD-034 with missing configuration USER cannot match and PASS answers 530 straight away (fail-closed)"); } int main(void) diff --git a/test/host/lftpd_inet/lftpd_inet_test.c b/test/host/lftpd_inet/lftpd_inet_test.c index 17687bb5..c2d81cde 100644 --- a/test/host/lftpd_inet/lftpd_inet_test.c +++ b/test/host/lftpd_inet/lftpd_inet_test.c @@ -241,7 +241,7 @@ void vTaskDelay(TickType_t xTicksToDelay) if (g_net.delay_calls > 100) { /* 跑飞保险:本模块每条用例都必须在有限轮内退出(accept 序列要么成功、 * 要么撤防、要么代次变化)。真跑飞就退出,绝不把挂死留给 pre-commit。 */ - printf(" ABORT accept/等待循环跑飞(>100 轮未退出)\n"); + printf(" ABORT accept/wait loop runaway (>100 rounds without exit)\n"); fflush(stdout); exit(2); } @@ -262,32 +262,32 @@ static void tc_listen(void) net_reset(); logs_clear(); g_net.socket_rc = -1; CHECK((lftpd_inet_listen(21) == -1) && (g_net.bind_calls == 0) && - (g_lfi_error_count == 1), "TC-LFTINET-001 建 socket 失败即返回,不再 bind"); + (g_lfi_error_count == 1), "TC-LFTINET-001 a socket creation failure returns at once, no bind attempt"); net_reset(); logs_clear(); g_net.bind_rc = -1; CHECK((lftpd_inet_listen(21) == -1) && (g_net.close_calls == 1) && - (g_net.listen_calls == 0), "TC-LFTINET-002 bind 失败要把 socket 关掉"); + (g_net.listen_calls == 0), "TC-LFTINET-002 a bind failure must close the socket"); net_reset(); logs_clear(); g_net.listen_rc = -1; CHECK((lftpd_inet_listen(21) == -1) && (g_net.close_calls == 1) && - (g_lfi_error_count == 1), "TC-LFTINET-003 listen 失败同样关socket 并留痕"); + (g_lfi_error_count == 1), "TC-LFTINET-003 a listen failure also closes the socket and logs it"); net_reset(); logs_clear(); CHECK((lftpd_inet_listen(21) == 3) && (g_net.last_domain == NET_AF_INET) && (g_net.last_type == NET_SOCK_STREAM) && (g_net.last_bind_port_net == net_htons(21u)) && (g_net.listen_calls == 1), - "TC-LFTINET-004 流式监听口,且**端口过了 htons**(sin_port 是网络序)"); + "TC-LFTINET-004 a stream listener whose port went through htons (sin_port is network order)"); net_reset(); logs_clear(); g_net.getsock_rc = -1; CHECK((lftpd_inet_get_socket_port(3) == -1) && (g_lfi_error_count == 1), - "TC-LFTINET-005 问不到名字就报 -1(不拿脏端口当结果)"); + "TC-LFTINET-005 a failing getsockname returns -1 (never report a stale port as the result)"); net_reset(); logs_clear(); g_net.getsock_port_net = net_htons(8888u); CHECK(lftpd_inet_get_socket_port(3) == 8888, - "TC-LFTINET-006 端口回来要 ntohs 还原成宿主序"); + "TC-LFTINET-006 the port comes back through ntohs into host order"); } /* ===================== accept:喂狗、代次、撤防 ===================== */ @@ -298,14 +298,14 @@ static void tc_accept(void) net_reset(); logs_clear(); g_net.accept_seq[0] = 9; g_net.accept_n = 1; CHECK((lftpd_inet_accept(3) == 9) && (g_net.delay_calls == 0), - "TC-LFTINET-010 一击即中不睡不等"); + "TC-LFTINET-010 an immediate hit neither sleeps nor waits"); net_reset(); logs_clear(); g_net.accept_seq[0] = -1; g_net.accept_seq[1] = -1; g_net.accept_seq[2] = 9; g_net.accept_n = 3; CHECK((lftpd_inet_accept(3) == 9) && (g_net.delay_calls == 2) && (g_lfi_info_count == 0), - "TC-LFTINET-011 每轮失败都让出一次 CPU(同段代码里也喂狗),直到成功"); + "TC-LFTINET-011 every failed round yields the CPU (and feeds the watchdog in the same block) until it succeeds"); net_reset(); logs_clear(); g_net.accept_seq[0] = -1; g_net.accept_seq[1] = -1; g_net.accept_seq[2] = -1; @@ -313,25 +313,25 @@ static void tc_accept(void) g_net.gen_flip_after = 3; /* 第 3 轮时网络重建 */ CHECK((lftpd_inet_accept(3) == -1) && (g_lfi_info_count == 1) && (g_net.accept_calls == 3), - "TC-LFTINET-012 **代次一变立刻撤掉 accept**(否则新 IP 生效后监听还挂在旧代次)"); + "TC-LFTINET-012 a generation change aborts accept immediately (otherwise the listener stays on the old generation after the new IP takes effect)"); net_reset(); logs_clear(); g_net.accept_seq[0] = -1; g_net.accept_seq[1] = 9; g_net.accept_n = 2; CHECK((lftpd_inet_accept_timeout(3, 5000) == 9) && (g_net.delay_calls == 1), - "TC-LFTINET-020 超时窗内等到数据通道"); + "TC-LFTINET-020 the data channel is accepted inside the timeout window"); net_reset(); logs_clear(); g_net.accept_seq[0] = -1; g_net.accept_seq[1] = -1; g_net.accept_n = 2; g_net.armed = 0; /* 监听门被撤(会话已放弃) */ CHECK((lftpd_inet_accept_timeout(3, 5000) == -1) && (g_net.accept_calls == 1) && (g_lfi_error_count == 1), - "TC-LFTINET-021 监听门撤防立即放弃,不对着死监听耗满 5 s"); + "TC-LFTINET-021 lowering the listener gate gives up at once instead of burning the full 5 s on a dead listener"); net_reset(); logs_clear(); g_net.accept_seq[0] = -1; g_net.accept_n = 1; CHECK((lftpd_inet_accept_timeout(3, 300) == -1) && (g_net.delay_calls == 3) && (g_lfi_info_count == 1), - "TC-LFTINET-022 对端一直不开数据通道:按 100ms 步进等满后 INFO 收场"); + "TC-LFTINET-022 the peer never opens the data channel: step by 100ms to the limit and finish as INFO"); } /* ===================== read_line:分片、截断、预算 ===================== */ @@ -347,38 +347,38 @@ static void tc_read_line(void) g_net.recv_seq[0] = 12; g_net.recv_n = 1; rc = lftpd_inet_read_line(3, b, sizeof(b)); CHECK((rc == 0) && (strcmp(b, "USER admin") == 0), - "TC-LFTINET-030 一次到位:CRLF 就地截成结束符(FTP 命令行的边界)"); + "TC-LFTINET-030 one shot: CRLF is cut into the terminator in place (the FTP command line boundary)"); net_reset(); logs_clear(); (void)strcpy(g_net.rx, "USER admin\r\n"); g_net.recv_seq[0] = 4; g_net.recv_seq[1] = 8; g_net.recv_n = 2; rc = lftpd_inet_read_line(3, b, sizeof(b)); CHECK((rc == 0) && (strcmp(b, "USER admin") == 0), - "TC-LFTINET-031 分两片到达也要拼出整行(跨包命令行)"); + "TC-LFTINET-031 two arriving halves are stitched into one line (a command line spanning packets)"); net_reset(); logs_clear(); g_net.recv_seq[0] = 0; g_net.recv_n = 1; CHECK(lftpd_inet_read_line(3, b, sizeof(b)) == -1, - "TC-LFTINET-032 读到 0(对端关闭)立刻失败,不进死循环"); + "TC-LFTINET-032 reading 0 (peer closed) fails at once and must not spin"); net_reset(); logs_clear(); (void)strcpy(g_net.rx, "NOOP\r\n"); g_net.recv_seq[0] = -2; g_net.recv_seq[1] = 6; g_net.recv_n = 2; rc = lftpd_inet_read_line(3, b, sizeof(b)); CHECK((rc == 0) && (strcmp(b, "NOOP") == 0), - "TC-LFTINET-033 -2 表示这一片超时,继续等而不是当错误"); + "TC-LFTINET-033 -2 means this slice timed out: keep waiting instead of treating it as an error"); net_reset(); logs_clear(); g_net.recv_seq[0] = -5; g_net.recv_n = 1; CHECK(lftpd_inet_read_line(3, b, sizeof(b)) == -5, - "TC-LFTINET-034 其它负值**原样返回**(错误码不许被吞成 -1)"); + "TC-LFTINET-034 any other negative value is returned verbatim (an error code must not be swallowed into -1)"); net_reset(); logs_clear(); g_net.recv_seq[0] = -2; g_net.recv_n = 1; /* 一直超时,每轮耗 200ms */ rc = lftpd_inet_read_line(3, b, sizeof(b)); CHECK((rc == -1) && (g_net.recv_calls == 150) && (g_net.last_recv_timeout <= 200u), - "TC-LFTINET-035 30 s 总预算按 200ms 分片累加,到点退出(饿不到看门狗)"); + "TC-LFTINET-035 the 30 s total budget accumulates in 200ms slices and exits on time (the watchdog never starves)"); net_reset(); logs_clear(); (void)memset(g_net.rx, 'A', 40); /* 没有 CRLF 的长行 */ @@ -386,7 +386,7 @@ static void tc_read_line(void) (void)memset(b, 0, sizeof(b)); rc = lftpd_inet_read_line(3, b, 8); CHECK((rc == -1) && (b[7] == '\0'), - "TC-LFTINET-036 缓冲填满仍无行尾:失败且**不越界写**(留最后一格给结束符)"); + "TC-LFTINET-036 buffer full with no line end: fail without writing out of bounds (the last byte is reserved for the terminator)"); } /* ===================== 写与读 ===================== */ @@ -400,45 +400,45 @@ static void tc_write_read(void) net_reset(); logs_clear(); g_net.send_seq[0] = 12; g_net.send_n = 1; CHECK((lftpd_inet_write_string(3, msg) == 0) && (g_net.send_calls == 1), - "TC-LFTINET-040 一次写完"); + "TC-LFTINET-040 everything written in a single call"); net_reset(); logs_clear(); g_net.send_seq[0] = 5; g_net.send_seq[1] = 7; g_net.send_n = 2; CHECK((lftpd_inet_write_string(3, msg) == 0) && (g_net.send_calls == 2) && (g_net.send_off[1] == 5), - "TC-LFTINET-041 短写后续传从**正确的偏移**接着写(少半条响应就是协议错乱)"); + "TC-LFTINET-041 after a short write the continuation resumes at the correct offset (half a response is a protocol break)"); net_reset(); logs_clear(); g_net.send_seq[0] = 0; g_net.send_n = 1; CHECK((lftpd_inet_write_string(3, msg) == -1) && (g_lfi_error_count == 1), - "TC-LFTINET-042 写 0 字节按失败处理(不是当成成功写了 0 字节)"); + "TC-LFTINET-042 writing 0 bytes counts as a failure (not a successful zero-byte write)"); net_reset(); logs_clear(); g_net.send_seq[0] = -1; g_net.send_n = 1; - CHECK(lftpd_inet_write(3, msg, 12) == -1, "TC-LFTINET-043 写失败原样回 -1"); + CHECK(lftpd_inet_write(3, msg, 12) == -1, "TC-LFTINET-043 a write failure returns -1 as is"); net_reset(); logs_clear(); g_net.send_seq[0] = 4; g_net.send_seq[1] = 6; g_net.send_n = 2; CHECK((lftpd_inet_write(3, msg, 10) == 10) && (g_net.send_calls == 2), - "TC-LFTINET-050 二进制写也走短写续传,成功时回**请求长度**"); + "TC-LFTINET-050 binary writes also resume after short writes and return the requested length on success"); net_reset(); logs_clear(); (void)strcpy(g_net.rx, "STOR\r\n"); g_net.recv_seq[0] = 4; g_net.recv_n = 1; - CHECK(lftpd_inet_read(3, b, sizeof(b)) == 4, "TC-LFTINET-060 读到数据立刻交还"); + CHECK(lftpd_inet_read(3, b, sizeof(b)) == 4, "TC-LFTINET-060 data read is handed back immediately"); net_reset(); logs_clear(); g_net.recv_seq[0] = -1; g_net.recv_n = 1; - CHECK(lftpd_inet_read(3, b, sizeof(b)) == -1, "TC-LFTINET-061 -1 直接失败返回"); + CHECK(lftpd_inet_read(3, b, sizeof(b)) == -1, "TC-LFTINET-061 -1 fails and returns directly"); net_reset(); logs_clear(); g_net.recv_seq[0] = -3; g_net.recv_n = 1; CHECK((lftpd_inet_read(3, b, sizeof(b)) == -1) && (g_net.recv_calls > 1), - "TC-LFTINET-062 其它负值继续等,直到 30 s 预算耗尽"); + "TC-LFTINET-062 other negative values keep waiting until the 30 s budget is exhausted"); net_reset(); logs_clear(); CHECK((lftpd_inet_close(3) == 0) && (g_net.close_calls == 1), - "TC-LFTINET-070 close 就是转 net_close"); + "TC-LFTINET-070 close only forwards to net_close"); } int main(void) diff --git a/test/host/lftpd_io/lftpd_io_test.c b/test/host/lftpd_io/lftpd_io_test.c index 40d3c8ba..9e24ae0f 100644 --- a/test/host/lftpd_io/lftpd_io_test.c +++ b/test/host/lftpd_io/lftpd_io_test.c @@ -276,11 +276,11 @@ static void tc_fatfs_path(void) { printf("-- TC-LFTPIO-001..004 to_fatfs_path --\n"); CHECK((strcmp(to_fatfs_path(NULL), "0:") == 0) && - (strcmp(to_fatfs_path(""), "0:") == 0), "TC-LFTPIO-001 NULL/空串 -> 0:"); - CHECK(strcmp(to_fatfs_path("/"), "0:") == 0, "TC-LFTPIO-002 根 -> 0:"); + (strcmp(to_fatfs_path(""), "0:") == 0), "TC-LFTPIO-001 NULL/empty string -> 0:"); + CHECK(strcmp(to_fatfs_path("/"), "0:") == 0, "TC-LFTPIO-002 root -> 0:"); CHECK(strcmp(to_fatfs_path("/a/b.txt"), "a/b.txt") == 0, - "TC-LFTPIO-003 去掉前导斜杠"); - CHECK(strcmp(to_fatfs_path("a.txt"), "a.txt") == 0, "TC-LFTPIO-004 原样返回"); + "TC-LFTPIO-003 the leading slash is stripped"); + CHECK(strcmp(to_fatfs_path("a.txt"), "a.txt") == 0, "TC-LFTPIO-004 returned unchanged"); } /* ===================== 路径规范化 ===================== */ @@ -289,32 +289,32 @@ static void tc_canon(void) { printf("-- TC-LFTPIO-010..022 canonicalize --\n"); reset_all(); - CHECK(strcmp(canon("/dir", "f.txt"), "/dir/f.txt") == 0, "TC-LFTPIO-010 相对拼接"); - CHECK(strcmp(canon("/dir", "/abs.txt"), "/abs.txt") == 0, "TC-LFTPIO-011 绝对忽略 base"); - CHECK(strcmp(canon("/a/b", "../c"), "/a/c") == 0, "TC-LFTPIO-012 上跳一级"); + CHECK(strcmp(canon("/dir", "f.txt"), "/dir/f.txt") == 0, "TC-LFTPIO-010 relative join"); + CHECK(strcmp(canon("/dir", "/abs.txt"), "/abs.txt") == 0, "TC-LFTPIO-011 an absolute name ignores base"); + CHECK(strcmp(canon("/a/b", "../c"), "/a/c") == 0, "TC-LFTPIO-012 go up one level"); CHECK(strcmp(canon("/a", "../../x"), "/x") == 0, - "TC-LFTPIO-013 上跳过头仍被钳在根内(安全属性)"); - CHECK(strcmp(canon("/a", "."), "/a") == 0, "TC-LFTPIO-014 丢弃 . 段"); - CHECK(strcmp(canon("/a", ".."), "/") == 0, "TC-LFTPIO-015 回退到根"); - CHECK(strcmp(canon("/a//", "b"), "/a/b") == 0, "TC-LFTPIO-016 段间多余斜杠被折叠"); + "TC-LFTPIO-013 over-shooting .. is still clamped inside the root (safety property)"); + CHECK(strcmp(canon("/a", "."), "/a") == 0, "TC-LFTPIO-014 a . segment is dropped"); + CHECK(strcmp(canon("/a", ".."), "/") == 0, "TC-LFTPIO-015 .. at the top falls back to the root"); + CHECK(strcmp(canon("/a//", "b"), "/a/b") == 0, "TC-LFTPIO-016 redundant slashes between segments are collapsed"); CHECK(strcmp(canon("/dir", "//x"), "/x") == 0, - "TC-LFTPIO-016b name 以斜杠开头按**绝对路径**处理(忽略 base,仍钳在根内)"); - CHECK(strcmp(canon(NULL, "x"), "/x") == 0, "TC-LFTPIO-017 base NULL 视作空串"); - CHECK(strcmp(canon("/a", NULL), "/a") == 0, "TC-LFTPIO-018 name NULL 视作空串"); - CHECK(strcmp(canon(NULL, NULL), "/") == 0, "TC-LFTPIO-019 两个 NULL -> /"); - CHECK(strcmp(canon("/", ".."), "/") == 0, "TC-LFTPIO-020 根上加 .. 仍是根"); + "TC-LFTPIO-016b a name starting with a slash is treated as an absolute path (base ignored, still clamped inside the root)"); + CHECK(strcmp(canon(NULL, "x"), "/x") == 0, "TC-LFTPIO-017 a NULL base counts as an empty string"); + CHECK(strcmp(canon("/a", NULL), "/a") == 0, "TC-LFTPIO-018 a NULL name counts as an empty string"); + CHECK(strcmp(canon(NULL, NULL), "/") == 0, "TC-LFTPIO-019 both NULL -> /"); + CHECK(strcmp(canon("/", ".."), "/") == 0, "TC-LFTPIO-020 .. on the root is still the root"); reset_all(); g_fail_at = 1; CHECK(lftpd_io_canonicalize_path("/a", "b") == NULL, - "TC-LFTPIO-021 首块分配失败返回 NULL"); - CHECK(g_alloc_calls == 1, "TC-LFTPIO-021b 失败后不再分配第二块"); + "TC-LFTPIO-021 the first allocation failing returns NULL"); + CHECK(g_alloc_calls == 1, "TC-LFTPIO-021b no second allocation is attempted after that failure"); reset_all(); g_fail_at = 2; CHECK(lftpd_io_canonicalize_path("/a", "b") == NULL, - "TC-LFTPIO-022 结果缓冲分配失败返回 NULL"); - CHECK(g_free_calls == 1, "TC-LFTPIO-022b 第一块已释放(不泄漏堆)"); + "TC-LFTPIO-022 the result buffer allocation failing returns NULL"); + CHECK(g_free_calls == 1, "TC-LFTPIO-022b the first block was freed (no heap leak)"); } /* ===================== 打开文件:守卫 / 卷锁 / 错误通道 ===================== */ @@ -329,24 +329,24 @@ static void tc_open(void) rc = lftpd_io_open_read("/a/b.txt"); CHECK((rc == 0) && (g_open_mode == FA_READ) && (strcmp(g_open_path, "a/b.txt") == 0), - "TC-LFTPIO-030 成功:FA_READ + 映射后的路径"); + "TC-LFTPIO-030 success: FA_READ plus the mapped path"); reset_all(); s_file_open = 1; rc = lftpd_io_open_read("/x"); CHECK((rc == -1) && (g_open_calls == 0) && (g_wait_calls == 0), - "TC-LFTPIO-031 单文件槽守卫:已打开时不碰卷锁与 FatFs"); + "TC-LFTPIO-031 single-file slot guard: while a file is open it touches neither the volume lock nor FatFs"); reset_all(); g_open_rc = FR_NO_FILE; rc = lftpd_io_open_read("/x"); CHECK((rc == -1) && (g_release_calls == 1) && (g_lfio_error_count == 1), - "TC-LFTPIO-032 打开失败:返回 -1 + 留痕 + 释放卷锁"); + "TC-LFTPIO-032 open failure: return -1 + log + release the volume lock"); reset_all(); rc = lftpd_io_open_read("/x"); CHECK((rc == 0) && (g_release_calls == 0) && (s_file_open == 1), - "TC-LFTPIO-033 成功后卷锁不释放(传输期独占)"); + "TC-LFTPIO-033 the volume lock stays held after success (exclusive for the whole transfer)"); reset_all(); g_wait_seq[0] = 0; /* 第一轮:卷被 defaultTask 占着 */ @@ -354,22 +354,22 @@ static void tc_open(void) g_wait_seq[2] = 1; /* 第三轮:拿到 */ rc = lftpd_io_open_read("/x"); CHECK((rc == 0) && (g_beat_calls == 2) && (g_wait_calls == 3), - "TC-LFTPIO-034 等锁循环每轮喂看门狗(漏喂 = 整机复位)"); + "TC-LFTPIO-034 the lock-wait loop feeds the watchdog every round (missing a feed resets the whole device)"); reset_all(); rc = lftpd_io_open_write("/up.bin"); CHECK((rc == 0) && (g_open_mode == (BYTE)(FA_WRITE | FA_CREATE_ALWAYS)), - "TC-LFTPIO-035 open_write 用覆盖写模式"); + "TC-LFTPIO-035 open_write uses overwrite mode"); reset_all(); s_file_open = 1; rc = lftpd_io_open_write("/up.bin"); - CHECK((rc == -1) && (g_open_calls == 0), "TC-LFTPIO-036 open_write 同样有槽守卫"); + CHECK((rc == -1) && (g_open_calls == 0), "TC-LFTPIO-036 open_write has the same slot guard"); reset_all(); g_open_rc = FR_DISK_ERR; rc = lftpd_io_open_write("/up.bin"); - CHECK((rc == -1) && (g_release_calls == 1), "TC-LFTPIO-037 open_write 失败也释放卷锁"); + CHECK((rc == -1) && (g_release_calls == 1), "TC-LFTPIO-037 an open_write failure also releases the volume lock"); } /* ===================== trim ===================== */ @@ -386,19 +386,19 @@ static void tc_trim(void) (void)strcpy(buf, " PASS x"); r = lftpd_string_ltrim(buf); CHECK((r != buf) && (strcmp(r, "PASS x") == 0) && (buf[0] == ' '), - "TC-LFTSTR-001 行首空白靠返回指针跳过,原缓冲不搬移"); + "TC-LFTSTR-001 leading blanks are skipped via the returned pointer, the buffer itself is not moved"); (void)strcpy(buf, "NOOP"); r = lftpd_string_ltrim(buf); - CHECK((r == buf) && (strcmp(buf, "NOOP") == 0), "TC-LFTSTR-002 无前导空白返回同一指针"); + CHECK((r == buf) && (strcmp(buf, "NOOP") == 0), "TC-LFTSTR-002 with no leading blanks the same pointer comes back"); (void)strcpy(buf, " USER admin "); r = lftpd_string_ltrim(buf); - CHECK(strcmp(r, "USER admin ") == 0, "TC-LFTSTR-003 词中间空白保留"); + CHECK(strcmp(r, "USER admin ") == 0, "TC-LFTSTR-003 blanks inside the text are kept"); (void)strcpy(buf, " \t\r\n"); r = lftpd_string_ltrim(buf); - CHECK(r[0] == '\0', "TC-LFTSTR-004 全空白 -> 空串"); + CHECK(r[0] == '\0', "TC-LFTSTR-004 all blanks -> empty string"); /* 现状桩(不是期望行为):尾部循环从 strlen(p) 起步,那里是 '\0', * isspace(0)=0 立刻退出 —— **尾部空白/CRLF 实际从未被裁**。今天无害是因为 @@ -411,7 +411,7 @@ static void tc_trim(void) (void)strcpy(buf, "LIST "); r = lftpd_string_ltrim(buf); CHECK(strcmp(r, "LIST ") == 0, - "TC-LFTSTR-005 尾随空格必须保留(ltrim 语义,RFC 959 参数本体)"); + "TC-LFTSTR-005 trailing spaces must survive (ltrim semantics, they belong to the RFC 959 argument)"); } /* ===================== 入口 ===================== */ diff --git a/test/host/net_cfg/net_cfg_test.c b/test/host/net_cfg/net_cfg_test.c index a53f0557..5143bd91 100644 --- a/test/host/net_cfg/net_cfg_test.c +++ b/test/host/net_cfg/net_cfg_test.c @@ -266,7 +266,7 @@ static void tc_defaults(void) CHECK(bytes_eq(p->ip, def_ip, 4u), "TC-NETCFG-001 ip = 192.168.1.100"); CHECK(bytes_eq(p->mask, def_mask, 4u), "TC-NETCFG-002 mask = 255.255.255.0"); CHECK(bytes_eq(p->gw, def_gw, 4u), "TC-NETCFG-003 gw = 192.168.1.1"); - CHECK(mac_eq(p->mac, zero), "TC-NETCFG-004 mac = 全零(芯片内置哨兵)"); + CHECK(mac_eq(p->mac, zero), "TC-NETCFG-004 mac = all zero (chip built-in sentinel)"); } /* ===================== 注册与 load 契约 ===================== */ @@ -279,13 +279,13 @@ static void tc_register_load(void) fake_reset(); rc = net_cfg_load(); CHECK((rc == 0) && (g_reg_n == 1) && (strcmp(g_regs[0].name, "network") == 0), - "TC-NETCFG-005 首次 load 注册 [network] 恰好一次"); + "TC-NETCFG-005 first load registers [network] exactly once"); CHECK((g_ftp_reg_calls == 1) && (g_load_calls == 1), - "TC-NETCFG-006 一并注册 [ftp],且注册在 load 之前"); + "TC-NETCFG-006 also registers [ftp], registered before load"); rc = net_cfg_load(); CHECK((rc == 0) && (g_reg_n == 1) && (g_ftp_reg_calls == 2), - "TC-NETCFG-007 重复 load 不重复注册 [network]"); + "TC-NETCFG-007 repeated load does not re-register [network]"); CHECK((strcmp(g_regs[0].name, "network") == 0) && (g_regs[0].data_size == sizeof(net_cfg_t)) && @@ -293,18 +293,18 @@ static void tc_register_load(void) (g_regs[0].p_defaults != NULL) && (g_regs[0].p_cb != NULL) && (g_regs[0].p_data == (const void *)&s_cfg), - "TC-NETCFG-008 注册内容:尺寸/键数/默认值/回调/数据指针=RAM 副本"); + "TC-NETCFG-008 registration content: size/key count/defaults/callback/data pointer = RAM copy"); fake_reset(); rc = net_cfg_load(); CHECK((rc == 0) && (g_netcfg_info_count == 1) && (g_netcfg_error_count == 0), - "TC-NETCFG-009 load 成功:返回 0 + 一条 INFO"); + "TC-NETCFG-009 load success: returns 0 + one INFO line"); fake_reset(); g_load_rc = -1; rc = net_cfg_load(); - CHECK(rc == 0, "TC-NETCFG-010 引擎 -1 时仍返回 0(RAM 恒有效契约)"); - CHECK(g_netcfg_error_count == 1, "TC-NETCFG-011 load 失败必须留 ERROR"); + CHECK(rc == 0, "TC-NETCFG-010 engine -1 still returns 0 (RAM copy is always valid, by contract)"); + CHECK(g_netcfg_error_count == 1, "TC-NETCFG-011 load failure must leave an ERROR line"); } /* ===================== RAM 副本读写 ===================== */ @@ -321,10 +321,10 @@ static void tc_set_get(void) memcpy(c.mac, mac, 6u); net_cfg_set(&c); CHECK(bytes_eq(net_cfg_get()->ip, ip, 4u) && - mac_eq(net_cfg_get()->mac, mac), "TC-NETCFG-012 set 被 get 读回"); + mac_eq(net_cfg_get()->mac, mac), "TC-NETCFG-012 set is read back by get"); net_cfg_set(NULL); - CHECK(bytes_eq(net_cfg_get()->ip, ip, 4u), "TC-NETCFG-013 set(NULL) 不改写"); + CHECK(bytes_eq(net_cfg_get()->ip, ip, 4u), "TC-NETCFG-013 set(NULL) rewrites nothing"); } /* ===================== 直接保存 ===================== */ @@ -336,13 +336,13 @@ static void tc_save_direct(void) printf("-- TC-NETCFG-014..015 save --\n"); fake_reset(); rc = net_cfg_save(); - CHECK((rc == 0) && (g_save_calls == 1), "TC-NETCFG-014 写盘成功返回 0"); + CHECK((rc == 0) && (g_save_calls == 1), "TC-NETCFG-014 write success returns 0"); fake_reset(); g_save_rc = -1; rc = net_cfg_save(); CHECK((rc == -1) && (g_netcfg_error_count == 1), - "TC-NETCFG-015 写盘失败返回 -1 并留痕"); + "TC-NETCFG-015 write failure returns -1 and leaves a trace"); } /* ===================== 跨任务保存交接状态机 ===================== */ @@ -357,40 +357,40 @@ static void tc_save_handoff(void) net_cfg_set_save_req_cb(NULL); s_save_pending = 0u; /* 白盒复位:上一组的 save() 不碰 pending/result,此处 */ s_save_result = 0u; /* 只是防止将来有人调整后漏出脏态 */ - CHECK(net_cfg_save_state() == NET_CFG_SAVE_ST_IDLE, "TC-NETCFG-020 初始 IDLE"); + CHECK(net_cfg_save_state() == NET_CFG_SAVE_ST_IDLE, "TC-NETCFG-020 initial state IDLE"); CHECK((net_cfg_save_request() == 0) && - (net_cfg_save_state() == NET_CFG_SAVE_ST_WAIT), "TC-NETCFG-021 投递后 WAIT"); + (net_cfg_save_state() == NET_CFG_SAVE_ST_WAIT), "TC-NETCFG-021 WAIT after posting"); net_cfg_set_save_req_cb(req_cb); g_req_cb_calls = 0; (void)net_cfg_save_request(); - CHECK(g_req_cb_calls == 1, "TC-NETCFG-022 投递经回调唤醒属主任务"); + CHECK(g_req_cb_calls == 1, "TC-NETCFG-022 posting wakes the owner task through the callback"); net_cfg_set_save_req_cb(NULL); (void)net_cfg_save_request(); CHECK((g_req_cb_calls == 1) && (net_cfg_save_state() == NET_CFG_SAVE_ST_WAIT), - "TC-NETCFG-023 未注册回调时空操作,请求照样挂起"); + "TC-NETCFG-023 no callback registered -> no-op, request still pending"); g_save_rc = 0; g_save_calls = 0; rc = net_cfg_save_run(); - CHECK((rc == 0) && (g_save_calls == 1), "TC-NETCFG-024a 有请求时确实写盘一次"); + CHECK((rc == 0) && (g_save_calls == 1), "TC-NETCFG-024a with a pending request it really writes once"); g_save_calls = 0; rc = net_cfg_save_run(); CHECK((rc == 0) && (g_save_calls == 0), - "TC-NETCFG-024 无请求时空醒不写盘(2s 轮询不刷 Flash)"); + "TC-NETCFG-024 no request: empty wake does not write (2 s polling never flushes Flash)"); (void)net_cfg_save_request(); net_cfg_set_apply_cb(apply_cb); g_apply_calls = 0; g_save_rc = 0; rc = net_cfg_save_run(); - CHECK((rc == 0) && (s_save_pending == 0u), "TC-NETCFG-025 成功后 pending 清零"); + CHECK((rc == 0) && (s_save_pending == 0u), "TC-NETCFG-025 pending cleared after success"); CHECK((net_cfg_save_state() == NET_CFG_SAVE_ST_OK) && (s_save_busy == 0u), - "TC-NETCFG-026 成功后状态 OK 且写盘标志已清"); - CHECK(g_apply_calls == 1, "TC-NETCFG-027 成功后触发一次立即应用"); + "TC-NETCFG-026 state OK after success and the write flag is cleared"); + CHECK(g_apply_calls == 1, "TC-NETCFG-027 success triggers one immediate apply"); (void)net_cfg_save_request(); g_save_hook = save_hook_probe; @@ -399,7 +399,7 @@ static void tc_save_handoff(void) g_save_rc = 0; rc = net_cfg_save_run(); CHECK((rc == 0) && (g_state_during_save == (int)NET_CFG_SAVE_ST_WAIT), - "TC-NETCFG-028 写盘进行中状态仍是 WAIT"); + "TC-NETCFG-028 state stays WAIT while the write is in progress"); /* 写盘期间再投递一次:本轮不得把它当已处理,下轮必须真的再写 */ g_requeue_during_save = 1; @@ -407,12 +407,12 @@ static void tc_save_handoff(void) g_save_calls = 0; rc = net_cfg_save_run(); CHECK((rc == 0) && (net_cfg_save_state() == NET_CFG_SAVE_ST_WAIT), - "TC-NETCFG-029a 写盘期间的新请求没丢"); + "TC-NETCFG-029a a new request during the write is not lost"); g_requeue_during_save = 0; g_save_hook = NULL; g_save_calls = 0; rc = net_cfg_save_run(); - CHECK((rc == 0) && (g_save_calls == 1), "TC-NETCFG-029b 下一轮真的再写一次"); + CHECK((rc == 0) && (g_save_calls == 1), "TC-NETCFG-029b the next round really writes once more"); /* 写盘失败:置 FAIL 且**不得**触发应用(内存值没落盘,网络不能重建) */ s_save_pending = 0u; @@ -423,20 +423,20 @@ static void tc_save_handoff(void) rc = net_cfg_save_run(); CHECK((rc == -1) && (net_cfg_save_state() == NET_CFG_SAVE_ST_FAIL) && (s_save_busy == 0u), - "TC-NETCFG-030 失败置 FAIL 且写盘标志已清(否则 UI 永远卡 WAIT)"); - CHECK(g_apply_calls == 0, "TC-NETCFG-031 写盘失败不得触发立即应用"); + "TC-NETCFG-030 failure sets FAIL and clears the write flag (else UI sticks in WAIT forever)"); + CHECK(g_apply_calls == 0, "TC-NETCFG-031 write failure must not trigger an immediate apply"); net_cfg_set_apply_cb(NULL); g_apply_calls = 0; net_cfg_request_apply(); - CHECK(g_apply_calls == 0, "TC-NETCFG-032 未注册应用回调时是空操作"); + CHECK(g_apply_calls == 0, "TC-NETCFG-032 apply is a no-op while no callback is registered"); net_cfg_set_apply_cb(apply_cb); net_cfg_request_apply(); - CHECK(g_apply_calls == 1, "TC-NETCFG-033a 注册后可被触发"); + CHECK(g_apply_calls == 1, "TC-NETCFG-033a after registering it can be triggered"); net_cfg_set_apply_cb(NULL); net_cfg_request_apply(); - CHECK(g_apply_calls == 1, "TC-NETCFG-033b 注销后不再被触发"); + CHECK(g_apply_calls == 1, "TC-NETCFG-033b after unregistering it is no longer triggered"); } /* ===================== MAC 三态优先级 ===================== */ @@ -457,30 +457,30 @@ static void tc_mac_priority(void) net_cfg_set_active_mac(shadow); memset(out, 0xFF, sizeof(out)); net_cfg_get_mac(out); - CHECK(mac_eq(out, stored), "TC-NETCFG-040 存储非零优先于芯片影子"); + CHECK(mac_eq(out, stored), "TC-NETCFG-040 stored non-zero takes precedence over the chip shadow"); c = *net_cfg_get(); memcpy(c.mac, zero, 6u); net_cfg_set(&c); memset(out, 0xFF, sizeof(out)); net_cfg_get_mac(out); - CHECK(mac_eq(out, shadow), "TC-NETCFG-041 存储全零则用芯片回写影子"); + CHECK(mac_eq(out, shadow), "TC-NETCFG-041 stored all zero -> use the chip shadow write-back"); s_active_valid = 0u; /* 白盒:回到"芯片还没回写"的上电初态 */ memset(out, 0xFF, sizeof(out)); net_cfg_get_mac(out); - CHECK(mac_eq(out, zero), "TC-NETCFG-042 两者皆无 → 全零"); + CHECK(mac_eq(out, zero), "TC-NETCFG-042 neither available -> all zero"); net_cfg_set_active_mac(NULL); - CHECK(s_active_valid == 0u, "TC-NETCFG-043 NULL 回写不得把影子置有效"); + CHECK(s_active_valid == 0u, "TC-NETCFG-043 NULL write-back must not mark the shadow valid"); net_cfg_set_active_mac(shadow); memset(out, 0xFF, sizeof(out)); net_cfg_get_mac(out); - CHECK(mac_eq(out, shadow), "TC-NETCFG-044 正常回写后影子生效"); + CHECK(mac_eq(out, shadow), "TC-NETCFG-044 shadow becomes active after a normal write-back"); net_cfg_get_mac(NULL); - CHECK(1, "TC-NETCFG-045 get_mac(NULL) 安全返回"); + CHECK(1, "TC-NETCFG-045 get_mac(NULL) returns safely"); } /* ===================== IPv4 定长格式化 ===================== */ @@ -500,33 +500,33 @@ static void tc_fmt_ipv4(void) /* 定长 = 4 段 × 3 位 + 3 个点 = 15(曾有误记为 11 的注释,已同日更正) * 钉死这个长度是 UI 光标偏移(段 i 起点 4i、点号 3/7/11)的前提 */ CHECK((strcmp(buf, "192.168.001.100") == 0) && (strlen(buf) == 15u), - "TC-NETCFG-050 定长 15 字符且每段补零"); + "TC-NETCFG-050 fixed 15 chars with zero padding in every segment"); memset(buf, 0x7A, sizeof(buf)); net_cfg_fmt_ipv4(ip0, buf, sizeof(buf)); - CHECK(strcmp(buf, "000.000.000.000") == 0, "TC-NETCFG-051 全零也占满 15 字符"); + CHECK(strcmp(buf, "000.000.000.000") == 0, "TC-NETCFG-051 all zero still fills 15 chars"); memset(buf, 0x7A, sizeof(buf)); net_cfg_fmt_ipv4(ipm, buf, sizeof(buf)); - CHECK(strcmp(buf, "255.255.255.255") == 0, "TC-NETCFG-052 255 边界"); + CHECK(strcmp(buf, "255.255.255.255") == 0, "TC-NETCFG-052 255 boundary"); memset(guard, 0x7A, sizeof(guard)); memcpy(buf, guard, sizeof(buf)); net_cfg_fmt_ipv4(NULL, buf, sizeof(buf)); - CHECK(memcmp(buf, guard, sizeof(buf)) == 0, "TC-NETCFG-053 p_ip NULL 不写缓冲"); + CHECK(memcmp(buf, guard, sizeof(buf)) == 0, "TC-NETCFG-053 p_ip NULL does not touch the buffer"); net_cfg_fmt_ipv4(ip1, NULL, 16u); - CHECK(1, "TC-NETCFG-054 p_buf NULL 不崩"); + CHECK(1, "TC-NETCFG-054 p_buf NULL does not crash"); memset(guard, 0x7A, sizeof(guard)); memcpy(buf, guard, sizeof(buf)); net_cfg_fmt_ipv4(ip1, buf, 0u); - CHECK(memcmp(buf, guard, sizeof(buf)) == 0, "TC-NETCFG-055 len 0 不写缓冲"); + CHECK(memcmp(buf, guard, sizeof(buf)) == 0, "TC-NETCFG-055 len 0 does not touch the buffer"); memset(buf, 0x7A, sizeof(buf)); net_cfg_fmt_ipv4(ip1, buf, 5u); CHECK((strlen(buf) == 4u) && (buf[4] == '\0') && (buf[5] == (char)0x7A), - "TC-NETCFG-056 len 不足:截断但必须 NUL 结尾且不越界"); + "TC-NETCFG-056 short len: truncate but must stay NUL-terminated and in bounds"); } /* ===================== 入口 ===================== */ diff --git a/test/host/net_events/net_events_test.c b/test/host/net_events/net_events_test.c index 48231fa3..5eef16b2 100644 --- a/test/host/net_events/net_events_test.c +++ b/test/host/net_events/net_events_test.c @@ -217,16 +217,16 @@ static void tc_connect(void) CHECK((p->remote_ip_arr[0] == 192u) && (p->remote_ip_arr[3] == 50u) && (p->remote_ip == ((192u) | (168u << 8) | (1u << 16) | (50u << 24))) && (p->remote_port == 51234u), - "TC-NETEV-001 对端六元组解析:ip 低字节在前拼 32 位、端口取第 5/6 字节"); + "TC-NETEV-001 peer tuple parsing: ip assembled little-endian into 32 bits, port from bytes 5/6"); CHECK((p->state == NET_SOCK_STATE_ESTABLISHED) && (p->session_dead == 0u) && (p->lost_conn_seen == 0u) && (p->send_ready == 1u), - "TC-NETEV-002 监听口自接后转已连接并立刻可写"); + "TC-NETEV-002 a listened socket becomes established after self-accept and is writable at once"); CHECK((g_chip.keepalive_calls == 1) && (g_chip.last_keepalive == 1u) && (g_chip.int_status_calls == 1), - "TC-NETEV-003 建链即开 keepalive 并清一次挂起位(读即清)"); + "TC-NETEV-003 on connect, enable keepalive and clear the pending bit once (read clears)"); CHECK((g_ev_n == 1) && (g_ev_kind[0] == (int)NET_EVENT_CONNECTED) && (g_ev_fd[0] == 0) && (g_ev_arg[0] == (void *)&g_ev_token), - "TC-NETEV-004 事件带 fd 与调用方 arg 回调给应用"); + "TC-NETEV-004 the event calls back into the app with fd and the caller arg"); reset_all(); p = mk(0, NET_SOCK_STATE_CONNECTING, 0u); @@ -234,13 +234,13 @@ static void tc_connect(void) handle_connect_event(p); CHECK((p->state == NET_SOCK_STATE_ESTABLISHED) && (p->send_ready == 0u) && (g_chip.keepalive_calls == 1) && (g_ev_n == 1), - "TC-NETEV-005 主动连接分支同样转已连接,但**不动 send_ready**(与自接有别)"); + "TC-NETEV-005 the active-connect branch also becomes established but does NOT touch send_ready (differs from self-accept)"); reset_all(); p = mk(0, NET_SOCK_STATE_CLOSED, 2404u); handle_connect_event(p); CHECK((g_ev_n == 0) && (p->state == NET_SOCK_STATE_CLOSED), - "TC-NETEV-006 其它状态收到 CONNECT 中断一律忽略(不许凭空造会话)"); + "TC-NETEV-006 a CONNECT interrupt in any other state is ignored (never invent a session)"); } /* ===================== DISCONNECT ===================== */ @@ -257,7 +257,7 @@ static void tc_disconnect(void) handle_disconnect_event(p); CHECK((p->state == NET_SOCK_STATE_ESTABLISHED) && (g_ev_n == 0) && (g_nev_error_count == 1), - "TC-NETEV-010 芯片说还在连接:忽略这个陈旧 DISCONNECT(不许拆活会话)"); + "TC-NETEV-010 the chip still says connecting: ignore this stale DISCONNECT (never tear down a live session)"); reset_all(); p = mk(0, NET_SOCK_STATE_ESTABLISHED, 2404u); @@ -267,7 +267,7 @@ static void tc_disconnect(void) handle_disconnect_event(p); CHECK((p->state == NET_SOCK_STATE_ESTABLISHED) && (p->lost_conn_seen == 1u) && (g_ev_n == 0) && (g_settle_n == 0), - "TC-NETEV-011 疑似误报(一条数据都没收就断):延后交给对账器,不立即拆"); + "TC-NETEV-011 suspected false alarm (dropped before any data): defer to the reconciler instead of tearing down"); reset_all(); p = mk(0, NET_SOCK_STATE_ESTABLISHED, 2404u); @@ -280,7 +280,7 @@ static void tc_disconnect(void) (p->last_peer_port == 51234u) && (p->state == NET_SOCK_STATE_CLOSED) && (g_ev_kind[0] == (int)NET_EVENT_DISCONNECTED), - "TC-NETEV-012 正常断开:优雅沉降 + 会话标死 + 记旧端口 + 发事件"); + "TC-NETEV-012 normal disconnect: graceful settle + mark session dead + remember old port + post event"); reset_all(); p = mk(0, NET_SOCK_STATE_LISTENING, 2404u); @@ -289,20 +289,20 @@ static void tc_disconnect(void) handle_disconnect_event(p); CHECK((p->state == NET_SOCK_STATE_LISTENING) && (g_ev_n == 0) && (g_nev_info_count == 1) && (g_nev_error_count == 0), - "TC-NETEV-013 监听还在:陈旧监听 DISCONNECT 只留痕,不报 ERROR"); + "TC-NETEV-013 listen still alive: a stale listen DISCONNECT is only logged, not reported as ERROR"); reset_all(); p = mk(0, NET_SOCK_STATE_LISTENING, 2404u); g_fake.status_byte1[0] = CH395F_TCP_CLOSED; /* 芯片说不在 LISTEN */ handle_disconnect_event(p); CHECK((p->state == NET_SOCK_STATE_LISTENING) && (g_ev_n == 0) && (g_req_n == 0), - "TC-NETEV-013b 监听丢了也只留痕:重开交给对账器,事件层不越权"); + "TC-NETEV-013b even a lost listener is only logged: reopening belongs to the reconciler, the event layer must not overreach"); reset_all(); p = mk(0, NET_SOCK_STATE_CONNECTING, 0u); handle_disconnect_event(p); CHECK((g_nev_error_count == 1) && (g_ev_kind[0] == (int)NET_EVENT_DISCONNECTED), - "TC-NETEV-014 非常规状态收到 DISCONNECT:报 ERROR 但仍要通知应用"); + "TC-NETEV-014 DISCONNECT in an unusual state: report ERROR but still notify the application"); } /* ===================== RECV / SEND / TIMEOUT ===================== */ @@ -316,21 +316,21 @@ static void tc_recv_send_timeout(void) p = mk(0, NET_SOCK_STATE_ESTABLISHED, 2404u); handle_recv_event(p); CHECK((p->readable == 1u) && (g_ev_kind[0] == (int)NET_EVENT_DATA_RECEIVED), - "TC-NETEV-020 RECV 事件置可读并通知应用"); + "TC-NETEV-020 a RECV event sets readable and notifies the application"); reset_all(); p = mk(0, NET_SOCK_STATE_ESTABLISHED, 2404u); p->send_ready = 1u; handle_send_event(p); CHECK((g_ev_kind[0] == (int)NET_EVENT_SEND_COMPLETE) && (p->send_ready == 1u), - "TC-NETEV-021 SEND 完成只发事件,字段留给写路径自己管"); + "TC-NETEV-021 SEND completion only posts the event; the fields stay owned by the write path"); reset_all(); p = mk(0, NET_SOCK_STATE_CONNECTING, 0u); handle_timeout_event(p); CHECK((p->state == NET_SOCK_STATE_CREATED) && (g_nev_error_count == 1) && (g_ev_kind[0] == (int)NET_EVENT_TIMEOUT), - "TC-NETEV-030 连接超时:退回 CREATED 并通知应用"); + "TC-NETEV-030 connect timeout: fall back to CREATED and notify the application"); reset_all(); p = mk(0, NET_SOCK_STATE_ESTABLISHED, 2404u); @@ -339,14 +339,14 @@ static void tc_recv_send_timeout(void) CHECK((g_settle_level == (int)NET_LISTENER_SETTLE_QUARANTINE) && (p->released_abnormal == 1u) && (p->session_dead == 1u) && (p->last_peer_port == 777u) && (p->state == NET_SOCK_STATE_CLOSED), - "TC-NETEV-031 会话超时:隔离级沉降 + 标异常释放(net_pending 收尾据此报 CONNRESET)"); + "TC-NETEV-031 session timeout: quarantine-level settle + mark released abnormally (net_pending reports CONNRESET from it)"); reset_all(); p = mk(0, NET_SOCK_STATE_LISTENING, 2404u); handle_timeout_event(p); CHECK((p->state == NET_SOCK_STATE_LISTENING) && (g_nev_error_count == 1) && (g_ev_kind[0] == (int)NET_EVENT_TIMEOUT), - "TC-NETEV-032 监听超时只留痕:不改状态,但仍要通知等待方"); + "TC-NETEV-032 listen timeout is only logged: state unchanged but waiters are still notified"); } /* ===================== 掉线自愈 ===================== */ @@ -362,7 +362,7 @@ static void tc_lost_probe(void) g_fake.cached_tcp[0] = CH395F_TCP_CLOSED; net_lost_connect_probe(p); CHECK((p->lost_conn_seen == 0u) && (g_ev_n == 0), - "TC-NETEV-040 芯片不在已连接态:只清标记,不自作主张建会话"); + "TC-NETEV-040 the chip is not established: only clear the flag, do not create a session on our own"); reset_all(); p = mk(0, NET_SOCK_STATE_CLOSED, 2404u); @@ -372,7 +372,7 @@ static void tc_lost_probe(void) ch395f_fake_set_peer(0, 10u, 0u, 0u, 9u, 51234u); net_lost_connect_probe(p); CHECK((p->lost_conn_seen == 0u) && (g_ev_n == 0), - "TC-NETEV-041 对端口与上次相同:认定是自己没看到 CONNECT,不自接第二遍"); + "TC-NETEV-041 peer port identical to last time: assume we missed CONNECT, do not accept a second time"); /* 自愈的适用面是软件还写着 LISTENING、芯片其实已经连上——accept 分支只认 * LISTENING/CONNECTING。若软件态已被别处改成 CLOSED,本函数打完 INFO 后什么都 @@ -387,7 +387,7 @@ static void tc_lost_probe(void) CHECK((g_ev_n == 1) && (g_ev_kind[0] == (int)NET_EVENT_CONNECTED) && (p->state == NET_SOCK_STATE_ESTABLISHED) && (p->remote_port == 55555u) && (p->lost_conn_seen == 0u), - "TC-NETEV-042 丢了 CONNECT 中断时自愈:补一次 accept,会话不至于永久失联"); + "TC-NETEV-042 self-heal after a lost CONNECT interrupt: make up one accept so the session is not stranded forever"); reset_all(); p = mk(0, NET_SOCK_STATE_CLOSED, 2404u); @@ -395,7 +395,7 @@ static void tc_lost_probe(void) ch395f_fake_set_peer(0, 10u, 0u, 0u, 9u, 55555u); net_lost_connect_probe(p); CHECK((g_ev_n == 0) && (p->state == NET_SOCK_STATE_CLOSED), - "TC-NETEV-042b 现状:软件已 CLOSED 时自愈接不上(只留痕,不凭空造会话)"); + "TC-NETEV-042b current state: self-heal cannot accept once the software side is CLOSED (logged only, no invented session)"); } /* ===================== 周期对账 ===================== */ @@ -419,10 +419,10 @@ static void tc_reconcile(void) infos = g_nev_info_count; recon_step(1000u); /* priming:链路计数记基线 */ CHECK(g_nev_info_count == infos, - "TC-NETEV-051a 上电第一趟不因链路计数打日志(0xFFFF 哨兵只记基线)"); + "TC-NETEV-051a the first pass after power-up logs nothing for the link counter (the 0xFFFF sentinel only records the baseline)"); c = g_chip.cached_calls; recon_step(1000u); /* 同一时刻再调一次 */ - CHECK(g_chip.cached_calls == c, "TC-NETEV-050 100ms 周期闸门:同一时刻不重复查芯片"); + CHECK(g_chip.cached_calls == c, "TC-NETEV-050 100ms period gate: do not query the chip twice at the same instant"); reset_all(); p = mk(1, NET_SOCK_STATE_ESTABLISHED, 2404u); @@ -434,17 +434,17 @@ static void tc_reconcile(void) recon_step(1300u); CHECK((p->state == NET_SOCK_STATE_ESTABLISHED) && (g_ev_n == 0) && (g_nev_info_count == infos), - "TC-NETEV-052 会话死亡要**连观 4 次**才动手:前三次保持原状"); + "TC-NETEV-052 a dead session needs 4 consecutive observations before acting: the first three change nothing"); recon_step(1400u); CHECK((p->state == NET_SOCK_STATE_CLOSED) && (p->session_dead == 1u) && (g_ev_kind[0] == (int)NET_EVENT_DISCONNECTED), - "TC-NETEV-052b 第 4 次稳定后走断开收尾"); + "TC-NETEV-052b once the 4th observation is stable, run the disconnect teardown"); p->state = NET_SOCK_STATE_ESTABLISHED; /* 假装又活了,验证冷却 */ recon_step(1500u); recon_step(1600u); recon_step(1700u); recon_step(1800u); - CHECK(g_ev_n == 1, "TC-NETEV-052c 动作后 1000ms 冷却内不再重复折腾(哪怕稳定计数够了)"); + CHECK(g_ev_n == 1, "TC-NETEV-052c no repeat action inside the 1000ms cooldown after acting (even when the stable count is met)"); reset_all(); p = mk(2, NET_SOCK_STATE_ESTABLISHED, 2404u); @@ -452,11 +452,11 @@ static void tc_reconcile(void) g_fake.cached_tcp[2] = CH395F_TCP_LISTEN; /* 芯片自己重开监听了,却没发 DISCONNECT */ recon_step(2900u); CHECK((p->state == NET_SOCK_STATE_ESTABLISHED) && (g_pcan_n == 0), - "TC-NETEV-053 芯片偷偷重开监听:需要 2 次稳定,第一次只累计"); + "TC-NETEV-053 the chip reopened the listener behind our back: needs 2 stable passes, the first one only accumulates"); recon_step(3000u); CHECK((p->state == NET_SOCK_STATE_LISTENING) && (g_pcan_n == 1) && (g_scan_n == 1) && (g_pcan_err == NET_ERR_CONNRESET), - "TC-NETEV-053b 第 2 次稳定:重同步成监听并**取消两条挂起**(否则任务永远等不到回)"); + "TC-NETEV-053b second stable pass: resync to listen and cancel both pending waits (otherwise a task would wait forever)"); reset_all(); p = mk(3, NET_SOCK_STATE_LISTENING, 2404u); @@ -466,7 +466,7 @@ static void tc_reconcile(void) recon_step(4100u); CHECK((p->state == NET_SOCK_STATE_ESTABLISHED) && (p->remote_port == 40000u) && (g_ev_kind[0] == (int)NET_EVENT_CONNECTED), - "TC-NETEV-054 连接完成但中断丢了:1 次即补 accept"); + "TC-NETEV-054 connect completed but the interrupt was lost: a single pass is enough to make up the accept"); reset_all(); p = mk(4, NET_SOCK_STATE_LISTENING, 2404u); @@ -476,7 +476,7 @@ static void tc_reconcile(void) recon_step(5300u); CHECK((g_req_n == 1) && (g_req_sock == 4) && (g_req_reason == (int)NET_LISTENER_REQ_RECON), - "TC-NETEV-055 监听丢了:2 次稳定后请求重开监听(不自已在事件层里开)"); + "TC-NETEV-055 listener lost: request a reopen after 2 stable passes (the event layer does not open it itself)"); reset_all(); p = mk(5, NET_SOCK_STATE_CLOSED, 2404u); @@ -487,7 +487,7 @@ static void tc_reconcile(void) recon_step(6400u); CHECK((p->state == NET_SOCK_STATE_LISTENING) && (p->last_peer_port == 999u) && (p->lost_conn_seen == 0u) && (g_req_n == 0), - "TC-NETEV-056 U11 重同步:软件 CLOSED 而芯片在 LISTEN -> 直接跟芯片,不多余重开"); + "TC-NETEV-056 U11 resync: software CLOSED while the chip is LISTEN -> follow the chip, no redundant reopen"); reset_all(); p = mk(6, NET_SOCK_STATE_CLOSED, 2404u); @@ -495,13 +495,13 @@ static void tc_reconcile(void) recon_step(7500u); recon_step(7600u); CHECK((g_req_n == 1) && (g_req_sock == 6), - "TC-NETEV-057 软件 CLOSED 且芯片也不在监听:请求重开(重建交回监听层)"); + "TC-NETEV-057 software CLOSED and the chip is not listening either: request a reopen (the listener layer rebuilds it)"); reset_all(); (void)memset(&g_tbl[7], 0, sizeof(g_tbl[7])); /* 槽位不在用 */ infos = g_nev_info_count; recon_step(8700u); - CHECK(g_nev_info_count == infos, "TC-NETEV-058 不在用的槽位直接跳过(不产生任何动作)"); + CHECK(g_nev_info_count == infos, "TC-NETEV-058 unused slots are skipped outright (no action at all)"); /* 链路日志:s_link_last 初值 0xFFFF 是哨兵——第一次看到计数只记基线、不打日志 * (否则每次上电都会冒一条"链路 up"的假事件);此后计数一变就必须留痕。 @@ -511,7 +511,7 @@ static void tc_reconcile(void) infos = g_nev_info_count; recon_step(9800u); CHECK(g_nev_info_count == (infos + 1), - "TC-NETEV-051b 链路变更计数一变就留痕(基线那趟已由 051a 验证不打)"); + "TC-NETEV-051b any change of the link-change counter is logged (the baseline pass is already covered by 051a)"); } int main(void) diff --git a/test/host/net_listener/net_listener_test.c b/test/host/net_listener/net_listener_test.c index 30af09af..3d240509 100644 --- a/test/host/net_listener/net_listener_test.c +++ b/test/host/net_listener/net_listener_test.c @@ -194,14 +194,14 @@ static void tc_bounds(void) net_listener_tick(); CHECK((g_chip.open_calls == 0) && (g_chip.close_calls == 0) && (g_nlis_error_count == 0), - "TC-NETLIS-001 越界 fd 静默返回,不打扰芯片"); + "TC-NETLIS-001 an out-of-range fd returns silently without touching the chip"); reset_all(); mk_closed_listen(0, 2404); net_listener_request(0, NET_LISTENER_REQ_ACCEPT); net_listener_request(0, NET_LISTENER_REQ_DROP); /* 应被忽略 */ CHECK(s_relisten_req[0] == (uint8_t)(NET_LISTENER_REQ_ACCEPT + 1U), - "TC-NETLIS-019 请求去重:后来的 reason 不覆盖首个"); + "TC-NETLIS-019 request de-duplication: a later reason must not overwrite the first one"); } /* ===================== 该不该重建 ===================== */ @@ -215,12 +215,12 @@ static void tc_should_or_not(void) net_listener_request(0, NET_LISTENER_REQ_ACCEPT); net_listener_tick(); CHECK((g_chip.open_calls == 0) && (s_relisten_req[0] == 0u), - "TC-NETLIS-010 监听仍活着就不重建,且请求已 clear"); + "TC-NETLIS-010 while the listener is alive nothing is rebuilt and the request is cleared"); g_fake.cached_open[0] = CH395F_SOCKET_CLOSED; /* 之后才真死了 */ net_listener_request(0, NET_LISTENER_REQ_RECON); net_listener_tick(); CHECK(g_chip.open_calls == 1, - "TC-NETLIS-010b 上一步确实清掉了请求(否则这里会被去重吞掉)"); + "TC-NETLIS-010b the previous step really cleared the request (otherwise de-duplication would swallow it here)"); reset_all(); mk_closed_listen(0, 2404); @@ -228,23 +228,23 @@ static void tc_should_or_not(void) net_listener_request(0, NET_LISTENER_REQ_EOF); net_listener_tick(); CHECK((g_chip.open_calls == 0) && (s_relisten_req[0] != 0u), - "TC-NETLIS-011 挂起 recv 未结束时让路但保留请求"); + "TC-NETLIS-011 a pending recv yields the way but keeps the request"); g_pending[0] = 0; g_send_pending[0] = 1; net_listener_tick(); CHECK((g_chip.open_calls == 0) && (s_relisten_req[0] != 0u), - "TC-NETLIS-011b 挂起 send 同样挡路"); + "TC-NETLIS-011b a pending send blocks the same way"); g_send_pending[0] = 0; net_listener_tick(); CHECK((g_chip.open_calls == 1) && (s_relisten_req[0] == 0u), - "TC-NETLIS-011c 挂起结束后自动补上重建"); + "TC-NETLIS-011c once the pending op ends the rebuild happens automatically"); reset_all(); mk_closed_listen(0, 2404); net_listener_request(0, NET_LISTENER_REQ_RECON); net_listener_tick(); net_listener_tick(); - CHECK(g_chip.open_calls == 1, "TC-NETLIS-013 重建成功后不重复重建"); + CHECK(g_chip.open_calls == 1, "TC-NETLIS-013 a successful rebuild is not repeated"); } static void tc_giveup_conditions(void) @@ -254,7 +254,7 @@ static void tc_giveup_conditions(void) int cleared[5]; int errs[5]; - printf("-- TC-NETLIS-012 五种放弃条件 --\n"); + printf("-- TC-NETLIS-012 the five give-up conditions --\n"); reset_all(); for (i = 0; i < 5; i++) { uint8_t before_open = (uint8_t)g_chip.open_calls; @@ -276,19 +276,19 @@ static void tc_giveup_conditions(void) } CHECK((opened[0] == 0) && (opened[1] == 0) && (opened[2] == 0) && (opened[3] == 0) && (opened[4] == 0), - "TC-NETLIS-012 五种条件下都不碰芯片"); + "TC-NETLIS-012 none of the five conditions touches the chip"); CHECK((cleared[0] == 1) && (cleared[1] == 1) && (cleared[2] == 1) && (cleared[3] == 1) && (cleared[4] == 1), - "TC-NETLIS-012b 放弃即清请求(不留在表里反复白试)"); + "TC-NETLIS-012b giving up also clears the request (no repeated futile attempts left in the table)"); CHECK((errs[0] == 0) && (errs[2] == 0) && (errs[4] == 0), - "TC-NETLIS-012c 放弃是静默的(不该报 ERROR,那是对账器的活)"); + "TC-NETLIS-012c giving up is silent (no ERROR here, that is the reconciler's job)"); reset_all(); g_sock_valid[0] = 0u; /* 连表项都没有 */ net_listener_request(0, NET_LISTENER_REQ_RECON); net_listener_tick(); CHECK((g_chip.open_calls == 0) && (s_relisten_req[0] == 0u), - "TC-NETLIS-026 表项不存在由 tick 直接放弃"); + "TC-NETLIS-026 a missing table entry is given up directly by the tick"); /* 注:net_relisten_locked() 里的 NET_ERR_BADF 分支因此从 tick **不可达** * (net_listener.c:112 那段只在 p_sock 非空时才可能被调到)——留痕:它是 * 内部兜底,不是活路径;将来若新增调用点,要重新审视这条。 */ @@ -308,13 +308,13 @@ static void tc_backoff_and_budget(void) CHECK((g_chip.open_calls == 1) && (g_chip.close_calls == 1) && (g_errno_last == NET_ERR_BUSY) && (s_relisten_req[0] != 0u) && (s_relisten_next[0] == 1030u) && (s_relisten_dead[0] == 3000u), - "TC-NETLIS-014 open 失败:关回去 + BUSY + 30ms 退避 + 首轮建 2000ms 预算"); + "TC-NETLIS-014 open failure: close back + BUSY + 30ms backoff + a 2000ms budget armed on the first round"); g_now = 1020u; net_listener_tick(); - CHECK(g_chip.open_calls == 1, "TC-NETLIS-014b 退避未到不重试(不空转打芯片)"); + CHECK(g_chip.open_calls == 1, "TC-NETLIS-014b no retry before the backoff expires (no spinning on the chip)"); g_now = 1030u; net_listener_tick(); - CHECK(g_chip.open_calls == 2, "TC-NETLIS-014c 退避到点再试一次"); + CHECK(g_chip.open_calls == 2, "TC-NETLIS-014c once the backoff expires it tries exactly once more"); reset_all(); mk_closed_listen(0, 2404); @@ -323,7 +323,7 @@ static void tc_backoff_and_budget(void) net_listener_tick(); CHECK((g_chip.listen_calls == 1) && (g_chip.close_calls == 1) && (s_relisten_req[0] != 0u), - "TC-NETLIS-015 listen 失败也要关断(不留下开了一半的 socket)"); + "TC-NETLIS-015 a listen failure must also close (no half-open socket left behind)"); reset_all(); mk_closed_listen(0, 2404); @@ -336,7 +336,7 @@ static void tc_backoff_and_budget(void) net_listener_tick(); CHECK((g_nlis_error_count == 1) && (s_relisten_req[0] == 0u) && (g_chip.open_calls == 1), - "TC-NETLIS-018 预算耗尽:报一次 ERROR 交对账器,之后不再自己试"); + "TC-NETLIS-018 budget exhausted: report ERROR once and hand over to the reconciler, never retry on its own"); } /* ===================== 成功重建的簿记 ===================== */ @@ -363,22 +363,22 @@ static void tc_bookkeeping(void) CHECK((p->state == NET_SOCK_STATE_LISTENING) && (p->send_ready == 0u) && (p->recv_bytes == 0u) && (p->remote_port == 0u) && (p->remote_ip == 0u), - "TC-NETLIS-016 重建后回到干净监听态"); + "TC-NETLIS-016 after the rebuild the state is a clean listener again"); CHECK((p->last_peer_port == 1234u) && (p->lost_conn_seen == 0u) && (p->released_abnormal == 0u) && (p->remote_ip_arr[0] == 0u) && (p->remote_ip_arr[3] == 0u), - "TC-NETLIS-016b 旧对端端口进 last_peer_port,其余对端痕迹清零"); + "TC-NETLIS-016b the old peer port goes into last_peer_port and the other peer traces are zeroed"); CHECK((g_chip.set_port_calls == 1) && (g_chip.last_port == 2404u) && (g_chip.set_proto_calls == 1) && (g_chip.last_proto == CH395F_PROTO_TYPE_TCP), - "TC-NETLIS-017 源端口与协议取自表项本身(监听端口不能漂)"); + "TC-NETLIS-017 the source port and protocol come from the table entry itself (the listening port must not drift)"); } /* ===================== 沉降窗:隔离 400 / 优雅 100 ===================== */ static void tc_settle_windows(void) { - printf("-- TC-NETLIS-020/021 沉降窗 --\n"); + printf("-- TC-NETLIS-020/021 settle windows --\n"); reset_all(); mk_closed_listen(0, 2404); g_fake.status_byte0[0] = CH395F_SOCKET_OPEN; /* 芯片关不掉 */ @@ -390,11 +390,11 @@ static void tc_settle_windows(void) CHECK((g_chip.open_calls == 0) && (g_nlis_info_count == 1) && (s_relisten_settle_start[0] == 1000u) && (s_relisten_settle_dead[0] == 1800u) && (g_errno_last == NET_ERR_BUSY), - "TC-NETLIS-020 关不掉就等:首次记 start 并给 800ms 留痕线,返回 BUSY"); + "TC-NETLIS-020 if it will not close, wait: the first pass records start plus an 800ms logging line and returns BUSY"); g_now = 1030u; net_listener_tick(); CHECK(g_nlis_info_count == 1, - "TC-NETLIS-020b 等待期间**只在第一次**打日志(否则每 30ms 刷一条)"); + "TC-NETLIS-020b while waiting the log is written only the first time (otherwise one line every 30ms)"); /* 边界必须在**独立场景**里测:放行判定与 30ms 退避共用 s_relisten_next, * 上一轮等待会把 next 设成"当次 + 30",于是同一条链里"恰好 400ms"那一次 tick @@ -411,7 +411,7 @@ static void tc_settle_windows(void) g_now = 1399u; net_listener_tick(); CHECK((g_chip.open_calls == 0) && (s_relisten_quarantine[0] != 0u), - "TC-NETLIS-021 隔离级 hold=400ms:第 399ms 仍不放行"); + "TC-NETLIS-021 quarantine level hold=400ms: at 399ms it still does not proceed"); reset_all(); mk_closed_listen(0, 2404); @@ -424,7 +424,7 @@ static void tc_settle_windows(void) g_now = 1400u; net_listener_tick(); CHECK((g_chip.open_calls == 1) && (s_relisten_quarantine[0] == 0u), - "TC-NETLIS-021b 第 400ms 放行并清隔离(独立场景,不受退避槽遮挡)"); + "TC-NETLIS-021b at 400ms it proceeds and clears the quarantine (standalone scenario, not masked by a backoff slot)"); reset_all(); mk_closed_listen(0, 2404); @@ -433,10 +433,10 @@ static void tc_settle_windows(void) g_now = 1000u; net_listener_tick(); CHECK((g_chip.open_calls == 0) && (s_relisten_settle_start[0] == 1000u), - "TC-NETLIS-021c 优雅级同样先等(0 < 100ms)"); + "TC-NETLIS-021c the graceful level also waits first (0 < 100ms)"); g_now = 1099u; net_listener_tick(); - CHECK(g_chip.open_calls == 0, "TC-NETLIS-021c 优雅级 hold=100ms:第 99ms 不放行"); + CHECK(g_chip.open_calls == 0, "TC-NETLIS-021c graceful level hold=100ms: at 99ms it does not proceed"); reset_all(); mk_closed_listen(0, 2404); @@ -446,12 +446,12 @@ static void tc_settle_windows(void) net_listener_tick(); g_now = 1100u; net_listener_tick(); - CHECK(g_chip.open_calls == 1, "TC-NETLIS-021d 优雅级第 100ms 放行(比隔离级快 4 倍)"); + CHECK(g_chip.open_calls == 1, "TC-NETLIS-021d the graceful level proceeds at 100ms (4x faster than the quarantine level)"); } static void tc_cap_is_trace_only(void) { - printf("-- TC-NETLIS-022 800ms 上限只留痕 --\n"); + printf("-- TC-NETLIS-022 the 800ms ceiling only logs --\n"); reset_all(); mk_closed_listen(0, 2404); g_fake.status_byte0[0] = CH395F_SOCKET_OPEN; /* 永远关不掉 */ @@ -464,15 +464,15 @@ static void tc_cap_is_trace_only(void) net_listener_tick(); CHECK((s_relisten_capped[0] == 1u) && (g_nlis_info_count == 2) && (g_chip.open_calls == 0) && (s_relisten_req[0] != 0u), - "TC-NETLIS-022 到 800ms 只**留痕一次**,既不重建也**不放弃请求**"); + "TC-NETLIS-022 reaching 800ms logs exactly once, rebuilds nothing and does not give up the request"); g_now = 1830u; net_listener_tick(); CHECK(g_nlis_info_count == 2, - "TC-NETLIS-022b 留痕只打一次(之后继续默默等,不刷屏)"); + "TC-NETLIS-022b the log line is emitted only once (it keeps waiting quietly afterwards, no flood)"); g_now = 3000u; net_listener_tick(); CHECK((g_nlis_error_count == 1) && (s_relisten_req[0] == 0u), - "TC-NETLIS-022c 最终由 2000ms 预算接手:报 ERROR 并交出请求"); + "TC-NETLIS-022c the 2000ms budget takes over in the end: report ERROR and release the request"); } /* ===================== 芯片交互:清理、顺序、读即清 ===================== */ @@ -488,7 +488,7 @@ static void tc_chip_interaction(void) g_now = 1000u; net_listener_tick(); CHECK((g_chip.read_calls == 16) && (g_chip.last_read_len == 256u), - "TC-NETLIS-023 清接收区:单次钳到 256 字节、最多 16 轮(有守卫不死循环)"); + "TC-NETLIS-023 clearing the receive area: clamped to 256 bytes per call and at most 16 rounds (a guard prevents an infinite loop)"); reset_all(); mk_closed_listen(0, 2404); @@ -499,7 +499,7 @@ static void tc_chip_interaction(void) g_now = 1000u; net_listener_tick(); CHECK((g_chip.read_calls == 1) && (g_chip.last_read_len == 5u), - "TC-NETLIS-023b 读到空立刻停手(不硬凑 16 轮)"); + "TC-NETLIS-023b an empty read stops it immediately (never padding up to 16 rounds)"); reset_all(); mk_closed_listen(0, 2404); @@ -510,7 +510,7 @@ static void tc_chip_interaction(void) net_listener_tick(); CHECK((strcmp(g_chip.log, "Rcis") == 0) && (g_chip.int_status_calls == 1) && (g_chip.get_status_calls == 1), - "TC-NETLIS-024 顺序:清接收 → 关断 → 读即清 → 读状态(不可换)"); + "TC-NETLIS-024 order: clear recv -> close -> read-to-clear -> read status (fixed, must not be reordered)"); reset_all(); mk_closed_listen(0, 2404); @@ -521,7 +521,7 @@ static void tc_chip_interaction(void) g_now = 1000u; net_listener_tick(); CHECK((g_chip.int_status_calls >= 1) && (g_fake.int_status[0] == 0u), - "TC-NETLIS-025 读即清真的清零(复刻芯片无按位清除的怪癖)"); + "TC-NETLIS-025 read-to-clear really clears everything (mirrors the chip having no per-bit clear)"); } /* ===================== 入口 ===================== */ diff --git a/test/host/net_pending/net_pending_test.c b/test/host/net_pending/net_pending_test.c index eef73a0c..42d1a3a2 100644 --- a/test/host/net_pending/net_pending_test.c +++ b/test/host/net_pending/net_pending_test.c @@ -168,24 +168,24 @@ static void tc_recv_register(void) printf("-- TC-NETPEND-001..006 recv register --\n"); reset_all(); rc = net_pending_register(-1, g_rbuf, 10, 100u, (TaskHandle_t)&g_caller_obj); - CHECK((rc == -1) && (g_errno_last == NET_ERR_BADF), "TC-NETPEND-001 下越界 fd 报 BADF"); + CHECK((rc == -1) && (g_errno_last == NET_ERR_BADF), "TC-NETPEND-001 an fd below range reports BADF"); rc = net_pending_register(NET_MAX_SOCKETS, g_rbuf, 10, 100u, (TaskHandle_t)&g_caller_obj); - CHECK((rc == -1) && (g_errno_last == NET_ERR_BADF), "TC-NETPEND-001b 上越界同样拦下"); + CHECK((rc == -1) && (g_errno_last == NET_ERR_BADF), "TC-NETPEND-001b an fd above range is rejected the same way"); reset_all(); rc = net_pending_register(0, g_rbuf, 10, 100u, (TaskHandle_t)&g_caller_obj); - CHECK(rc == NET_PENDING_REGISTERED, "TC-NETPEND-005 注册成功回 0x70000000 标记"); + CHECK(rc == NET_PENDING_REGISTERED, "TC-NETPEND-005 a successful registration returns the 0x70000000 marker"); rc = net_pending_register(0, g_rbuf, 10, 100u, (TaskHandle_t)&g_caller_obj); CHECK((rc == -1) && (g_errno_last == NET_ERR_BUSY), - "TC-NETPEND-002 同 fd 已有挂起就拒绝(一条 socket 只挂一个 recv)"); + "TC-NETPEND-002 a pending op on the same fd is refused (one recv per socket at most)"); reset_all(); rc = net_pending_register(0, g_rbuf, 10, 100u, NULL); CHECK((rc == -1) && (g_errno_last == NET_ERR_BUSY), - "TC-NETPEND-003 caller 为空拒绝(没有回传目标就别挂起)"); + "TC-NETPEND-003 a NULL caller is refused (nothing to report back to, so do not suspend)"); rc = net_pending_register(0, g_rbuf, 10, 100u, (TaskHandle_t)&g_owner_obj); CHECK((rc == -1) && (g_errno_last == NET_ERR_BUSY), - "TC-NETPEND-004 属主任务自己发起被拒(自己等自己 = 死锁 netTask)"); + "TC-NETPEND-004 the owning task starting it is refused (waiting for itself would deadlock netTask)"); reset_all(); /* 必须先把槽位置成"在用且已建立":否则 tick 第一条兜底(in_use == 0 → @@ -193,11 +193,11 @@ static void tc_recv_register(void) mk_sock(0, NET_SOCK_STATE_ESTABLISHED); (void)net_pending_register(0, g_rbuf, 10, 0u, (TaskHandle_t)&g_caller_obj); CHECK((s_net_pending[0].infinite == 1u) && (s_net_pending[0].deadline == 0u), - "TC-NETPEND-006 to_ms=0 记为无限等(不置 deadline)"); + "TC-NETPEND-006 to_ms=0 is recorded as an infinite wait (no deadline armed)"); g_now = 999999u; net_pending_tick(g_socks); CHECK((s_net_pending[0].active == 1u) && (g_notify_n == 0), - "TC-NETPEND-006b 无限等不被时间掐掉(也不会偷偷发通知)"); + "TC-NETPEND-006b an infinite wait is never cut off by time (and no notification is sent behind the scenes)"); } static void tc_recv_paths(void) @@ -213,7 +213,7 @@ static void tc_recv_paths(void) (g_notify_target[0] == (void *)&g_caller_obj) && (g_socks[0].recv_bytes == 5u) && (g_socks[0].readable == 0u) && (s_net_pending[0].active == 0u), - "TC-NETPEND-007 数据到达:字节数经通知值回传给发起任务"); + "TC-NETPEND-007 data arrived: the byte count is returned to the calling task through the notification value"); reset_all(); mk_sock(0, NET_SOCK_STATE_ESTABLISHED); @@ -222,7 +222,7 @@ static void tc_recv_paths(void) ch395f_fake_push_recv_len(0, 100u); net_pending_tick(g_socks); CHECK((g_notify_value[0] == 10u) && (g_chip.last_read_len == 10u), - "TC-NETPEND-008 读量钳在调用方缓冲内(绝不越界写别人的 buf)"); + "TC-NETPEND-008 the read amount is clamped into the caller buffer (never writing past someone else's buf)"); reset_all(); mk_sock(0, NET_SOCK_STATE_ESTABLISHED); @@ -231,7 +231,7 @@ static void tc_recv_paths(void) net_pending_tick(g_socks); CHECK((g_notify_n == 0) && (g_socks[0].readable == 0u) && (s_net_pending[0].active == 1u), - "TC-NETPEND-009 空 readable:清标志继续等,不误交 0 字节"); + "TC-NETPEND-009 an empty readable: clear the flag and keep waiting instead of handing over 0 bytes"); reset_all(); mk_sock(0, NET_SOCK_STATE_ESTABLISHED); @@ -240,14 +240,14 @@ static void tc_recv_paths(void) net_pending_tick(g_socks); CHECK((g_notify_value[0] == (uint32_t)NET_ERR_TIMEDOUT) && (g_errno_last == NET_ERR_TIMEDOUT) && (s_net_pending[0].active == 0u), - "TC-NETPEND-010 超时:错误码同时进通知值与 errno(跨上下文拿得到)"); + "TC-NETPEND-010 timeout: the error code goes into both the notification value and errno (available across contexts)"); reset_all(); (void)net_pending_register(0, g_rbuf, 10, 500u, (TaskHandle_t)&g_caller_obj); g_socks[0].in_use = 0u; net_pending_tick(g_socks); CHECK(g_notify_value[0] == (uint32_t)NET_ERR_CONNRESET, - "TC-NETPEND-011 槽位消失报 CONNRESET(不能让任务熬到超时才发现)"); + "TC-NETPEND-011 a vanished slot reports CONNRESET (the task must not have to survive until the timeout to notice)"); reset_all(); mk_sock(0, NET_SOCK_STATE_CLOSED); @@ -256,7 +256,7 @@ static void tc_recv_paths(void) net_pending_tick(g_socks); CHECK((g_notify_value[0] == 12u) && (g_socks[0].recv_bytes == 12u) && (g_lis_req_n == 0), - "TC-NETPEND-012 关闭但有残留:先把最后一包读走再收尾(不丢尾包)"); + "TC-NETPEND-012 closed with leftovers: drain the last packet before finishing (no tail data lost)"); reset_all(); mk_sock(0, NET_SOCK_STATE_CLOSED); @@ -264,7 +264,7 @@ static void tc_recv_paths(void) net_pending_tick(g_socks); CHECK((g_notify_value[0] == 0u) && (g_lis_req_n == 1) && (g_lis_req_sock == 0) && (g_lis_req_reason == (int)NET_LISTENER_REQ_PENDING), - "TC-NETPEND-013 干净结束:报 0 并请求重开监听(单连接 socket 必须回 LISTEN)"); + "TC-NETPEND-013 a clean end reports 0 and requests a listener reopen (a single-connection socket must return to LISTEN)"); reset_all(); mk_sock(0, NET_SOCK_STATE_CLOSED); @@ -272,7 +272,7 @@ static void tc_recv_paths(void) (void)net_pending_register(0, g_rbuf, 20, 500u, (TaskHandle_t)&g_caller_obj); net_pending_tick(g_socks); CHECK((g_notify_value[0] == 0u) && (g_lis_req_n == 0), - "TC-NETPEND-013b 不自动重开的 socket 不会被偷偷要求重建监听"); + "TC-NETPEND-013b a socket with auto-relisten off is never asked to rebuild the listener behind its back"); reset_all(); mk_sock(0, NET_SOCK_STATE_CLOSED); @@ -280,7 +280,7 @@ static void tc_recv_paths(void) (void)net_pending_register(0, g_rbuf, 20, 500u, (TaskHandle_t)&g_caller_obj); net_pending_tick(g_socks); CHECK(g_notify_value[0] == (uint32_t)NET_ERR_CONNRESET, - "TC-NETPEND-014 异常释放报 CONNRESET 而不是 0(调用方要能分辨好坏收尾)"); + "TC-NETPEND-014 an abnormal release reports CONNRESET instead of 0 (the caller must tell a good end from a bad one)"); reset_all(); mk_sock(0, NET_SOCK_STATE_ESTABLISHED); @@ -288,7 +288,7 @@ static void tc_recv_paths(void) (void)net_pending_register(0, g_rbuf, 20, 500u, (TaskHandle_t)&g_caller_obj); net_pending_tick(g_socks); CHECK((g_notify_n == 1) && (g_lis_req_n == 1), - "TC-NETPEND-015 session_dead 与 CLOSED 同路(状态滞后时仍能收口)"); + "TC-NETPEND-015 session_dead takes the same path as CLOSED (a stale state still gets a proper close)"); reset_all(); mk_sock(0, NET_SOCK_STATE_ESTABLISHED); @@ -296,9 +296,9 @@ static void tc_recv_paths(void) net_pending_cancel(0, NET_ERR_CONNRESET); CHECK((g_notify_value[0] == (uint32_t)NET_ERR_CONNRESET) && (g_errno_last == NET_ERR_CONNRESET) && (s_net_pending[0].active == 0u), - "TC-NETPEND-016 取消:错误码经通知值送达并解除挂起"); + "TC-NETPEND-016 cancel: the error code is delivered through the notification value and the suspension is released"); net_pending_cancel(0, NET_ERR_CONNRESET); - CHECK(g_notify_n == 1, "TC-NETPEND-016b 重复取消幂等(不给同一任务发两次通知)"); + CHECK(g_notify_n == 1, "TC-NETPEND-016b a repeated cancel is idempotent (the same task is never notified twice)"); reset_all(); mk_sock(0, NET_SOCK_STATE_ESTABLISHED); @@ -308,14 +308,14 @@ static void tc_recv_paths(void) net_pending_cancel_all(NET_ERR_CONNRESET); CHECK((g_notify_n == 2) && (s_net_pending[0].active == 0u) && (s_net_pending[2].active == 0u), - "TC-NETPEND-017 cancel_all 只通知挂着的那两个(网络整体复位时用)"); + "TC-NETPEND-017 cancel_all notifies only the two suspended ops (used on a full network reset)"); reset_all(); mk_sock(0, NET_SOCK_STATE_ESTABLISHED); (void)net_pending_register(0, g_rbuf, 10, 500u, (TaskHandle_t)&g_caller_obj); net_pending_clear(0); CHECK((s_net_pending[0].active == 0u) && (g_notify_n == 0), - "TC-NETPEND-018 clear 只解除挂起、不发通知(不给调用方假答复)"); + "TC-NETPEND-018 clear only releases the suspension and sends no notification (the caller gets no fake answer)"); } static void tc_settle_close(void) @@ -328,7 +328,7 @@ static void tc_settle_close(void) before = g_chip.read_calls + g_chip.get_status_calls; net_pending_settle_close(0, &g_socks[0]); CHECK((g_chip.read_calls + g_chip.get_status_calls) == before, - "TC-NETPEND-019 没挂起时直接返回(不打扰芯片)"); + "TC-NETPEND-019 with nothing suspended it returns directly (the chip is not disturbed)"); reset_all(); mk_sock(0, NET_SOCK_STATE_CLOSED); @@ -337,14 +337,14 @@ static void tc_settle_close(void) net_pending_settle_close(0, &g_socks[0]); CHECK((g_notify_value[0] == 7u) && (g_socks[0].recv_bytes == 7u) && (g_socks[0].readable == 0u), - "TC-NETPEND-020 收尾时把剩余字节读走并交还字节数(收口不丢数据)"); + "TC-NETPEND-020 the teardown drains the remaining bytes and returns their count (closing loses no data)"); reset_all(); mk_sock(0, NET_SOCK_STATE_CLOSED); (void)net_pending_register(0, g_rbuf, 20, 500u, (TaskHandle_t)&g_caller_obj); net_pending_settle_close(0, &g_socks[0]); CHECK(g_notify_value[0] == (uint32_t)NET_ERR_CONNRESET, - "TC-NETPEND-021 无残留则报 CONNRESET(关闭收尾不该被当成读到 0 字节)"); + "TC-NETPEND-021 with nothing left it reports CONNRESET (a close teardown must not look like a zero-byte read)"); } static void tc_send_paths(void) @@ -354,31 +354,31 @@ static void tc_send_paths(void) printf("-- TC-NETPEND-030..040 send pending --\n"); reset_all(); rc = net_send_pending_register(-1, g_wbuf, 100, 0, (TaskHandle_t)&g_caller_obj); - CHECK((rc == -1) && (g_errno_last == NET_ERR_BADF), "TC-NETPEND-030 越界 fd 报 BADF"); + CHECK((rc == -1) && (g_errno_last == NET_ERR_BADF), "TC-NETPEND-030 an out-of-range fd reports BADF"); rc = net_send_pending_register(0, NULL, 100, 0, (TaskHandle_t)&g_caller_obj); - CHECK(g_errno_last == NET_ERR_INVAL, "TC-NETPEND-030b buf 为空报 INVAL"); + CHECK(g_errno_last == NET_ERR_INVAL, "TC-NETPEND-030b a NULL buffer reports INVAL"); rc = net_send_pending_register(0, g_wbuf, 0, 0, (TaskHandle_t)&g_caller_obj); - CHECK(g_errno_last == NET_ERR_INVAL, "TC-NETPEND-030c len 非正报 INVAL"); + CHECK(g_errno_last == NET_ERR_INVAL, "TC-NETPEND-030c a non-positive length reports INVAL"); rc = net_send_pending_register(0, g_wbuf, 100, -1, (TaskHandle_t)&g_caller_obj); - CHECK(g_errno_last == NET_ERR_INVAL, "TC-NETPEND-030d sent 为负报 INVAL"); + CHECK(g_errno_last == NET_ERR_INVAL, "TC-NETPEND-030d a negative sent count reports INVAL"); rc = net_send_pending_register(0, g_wbuf, 100, 100, (TaskHandle_t)&g_caller_obj); CHECK((g_errno_last == NET_ERR_INVAL) && (s_net_send[0].active == 0u), - "TC-NETPEND-030e sent>=len 报 INVAL(已发完的不必挂)"); + "TC-NETPEND-030e sent >= len reports INVAL (nothing left to send, no need to suspend)"); rc = net_send_pending_register(0, g_wbuf, 100, 50, NULL); - CHECK(g_errno_last == NET_ERR_BUSY, "TC-NETPEND-031 caller 为空报 BUSY"); + CHECK(g_errno_last == NET_ERR_BUSY, "TC-NETPEND-031 a NULL caller reports BUSY"); rc = net_send_pending_register(0, g_wbuf, 100, 50, (TaskHandle_t)&g_owner_obj); - CHECK(g_errno_last == NET_ERR_BUSY, "TC-NETPEND-031b 属主自己发报 BUSY"); + CHECK(g_errno_last == NET_ERR_BUSY, "TC-NETPEND-031b the owning task sending it itself reports BUSY"); rc = net_send_pending_register(0, g_wbuf, 100, 50, (TaskHandle_t)&g_caller_obj); - CHECK(rc == NET_PENDING_REGISTERED, "TC-NETPEND-032 挂起发送注册成功"); + CHECK(rc == NET_PENDING_REGISTERED, "TC-NETPEND-032 a suspended send registers successfully"); rc = net_send_pending_register(0, g_wbuf, 100, 50, (TaskHandle_t)&g_caller_obj); - CHECK(g_errno_last == NET_ERR_BUSY, "TC-NETPEND-031c 同 fd 只允许一条挂起发送"); + CHECK(g_errno_last == NET_ERR_BUSY, "TC-NETPEND-031c only one suspended send per fd is allowed"); reset_all(); (void)net_send_pending_register(0, g_wbuf, 3000, 700, (TaskHandle_t)&g_caller_obj); g_socks[0].in_use = 0u; net_send_pending_tick(g_socks); CHECK((g_notify_n == 1) && (g_notify_value[0] == 700u), - "TC-NETPEND-033 槽位消失回**已发字节数**(不是错误码,调用方据此算进度)"); + "TC-NETPEND-033 a vanished slot returns the number of bytes already sent (not an error code; the caller computes progress from it)"); reset_all(); mk_sock(0, NET_SOCK_STATE_CLOSED); @@ -386,7 +386,7 @@ static void tc_send_paths(void) net_send_pending_tick(g_socks); CHECK((g_npd_error_count == 1) && (g_errno_last == NET_ERR_CONNRESET) && (g_notify_value[0] == 700u), - "TC-NETPEND-034 会话塌了:留 ERROR + 报 CONNRESET,但仍把已发字节交回去"); + "TC-NETPEND-034 a collapsed session logs ERROR + reports CONNRESET yet still hands back the bytes already sent"); reset_all(); mk_sock(0, NET_SOCK_STATE_ESTABLISHED); @@ -397,7 +397,7 @@ static void tc_send_paths(void) (g_chip.last_read_len == (uint16_t)NET_SEND_CHUNK_MAX) && (g_socks[0].send_bytes == (uint32_t)NET_SEND_CHUNK_MAX) && (g_socks[0].send_ready == 0u) && (s_net_send[0].active == 1u), - "TC-NETPEND-035 单次写入钳在 NET_SEND_CHUNK_MAX(芯片发送缓冲上界)"); + "TC-NETPEND-035 a single write is clamped to NET_SEND_CHUNK_MAX (the chip send buffer upper bound)"); reset_all(); mk_sock(0, NET_SOCK_STATE_ESTABLISHED); @@ -410,7 +410,7 @@ static void tc_send_paths(void) net_send_pending_tick(g_socks); CHECK((g_notify_value[0] == 3000u) && (s_net_send[0].active == 0u) && (g_chip.write_calls == 3), - "TC-NETPEND-036 分三块发完 3000 字节后交还总长度"); + "TC-NETPEND-036 3000 bytes finish in three chunks and the total length is returned"); reset_all(); mk_sock(0, NET_SOCK_STATE_ESTABLISHED); @@ -423,7 +423,7 @@ static void tc_send_paths(void) net_send_pending_tick(g_socks); CHECK((g_npd_error_count == 0) && (s_net_send[0].active == 1u) && (g_chip.write_calls == 2), - "TC-NETPEND-038 每写一轮续期 deadline:还在推进就不该被 1000ms 掐死"); + "TC-NETPEND-038 every written round renews the deadline: while it progresses it must not be killed at 1000ms"); reset_all(); mk_sock(0, NET_SOCK_STATE_ESTABLISHED); @@ -432,7 +432,7 @@ static void tc_send_paths(void) net_send_pending_tick(g_socks); CHECK((g_npd_error_count == 1) && (g_errno_last == NET_ERR_TIMEDOUT) && (g_notify_value[0] == 0u), - "TC-NETPEND-037 停滞超时报 TIMEDOUT(对端不收时不能永久占着发送通道)"); + "TC-NETPEND-037 a stalled wait times out with TIMEDOUT (a peer that never reads must not hold the send path forever)"); reset_all(); mk_sock(0, NET_SOCK_STATE_ESTABLISHED); @@ -440,16 +440,16 @@ static void tc_send_paths(void) net_send_pending_cancel(0, NET_ERR_CONNRESET); CHECK((g_npd_error_count == 1) && (g_errno_last == NET_ERR_CONNRESET) && (g_notify_value[0] == 40u) && (s_net_send[0].active == 0u), - "TC-NETPEND-039 取消挂起发送:留痕 + 交还已发字节"); + "TC-NETPEND-039 cancelling a suspended send logs it and hands back the bytes already sent"); net_send_pending_cancel(0, NET_ERR_CONNRESET); - CHECK(g_notify_n == 1, "TC-NETPEND-039b 重复取消幂等"); + CHECK(g_notify_n == 1, "TC-NETPEND-039b a repeated cancel is idempotent"); reset_all(); mk_sock(0, NET_SOCK_STATE_ESTABLISHED); (void)net_send_pending_register(0, g_wbuf, 100, 40, (TaskHandle_t)&g_caller_obj); net_send_pending_clear(0); CHECK((s_net_send[0].active == 0u) && (g_notify_n == 0), - "TC-NETPEND-040 clear 不发通知(与 recv 侧同一条纪律)"); + "TC-NETPEND-040 clear sends no notification (the same discipline as the recv side)"); } int main(void) diff --git a/test/host/net_select/net_select_test.c b/test/host/net_select/net_select_test.c index 907f2214..81b14b89 100644 --- a/test/host/net_select/net_select_test.c +++ b/test/host/net_select/net_select_test.c @@ -106,7 +106,7 @@ void osDelay(uint32_t ticks) /* 保险:本模块每条用例都必须在有限轮内退出(要么就绪、要么超时、要么由 * g_release_after 造事件)。跑飞就说明用例或实现出了问题——直接退出, * 绝不能把挂死留给 pre-commit / CI(上一次就是这么卡住 exe 文件名的)。 */ - printf(" ABORT 轮询跑飞(>500 轮未退出)\n"); + printf(" ABORT poll runaway (>500 rounds without exit)\n"); fflush(stdout); exit(2); } @@ -147,9 +147,9 @@ static void tc_bounds(void) reset_all(); NET_FD_ZERO(&r); CHECK(net_select(0, &r, NULL, NULL, NULL) == -1, "TC-NETSEL-001 nfds=0 -> -1"); - CHECK(net_select(-1, &r, NULL, NULL, NULL) == -1, "TC-NETSEL-002 nfds 为负 -> -1"); + CHECK(net_select(-1, &r, NULL, NULL, NULL) == -1, "TC-NETSEL-002 negative nfds -> -1"); CHECK(net_select(NET_MAX_SOCKETS + 1, &r, NULL, NULL, NULL) == -1, - "TC-NETSEL-003 nfds 越界 -> -1(不许扫出表外)"); + "TC-NETSEL-003 nfds out of range -> -1 (must not scan past the table)"); } /* ===================== 就绪位与集合回写 ===================== */ @@ -169,14 +169,14 @@ static void tc_ready_sets(void) NET_FD_SET(1, &r); rc = net_select(4, &r, NULL, NULL, NULL); CHECK((rc == 1) && NET_FD_ISSET(1, &r) && !NET_FD_ISSET(0, &r), - "TC-NETSEL-004 回写只保留就绪位,未就绪的 fd0 被清掉"); + "TC-NETSEL-004 write-back keeps only the ready bits; not-ready fd0 is cleared"); reset_all(); make_sock(2, NET_SOCK_STATE_ESTABLISHED, 1u, 0u); NET_FD_ZERO(&r); NET_FD_SET(2, &r); rc = net_select(3, &r, NULL, NULL, NULL); /* write/except 传 NULL */ - CHECK((rc == 1) && (NET_FD_ISSET(2, &r)), "TC-NETSEL-005 其余集合可为 NULL"); + CHECK((rc == 1) && (NET_FD_ISSET(2, &r)), "TC-NETSEL-005 the other sets may be NULL"); /* 注意:timeout 传 NULL 时本函数会一直等到有事件(见 008 的现状说明), * 所以这类用例必须让被请求的 fd 真的就绪,否则就是用例自己写死的死循环。 */ @@ -187,7 +187,7 @@ static void tc_ready_sets(void) NET_FD_SET(2, &w); rc = net_select(3, NULL, &w, NULL, NULL); CHECK((rc == 1) && NET_FD_ISSET(2, &w) && (r.fd_bits == 0u), - "TC-NETSEL-005b 只回写调用方真正请求过的集合"); + "TC-NETSEL-005b only the sets the caller actually requested get written back"); } /* ===================== 超时算术 ===================== */ @@ -205,7 +205,7 @@ static void tc_timeout(void) NET_FD_SET(0, &r); rc = net_select(1, &r, NULL, NULL, NULL); /* timeout = NULL:无限等 */ CHECK((rc == 1) && (g_delay_calls == 3) && NET_FD_ISSET(0, &r), - "TC-NETSEL-006 无限等被对端事件唤醒(第 3 轮)"); + "TC-NETSEL-006 infinite wait wakes on a peer event (round 3)"); reset_all(); make_sock(0, NET_SOCK_STATE_ESTABLISHED, 0u, 0u); @@ -215,7 +215,7 @@ static void tc_timeout(void) tv.tv_usec = 1999; /* 应为 1ms,不是 2ms */ rc = net_select(1, &r, NULL, NULL, &tv); CHECK((rc == 0) && (g_delay_calls == 0), - "TC-NETSEL-007 tv_usec 整除截断:1999us 当 1ms,首轮即退"); + "TC-NETSEL-007 tv_usec integer truncation: 1999us counts as 1ms, exits on the first round"); /* 已修(2026-10-23):原来这里写的是 (timeout_ms > 0) && (已用时 >= timeout_ms), * timeout = {0,0} 换算出 0 后**永不超时**,只能干等事件——而 POSIX 语义是 @@ -229,7 +229,7 @@ static void tc_timeout(void) tv.tv_usec = 0; rc = net_select(1, &r, NULL, NULL, &tv); CHECK((rc == 0) && (g_delay_calls == 0) && !NET_FD_ISSET(0, &r), - "TC-NETSEL-008 timeout={0,0} 只查一轮立即返回(与 poll 的 0 对齐)"); + "TC-NETSEL-008 timeout={0,0} checks one round and returns at once (aligned with poll timeout 0)"); } /* ===================== 状态准入 ===================== */ @@ -250,7 +250,7 @@ static void tc_state_admission(void) tv.tv_usec = 1000; rc = net_select(1, &r, NULL, NULL, &tv); CHECK((rc == 0) && !NET_FD_ISSET(0, &r), - "TC-NETSEL-009 监听态不可读(accept 语义不在 select 这层)"); + "TC-NETSEL-009 listen state is not readable (accept semantics are not in the select layer)"); reset_all(); make_sock(0, NET_SOCK_STATE_ESTABLISHED, 0u, 1u); @@ -258,7 +258,7 @@ static void tc_state_admission(void) NET_FD_SET(0, &w); rc = net_select(1, NULL, &w, NULL, &tv); CHECK((rc == 1) && NET_FD_ISSET(0, &w), - "TC-NETSEL-010 已建立 + send_ready 才可写"); + "TC-NETSEL-010 established + send_ready is what makes it writable"); reset_all(); make_sock(0, NET_SOCK_STATE_CONNECTING, 0u, 1u); @@ -266,7 +266,7 @@ static void tc_state_admission(void) NET_FD_SET(0, &w); rc = net_select(1, NULL, &w, NULL, &tv); CHECK((rc == 0) && !NET_FD_ISSET(0, &w), - "TC-NETSEL-011 连接中不可写(send_ready 不作数)"); + "TC-NETSEL-011 connecting state is not writable (send_ready does not count)"); /* 已修(2026-10-23):异常判定原先排在 p_sock == NULL → continue 之后,而 * check_socket_error() 只有"表项为空 / fd 越界"才返回 1、越界的 i 又不在本循环 @@ -279,14 +279,14 @@ static void tc_state_admission(void) NET_FD_SET(0, &r); rc = net_select(1, NULL, NULL, &r, &tv); CHECK((rc == 1) && NET_FD_ISSET(0, &r), - "TC-NETSEL-012 表项不存在的 fd 计入异常集合"); + "TC-NETSEL-012 an fd with no table entry counts into the exception set"); reset_all(); g_sock_valid[0] = 0u; NET_FD_ZERO(&r); NET_FD_SET(0, &r); /* 只请求可读 */ rc = net_select(1, &r, NULL, NULL, &tv); CHECK((rc == 0) && !NET_FD_ISSET(0, &r) && (g_delay_calls == 0), - "TC-NETSEL-012b 未请求异常集时不因缺失 fd 计数(不误伤只查可读的调用方)"); + "TC-NETSEL-012b a missing fd is not counted when the exception set was not requested"); reset_all(); g_sock_valid[0] = 0u; NET_FD_ZERO(&r); @@ -295,7 +295,7 @@ static void tc_state_admission(void) NET_FD_SET(0, &w); /* 请求异常:应该置位 */ rc = net_select(1, &r, NULL, &w, &tv); CHECK((rc == 1) && NET_FD_ISSET(0, &w) && !NET_FD_ISSET(0, &r), - "TC-NETSEL-012c 异常位只落到被请求的那个集合,不污染可读集合"); + "TC-NETSEL-012c the exception bit lands only in the requested set, never polluting the read set"); } /* ===================== poll 语义 ===================== */ @@ -308,7 +308,7 @@ static void tc_poll(void) printf("-- TC-NETSEL-013..019 poll --\n"); reset_all(); CHECK((net_poll_events(NULL, 1, 0) == -1) && (net_poll_events(p, 0, 0) == -1), - "TC-NETSEL-013 poll 参数非法 -> -1"); + "TC-NETSEL-013 invalid poll arguments -> -1"); reset_all(); (void)memset(p, 0, sizeof(p)); @@ -319,7 +319,7 @@ static void tc_poll(void) rc = net_poll_events(p, 2, 0); CHECK((rc == 2) && ((p[0].revents & NET_POLLNVAL) != 0) && ((p[1].revents & NET_POLLNVAL) != 0), - "TC-NETSEL-014 负 fd 与越界 fd 都置 POLLNVAL 并计入 ready"); + "TC-NETSEL-014 negative and out-of-range fd both set POLLNVAL and count as ready"); reset_all(); make_sock(0, NET_SOCK_STATE_CLOSED, 0u, 0u); @@ -328,7 +328,7 @@ static void tc_poll(void) p[0].events = NET_POLLIN; rc = net_poll_events(p, 1, 0); CHECK((rc == 1) && ((p[0].revents & NET_POLLHUP) != 0), - "TC-NETSEL-015 CLOSED 置 POLLHUP"); + "TC-NETSEL-015 CLOSED sets POLLHUP"); reset_all(); make_sock(0, NET_SOCK_STATE_ESTABLISHED, 1u, 0u); @@ -338,7 +338,7 @@ static void tc_poll(void) rc = net_poll_events(p, 1, 0); CHECK((rc == 1) && ((p[0].revents & NET_POLLIN) != 0) && ((p[0].revents & NET_POLLHUP) == 0), - "TC-NETSEL-016 可读置 POLLIN 且不误置 HUP"); + "TC-NETSEL-016 readable sets POLLIN without falsely setting HUP"); reset_all(); make_sock(0, NET_SOCK_STATE_ESTABLISHED, 1u, 1u); @@ -347,7 +347,7 @@ static void tc_poll(void) p[0].events = 0; /* 什么都不请求 */ (void)net_poll_events(p, 1, 0); CHECK((p[0].revents & NET_POLLERR) == 0, - "TC-NETSEL-017 现状:POLLERR 实际永不为真(表项为空已被 POLLNVAL 抢先)"); + "TC-NETSEL-017 current state: POLLERR is never true (an empty entry is caught earlier by POLLNVAL)"); reset_all(); make_sock(0, NET_SOCK_STATE_ESTABLISHED, 0u, 0u); @@ -356,7 +356,7 @@ static void tc_poll(void) p[0].events = NET_POLLIN; rc = net_poll_events(p, 1, 0); /* timeout = 0 */ CHECK((rc == 0) && (g_delay_calls == 0), - "TC-NETSEL-018 poll 的 timeout=0 立即返回(与 select 那条形成对照)"); + "TC-NETSEL-018 poll timeout=0 returns at once (contrast with the matching select case)"); reset_all(); make_sock(0, NET_SOCK_STATE_ESTABLISHED, 1u, 0u); @@ -365,7 +365,7 @@ static void tc_poll(void) p[0].events = NET_POLLIN; p[0].revents = NET_POLLOUT; /* 脏的上一轮残留 */ (void)net_poll_events(p, 1, 0); - CHECK((p[0].revents & NET_POLLOUT) == 0, "TC-NETSEL-019 每轮先清 revents"); + CHECK((p[0].revents & NET_POLLOUT) == 0, "TC-NETSEL-019 revents is cleared at the start of every round"); } /* ===================== 入口 ===================== */ diff --git a/test/host/net_socket/net_socket_test.c b/test/host/net_socket/net_socket_test.c index 8a2107d6..a16ccbf9 100644 --- a/test/host/net_socket/net_socket_test.c +++ b/test/host/net_socket/net_socket_test.c @@ -222,10 +222,10 @@ static void tc_101_byteorder(void) { reset_all(); - CHECK(net_htons(0x1234U) == 0x3412U, "TC-NETSOCK-101a htons 换端"); - CHECK(net_ntohs(net_htons(80U)) == 80U, "TC-NETSOCK-101b htons/ntohs 互逆"); - CHECK(net_htonl(0x01020304U) == 0x04030201U, "TC-NETSOCK-101c htonl 换端"); - CHECK(net_ntohl(net_htonl(0xDEADBEEFU)) == 0xDEADBEEFU, "TC-NETSOCK-101d htonl/ntohl 互逆"); + CHECK(net_htons(0x1234U) == 0x3412U, "TC-NETSOCK-101a htons byte swap"); + CHECK(net_ntohs(net_htons(80U)) == 80U, "TC-NETSOCK-101b htons/ntohs are inverses"); + CHECK(net_htonl(0x01020304U) == 0x04030201U, "TC-NETSOCK-101c htonl byte swap"); + CHECK(net_ntohl(net_htonl(0xDEADBEEFU)) == 0xDEADBEEFU, "TC-NETSOCK-101d htonl/ntohl are inverses"); } static void tc_102_parse_ip(void) @@ -236,12 +236,12 @@ static void tc_102_parse_ip(void) (void)memset(a, 0xEE, sizeof(a)); parse_ip_string(NULL, a); - CHECK(a[0] == 0xEEU, "TC-NETSOCK-102a parse_ip_string(NULL) 直接返回,不写目标缓冲"); + CHECK(a[0] == 0xEEU, "TC-NETSOCK-102a parse_ip_string(NULL) returns at once, target buffer untouched"); parse_ip_string("192.168.1.100", a); CHECK(a[0] == 192U && a[1] == 168U && a[2] == 1U && a[3] == 100U, - "TC-NETSOCK-102b parse_ip_string 段 0 落在 [0](芯片 set_ip_addr 要的顺位)"); + "TC-NETSOCK-102b parse_ip_string puts segment 0 at [0] (the order chip set_ip_addr wants)"); parse_ip_string("10.20.30.40", NULL); /* 只验不崩 */ - CHECK(1, "TC-NETSOCK-102c parse_ip_string 目标为 NULL 不崩"); + CHECK(1, "TC-NETSOCK-102c parse_ip_string with NULL target does not crash"); } static void tc_103_alloc_and_getsock(void) @@ -253,11 +253,11 @@ static void tc_103_alloc_and_getsock(void) reset_all(); CHECK(net_get_sock(-1) == NULL && net_get_sock(NET_MAX_SOCKETS) == NULL, - "TC-NETSOCK-103a net_get_sock 越界返 NULL(含负数)"); - CHECK(net_get_sock(0) == NULL, "TC-NETSOCK-103b 未分配的槽位返 NULL"); + "TC-NETSOCK-103a net_get_sock out of range returns NULL (incl. negative)"); + CHECK(net_get_sock(0) == NULL, "TC-NETSOCK-103b unallocated slot returns NULL"); CHECK(net_sock_raw(3) == &s_net_socks[3], - "TC-NETSOCK-103c net_sock_raw 不判 in_use(对账必须看到 CLOSED 槽位)"); - CHECK(net_sock_state(0) == -1, "TC-NETSOCK-103d 未占用 sock_state 返 -1 且不设 errno"); + "TC-NETSOCK-103c net_sock_raw skips the in_use check (reconciler must see CLOSED slots)"); + CHECK(net_sock_state(0) == -1, "TC-NETSOCK-103d unused sock_state returns -1 and leaves errno alone"); /* 逐个占满:alloc_socket 线性扫描首个空闲槽 */ for (i = 0; i < NET_MAX_SOCKETS; i++) { @@ -266,9 +266,9 @@ static void tc_103_alloc_and_getsock(void) break; } } - CHECK(i == NET_MAX_SOCKETS, "TC-NETSOCK-103e alloc_socket 按序分配 0..7"); + CHECK(i == NET_MAX_SOCKETS, "TC-NETSOCK-103e alloc_socket hands out 0..7 in order"); p = net_get_sock(0); - CHECK(p != NULL && p->in_use == 1U, "TC-NETSOCK-103f 分配的槽位 in_use=1"); + CHECK(p != NULL && p->in_use == 1U, "TC-NETSOCK-103f allocated slot has in_use=1"); reset_all(); } @@ -281,20 +281,20 @@ static void tc_104_socket_no_inherit(void) reset_all(); fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); - CHECK(fd == 0, "TC-NETSOCK-104a net_socket 返回首个空闲 fd"); + CHECK(fd == 0, "TC-NETSOCK-104a net_socket returns the first free fd"); p = &s_net_socks[fd]; - CHECK(p->ch395_sock == (uint8_t)fd, "TC-NETSOCK-104b 芯片 Socket 号与描述符一一对应"); + CHECK(p->ch395_sock == (uint8_t)fd, "TC-NETSOCK-104b chip socket number maps one-to-one to the descriptor"); CHECK(p->state == NET_SOCK_STATE_CREATED && p->type == NET_SOCK_STREAM, - "TC-NETSOCK-104c 初态 CREATED + 类型记下"); + "TC-NETSOCK-104c initial state CREATED with type recorded"); CHECK(p->send_ready == 1U && p->readable == 0U, - "TC-NETSOCK-104d 初态:发送缓冲视为空闲、无可读"); + "TC-NETSOCK-104d initial state: send buffer seen as free, nothing readable"); /* 三条"新 fd 不得继承"的定案,逐条钉(都是真机上静默出错的形态) */ - CHECK(p->blocking == 1U, "TC-NETSOCK-104e blocking 默认必须显式置 1(BSD 语义)"); - CHECK(p->released_abnormal == 0U, "TC-NETSOCK-104f 不得继承上一条的释放原因(TRAP-NET-18)"); - CHECK(p->session_dead == 0U, "TC-NETSOCK-104g 不得继承上一条的会话结束电平(N-32 P1)"); + CHECK(p->blocking == 1U, "TC-NETSOCK-104e blocking must default to explicitly 1 (BSD semantics)"); + CHECK(p->released_abnormal == 0U, "TC-NETSOCK-104f must not inherit the previous release reason (TRAP-NET-18)"); + CHECK(p->session_dead == 0U, "TC-NETSOCK-104g must not inherit the previous session-dead level (N-32 P1)"); CHECK(g_peers.listener_clear_calls == 1 && g_peers.pending_clear_calls == 1 && g_peers.send_clear_calls == 1, - "TC-NETSOCK-104h 新 fd 必须清监听重试 + 两张挂起表(各一次)"); + "TC-NETSOCK-104h new fd clears listener retry and both pending tables (once each)"); /* 脏槽位复用:把上一条会话的残留写进去,再看新建是否清干净 */ p->blocking = 0U; @@ -307,17 +307,17 @@ static void tc_104_socket_no_inherit(void) * 本场景没绑消息队列,公开入口会先撞上"队列未创建"的 NET_ERR, * 而那属于分片 3 的断言面(TC-NETSOCK-110h)。close 的清零主路径在 net_close_locked。 */ CHECK(net_close_sock(&s_net_socks[fd]) == 0, - "TC-NETSOCK-104i net_close_sock 成功(close 的 memset 是清零主路径)"); + "TC-NETSOCK-104i net_close_sock succeeds (its memset is the main reset path)"); fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); p = &s_net_socks[fd]; CHECK(fd == 0 && p->blocking == 1U && p->released_abnormal == 0U && p->session_dead == 0U && p->readable == 0U && p->send_ready == 1U && p->event_cb == NULL, - "TC-NETSOCK-104j 复用同一槽位:残留字段全部不得带走"); + "TC-NETSOCK-104j reusing the slot: no leftover field may carry over"); /* 地址族不支持 → INVAL(在 alloc 之前,不占槽) */ CHECK(net_socket(NET_AF_INET6, NET_SOCK_STREAM) == -1 && net_get_errno() == NET_ERR_INVAL && s_net_socks[1].in_use == 0U, - "TC-NETSOCK-104k 非 INET 地址族 → INVAL 且不占槽位"); + "TC-NETSOCK-104k non-INET address family -> INVAL and no slot taken"); reset_all(); } @@ -336,22 +336,22 @@ static void tc_105_bind(void) in.sin_addr.s_addr = net_inet_addr("192.168.1.100"); CHECK(net_bind(-1, (struct net_sockaddr *)&in, sizeof(in)) == -1 && - net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-105a 越界 fd → BADF"); + net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-105a out of range fd -> BADF"); CHECK(net_bind(0, (struct net_sockaddr *)&in, sizeof(in)) == -1 && - net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-105b 未创建就 bind → BADF"); + net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-105b bind before socket -> BADF"); fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); CHECK(net_bind(fd, NULL, sizeof(in)) == -1 && net_get_errno() == NET_ERR_INVAL, - "TC-NETSOCK-105c addr 为 NULL → INVAL"); + "TC-NETSOCK-105c addr NULL -> INVAL"); CHECK(net_bind(fd, (struct net_sockaddr *)&in, 1) == -1 && - net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-105d addrlen 不足 → INVAL"); + net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-105d addrlen too small -> INVAL"); CHECK(net_bind(fd, (struct net_sockaddr *)&in, sizeof(in)) == 0, - "TC-NETSOCK-105e TCP bind 成功"); + "TC-NETSOCK-105e TCP bind succeeds"); CHECK(s_net_socks[fd].local_port == 2404U && s_net_socks[fd].state == NET_SOCK_STATE_BOUND, - "TC-NETSOCK-105f TCP 只记端口转主机序 + 进 BOUND,不碰芯片"); + "TC-NETSOCK-105f TCP bind only stores host-order port and goes BOUND, no chip touch"); CHECK(g_chip.set_port_calls == 0 && g_chip.open_calls == 0, - "TC-NETSOCK-105g TCP bind 期间不得下发源端口/开芯片 Socket(打开留给 listen)"); + "TC-NETSOCK-105g bind must not set source port or open the chip socket (open belongs to listen)"); /* port=0 → 动态端口 49152 起,并推进 */ reset_all(); @@ -360,16 +360,16 @@ static void tc_105_bind(void) fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); rc = net_bind(fd, (struct net_sockaddr *)&in, sizeof(in)); CHECK(rc == 0 && s_net_socks[fd].local_port == 49152U, - "TC-NETSOCK-105h port=0 → 分配 49152"); + "TC-NETSOCK-105h port=0 allocates 49152"); CHECK(s_dynamic_port == 49153U, - "TC-NETSOCK-105h2 计数器已推进到 49153(分配即推进,不留重复)"); + "TC-NETSOCK-105h2 counter already advanced to 49153 (advance on allocate, never reuse)"); (void)net_socket(NET_AF_INET, NET_SOCK_STREAM); /* 只创建不 bind */ CHECK(s_dynamic_port == 49153U, - "TC-NETSOCK-105i3 创建 socket **不**消耗动态端口(只有 bind 消耗)"); + "TC-NETSOCK-105i3 creating a socket does NOT consume a dynamic port (only bind does)"); fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); rc = net_bind(fd, (struct net_sockaddr *)&in, sizeof(in)); CHECK(rc == 0 && s_net_socks[fd].local_port == 49153U && s_dynamic_port == 49154U, - "TC-NETSOCK-105i 第二次 bind 拿下一个端口(不会把同一个端口发两次)"); + "TC-NETSOCK-105i second bind gets the next port (same port never issued twice)"); /* 回绕:把计数器压到 65535,分配后应回 49152(不是 0——0 会让芯片按"未绑定"处理) */ s_dynamic_port = 65535U; @@ -378,7 +378,7 @@ static void tc_105_bind(void) fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); rc = net_bind(fd, (struct net_sockaddr *)&in, sizeof(in)); CHECK(rc == 0 && s_net_socks[fd].local_port == 65535U && s_dynamic_port == 49152U, - "TC-NETSOCK-105j 动态端口越过 65535 回绕到 49152(不回 0)"); + "TC-NETSOCK-105j dynamic port wraps from 65535 back to 49152 (never to 0)"); } static void tc_106_bind_udp(void) @@ -393,23 +393,23 @@ static void tc_106_bind_udp(void) /* UDP:bind 就直接开芯片侧(无监听态),且必须配 DesIP=255.255.255.255 收任意源 */ fd = net_socket(NET_AF_INET, NET_SOCK_DGRAM); - CHECK(net_bind(fd, (struct net_sockaddr *)&in, sizeof(in)) == 0, "TC-NETSOCK-106a UDP bind 成功"); - CHECK(s_net_socks[fd].state == NET_SOCK_STATE_UDP_OPEN, "TC-NETSOCK-106b UDP 直接进 UDP_OPEN"); + CHECK(net_bind(fd, (struct net_sockaddr *)&in, sizeof(in)) == 0, "TC-NETSOCK-106a UDP bind succeeds"); + CHECK(s_net_socks[fd].state == NET_SOCK_STATE_UDP_OPEN, "TC-NETSOCK-106b UDP goes straight to UDP_OPEN"); CHECK(g_chip.set_proto_calls == 1 && g_chip.last_proto == CH395F_PROTO_TYPE_UDP, - "TC-NETSOCK-106c 协议下发为 UDP(不是 TCP)"); + "TC-NETSOCK-106c protocol set to UDP (not TCP)"); CHECK(g_chip.set_port_calls == 1 && g_chip.last_port == 8888U, - "TC-NETSOCK-106d 源端口随 bind 下发"); + "TC-NETSOCK-106d source port delivered with bind"); CHECK(g_fx.des_ip[0][0] == 0xFFU && g_fx.des_ip[0][1] == 0xFFU && g_fx.des_ip[0][2] == 0xFFU && g_fx.des_ip[0][3] == 0xFFU && g_fx.des_port[0] == 0U, - "TC-NETSOCK-106e UDP Server 模式:DesIP=全 FF + 目的端口 0(否则只收单一对端)"); - CHECK(g_chip.open_calls == 1, "TC-NETSOCK-106f UDP bind 开一次芯片 Socket"); + "TC-NETSOCK-106e UDP server mode: DesIP all FF and dest port 0 (else only one peer is received)"); + CHECK(g_chip.open_calls == 1, "TC-NETSOCK-106f UDP bind opens the chip socket once"); /* 槽位 >=4 必须补设收发缓冲(net_init 已配过,这里是兜底):布局 6 块/槽 */ reset_all(); fd = net_socket(NET_AF_INET, NET_SOCK_DGRAM); - CHECK(fd == 0, "TC-NETSOCK-106g 先拿 fd0(对照:不补缓冲)"); - CHECK(g_fxchip.set_recv_buf_calls == 0, "TC-NETSOCK-106h fd<4 的 UDP bind 不重设缓冲"); + CHECK(fd == 0, "TC-NETSOCK-106g take fd0 first (control case: no buffer reconfig)"); + CHECK(g_fxchip.set_recv_buf_calls == 0, "TC-NETSOCK-106h UDP bind on fd<4 does not reconfigure buffers"); reset_all(); for (fd = 0; fd < 4; fd++) { @@ -421,7 +421,7 @@ static void tc_106_bind_udp(void) g_fx.recv_blk_cnt[4] == (uint8_t)CH395F_RECV_BLOCKS && g_fx.send_blk_start[4] == (uint8_t)(4 * 6 + (int)CH395F_RECV_BLOCKS) && g_fx.send_blk_cnt[4] == (uint8_t)CH395F_SEND_BLOCKS, - "TC-NETSOCK-106i fd>=4 兜底重设收发缓冲,块布局与 net_init 同构(6 块/槽)"); + "TC-NETSOCK-106i fd>=4 falls back to reconfiguring rx/tx buffers, same 6-block layout as net_init"); /* open 失败 → BUSY 且留在原状态(不得谎报 UDP_OPEN) */ reset_all(); @@ -431,7 +431,7 @@ static void tc_106_bind_udp(void) net_get_errno() == NET_ERR_BUSY && s_net_socks[fd].state != NET_SOCK_STATE_UDP_OPEN && g_ns_error_count == 1, - "TC-NETSOCK-106j UDP open 失败 → BUSY + 留痕 + 状态不前进"); + "TC-NETSOCK-106j UDP open failure -> BUSY plus error log and state does not advance"); } static void tc_107_peer_and_localname(void) @@ -445,40 +445,40 @@ static void tc_107_peer_and_localname(void) (void)net_init("192.168.1.100", "255.255.255.0", "192.168.1.1", NULL); CHECK(net_getsockname(-1, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-107a getsockname 越界 → BADF"); + "TC-NETSOCK-107a getsockname out of range -> BADF"); CHECK(net_getsockname(0, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-107b 未用且 CLOSED 的槽 → BADF"); + "TC-NETSOCK-107b unused CLOSED slot -> BADF"); fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); (void)memset(&in, 0, sizeof(in)); in.sin_port = net_htons(7003); - CHECK(net_bind(fd, sa, (int)sizeof(in)) == 0, "TC-NETSOCK-107c bind 前置成功"); + CHECK(net_bind(fd, sa, (int)sizeof(in)) == 0, "TC-NETSOCK-107c bind precondition ok"); addrlen = (int)sizeof(in); (void)memset(&in, 0, sizeof(in)); - CHECK(net_getsockname(fd, sa, &addrlen) == 0, "TC-NETSOCK-107d getsockname 成功"); + CHECK(net_getsockname(fd, sa, &addrlen) == 0, "TC-NETSOCK-107d getsockname succeeds"); CHECK(in.sin_family == NET_AF_INET && net_ntohs(in.sin_port) == 7003U && addrlen == (int)sizeof(in), - "TC-NETSOCK-107e 回填族/端口(网络序)/长度"); + "TC-NETSOCK-107e fills family, port (network order) and length"); /* 钉**具体顺位**而不是二选一:getsockname 走的是「首段在最低字节」这一族 * (与 net_inet_ntoa、net_events 的 remote_ip 同族),所以 192.168.1.100 = * 0x6401A8C0。net_inet_addr 返回的是另一族(首段在最高字节,0xC0A80164), * 两族不互逆——已作为疑似缺陷报出,这里刻意不写成「两个都行」。 */ CHECK(in.sin_addr.s_addr == 0x6401A8C0U, - "TC-NETSOCK-107f 本机 IP 顺位=首段在最低字节(与 ntoa 同族;net_inet_addr 是另一族)"); + "TC-NETSOCK-107f local IP byte order = first octet in low byte (ntoa family)"); addrlen = 1; CHECK(net_getsockname(fd, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_INVAL, - "TC-NETSOCK-107g 长度不足 → INVAL"); + "TC-NETSOCK-107g length too small -> INVAL"); CHECK(net_getsockname(fd, sa, NULL) == -1 && net_get_errno() == NET_ERR_INVAL, - "TC-NETSOCK-107h addrlen 为 NULL → INVAL"); + "TC-NETSOCK-107h addrlen NULL -> INVAL"); /* getpeername:没有 CONNECT 回读过对端 → NOTCONN(不发 SPI 是它的卖点) */ (void)memset(&in, 0, sizeof(in)); addrlen = (int)sizeof(in); CHECK(net_getpeername(fd, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_NOTCONN, - "TC-NETSOCK-107i 尚无对端 → NOTCONN(remote_port==0 判据)"); + "TC-NETSOCK-107i no peer yet -> NOTCONN (judged by remote_port==0)"); CHECK(g_chip.get_status_calls == 0 && g_fxchip.glob_calls == 0, - "TC-NETSOCK-107j getpeername 纯读缓存,不发任何芯片事务"); + "TC-NETSOCK-107j getpeername only reads the cache, issues no chip transactions"); s_net_socks[fd].remote_port = 51999U; s_net_socks[fd].remote_ip = 0x0B01A8C0U; @@ -487,14 +487,14 @@ static void tc_107_peer_and_localname(void) CHECK(net_getpeername(fd, sa, &addrlen) == 0 && net_ntohs(in.sin_port) == 51999U && in.sin_addr.s_addr == 0x0B01A8C0U && in.sin_family == NET_AF_INET, - "TC-NETSOCK-107k getpeername 回填缓存的对端 IP:端口"); + "TC-NETSOCK-107k getpeername fills the cached peer IP and port"); CHECK(net_getpeername(-1, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-107l getpeername 越界 → BADF"); + "TC-NETSOCK-107l getpeername out of range -> BADF"); CHECK(net_getpeername(5, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-107m getpeername 未在用 → BADF"); + "TC-NETSOCK-107m getpeername on unused fd -> BADF"); addrlen = 2; CHECK(net_getpeername(fd, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_INVAL, - "TC-NETSOCK-107n getpeername 长度不足 → INVAL"); + "TC-NETSOCK-107n getpeername length too small -> INVAL"); reset_all(); } @@ -506,31 +506,31 @@ static void tc_108_sockprops(void) reset_all(); CHECK(net_setblocking(-1, 1) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-108a setblocking 越界 → BADF"); + "TC-NETSOCK-108a setblocking out of range -> BADF"); CHECK(net_setblocking(0, 1) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-108b 未占用 → BADF"); + "TC-NETSOCK-108b not in use -> BADF"); CHECK(net_set_event_cb(-1, NULL, NULL) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-108c set_event_cb 越界 → BADF"); + "TC-NETSOCK-108c set_event_cb out of range -> BADF"); CHECK(net_set_event_cb(0, NULL, NULL) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-108d set_event_cb 未占用 → BADF"); + "TC-NETSOCK-108d set_event_cb not in use -> BADF"); fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); CHECK(net_setblocking(fd, 0) == 0 && s_net_socks[fd].blocking == 0U, - "TC-NETSOCK-108e setblocking(0) 落属性(模式挂控制块,不是单次参数)"); + "TC-NETSOCK-108e setblocking(0) sets the attribute (mode lives in the control block, not per call)"); CHECK(net_setblocking(fd, 5) == 0 && s_net_socks[fd].blocking == 1U, - "TC-NETSOCK-108f 非 0 一律视为阻塞"); + "TC-NETSOCK-108f any non-zero value counts as blocking"); CHECK(net_set_event_cb(fd, (net_event_cb_t)0x1234, &arg) == 0 && s_net_socks[fd].event_cb == (net_event_cb_t)0x1234 && s_net_socks[fd].event_arg == &arg, - "TC-NETSOCK-108g 注册回调与用户参数"); + "TC-NETSOCK-108g registers callback and user argument"); CHECK(net_set_event_cb(fd, NULL, NULL) == 0 && s_net_socks[fd].event_cb == NULL, - "TC-NETSOCK-108h cb=NULL 取消注册"); + "TC-NETSOCK-108h cb=NULL unregisters"); s_net_socks[fd].state = NET_SOCK_STATE_ESTABLISHED; CHECK(net_sock_state(fd) == (int)NET_SOCK_STATE_ESTABLISHED, - "TC-NETSOCK-108i sock_state 返状态快照"); - CHECK(net_sock_state(NET_MAX_SOCKETS) == -1, "TC-NETSOCK-108j sock_state 越界 -1"); + "TC-NETSOCK-108i sock_state returns the state snapshot"); + CHECK(net_sock_state(NET_MAX_SOCKETS) == -1, "TC-NETSOCK-108j sock_state out of range -> -1"); s_net_socks[fd].in_use = 0U; - CHECK(net_sock_state(fd) == -1, "TC-NETSOCK-108k sock_state 未占用 -1"); + CHECK(net_sock_state(fd) == -1, "TC-NETSOCK-108k sock_state on unused fd -> -1"); reset_all(); } @@ -538,10 +538,10 @@ static void tc_108_sockprops(void) static void tc_109_generation(void) { reset_all(); - CHECK(net_get_generation() == 0U, "TC-NETSOCK-109a 初值 0"); + CHECK(net_get_generation() == 0U, "TC-NETSOCK-109a initial value 0"); net_generation_inc(); net_generation_inc(); - CHECK(net_get_generation() == 2U, "TC-NETSOCK-109b 每次网络重建 +1(服务据此重建监听)"); + CHECK(net_get_generation() == 2U, "TC-NETSOCK-109b each network rebuild adds 1 (services rebuild listeners from it)"); reset_all(); } @@ -551,33 +551,33 @@ static void tc_110_queue_adopt(void) static int q2; reset_all(); - CHECK(net_msg_queue_adopt(NULL) == -1, "TC-NETSOCK-110a 空句柄 → -1"); - CHECK(net_msg_queue_adopt((osMessageQueueId_t)&q1) == 0, "TC-NETSOCK-110b 首次绑定成功"); + CHECK(net_msg_queue_adopt(NULL) == -1, "TC-NETSOCK-110a NULL handle -> -1"); + CHECK(net_msg_queue_adopt((osMessageQueueId_t)&q1) == 0, "TC-NETSOCK-110b first binding succeeds"); CHECK(net_msg_queue_adopt((osMessageQueueId_t)&q2) == -1, - "TC-NETSOCK-110c 重复绑定必须被拒(不静默换句柄)"); + "TC-NETSOCK-110c rebinding must be refused (no silent handle swap)"); CHECK(s_net_msg_queue == (osMessageQueueId_t)&q1, - "TC-NETSOCK-110d 重复绑定**保留首次**句柄——换掉会让已入队请求永不处理"); + "TC-NETSOCK-110d rebinding keeps the FIRST handle - swapping would strand queued requests forever"); /* 未绑定时所有公开 API 一律 NET_ERR,而不是崩在空句柄上 */ reset_all(); CHECK(net_listen(0) == -1 && net_get_errno() == NET_ERR, - "TC-NETSOCK-110e 未绑定队列:net_listen → NET_ERR"); + "TC-NETSOCK-110e without a bound queue: net_listen -> NET_ERR"); CHECK(net_recv(0, NULL, 0, 0) == -1 && net_get_errno() == NET_ERR, - "TC-NETSOCK-110f 未绑定队列:net_recv → NET_ERR(越界检查在队检查之前)"); + "TC-NETSOCK-110f without a bound queue: net_recv -> NET_ERR (range check precedes queue check)"); CHECK(net_send(0, "x", 1, 0) == -1 && net_get_errno() == NET_ERR, - "TC-NETSOCK-110g 未绑定队列:net_send → NET_ERR"); + "TC-NETSOCK-110g without a bound queue: net_send -> NET_ERR"); CHECK(net_close(0) == -1 && net_get_errno() == NET_ERR, - "TC-NETSOCK-110h 未绑定队列:net_close → NET_ERR"); + "TC-NETSOCK-110h without a bound queue: net_close -> NET_ERR"); CHECK(net_drop_conn(0) == -1 && net_get_errno() == NET_ERR, - "TC-NETSOCK-110i 未绑定队列:net_drop_conn → NET_ERR"); + "TC-NETSOCK-110i without a bound queue: net_drop_conn -> NET_ERR"); CHECK(net_recv_to(0, NULL, 0, 10U) == -1 && net_get_errno() == NET_ERR, - "TC-NETSOCK-110j 未绑定队列:net_recv_to → NET_ERR"); + "TC-NETSOCK-110j without a bound queue: net_recv_to -> NET_ERR"); CHECK(net_accept(0, NULL, NULL) == -1 && net_get_errno() == NET_ERR, - "TC-NETSOCK-110k 未绑定队列:net_accept → NET_ERR"); + "TC-NETSOCK-110k without a bound queue: net_accept -> NET_ERR"); CHECK(net_connect(0, NULL, 0) == -1 && net_get_errno() == NET_ERR, - "TC-NETSOCK-110l 未绑定队列:net_connect → NET_ERR"); + "TC-NETSOCK-110l without a bound queue: net_connect -> NET_ERR"); /* 越界优先于"未初始化":调用方拿到的码要能区分"我传错了"和"网还没起来" */ CHECK(net_send(NET_MAX_SOCKETS, "x", 1, 0) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-110m 越界检查先于队列检查 → BADF"); + "TC-NETSOCK-110m range check before queue check -> BADF"); reset_all(); } @@ -592,10 +592,10 @@ static void tc_120_errno_slot_per_task(void) g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; (void)net_set_errno(NET_ERR_BADF); CHECK(net_get_errno() == NET_ERR_BADF && s_net_errno_slots[0].owner == NULL, - "TC-NETSOCK-120a 内核未运行 → 用 [0] 槽且**不占槽**(不写 owner)"); + "TC-NETSOCK-120a kernel not running -> uses slot [0] and takes no slot (owner not written)"); g_ns_cur_task = (TaskHandle_t)&g_ns_task_net; CHECK(net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-120b 内核未运行时所有任务共享 [0] 槽(退化语义)"); + "TC-NETSOCK-120b with the kernel down all tasks share slot [0] (degraded semantics)"); /* 内核在跑:每个任务自己的槽位 */ g_ns_kernel_state = osKernelRunning; @@ -605,15 +605,15 @@ static void tc_120_errno_slot_per_task(void) (void)net_set_errno(NET_ERR_TIMEDOUT); g_ns_cur_task = (TaskHandle_t)&g_ns_task_net; CHECK(net_get_errno() == NET_OK, - "TC-NETSOCK-120c 另一个任务读不到 caller 的码(E-03 的正面表述)"); + "TC-NETSOCK-120c another task cannot read the caller code (the positive wording of E-03)"); (void)net_set_errno(NET_ERR_WOULDBLOCK); - CHECK(net_get_errno() == NET_ERR_WOULDBLOCK, "TC-NETSOCK-120d 本任务读自己的码"); + CHECK(net_get_errno() == NET_ERR_WOULDBLOCK, "TC-NETSOCK-120d a task reads its own code"); g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; CHECK(net_get_errno() == NET_ERR_TIMEDOUT, - "TC-NETSOCK-120e 互不覆写:caller 的码没被 netTask 抢走(旧实现的红线)"); + "TC-NETSOCK-120e no cross overwrite: caller code survives the netTask write (old red line)"); /* 临界区:两个任务各占一次槽 → 两次进入、两次退出,绝不泄漏嵌套计数 */ CHECK(g_ns_crit_enter == 2 && g_ns_crit_exit == 2 && ns_os_crit_depth() == 0, - "TC-NETSOCK-120f 每次**首次占槽**进一次临界区且成对退出(无泄漏)"); + "TC-NETSOCK-120f each first slot take enters the critical section once and leaves in pairs"); /* 快路径只读不写:已有槽位的任务反复读写都不该再进临界区、也不该再占槽 */ { @@ -623,18 +623,18 @@ static void tc_120_errno_slot_per_task(void) int i_net = ns_slot_index_of((TaskHandle_t)&g_ns_task_net); CHECK(i_caller >= 0 && i_net >= 0 && i_caller != i_net, - "TC-NETSOCK-120g 两个任务落在**不同**槽位(槽位表可查,不是靠约定)"); + "TC-NETSOCK-120g two tasks land in DIFFERENT slots (table is inspectable, not convention)"); g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; (void)net_set_errno(NET_ERR_BUSY); (void)net_get_errno(); (void)net_set_errno(NET_ERR_CONNRESET); - CHECK(g_ns_crit_enter == e0, "TC-NETSOCK-120h 命中已有槽位:全程零临界区(快路径只读)"); + CHECK(g_ns_crit_enter == e0, "TC-NETSOCK-120h existing slot hit: zero critical sections (fast path is read-only)"); g_ns_cur_task = (TaskHandle_t)&g_ns_task_net; CHECK(net_get_errno() == NET_ERR_WOULDBLOCK && ns_slot_owner_count() == owners0, - "TC-NETSOCK-120i 别的任务反复读也不新增槽位、也读不到 caller 的码"); + "TC-NETSOCK-120i repeated reads by another task add no slot and never see the caller code"); g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; - CHECK(net_get_errno() == NET_ERR_CONNRESET, "TC-NETSOCK-120j caller 读到自己最新的码"); + CHECK(net_get_errno() == NET_ERR_CONNRESET, "TC-NETSOCK-120j caller reads its own latest code"); } /* 槽位用尽 → 回退 [0](刻意不重试,避免把竞态带回来) */ @@ -648,14 +648,14 @@ static void tc_120_errno_slot_per_task(void) (void)net_set_errno(NET_ERR_ISCONN); } g_ns_cur_task = (TaskHandle_t)&filler[0]; - CHECK(net_get_errno() == NET_ERR_ISCONN, "TC-NETSOCK-120k 8 个槽各归各主"); + CHECK(net_get_errno() == NET_ERR_ISCONN, "TC-NETSOCK-120k 8 slots, one owner each"); g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; /* 第 9 个任务 */ (void)net_set_errno(NET_ERR_NOMEM); CHECK(net_get_errno() == NET_ERR_NOMEM, - "TC-NETSOCK-120l 槽位用尽:新任务落 [0] 槽仍读得到自己的码"); + "TC-NETSOCK-120l slots exhausted: a new task still reads its own code from slot [0]"); g_ns_cur_task = (TaskHandle_t)&filler[0]; CHECK(net_get_errno() == NET_ERR_NOMEM, - "TC-NETSOCK-120m 用尽后退化为共享 [0] 槽(只影响排障可读性,不新增共享槽位)"); + "TC-NETSOCK-120m after exhaustion it degrades to the shared slot [0] (only hurts debuggability)"); } reset_all(); } @@ -667,7 +667,7 @@ static void tc_121_errno_slot_isr(void) g_ns_cur_task = NULL; /* 中断上下文/无句柄 */ (void)net_set_errno(NET_ERR_CONNRESET); CHECK(net_get_errno() == NET_ERR_CONNRESET && s_net_errno_slots[0].owner == NULL, - "TC-NETSOCK-121 句柄为 NULL(中断上下文)→ 退 [0] 槽且不改槽位表"); + "TC-NETSOCK-121 NULL handle (ISR context) -> falls back to slot [0] and leaves the table alone"); reset_all(); } @@ -675,9 +675,9 @@ static void tc_121_errno_slot_isr(void) int main(void) { - printf("=== NET Socket Tests (net_socket.c 主机单测) ===\n"); + printf("=== NET Socket Tests (net_socket.c host unit tests) ===\n"); - printf("[shard1] 纯函数面与 fd 表\n"); + printf("[shard1] pure functions and fd table\n"); tc_100_inet_helpers(); tc_101_byteorder(); tc_102_parse_ip(); @@ -690,20 +690,20 @@ int main(void) tc_109_generation(); tc_110_queue_adopt(); - printf("[shard2] 每任务错误码槽 + 队列绑定\n"); + printf("[shard2] per-task errno slots and queue binding\n"); tc_120_errno_slot_per_task(); tc_121_errno_slot_isr(); - printf("[shard3] 跨上下文消息与通知值回传\n"); + printf("[shard3] cross-context messages and notify-value return\n"); ns_run_s3(); - printf("[shard4] 状态机与闸门\n"); + printf("[shard4] state machine and gates\n"); ns_run_s4(); - printf("[shard5] 建流与读写分支\n"); + printf("[shard5] stream setup and read/write branches\n"); ns_run_s5(); - printf("[shard6] 边界残支与其余出口\n"); + printf("[shard6] edge branches and remaining exits\n"); ns_run_s6(); printf("=== NET Socket Tests: %d/%d PASSED (failed=%d) ===\n", diff --git a/test/host/net_socket/ns_rtos.c b/test/host/net_socket/ns_rtos.c index d4061ae9..116baa6f 100644 --- a/test/host/net_socket/ns_rtos.c +++ b/test/host/net_socket/ns_rtos.c @@ -118,7 +118,7 @@ void ns_rtos_post_notify(TaskHandle_t to, uint32_t v) return; } } - printf("FATAL: ns_rtos_post_notify 收到未知任务句柄\n"); + printf("FATAL: ns_rtos_post_notify got an unknown task handle\n"); exit(2); } @@ -185,7 +185,7 @@ osStatus_t osDelay(uint32_t ticks) g_ns_tick += ticks; if (++guard > 20000) { - printf("FATAL: osDelay 跑飞(%d 次)—— 等待条件永不满足\n", guard); + printf("FATAL: osDelay runaway (%d calls) - the wait condition is never met\n", guard); exit(2); } if (guard > 0) { @@ -212,7 +212,7 @@ BaseType_t xTaskNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue, g_ns_notify_last_val = ulValue; g_ns_notify_last_to = xTaskToNotify; if (p == NULL) { - printf("FATAL: xTaskNotify 收到未知任务句柄\n"); + printf("FATAL: xTaskNotify got an unknown task handle\n"); exit(2); } p->val = ulValue; @@ -228,7 +228,7 @@ BaseType_t xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, ns_notify_slot_t *p = slot_of(g_ns_cur_task); if (p == NULL) { - printf("FATAL: xTaskNotifyWait 当前任务句柄未知\n"); + printf("FATAL: xTaskNotifyWait current task handle unknown\n"); exit(2); } if (pulNotificationValue != NULL) { @@ -249,7 +249,7 @@ BaseType_t xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, /* 阻塞分支:这就是"睡到 netTask 回执"的调度点 → 驱动一轮 netTask 再拾取 */ g_ns_block_waits++; if (g_ns_pump == NULL) { - printf("FATAL: 走到阻塞等待但测试没装 pump 钩子\n"); + printf("FATAL: reached the blocking wait but the test installed no pump hook\n"); exit(2); } { @@ -267,7 +267,7 @@ BaseType_t xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, } } if (p->pending == 0) { - printf("FATAL: 阻塞等待 %d 轮仍无回执(该通知的没通知 = 真机必挂死)\n", rounds); + printf("FATAL: blocking wait still got no receipt after %d rounds (a missing notify would hang real hardware)\n", rounds); exit(2); } } @@ -326,7 +326,7 @@ GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) g_ns_on_poll(); /* 并发事件注入点(在时间推进之后,超时判定才量得到) */ } if (g_ns_poll_calls > 400000U) { - printf("FATAL: net_poll 轮询 %lu 次仍未收敛(等待条件永不满足)\n", + printf("FATAL: net_poll still not converged after %lu rounds (wait condition never met)\n", (unsigned long)g_ns_poll_calls); exit(2); } diff --git a/test/host/net_socket/ns_s3_msg.c b/test/host/net_socket/ns_s3_msg.c index 5dcb07d5..37d0404d 100644 --- a/test/host/net_socket/ns_s3_msg.c +++ b/test/host/net_socket/ns_s3_msg.c @@ -49,15 +49,15 @@ static void tc_200_unknown_type(void) msg.sockfd = 0; msg.caller = (TaskHandle_t)&g_ns_task_caller; msg.result = 12345; /* 脏值:分派必须覆写它 */ - CHECK(ns_rtos_q_put_raw(&msg) == 0, "TC-NETSOCK-200a 原始消息入队"); - CHECK(g_ns_notify_calls == 0, "TC-NETSOCK-200b 入队本身不产生通知"); + CHECK(ns_rtos_q_put_raw(&msg) == 0, "TC-NETSOCK-200a raw message enqueued"); + CHECK(g_ns_notify_calls == 0, "TC-NETSOCK-200b enqueue itself produces no notification"); net_process_messages(); /* 以 netTask 身份跑一轮 */ - CHECK(g_ns_notify_calls == 1, "TC-NETSOCK-200c 未知 type 仍必发回执(否则调用方永久悬挂)"); + CHECK(g_ns_notify_calls == 1, "TC-NETSOCK-200c unknown type must still send a receipt (else the caller hangs forever)"); CHECK(g_ns_notify_last_val == (uint32_t)NET_ERR, - "TC-NETSOCK-200d 未知 type 的通知值 = 本条的精确错误码 NET_ERR(不是上一条残留)"); - CHECK(ns_rtos_q_count() == 0, "TC-NETSOCK-200e 本轮队列被排空(非阻塞 while 语义)"); + "TC-NETSOCK-200d notify value for unknown type = this message exact code NET_ERR, not a leftover"); + CHECK(ns_rtos_q_count() == 0, "TC-NETSOCK-200e queue drained within this round (non-blocking while semantics)"); reset_all(); } @@ -70,9 +70,9 @@ static void tc_201_ticks_run_before_dispatch(void) CHECK(g_peers.listener_tick_calls == 1 && g_peers.pending_tick_calls == 1 && g_peers.send_tick_calls == 1 && g_peers.reconcile_calls == 1, - "TC-NETSOCK-201a 空队列也要跑满四个自愈 tick(D10/pending×2/对账)"); + "TC-NETSOCK-201a even with an empty queue all four self-heal ticks run (D10/pending x2/reconcile)"); CHECK(g_ns_notify_calls == 0 && g_ns_get_calls == 1, - "TC-NETSOCK-201b 空队列:取一次即退,不发通知"); + "TC-NETSOCK-201b empty queue: one peek then exit, no notification"); reset_all(); } @@ -85,7 +85,7 @@ static void tc_202_no_queue_bound(void) net_process_messages(); CHECK(g_peers.listener_tick_calls == 0 && g_ns_get_calls == 0, - "TC-NETSOCK-202 未绑定队列就调 net_process_messages → 立即返回(不碰芯片也不跑 tick)"); + "TC-NETSOCK-202 net_process_messages without a bound queue returns at once (no chip, no ticks)"); reset_all(); } @@ -103,16 +103,16 @@ static void tc_210_send_end_to_end(void) g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; rc = net_send(fd, buf, (int)sizeof(buf), 0); - CHECK(rc == (int)sizeof(buf), "TC-NETSOCK-210a net_send 返回实际写入字节数"); + CHECK(rc == (int)sizeof(buf), "TC-NETSOCK-210a net_send returns the number of bytes actually written"); CHECK(g_chip.write_calls == 1 && g_chip.last_read_len == (uint16_t)sizeof(buf), - "TC-NETSOCK-210b 一次写满(健康链路不拆块、不进挂起)"); - CHECK(s_net_socks[fd].send_bytes == sizeof(buf), "TC-NETSOCK-210c 发送字节统计累计"); + "TC-NETSOCK-210b one full write (a healthy path neither chunks nor goes pending)"); + CHECK(s_net_socks[fd].send_bytes == sizeof(buf), "TC-NETSOCK-210c sent byte statistic accumulates"); CHECK(g_ns_notify_calls == 1 && g_ns_notify_last_val == (uint32_t)sizeof(buf), - "TC-NETSOCK-210d 结果经通知值回传(32 位整体即结果)"); + "TC-NETSOCK-210d result travels back on the notify value (the whole 32 bits are the result)"); CHECK(g_ns_notify_last_to == (TaskHandle_t)&g_ns_task_caller, - "TC-NETSOCK-210e 通知发给**登记的那个 caller**,不是广播"); + "TC-NETSOCK-210e notify goes to the REGISTERED caller only, not a broadcast"); CHECK(g_ns_block_waits == 1, - "TC-NETSOCK-210f 零等待没拾到 → 走阻塞分支(两段式拾取的第二段)"); + "TC-NETSOCK-210f zero-wait found nothing -> blocking branch (second stage of the two-step peek)"); reset_all(); } @@ -135,11 +135,11 @@ static void tc_211_send_chunking(void) rc = net_send(fd, buf, 2500, 0); - CHECK(rc == 2500, "TC-NETSOCK-211a 2500 字节全部交付"); - CHECK(g_chip.write_calls == 3, "TC-NETSOCK-211b 按 1024 上界切成 3 块(1024/1024/452)"); - CHECK(g_chip.last_read_len == 452U, "TC-NETSOCK-211c 末块只写剩余量"); + CHECK(rc == 2500, "TC-NETSOCK-211a all 2500 bytes delivered"); + CHECK(g_chip.write_calls == 3, "TC-NETSOCK-211b split into 3 chunks at the 1024 bound (1024/1024/452)"); + CHECK(g_chip.last_read_len == 452U, "TC-NETSOCK-211c last chunk writes only the remainder"); CHECK(NET_SEND_CHUNK_MAX == 1024, - "TC-NETSOCK-211d 分块粒度取芯片发送缓冲(不是假件自定的数)"); + "TC-NETSOCK-211d chunk size comes from the chip send buffer, not a fake-defined number"); reset_all(); } @@ -160,24 +160,24 @@ static void tc_212_send_pending_defers_notify(void) msg.len = (int)sizeof(buf); msg.caller = (TaskHandle_t)&g_ns_task_caller; - CHECK(ns_rtos_q_put_raw(&msg) == 0, "TC-NETSOCK-212a SEND 消息入队"); + CHECK(ns_rtos_q_put_raw(&msg) == 0, "TC-NETSOCK-212a SEND message enqueued"); net_process_messages(); CHECK(g_peers.send_reg_calls == 1, - "TC-NETSOCK-212b 超自旋预算后登记挂起 send(而不是继续占着 netTask 忙等)"); + "TC-NETSOCK-212b past the spin budget it registers a pending send instead of busy-waiting in netTask"); CHECK(g_peers.last_snd_fd == fd && g_peers.last_snd_len == (int)sizeof(buf) && g_peers.last_snd_sent == 0, - "TC-NETSOCK-212c 登记的进度=已写芯片字节数(此处 0),总长与 caller 一并带走"); + "TC-NETSOCK-212c registered progress = bytes already written to the chip (0 here), length and caller travel too"); CHECK(g_ns_notify_calls == 0, - "TC-NETSOCK-212d 登记成功**绝不发即时回执**(否则「登记成功」被当成本次结果)"); + "TC-NETSOCK-212d a successful registration NEVER sends an immediate receipt (else it reads as the result)"); CHECK(g_ns_notify_last_to == NULL, - "TC-NETSOCK-212e 一次通知都没发生(0x70000000 哨兵值也没可能漏进通知值)"); + "TC-NETSOCK-212e not a single notification (the 0x70000000 sentinel can not leak into a notify value)"); /* 完成时刻:由挂起 send 的 tick 结束(本套由桩脚本模拟"缓冲腾出来了") */ ns_peers_arm_send_pending_done(fd, 64); net_process_messages(); CHECK(g_ns_notify_calls == 1 && g_ns_notify_last_val == 64U, - "TC-NETSOCK-212f 挂起完成后才发回执,通知值=实际写出字节数"); + "TC-NETSOCK-212f receipt only after the pending completes, notify value = bytes actually written"); reset_all(); } @@ -201,7 +201,7 @@ static void tc_213_send_error_code_roundtrip(void) net_process_messages(); CHECK(g_ns_notify_last_val == (uint32_t)NET_ERR_NOTCONN, - "TC-NETSOCK-213a 未连接的 SEND:通知值=NET_ERR_NOTCONN(精确码回传,供调用方分支)"); + "TC-NETSOCK-213a SEND on a not-connected socket: notify value = NET_ERR_NOTCONN (exact code for caller branches)"); /* 端到端:公开 net_send 的 BADF 形态(fd 越界由**分派侧**再判一次) */ reset_all(); @@ -215,16 +215,16 @@ static void tc_213_send_error_code_roundtrip(void) (void)ns_rtos_q_put_raw(&msg); net_process_messages(); CHECK(g_ns_notify_last_val == (uint32_t)NET_ERR_BADF, - "TC-NETSOCK-213b 范围内但未分配的 fd:net_get_sock 判空 → BADF 搭通知值回来"); + "TC-NETSOCK-213b in range but unallocated fd: net_get_sock null -> BADF travels on the notify value"); /* 调用方上下文恢复 errno:拿到的必须是"本任务的"精确码 */ reset_all(); bring_up(); g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; rc = net_send(6, buf, 4, 0); /* 6 未分配 → 分派侧 BADF → 通知值 -2 */ - CHECK(rc == -1, "TC-NETSOCK-213c 对外保持 BSD 语义:失败一律 -1"); + CHECK(rc == -1, "TC-NETSOCK-213c BSD semantics kept for callers: any failure is -1"); CHECK(net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-213d 调用方在自己的错误码槽里拿到精确码(E-03 + 通知值回传合力)"); + "TC-NETSOCK-213d caller reads the exact code from its own errno slot (E-03 plus notify value together)"); reset_all(); } @@ -243,13 +243,13 @@ static void tc_220_recv_fast_path(void) g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; rc = net_recv(fd, buf, 10, NET_MSG_DONTWAIT); - CHECK(rc == 10, "TC-NETSOCK-220a 缓冲 1400B、只给 10B 缓冲 → 读满 10(部分读合法)"); + CHECK(rc == 10, "TC-NETSOCK-220a chip has 1400B but the caller buffer is 10B -> reads 10 (a partial read is legal)"); CHECK(g_chip.read_calls == 1 && g_chip.last_read_len == 10U, - "TC-NETSOCK-220b 只读调用方给的量(不得按芯片可用量越界写)"); - CHECK(s_net_socks[fd].recv_bytes == 10U, "TC-NETSOCK-220c 接收字节统计累计"); + "TC-NETSOCK-220b reads only what the caller offered (never the chip available length)"); + CHECK(s_net_socks[fd].recv_bytes == 10U, "TC-NETSOCK-220c received byte statistic accumulates"); CHECK(s_net_socks[fd].readable == 0U, - "TC-NETSOCK-220d 读过即清 readable(下一次 RECV_OK 中断再置)"); - CHECK(g_peers.pending_reg_calls == 0, "TC-NETSOCK-220e 数据已在手,不该登记挂起"); + "TC-NETSOCK-220d reading clears readable (the next RECV_OK interrupt sets it again)"); + CHECK(g_peers.pending_reg_calls == 0, "TC-NETSOCK-220e data is already in hand, no pending registration"); reset_all(); } @@ -266,18 +266,18 @@ static void tc_221_recv_wouldblock(void) g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; rc = net_recv(fd, buf, (int)sizeof(buf), NET_MSG_DONTWAIT); CHECK(rc == -1 && net_get_errno() == NET_ERR_WOULDBLOCK, - "TC-NETSOCK-221a DONTWAIT 无数据 → -1 + WOULDBLOCK"); + "TC-NETSOCK-221a DONTWAIT with no data -> -1 plus WOULDBLOCK"); CHECK(g_peers.pending_reg_calls == 0, - "TC-NETSOCK-221b 非阻塞绝不登记挂起(否则调用方以为自己在等,实际已被挂住)"); + "TC-NETSOCK-221b non-blocking never registers pending (else the caller thinks it waits while it is parked)"); /* 模式属性(net_setblocking(0))与单次标志同判据 */ - CHECK(net_setblocking(fd, 0) == 0, "TC-NETSOCK-221c 切非阻塞模式成功"); + CHECK(net_setblocking(fd, 0) == 0, "TC-NETSOCK-221c switching to non-blocking mode succeeds"); rc = net_recv(fd, buf, (int)sizeof(buf), 0); CHECK(rc == -1 && net_get_errno() == NET_ERR_WOULDBLOCK, - "TC-NETSOCK-221d blocking 属性=0 与 NET_MSG_DONTWAIT 等价生效"); + "TC-NETSOCK-221d blocking attribute 0 behaves exactly like NET_MSG_DONTWAIT"); CHECK(net_recv_nb(fd, buf, (int)sizeof(buf)) == -1 && net_get_errno() == NET_ERR_WOULDBLOCK, - "TC-NETSOCK-221e net_recv_nb 具名入口同路径"); + "TC-NETSOCK-221e net_recv_nb named entry takes the same path"); reset_all(); } @@ -296,12 +296,12 @@ static void tc_222_recv_eof_relisten(void) g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; rc = net_recv(fd, buf, (int)sizeof(buf), NET_MSG_DONTWAIT); - CHECK(rc == 0, "TC-NETSOCK-222a CLOSED+无数据 → EOF(0),不是错误"); + CHECK(rc == 0, "TC-NETSOCK-222a CLOSED with no data -> EOF(0), not an error"); CHECK(g_peers.listener_req_calls == 1 && g_peers.last_req_reason == (int)NET_LISTENER_REQ_EOF, - "TC-NETSOCK-222b EOF 登记 REQ_EOF(重建动作交监听层唯一执行者,本层不动芯片)"); + "TC-NETSOCK-222b EOF registers REQ_EOF (the rebuild belongs to the listener layer, this layer never touches the chip)"); CHECK(g_chip.open_calls == 0 && g_chip.listen_calls == 0 && g_chip.close_calls == 0, - "TC-NETSOCK-222c 登记路径上**一个芯片事务都不发**(单一所有者不变量 II)"); + "TC-NETSOCK-222c the registration path issues NOT ONE chip transaction (single-owner invariant II)"); /* 抢先 relisten 后 state 已回 LISTENING,但会话电平仍是"已结束" */ reset_all(); @@ -313,7 +313,7 @@ static void tc_222_recv_eof_relisten(void) g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; rc = net_recv(fd, buf, (int)sizeof(buf), NET_MSG_DONTWAIT); CHECK(rc == 0, - "TC-NETSOCK-222d 已 relisten 回 LISTENING 仍判 EOF(N-32 P1 电平化:否则 EOF 永久失踪)"); + "TC-NETSOCK-222d still EOF after relisten moved it back to LISTENING (N-32 P1 level, else EOF vanishes forever)"); /* auto_relisten=0(客户端 fd):EOF 不登记重建,交调用方决定重连 */ reset_all(); @@ -325,7 +325,7 @@ static void tc_222_recv_eof_relisten(void) g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; rc = net_recv(fd, buf, (int)sizeof(buf), NET_MSG_DONTWAIT); CHECK(rc == 0 && g_peers.listener_req_calls == 0, - "TC-NETSOCK-222e 非监听 fd 的 EOF 不许替调用方擅自重建"); + "TC-NETSOCK-222e EOF on a non-listener fd must not rebuild behind the caller back"); reset_all(); } @@ -351,19 +351,19 @@ static void tc_223_recv_pending_roundtrip(void) net_process_messages(); CHECK(g_peers.pending_reg_calls == 1 && g_peers.last_pend_fd == fd, - "TC-NETSOCK-223a 阻塞无数据 → 登记挂起 recv(netTask 零占用返回)"); + "TC-NETSOCK-223a blocking with no data -> registers a pending recv (netTask returns with zero occupancy)"); CHECK(g_peers.last_pend_to == 250U, - "TC-NETSOCK-223b 调用方的显式预算随登记带走(0=无限,这里必须不是 0)"); + "TC-NETSOCK-223b the caller explicit budget travels with the registration (0 means infinite, here it must not be 0)"); CHECK(g_peers.last_pend_caller == (TaskHandle_t)&g_ns_task_caller, - "TC-NETSOCK-223c 完成时要知道通知谁"); + "TC-NETSOCK-223c completion must know whom to notify"); CHECK(g_ns_notify_calls == 0, - "TC-NETSOCK-223d 登记即发回执 = 把「登记成功」当结果,本条钉它没发生"); + "TC-NETSOCK-223d registering then immediately notifying would pass off registration as the result - pinned absent"); /* 数据到达:由挂起 recv 的 tick 结束(脚本模拟) */ ns_peers_arm_pending_done(fd, 7); net_process_messages(); CHECK(g_ns_notify_calls == 1 && g_ns_notify_last_val == 7U, - "TC-NETSOCK-223e 数据到达后才回执,通知值=字节数"); + "TC-NETSOCK-223e receipt only once data arrives, notify value = byte count"); reset_all(); } @@ -381,7 +381,7 @@ static void tc_224_recv_to_timeout_code(void) /* 先造一条"已登记"的挂起,再让 tick 判到点 */ ns_peers_arm_pending_done(fd, NET_ERR_TIMEDOUT); rc = net_recv_to(fd, buf, (int)sizeof(buf), 30U); - CHECK(rc == -2, "TC-NETSOCK-224a 本片超时 → 独立返回码 -2(与真错误 -1 区分)"); + CHECK(rc == -2, "TC-NETSOCK-224a this slice timed out -> dedicated return code -2 (distinct from a real error -1)"); reset_all(); } @@ -396,21 +396,21 @@ static void tc_225_recv_bad_args(void) g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; CHECK(net_recv_to(0, buf, 4, 0U) == -1 && net_get_errno() == NET_ERR_INVAL, - "TC-NETSOCK-225a net_recv_to(timeout=0) 直接拒——0 在 netTask 侧是「无限等待」," - "与本接口「有界占用」的存在理由相反"); - CHECK(g_ns_put_calls == 0, "TC-NETSOCK-225b 拒绝发生在入队之前"); + "TC-NETSOCK-225a net_recv_to(timeout=0) is refused up front - 0 means infinite wait on the netTask side," + "which contradicts this API whole reason for having a bounded occupancy"); + CHECK(g_ns_put_calls == 0, "TC-NETSOCK-225b the refusal happens before enqueue"); CHECK(net_recv(fd, NULL, 4, NET_MSG_DONTWAIT) == -1 && - net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-225c buf 为 NULL → INVAL"); + net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-225c buf NULL -> INVAL"); CHECK(net_recv(fd, buf, 0, NET_MSG_DONTWAIT) == -1 && - net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-225d len<=0 → INVAL"); + net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-225d len <= 0 -> INVAL"); CHECK(net_send(fd, NULL, 4, 0) == -1 && net_get_errno() == NET_ERR_INVAL, - "TC-NETSOCK-225e send 的 buf 为 NULL → INVAL"); + "TC-NETSOCK-225e send with buf NULL -> INVAL"); CHECK(net_send(fd, buf, -1, 0) == -1 && net_get_errno() == NET_ERR_INVAL, - "TC-NETSOCK-225f send 的 len<0 → INVAL"); + "TC-NETSOCK-225f send with len < 0 -> INVAL"); CHECK(g_chip.write_calls == 0 && g_chip.read_calls == 0 && g_peers.pending_reg_calls == 0 && g_peers.send_reg_calls == 0, - "TC-NETSOCK-225g 参数非法路径上零芯片事务、零挂起登记"); + "TC-NETSOCK-225g on the invalid-argument path: zero chip transactions and zero pending registrations"); reset_all(); } @@ -433,7 +433,7 @@ static void tc_230_close_order_and_peer(void) (void)ns_rtos_q_put_raw(&msg); net_process_messages(); /* 走登记路径(不发回执) */ CHECK(g_peers.pending_reg_calls == 1 && g_ns_notify_calls == 0, - "TC-NETSOCK-230a 前置:已登记挂起且未回执"); + "TC-NETSOCK-230a precondition: pending registered and no receipt yet"); /* 芯片侧此刻仍是 OPEN:close 才需要真去拆(已 CLOSED 的形态见 TC-NETSOCK-232) */ g_fake.cached_open[fd] = CH395F_SOCKET_OPEN; @@ -450,19 +450,19 @@ static void tc_230_close_order_and_peer(void) net_process_messages(); CHECK(g_peers.pending_settle_calls == s_close_base_settle + 1, - "TC-NETSOCK-230b close 必先结算本 fd 的挂起 recv(否则等待方永久悬挂)"); + "TC-NETSOCK-230b close must first settle this fd pending recv (else the waiter hangs forever)"); CHECK(g_peers.pending_notified == 1, - "TC-NETSOCK-230c 结算必通知(取消也要通知,不是静默清槽)"); + "TC-NETSOCK-230c settling always notifies (a cancel notifies too, not a silent slot clear)"); CHECK(g_chip.close_calls >= 1 && g_fxchip.rst_begin_calls == 1, - "TC-NETSOCK-230d 芯片仍 OPEN → 走 sock_reset 确定性排渣把它拆掉"); + "TC-NETSOCK-230d chip still OPEN -> sock_reset deterministically drains and tears it down"); CHECK(g_fxchip.glob_calls == 0, - "TC-NETSOCK-230e close 全程不得读全局中断寄存器(B3:唯一读者=net_poll)"); + "TC-NETSOCK-230e close must never read the global interrupt register (B3: sole reader is net_poll)"); CHECK(s_net_socks[fd].in_use == 0U && s_net_socks[fd].last_peer_port == 51999U, - "TC-NETSOCK-230f 控制块清零但 last_peer_port 保留(幽灵甄别基准属芯片 Socket 级)"); + "TC-NETSOCK-230f control block cleared but last_peer_port kept (ghost discrimination is chip-socket level)"); CHECK(g_peers.listener_clear_calls == s_close_base_clear + 1, - "TC-NETSOCK-230g close 幂等清理监听重试(关闭即取消待重试,D10)"); + "TC-NETSOCK-230g close idempotently clears the listener retry (closing cancels pending retries, D10)"); CHECK(g_peers.pend_active_now[fd] == 0, - "TC-NETSOCK-230h close 后本 fd 不再有挂起 recv(两张表都归零)"); + "TC-NETSOCK-230h after close this fd has no pending recv (both tables zeroed)"); reset_all(); } @@ -479,8 +479,8 @@ static void tc_231_close_badfd(void) (void)ns_rtos_q_put_raw(&msg); net_process_messages(); CHECK(g_ns_notify_last_val == (uint32_t)NET_ERR_BADF, - "TC-NETSOCK-231a close 未分配的 fd → BADF 经通知值回传"); - CHECK(g_chip.close_calls == 0, "TC-NETSOCK-231b BADF 不碰芯片"); + "TC-NETSOCK-231a close on an unallocated fd -> BADF travels back on the notify value"); + CHECK(g_chip.close_calls == 0, "TC-NETSOCK-231b BADF does not touch the chip"); bring_up(); (void)memset(&msg, 0, sizeof(msg)); @@ -490,7 +490,7 @@ static void tc_231_close_badfd(void) (void)ns_rtos_q_put_raw(&msg); net_process_messages(); CHECK(g_ns_notify_last_val == (uint32_t)NET_ERR_INVAL, - "TC-NETSOCK-231c accept 未在用 → INVAL(控制块级校验,不是 fd 越界)"); + "TC-NETSOCK-231c accept on an unused fd -> INVAL (control-block check, not fd range)"); reset_all(); } @@ -508,7 +508,7 @@ static void tc_240_drop_conn_branches(void) msg.caller = (TaskHandle_t)&g_ns_task_caller; (void)ns_rtos_q_put_raw(&msg); net_process_messages(); - CHECK(g_ns_notify_last_val == (uint32_t)NET_ERR_BADF, "TC-NETSOCK-240a 未分配 → BADF"); + CHECK(g_ns_notify_last_val == (uint32_t)NET_ERR_BADF, "TC-NETSOCK-240a unallocated -> BADF"); /* UDP → INVAL */ bring_up(); @@ -520,7 +520,7 @@ static void tc_240_drop_conn_branches(void) (void)ns_rtos_q_put_raw(&msg); net_process_messages(); CHECK(g_ns_notify_last_val == (uint32_t)NET_ERR_INVAL, - "TC-NETSOCK-240b 非 TCP 流 → INVAL(本 API 只拆 TCP 会话)"); + "TC-NETSOCK-240b not a TCP stream -> INVAL (this API only tears down TCP sessions)"); /* 监听态但无活动会话 → 幂等 0,不动芯片 */ bring_up(); @@ -533,9 +533,9 @@ static void tc_240_drop_conn_branches(void) msg.caller = (TaskHandle_t)&g_ns_task_caller; (void)ns_rtos_q_put_raw(&msg); net_process_messages(); - CHECK(g_ns_notify_last_val == 0U, "TC-NETSOCK-240c 无活动会话 → 幂等成功 0"); + CHECK(g_ns_notify_last_val == 0U, "TC-NETSOCK-240c no active session -> idempotent success 0"); CHECK(g_chip.close_calls == 0 && g_fxchip.rst_begin_calls == 0, - "TC-NETSOCK-240d 幂等分支不得拆芯片(会把在听的监听毁掉)"); + "TC-NETSOCK-240d the idempotent branch must not tear down the chip (it would destroy the live listener)"); /* ESTABLISHED + 监听型 → QUARANTINE 拆除 + 登记重建 */ bring_up(); @@ -549,18 +549,18 @@ static void tc_240_drop_conn_branches(void) net_process_messages(); CHECK(g_peers.pending_settle_calls == 1 && g_peers.send_cancel_calls == 1, - "TC-NETSOCK-240e 拆会话前先结束两张表的挂起(必通知)"); + "TC-NETSOCK-240e both pending tables are ended before dropping the session (with notification)"); CHECK(g_fxchip.rst_begin_calls == 1, - "TC-NETSOCK-240f 拆除走 sock_reset 确定性排渣(不是 close+盲等)"); + "TC-NETSOCK-240f teardown uses sock_reset deterministic draining, not close plus blind waiting"); CHECK(g_peers.listener_req_calls == 1 && g_peers.last_req_reason == (int)NET_LISTENER_REQ_DROP, - "TC-NETSOCK-240g 监听型 fd 拆完登记 REQ_DROP(重建交监听层,本层不自己 open)"); + "TC-NETSOCK-240g listener-type fd registers REQ_DROP after the drop (rebuild belongs to the listener layer)"); CHECK(s_net_socks[fd].state == NET_SOCK_STATE_CLOSED && s_net_socks[fd].in_use == 1U && s_net_socks[fd].local_port == 2404U && s_net_socks[fd].auto_relisten == 1U, - "TC-NETSOCK-240h 只收口会话簿记:fd 保留、监听属性与端口都留下"); + "TC-NETSOCK-240h only session bookkeeping is closed out: fd, listener attribute and port all survive"); CHECK(g_fxchip.glob_calls == 0, - "TC-NETSOCK-240i 拆除路径也只碰本 Socket(F-NET-7:不读全局)"); + "TC-NETSOCK-240i teardown only touches its own socket (F-NET-7: never reads the global register)"); reset_all(); } @@ -577,17 +577,17 @@ static void tc_250_put_fail_busy(void) rc = net_send(fd, "abc", 3, 0); CHECK(rc == -1 && net_get_errno() == NET_ERR_BUSY, - "TC-NETSOCK-250a 队列满 → net_send 报 BUSY(不是静默丢弃)"); + "TC-NETSOCK-250a queue full -> net_send reports BUSY, it does not silently drop"); CHECK(g_chip.write_calls == 0 && g_ns_notify_calls == 0, - "TC-NETSOCK-250b 入队失败时零芯片事务、零通知(调用方不会误等回执)"); + "TC-NETSOCK-250b on enqueue failure: zero chip transactions and zero notifications (caller will not wait in vain)"); CHECK(net_listen(fd) == -1 && net_get_errno() == NET_ERR_BUSY, - "TC-NETSOCK-250c 同一形态对 net_listen 成立"); + "TC-NETSOCK-250c the same shape holds for net_listen"); CHECK(net_close(fd) == -1 && net_get_errno() == NET_ERR_BUSY, - "TC-NETSOCK-250d 同一形态对 net_close 成立"); + "TC-NETSOCK-250d the same shape holds for net_close"); CHECK(net_drop_conn(fd) == -1 && net_get_errno() == NET_ERR_BUSY, - "TC-NETSOCK-250e 同一形态对 net_drop_conn 成立"); + "TC-NETSOCK-250e the same shape holds for net_drop_conn"); CHECK(net_recv_to(fd, (void *)"x", 1, 5U) == -1 && net_get_errno() == NET_ERR_BUSY, - "TC-NETSOCK-250f 同一形态对 net_recv_to 成立"); + "TC-NETSOCK-250f the same shape holds for net_recv_to"); reset_all(); } diff --git a/test/host/net_socket/ns_s4_state.c b/test/host/net_socket/ns_s4_state.c index 6ebe7890..2ba1efb4 100644 --- a/test/host/net_socket/ns_s4_state.c +++ b/test/host/net_socket/ns_s4_state.c @@ -31,24 +31,24 @@ static void tc_300_poll_gates(void) /* 1) 未初始化:直接 0,连引脚都不该读 */ reset_all(); g_ns_pump = net_process_messages; - CHECK(net_poll() == 0, "TC-NETSOCK-300a 未初始化 → 0 事件"); + CHECK(net_poll() == 0, "TC-NETSOCK-300a uninitialized -> 0 events"); CHECK(g_ns_poll_calls == 0U && g_fxchip.glob_calls == 0, - "TC-NETSOCK-300b 未初始化不得读 INT# 引脚、不得读全局中断(省 SPI)"); + "TC-NETSOCK-300b uninitialized must not read the INT# pin nor the global interrupt register (saves SPI)"); /* 2) 初始化了但 INT# 为高(无中断待处理):不读全局寄存器 */ bring_up(); g_ns_int_pin_set = 1; - CHECK(net_poll() == 0, "TC-NETSOCK-300c INT# 高 → 0 事件"); + CHECK(net_poll() == 0, "TC-NETSOCK-300c INT# high -> 0 events"); CHECK(g_fxchip.glob_calls == 0, - "TC-NETSOCK-300d INT# 高时不得发全局中断读取(引脚轮询就是为省这一步)"); + "TC-NETSOCK-300d with INT# high no global interrupt read may be issued (pin polling exists to save that step)"); /* 3) INT# 低但全局状态为 0:读了全局一次,且不进 Socket 循环 */ bring_up(); g_ns_int_pin_set = 0; ch395f_fake_push_glob(0U); - CHECK(net_poll() == 0, "TC-NETSOCK-300e 全局位全 0 → 0 事件"); + CHECK(net_poll() == 0, "TC-NETSOCK-300e all global bits clear -> 0 events"); CHECK(g_fxchip.glob_calls == 1 && g_chip.int_status_calls == 0, - "TC-NETSOCK-300f 全局只读一次,读到 0 立即收手(不逐个 Socket 扫)"); + "TC-NETSOCK-300f global register read exactly once and it stops on 0 (no per-socket sweep)"); reset_all(); } @@ -63,7 +63,7 @@ static void tc_301_poll_only_gated_sockets(void) a = mk_established(NET_SOCK_STREAM); b = mk_established(NET_SOCK_STREAM); (void)mk_established(NET_SOCK_STREAM); - CHECK(a == 0 && b == 1, "TC-NETSOCK-301a 前置:三个在用 fd"); + CHECK(a == 0 && b == 1, "TC-NETSOCK-301a precondition: three fds in use"); prime_sint_masks(); g_ns_int_pin_set = 0; @@ -73,15 +73,15 @@ static void tc_301_poll_only_gated_sockets(void) CHECK(g_fake.int_status[0] == (uint8_t)(0x01U << 0) && g_fake.int_status[2] == (uint8_t)(0x01U << 2), - "TC-NETSOCK-301b 未点亮的 Socket 0/2 挂起位图没被清(读即清=读过,没读=还在)"); - CHECK(g_fake.int_status[1] == 0U, "TC-NETSOCK-301c 点亮的 Socket 1 被读走(位图清零)"); - CHECK(g_chip.int_status_calls == 1, "TC-NETSOCK-301d 整轮只发了一次 SINT 读取"); + "TC-NETSOCK-301b pending bitmaps of unlit sockets 0/2 stay uncleared (read-clear means read, still there means not read)"); + CHECK(g_fake.int_status[1] == 0U, "TC-NETSOCK-301c the lit socket 1 got read (bitmap cleared)"); + CHECK(g_chip.int_status_calls == 1, "TC-NETSOCK-301d the whole round issued exactly one SINT read"); /* 缓存刷新环是另一回事:它对所有在用 fd 都要刷(单一事实源 I1) */ CHECK(g_fxchip.rst_poll_calls == 3, - "TC-NETSOCK-301e 每轮对全部 3 个在用 fd 步进 sock_reset(IDLE 槽零 SPI)"); + "TC-NETSOCK-301e every round steps sock_reset for all 3 in-use fds (IDLE slots cost zero SPI)"); (void)net_poll(); CHECK(g_fxchip.rst_poll_calls == 6, - "TC-NETSOCK-301f 再一轮再加 3 次:刷新环不受全局位门控(事件面与状态面分离)"); + "TC-NETSOCK-301f another round adds 3 more: the refresh loop is not gated by global bits (events vs state split)"); reset_all(); /* 高位字节:Socket 4~7 的全局位在 bit8~bit11 */ @@ -94,7 +94,7 @@ static void tc_301_poll_only_gated_sockets(void) ch395f_fake_push_glob((uint16_t)(1U << (4 + 4))); (void)net_poll(); CHECK(g_fake.int_status[4] == 0U && g_fake.int_status[3] == (uint8_t)(0x01U << 3), - "TC-NETSOCK-301g Socket4~7 用高位字节 bit(n+4)=bit8..11 定位(算错就永远收不到 4~7 的事件)"); + "TC-NETSOCK-301g sockets 4-7 are located in the high byte bit(n+4)=bit8..11 (a wrong shift never sees their events)"); reset_all(); } @@ -121,33 +121,33 @@ static void tc_302_poll_event_dispatch(void) ch395f_fake_push_glob((uint16_t)(1U << (fd + 4))); n = net_poll(); - CHECK(n == expect, "TC-NETSOCK-302a 事件计数按位型区分(SENBUF_FREE 是状态位不是事件)"); + CHECK(n == expect, "TC-NETSOCK-302a event counting distinguishes bit kinds (SENBUF_FREE is a state bit, not an event)"); switch (bits[k]) { case CH395F_SINT_STAT_CONNECT: - CHECK(g_peers.evt_connect_calls == 1, "TC-NETSOCK-302b CONNECT → handle_connect_event"); + CHECK(g_peers.evt_connect_calls == 1, "TC-NETSOCK-302b CONNECT -> handle_connect_event"); break; case CH395F_SINT_STAT_DISCONNECT: - CHECK(g_peers.evt_disconnect_calls == 1, "TC-NETSOCK-302c DISCONNECT → handle_disconnect_event"); + CHECK(g_peers.evt_disconnect_calls == 1, "TC-NETSOCK-302c DISCONNECT -> handle_disconnect_event"); break; case CH395F_SINT_STAT_RECV_OK: CHECK(g_peers.evt_recv_calls == 1 && s_net_socks[fd].readable == 1U, - "TC-NETSOCK-302d RECV_OK → handle_recv_event 置 readable 电平"); + "TC-NETSOCK-302d RECV_OK -> handle_recv_event sets the readable level"); break; case CH395F_SINT_STAT_SEND_OK: - CHECK(g_peers.evt_send_calls == 1, "TC-NETSOCK-302e SEND_OK → handle_send_event"); + CHECK(g_peers.evt_send_calls == 1, "TC-NETSOCK-302e SEND_OK -> handle_send_event"); break; case CH395F_SINT_STAT_SOCK_TIMEOUT: - CHECK(g_peers.evt_timeout_calls == 1, "TC-NETSOCK-302f TIMEOUT → handle_timeout_event"); + CHECK(g_peers.evt_timeout_calls == 1, "TC-NETSOCK-302f TIMEOUT -> handle_timeout_event"); break; default: CHECK(s_net_socks[fd].send_ready == 1U && g_peers.evt_send_calls == 0, - "TC-NETSOCK-302g SENBUF_FREE 只置 send_ready(不发事件、不误当 SEND_OK)"); + "TC-NETSOCK-302g SENBUF_FREE only sets send_ready (no event, never mistaken for SEND_OK)"); break; } CHECK(g_peers.evt_connect_calls + g_peers.evt_disconnect_calls + g_peers.evt_recv_calls + g_peers.evt_send_calls + g_peers.evt_timeout_calls <= 1, - "TC-NETSOCK-302h 一位进来只敲一个 handler(不串味)"); + "TC-NETSOCK-302h one incoming bit drives exactly one handler (no cross-talk)"); } /* 同一次 SINT 里多个位 → 多个 handler 都被叫到,事件数叠加 */ @@ -157,9 +157,9 @@ static void tc_302_poll_event_dispatch(void) g_ns_int_pin_set = 0; g_fake.int_status[fd] = (uint8_t)(CH395F_SINT_STAT_RECV_OK | CH395F_SINT_STAT_DISCONNECT); ch395f_fake_push_glob((uint16_t)(1U << (fd + 4))); - CHECK(net_poll() == 2, "TC-NETSOCK-302i 同批多事件位:各计一次(不吞后到的那位)"); + CHECK(net_poll() == 2, "TC-NETSOCK-302i multiple event bits in one batch: each counted (the later bit is not swallowed)"); CHECK(g_peers.evt_recv_calls == 1 && g_peers.evt_disconnect_calls == 1, - "TC-NETSOCK-302j 两位各归各的 handler"); + "TC-NETSOCK-302j two bits each reach their own handler"); reset_all(); } @@ -172,7 +172,7 @@ static void tc_303_phy_feed(void) ch395f_fake_push_glob(CH395F_GINT_STAT_PHY_CHANGE); (void)net_poll(); CHECK(g_fake.link_up == 0U && g_fake.link_change == 1U, - "TC-NETSOCK-303 PHY_CHANGE → 驱动重读 PHY 并计一次链路变更(拔网线不再静默)"); + "TC-NETSOCK-303 PHY_CHANGE -> driver re-reads PHY and counts one link change (cable pull is no longer silent)"); reset_all(); } @@ -183,34 +183,34 @@ static void tc_310_listener_armed(void) reset_all(); CHECK(net_listener_armed(-1) == 0 && net_listener_armed(NET_MAX_SOCKETS) == 0, - "TC-NETSOCK-310a 越界 fd → 0(纯 RAM 读,不发 RPC)"); - CHECK(net_listener_armed(0) == 0, "TC-NETSOCK-310b 未分配的 fd → 0"); + "TC-NETSOCK-310a out of range fd -> 0 (pure RAM read, no RPC)"); + CHECK(net_listener_armed(0) == 0, "TC-NETSOCK-310b unallocated fd -> 0"); bring_up(); fd = mk_established(NET_SOCK_STREAM); CHECK(net_listener_armed(fd) == 1, - "TC-NETSOCK-310c ESTABLISHED(待 accept 电平)必须放行:i104 台架实证不放行则会话整场饿死"); + "TC-NETSOCK-310c ESTABLISHED (pending-accept level) must pass: i104 bench proved starvation without it"); s_net_socks[fd].state = NET_SOCK_STATE_LISTENING; CHECK(net_listener_armed(fd) == 1, - "TC-NETSOCK-310d LISTENING 放行:补 accept 探针在 net_accept_locked 内部,挡住永远到不了"); + "TC-NETSOCK-310d LISTENING must pass: the missed-accept probe lives inside net_accept_locked, blocking it never runs"); s_net_socks[fd].state = NET_SOCK_STATE_CLOSED; s_net_socks[fd].auto_relisten = 1U; s_net_socks[fd].local_port = 7003U; s_net_socks[fd].readable = 1U; CHECK(net_listener_armed(fd) == 1, - "TC-NETSOCK-310e CLOSED+auto_relisten+有残留数据 → 放行(保住 closed-with-readable 接受)"); + "TC-NETSOCK-310e CLOSED plus auto_relisten plus leftover data -> pass (keeps closed-with-readable accept alive)"); s_net_socks[fd].readable = 0U; CHECK(net_listener_armed(fd) == 0, - "TC-NETSOCK-310f CLOSED 但无残留 → 必须挡下(否则整个 CLOSED 窗每轮发 RPC → 喂不上狗)"); + "TC-NETSOCK-310f CLOSED with no leftover must be blocked (else every round in that window sends an RPC and the watchdog starves)"); s_net_socks[fd].readable = 1U; s_net_socks[fd].auto_relisten = 0U; - CHECK(net_listener_armed(fd) == 0, "TC-NETSOCK-310g 非监听型 fd 的 CLOSED 不放行"); + CHECK(net_listener_armed(fd) == 0, "TC-NETSOCK-310g CLOSED on a non-listener fd does not pass"); s_net_socks[fd].auto_relisten = 1U; s_net_socks[fd].local_port = 0U; - CHECK(net_listener_armed(fd) == 0, "TC-NETSOCK-310h 还没绑端口的半成品监听不放行"); + CHECK(net_listener_armed(fd) == 0, "TC-NETSOCK-310h a half-built listener without a bound port does not pass"); s_net_socks[fd].state = NET_SOCK_STATE_CONNECTING; - CHECK(net_listener_armed(fd) == 0, "TC-NETSOCK-310i CONNECTING 不是监听态 → 0"); + CHECK(net_listener_armed(fd) == 0, "TC-NETSOCK-310i CONNECTING is not a listening state -> 0"); reset_all(); } @@ -221,17 +221,17 @@ static void tc_311_can_read(void) reset_all(); CHECK(net_can_read(0) == 1, - "TC-NETSOCK-311a 描述符失效 → 1:让 recv 去报 BADF,别把连接不存在藏住"); + "TC-NETSOCK-311a dead descriptor -> 1: let recv report BADF instead of hiding a missing connection"); bring_up(); fd = mk_established(NET_SOCK_STREAM); s_net_socks[fd].readable = 0U; - CHECK(net_can_read(fd) == 0, "TC-NETSOCK-311b ESTABLISHED 且无可读 → 0"); + CHECK(net_can_read(fd) == 0, "TC-NETSOCK-311b ESTABLISHED with nothing readable -> 0"); s_net_socks[fd].readable = 1U; - CHECK(net_can_read(fd) == 1, "TC-NETSOCK-311c readable 置位 → 1"); + CHECK(net_can_read(fd) == 1, "TC-NETSOCK-311c readable set -> 1"); s_net_socks[fd].state = NET_SOCK_STATE_CLOSED; s_net_socks[fd].readable = 0U; CHECK(net_can_read(fd) == 1, - "TC-NETSOCK-311d 连接已非 ESTABLISHED → 必须放行一次 recv 取回 EOF/错误"); + "TC-NETSOCK-311d connection no longer ESTABLISHED -> recv must pass once to fetch EOF or the error"); reset_all(); } @@ -244,23 +244,23 @@ static void tc_320_close_two_paths(void) bring_up(); fd = mk_established(NET_SOCK_STREAM); g_fake.cached_open[fd] = CH395F_SOCKET_CLOSED; - CHECK(net_close(fd) == 0, "TC-NETSOCK-320a close 成功(快路径)"); + CHECK(net_close(fd) == 0, "TC-NETSOCK-320a close succeeds (fast path)"); CHECK(g_fxchip.cmd_done_calls >= 1 && g_fxchip.rst_begin_calls == 0, - "TC-NETSOCK-320b 已 CLOSED → 跳过复位(省掉 100~600ms 的无占用)"); + "TC-NETSOCK-320b already CLOSED -> reset skipped (saves a pointless 100-600ms occupation)"); CHECK(g_fxchip.sock_events_calls >= 1, - "TC-NETSOCK-320c 快路径仍要清本 Socket 残留事件(防下一连接误判刚建立就断开)"); - CHECK(g_fxchip.glob_calls == 0, "TC-NETSOCK-320d 全程零全局读取(F-NET-7)"); + "TC-NETSOCK-320c the fast path still clears this socket leftover events (else the next connection sees a false immediate drop)"); + CHECK(g_fxchip.glob_calls == 0, "TC-NETSOCK-320d zero global reads throughout (F-NET-7)"); reset_all(); /* 慢路径:芯片还 OPEN → 走 sock_reset,且必须是 GRACEFUL */ bring_up(); fd = mk_established(NET_SOCK_STREAM); g_fake.cached_open[fd] = CH395F_SOCKET_OPEN; - CHECK(net_close(fd) == 0, "TC-NETSOCK-320e close 成功(慢路径)"); + CHECK(net_close(fd) == 0, "TC-NETSOCK-320e close succeeds (slow path)"); CHECK(g_fxchip.rst_begin_calls == 1 && g_fx.rst_mode[fd] == 0U, - "TC-NETSOCK-320f 慢路径用 GRACEFUL(正常释放 100ms 底),不是 QUARANTINE"); + "TC-NETSOCK-320f slow path uses GRACEFUL (100ms floor for a normal release), not QUARANTINE"); CHECK(g_fx.rst_state[fd] == (uint8_t)CH395F_FAKE_RST_IDLE, - "TC-NETSOCK-320g 复位机收口回 IDLE(槽位可复用,不搁浅)"); + "TC-NETSOCK-320g the reset machine ends back at IDLE (slot reusable, never stranded)"); reset_all(); /* 复位启动被拒(槽位已在运行)→ close 仍放行,只留痕 */ @@ -268,9 +268,9 @@ static void tc_320_close_two_paths(void) fd = mk_established(NET_SOCK_STREAM); g_fake.cached_open[fd] = CH395F_SOCKET_OPEN; g_fx.rst_state[fd] = (uint8_t)CH395F_FAKE_RST_DRAINED; - CHECK(net_close(fd) == 0, "TC-NETSOCK-320h 复位启动失败也放行 close(不卡调用方)"); + CHECK(net_close(fd) == 0, "TC-NETSOCK-320h close still succeeds when starting the reset fails (do not block the caller)"); CHECK(g_fxchip.rst_begin_reject == 1 && g_ns_error_count >= 1, - "TC-NETSOCK-320i 复位没成必须 [ERR] 留痕,交 reconciler/pump 对账接管"); + "TC-NETSOCK-320i a failed reset must leave an [ERR] line for the reconciler/pump to take over"); reset_all(); } @@ -286,19 +286,19 @@ static void tc_321_drop_conn_settle(void) s_net_socks[fd].lost_conn_seen = 3U; g_fake.cached_open[fd] = CH395F_SOCKET_OPEN; - CHECK(net_drop_conn(fd) == 0, "TC-NETSOCK-321a drop_conn 成功"); + CHECK(net_drop_conn(fd) == 0, "TC-NETSOCK-321a drop_conn succeeds"); CHECK(g_fxchip.rst_begin_calls == 1 && g_fx.rst_mode[fd] == 1U, - "TC-NETSOCK-321b 拆会话用 QUARANTINE 400ms 底(TRAP-NET-18 异常释放,与 close 分级)"); + "TC-NETSOCK-321b session drop uses QUARANTINE with a 400ms floor (TRAP-NET-18 abnormal release, graded against close)"); CHECK(s_net_socks[fd].lost_conn_seen == 0U, - "TC-NETSOCK-321c 新会话起点:事件未收到去抖计数清零(N-30)"); + "TC-NETSOCK-321c new session start: the missed-event debounce counter is cleared (N-30)"); CHECK(s_net_socks[fd].local_port == 2404U && s_net_socks[fd].auto_relisten == 1U && s_net_socks[fd].in_use == 1U, - "TC-NETSOCK-321d 端口/监听属性/fd 全部保留:这就是拆连接不拆监听"); + "TC-NETSOCK-321d port, listener attribute and fd all survive: this is drop-the-connection-not-the-listener"); CHECK(g_peers.listener_req_calls == 1 && g_peers.last_req_reason == (int)NET_LISTENER_REQ_DROP, - "TC-NETSOCK-321e 登记 REQ_DROP,重建动作在 net_listener_tick 一处"); + "TC-NETSOCK-321e registers REQ_DROP; the rebuild action lives only in net_listener_tick"); CHECK(s_net_socks[fd].readable == 0U && s_net_socks[fd].state == NET_SOCK_STATE_CLOSED, - "TC-NETSOCK-321f 收口会话簿记:清 readable + 转 CLOSED"); + "TC-NETSOCK-321f session bookkeeping closes out: clear readable and move to CLOSED"); reset_all(); } @@ -317,18 +317,18 @@ static void tc_322_close_before_chip(void) g_ns_pump = NULL; /* 本场景不靠泵,直接看登记结果 */ CHECK(net_recv_sock(&s_net_socks[fd], rxbuf, (int)sizeof(rxbuf), 0) == NET_PENDING_REGISTERED, - "TC-NETSOCK-322p 前置:阻塞 recv 登记了挂起(返回哨兵)"); + "TC-NETSOCK-322p precondition: blocking recv registered a pending request (returns the sentinel)"); ch395f_fake_clear_log(); settle_at = g_peers.pending_settle_calls; close_at = g_chip.close_calls; - CHECK(net_close_sock(&s_net_socks[fd]) == 0, "TC-NETSOCK-322a netTask 直调 close 成功"); + CHECK(net_close_sock(&s_net_socks[fd]) == 0, "TC-NETSOCK-322a netTask-direct close succeeds"); CHECK(g_peers.pending_settle_calls == settle_at + 1, - "TC-NETSOCK-322b close 必先结算本 fd 的挂起 recv"); + "TC-NETSOCK-322b close must first settle this fd pending recv"); CHECK(g_chip.close_calls > close_at || g_fxchip.rst_close_calls > 0, - "TC-NETSOCK-322c 结算之后芯片侧才收到 CLOSE"); + "TC-NETSOCK-322c the chip only sees CLOSE after the settlement"); CHECK(g_peers.pending_notified == 1, - "TC-NETSOCK-322d 结算必通知(取消也要通知,不是静默清槽 → 否则等待方永久悬挂)"); + "TC-NETSOCK-322d settlement always notifies (cancel notifies too, else the waiter hangs forever)"); reset_all(); } diff --git a/test/host/net_socket/ns_s5_io.c b/test/host/net_socket/ns_s5_io.c index fb02382d..8b51b029 100644 --- a/test/host/net_socket/ns_s5_io.c +++ b/test/host/net_socket/ns_s5_io.c @@ -34,80 +34,80 @@ static void tc_400_net_init_downlink(void) reset_all(); g_fx.exist_rc = (int)CH395F_STATUS_NOT_DETECTED; CHECK(net_init("192.168.1.100", "255.255.255.0", "192.168.1.1", NULL) == -1, - "TC-NETSOCK-400a 芯片不在位 → -1"); + "TC-NETSOCK-400a chip not present -> -1"); CHECK(g_fxchip.reset_calls == 0 && g_fxchip.init_calls == 0, - "TC-NETSOCK-400b 不在位就不再复位/初始化(别把错误拖到协议栈里)"); - CHECK(g_ns_error_count == 1, "TC-NETSOCK-400c 芯片不在位必留 [ERR](否则只剩端口不通的现象)"); + "TC-NETSOCK-400b when absent it must not reset or initialise (do not drag the error into the stack)"); + CHECK(g_ns_error_count == 1, "TC-NETSOCK-400c an absent chip must leave an [ERR] line (else only a dead port is left to observe)"); /* 2) 协议栈初始化失败 */ reset_all(); g_fx.init_rc = (int)CH395F_STATUS_ERROR; CHECK(net_init("192.168.1.100", "255.255.255.0", "192.168.1.1", NULL) == -1, - "TC-NETSOCK-400d ch395f_init 失败 → -1"); - CHECK(g_fxchip.ping_calls == 0, "TC-NETSOCK-400e 初始化失败后不得继续使能 PING(半配置状态)"); + "TC-NETSOCK-400d ch395f_init failure -> -1"); + CHECK(g_fxchip.ping_calls == 0, "TC-NETSOCK-400e after an init failure PING must not be enabled (half-configured state)"); /* 3) 版本门控:低于 0x46 必须**拒置** bit3(SOCKET_CLOSE),退回芯片自动关断 */ reset_all(); g_fx.version = 0x45U; CHECK(net_init("192.168.1.100", "255.255.255.0", "192.168.1.1", NULL) == 0, - "TC-NETSOCK-400f 版本不足不是致命错:继续起来"); + "TC-NETSOCK-400f a too-old version is not fatal: bring-up continues"); CHECK(g_fx.fun_para == 0U && g_ns_error_count == 1, - "TC-NETSOCK-400g ver<0x46 → FUN_PARA 实发 0(bit3 拒置)+ [ERR] 留痕,不静默带病运行"); + "TC-NETSOCK-400g ver<0x46 -> FUN_PARA actually sends 0 (bit3 refused) plus [ERR], never silently degraded"); /* 4) 版本够新:FUN_PARA=0x08;bit1(TCP_SERVER 多连接) 与 bit0(保留) 都必须为 0 */ reset_all(); CHECK(net_init("192.168.1.100", "255.255.255.0", "192.168.1.1", NULL) == 0, - "TC-NETSOCK-400h 正常初始化成功"); + "TC-NETSOCK-400h normal initialisation succeeds"); /* bit3=SOCKET_CLOSE 要置;bit1=TCP_SERVER 多连接(本项目单连接模型)与 * bit0=保留位都必须为 0——旧实现把 0x09 当「多 Socket 模式」下发,2026-10-11 * 定案为 0x08(bit0 是保留位,证据链 TRAP-NET-15)。所以掩码要考 bit0|bit1, * 拿 0x09 考会把我们正想要的 bit3 一起算进去(第一版就这么写错了)。 */ CHECK(g_fx.fun_para == CH395F_FUN_PARA_SOCKET_CLOSE && (g_fx.fun_para & 0x03UL) == 0UL, - "TC-NETSOCK-400i FUN_PARA 只置 bit3,bit0/bit1 为 0(0x09 是历史误值,TRAP-NET-15)"); + "TC-NETSOCK-400i FUN_PARA sets bit3 only, bit0/bit1 are 0 (0x09 was a historical mistake, TRAP-NET-15)"); CHECK(g_fx.mss == (uint16_t)CH395F_TCP_MSS && g_fx.retrans_cnt == 8U && g_fx.retrans_period == 200U, - "TC-NETSOCK-400j MSS/重传参数取 net_config.h 真值(8 次 / 200ms,P0-a)"); + "TC-NETSOCK-400j MSS and retransmit parameters come from net_config.h truth (8 tries / 200ms, P0-a)"); CHECK(g_fx.ka_idle == 60000U && g_fx.ka_intvl == 5000U && g_fx.ka_cnt == 3U, - "TC-NETSOCK-400k KeepAlive 60s/5s/3(且必须在 ch395f_init 之前下发)"); - CHECK(g_fx.mss != 0U || g_fx.ka_idle != 0U ? 1 : 0, "TC-NETSOCK-400k2 参数确有下发"); + "TC-NETSOCK-400k KeepAlive 60s/5s/3 and it must be issued before ch395f_init"); + CHECK(g_fx.mss != 0U || g_fx.ka_idle != 0U ? 1 : 0, "TC-NETSOCK-400k2 parameters really were issued"); CHECK(g_chip.log_n == 0 || ch395f_fake_log_find('n') > ch395f_fake_log_find('Q'), - "TC-NETSOCK-400l MSS/KeepAlive 等 SET 类命令排在 INIT_CH395 之前(手册硬约束)"); + "TC-NETSOCK-400l SET-class commands (MSS/KeepAlive) come before INIT_CH395 (manual hard requirement)"); /* 5) IP/掩码/网关三样都按点分顺位下发,并缓存本机 IP 供 getsockname 用 */ CHECK(g_fx.ip[0] == 192U && g_fx.ip[1] == 168U && g_fx.ip[2] == 1U && g_fx.ip[3] == 100U && g_fx.gw[3] == 1U && g_fx.mask[0] == 255U, - "TC-NETSOCK-400m IP/网关/掩码按 parse_ip_string 顺位下发(段 0 在 [0])"); + "TC-NETSOCK-400m IP, gateway and mask follow the parse_ip_string order (segment 0 lands at [0])"); CHECK(g_fxchip.set_dhcp_calls == 0 && g_fx.dhcp_enable == 0U, - "TC-NETSOCK-400n 指定了静态 IP 就绝不使能 DHCP"); + "TC-NETSOCK-400n with a static IP given, DHCP is never enabled"); /* 6) ip=NULL → 走 DHCP,不下发静态三样 */ reset_all(); (void)net_init(NULL, NULL, NULL, NULL); CHECK(g_fxchip.set_dhcp_calls == 1 && g_fx.dhcp_enable == 1U, - "TC-NETSOCK-400o ip=NULL → 使能 DHCP"); + "TC-NETSOCK-400o ip=NULL -> enables DHCP"); CHECK(g_fxchip.set_ip_calls == 0 && g_fxchip.set_gw_calls == 0 && - g_fxchip.set_mask_calls == 0, "TC-NETSOCK-400p DHCP 形态不下发静态地址"); + g_fxchip.set_mask_calls == 0, "TC-NETSOCK-400p the DHCP form issues no static address at all"); /* 7) MAC:全零=用芯片内置,不下发;非零必须下发(写 EEPROM,须在 INIT 之前) */ reset_all(); (void)net_init("192.168.1.100", "255.255.255.0", "192.168.1.1", mac_zero); - CHECK(g_fxchip.set_mac_calls == 0, "TC-NETSOCK-400q MAC 全零 → 保持芯片内置,不下发"); + CHECK(g_fxchip.set_mac_calls == 0, "TC-NETSOCK-400q all-zero MAC -> keep the chip built-in one, do not issue it"); reset_all(); (void)net_init("192.168.1.100", "255.255.255.0", "192.168.1.1", mac_real); CHECK(g_fxchip.set_mac_calls == 1 && g_fx.mac[0] == 0x02U && g_fx.mac[5] == 0x55U, - "TC-NETSOCK-400r 非零 MAC 下发(设备在线身份与 UI 显示一致)"); + "TC-NETSOCK-400r a non-zero MAC is issued (device online identity stays consistent with the UI)"); CHECK(ch395f_fake_log_find('M') < ch395f_fake_log_find('n') || ch395f_fake_log_find('M') < 0, - "TC-NETSOCK-400s SET_MAC 排在 INIT_CH395 **之前**(TRAP-NET-19:顺序反了本次上电不生效)"); + "TC-NETSOCK-400s SET_MAC comes BEFORE INIT_CH395 (TRAP-NET-19: reversed order does not take effect this power cycle)"); /* 8) 收发缓冲块布局:6 块/Socket,先配数据 Socket 再配监听 Socket 0(TRAP-NET-01) */ reset_all(); (void)net_init("192.168.1.100", "255.255.255.0", "192.168.1.1", NULL); CHECK(g_fxchip.set_recv_buf_calls == NET_MAX_SOCKETS && g_fxchip.set_send_buf_calls == NET_MAX_SOCKETS, - "TC-NETSOCK-400t 8 个 Socket 全部显式重分配(上电默认只给 0~3)"); + "TC-NETSOCK-400t all 8 sockets are explicitly reallocated (power-on defaults only cover 0-3)"); for (i = 0; i < NET_MAX_SOCKETS; i++) { if (g_fx.recv_blk_start[i] != (uint8_t)(i * 6) || g_fx.recv_blk_cnt[i] != (uint8_t)CH395F_RECV_BLOCKS || @@ -117,20 +117,20 @@ static void tc_400_net_init_downlink(void) } } CHECK(i == NET_MAX_SOCKETS, - "TC-NETSOCK-400u 块布局 recv=i*6 / send=recv+4,Socket7 恰好用尽 0~47(手册 §5.45)"); - CHECK(g_fx.ping_enable == 1U && g_fxchip.ping_calls == 1, "TC-NETSOCK-400v 使能 PING 响应"); + "TC-NETSOCK-400u layout recv=i*6 / send=recv+4, socket 7 uses exactly blocks 0..47 (manual 5.45)"); + CHECK(g_fx.ping_enable == 1U && g_fxchip.ping_calls == 1, "TC-NETSOCK-400v PING response enabled"); /* 9) net_init 的第一件事是取消挂起并通知调用方(顺序错了 = 调用方永久挂死) */ reset_all(); (void)net_init("192.168.1.100", "255.255.255.0", "192.168.1.1", NULL); CHECK(g_peers.pending_cancel_all_calls == 1 && g_peers.send_cancel_all_calls == 1, - "TC-NETSOCK-400w 重建前两张挂起表都要取消(recv/send 各一张,漏一张就有人永远等)"); + "TC-NETSOCK-400w both pending tables are cancelled before a rebuild (recv and send each one, missing one strands a task)"); CHECK(g_peers.last_pend_cancel_err == NET_ERR_CONNRESET && g_peers.last_snd_cancel_err == NET_ERR_CONNRESET, - "TC-NETSOCK-400x 取消原因 = CONNRESET"); + "TC-NETSOCK-400x cancellation reason = CONNRESET"); CHECK(g_peers.pending_capture_calls == 1, - "TC-NETSOCK-400y 登记执行任务(挂起登记的自等死锁守卫据此判「谁在执行」)"); + "TC-NETSOCK-400y registers the executing task (the pending self-wait guard judges who is executing from it)"); reset_all(); } @@ -144,32 +144,32 @@ static void tc_410_listen_locked(void) bring_up(); fd = net_socket(NET_AF_INET, NET_SOCK_DGRAM); CHECK(net_listen_locked(fd) == -1 && net_get_errno() == NET_ERR_INVAL, - "TC-NETSOCK-410a UDP 不能 listen"); + "TC-NETSOCK-410a UDP cannot listen"); /* 状态不对(还没 bind 也没到 CREATED)→ INVAL */ bring_up(); fd = mk_established(NET_SOCK_STREAM); CHECK(net_listen_locked(fd) == -1 && net_get_errno() == NET_ERR_INVAL, - "TC-NETSOCK-410b 已建立的 fd 再 listen → INVAL(不许把数据通道打回监听)"); + "TC-NETSOCK-410b listening again on an established fd -> INVAL (never demote a data channel to a listener)"); /* 成功路径:BOUND → LISTENING,并启用 auto_relisten */ bring_up(); fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); (void)memset(&in, 0, sizeof(in)); in.sin_port = net_htons(2404); - CHECK(net_bind(fd, (struct net_sockaddr *)&in, (int)sizeof(in)) == 0, "TC-NETSOCK-410c bind 前置"); + CHECK(net_bind(fd, (struct net_sockaddr *)&in, (int)sizeof(in)) == 0, "TC-NETSOCK-410c bind precondition"); ch395f_fake_clear_log(); - CHECK(net_listen_locked(fd) == 0, "TC-NETSOCK-410d listen 成功"); + CHECK(net_listen_locked(fd) == 0, "TC-NETSOCK-410d listen succeeds"); CHECK(s_net_socks[fd].state == NET_SOCK_STATE_LISTENING && s_net_socks[fd].auto_relisten == 1U && s_net_socks[fd].lost_conn_seen == 0U, - "TC-NETSOCK-410e 进 LISTENING + auto_relisten=1(BSD 监听常驻)+ 去抖计数清零"); + "TC-NETSOCK-410e enters LISTENING with auto_relisten=1 (BSD listener stays resident) and debounce cleared"); CHECK(g_chip.set_port_calls == 1 && g_chip.last_port == 2404U, - "TC-NETSOCK-410f 源端口取控制块的 local_port(端口不能漂)"); + "TC-NETSOCK-410f source port comes from the control block local_port (the port must not drift)"); CHECK(ch395f_fake_log_find('i') >= 0 && ch395f_fake_log_find('i') < ch395f_fake_log_find('l'), - "TC-NETSOCK-410g 清本 Socket 事件排在 TCP_LISTEN **之前**(E14:反了会吞掉新 CONNECT)"); + "TC-NETSOCK-410g clearing this socket events comes BEFORE TCP_LISTEN (E14: reversed swallows the new CONNECT)"); CHECK(g_fxchip.glob_calls == 0, - "TC-NETSOCK-410h listen 全程不得读全局中断寄存器(B3 审计掉的正是这个)"); + "TC-NETSOCK-410h listen must never read the global interrupt register (exactly what the B3 audit removed)"); /* open 一直失败:重试 3 次,每次都走确定性排渣,最后 BUSY */ reset_all(); @@ -177,10 +177,10 @@ static void tc_410_listen_locked(void) fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); g_fake.open_rc[fd] = CH395F_ERR_USE; CHECK(net_listen_locked(fd) == -1 && net_get_errno() == NET_ERR_BUSY, - "TC-NETSOCK-410i open 三次仍失败 → BUSY"); + "TC-NETSOCK-410i open still failing after 3 tries -> BUSY"); CHECK(g_chip.open_calls == 3 && g_fxchip.rst_begin_calls == 3, - "TC-NETSOCK-410j 三次 open + 三次 sock_reset(TRAP-NET-09 的重试语义保留,不是盲等 500ms)"); - CHECK(g_chip.listen_calls == 0, "TC-NETSOCK-410k open 没成绝不发 LISTEN 命令"); + "TC-NETSOCK-410j three opens plus three sock_reset (TRAP-NET-09 retry semantics kept, not a blind 500ms wait)"); + CHECK(g_chip.listen_calls == 0, "TC-NETSOCK-410k with no successful open, never issue the LISTEN command"); /* LISTEN 命令失败:open 已成的 Socket 必须关回去(U12 对称,否则卡 OPEN 无监听) */ reset_all(); @@ -188,11 +188,11 @@ static void tc_410_listen_locked(void) fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); g_fake.listen_rc[fd] = CH395F_ERR_VAL; CHECK(net_listen_locked(fd) == -1 && net_get_errno() == NET_ERR_BUSY, - "TC-NETSOCK-410l TCP_LISTEN 失败 → BUSY"); + "TC-NETSOCK-410l TCP_LISTEN failure -> BUSY"); CHECK(g_chip.close_calls == 1 && g_chip.open_calls == 1, - "TC-NETSOCK-410m LISTEN 失败必须 close 已开的 Socket(否则下次 open 恒返 USE)"); + "TC-NETSOCK-410m a failed LISTEN must close the opened socket (else every later open returns USE)"); CHECK(s_net_socks[fd].state != NET_SOCK_STATE_LISTENING, - "TC-NETSOCK-410n 失败不得谎报 LISTENING"); + "TC-NETSOCK-410n failure must not falsely report LISTENING"); reset_all(); } @@ -203,24 +203,24 @@ static void tc_411_listen_public(void) int fd; bring_up(); - CHECK(net_listen(-1) == -1 && net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-411a 越界 → BADF"); + CHECK(net_listen(-1) == -1 && net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-411a out of range -> BADF"); CHECK(net_listen(NET_MAX_SOCKETS) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-411b 上界越界 → BADF"); + "TC-NETSOCK-411b upper bound out of range -> BADF"); fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); (void)memset(&in, 0, sizeof(in)); in.sin_port = net_htons(7003); CHECK(net_bind(fd, (struct net_sockaddr *)&in, (int)sizeof(in)) == 0, "TC-NETSOCK-411c bind"); g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; - CHECK(net_listen(fd) == 0, "TC-NETSOCK-411d 端到端 listen 成功(入队→分派→通知值 0)"); + CHECK(net_listen(fd) == 0, "TC-NETSOCK-411d end-to-end listen succeeds (enqueue, dispatch, notify value 0)"); CHECK(s_net_socks[fd].state == NET_SOCK_STATE_LISTENING, - "TC-NETSOCK-411e 公开入口确实驱动了芯片侧监听"); + "TC-NETSOCK-411e the public entry really drove the chip-side listener"); CHECK(g_ns_notify_last_val == 0U, - "TC-NETSOCK-411f 成功的 listen 通知值=0(哨兵 0x70000000 不许漏进来)"); + "TC-NETSOCK-411f a successful listen notify value is 0 (the 0x70000000 sentinel must not leak)"); /* 已监听的 fd 再 listen:netTask 里 INVAL,经通知值回传 */ CHECK(net_listen(fd) == -1 && net_get_errno() == NET_ERR_INVAL, - "TC-NETSOCK-411g 重复 listen → -1 且 errno=INVAL(精确码,不是笼统 -1)"); + "TC-NETSOCK-411g listening twice -> -1 with errno INVAL (exact code, not a generic -1)"); reset_all(); } @@ -238,12 +238,12 @@ static void tc_420_accept_shapes(void) addrlen = (int)sizeof(in); (void)memset(&in, 0, sizeof(in)); g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; - CHECK(net_accept(fd, sa, &addrlen) == fd, "TC-NETSOCK-420a 单连接:accept 返回监听 fd 自身"); + CHECK(net_accept(fd, sa, &addrlen) == fd, "TC-NETSOCK-420a single connection: accept returns the listening fd itself"); CHECK(in.sin_family == NET_AF_INET && net_ntohs(in.sin_port) == 51999U && addrlen == (int)sizeof(in), - "TC-NETSOCK-420b 回填对端地址与长度(lftpd 打印「谁连进来」就靠这个)"); + "TC-NETSOCK-420b fills the peer address and length (lftpd prints who connected from this)"); CHECK(g_peers.lost_probe_calls == 0, - "TC-NETSOCK-420c 非 LISTENING 不触发补 accept 探针(探针是监听态专用自救)"); + "TC-NETSOCK-420c non-LISTENING never calls the missed-accept probe (the probe is listener-only self-rescue)"); /* 2) LISTENING 且探针命中 → 接受(CONNECT 事件未收到的自愈路径) */ reset_all(); @@ -255,9 +255,9 @@ static void tc_420_accept_shapes(void) g_peers.lost_probe_hit = 1; addrlen = 0; CHECK(net_accept(fd, NULL, NULL) == fd, - "TC-NETSOCK-420d 探针把监听转 ESTABLISHED → accept 立即成功(N-30 主根因修复)"); + "TC-NETSOCK-420d the probe moved the listener to ESTABLISHED -> accept succeeds at once (N-30 root fix)"); CHECK(g_peers.lost_probe_calls == 1, - "TC-NETSOCK-420e LISTENING 才调探针(每轮 accept 一次,带去抖计数)"); + "TC-NETSOCK-420e only LISTENING calls the probe (once per accept round, with debounce)"); /* 3) LISTENING 且无连接 → WOULDBLOCK,且不动监听重建 */ reset_all(); @@ -266,9 +266,9 @@ static void tc_420_accept_shapes(void) s_net_socks[fd].state = NET_SOCK_STATE_LISTENING; addrlen = (int)sizeof(in); CHECK(net_accept(fd, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_WOULDBLOCK, - "TC-NETSOCK-420f 无连接 → WOULDBLOCK(不阻塞 netTask)"); + "TC-NETSOCK-420f no connection -> WOULDBLOCK (never blocks netTask)"); CHECK(g_peers.listener_req_calls == 0, - "TC-NETSOCK-420g 监听还活着时绝不登记重建(那是 U12 事故的形态)"); + "TC-NETSOCK-420g while the listener is alive, never register a rebuild (that is the U12 accident shape)"); /* 4) CLOSED + auto_relisten + RX 有残留 → 接受"已关但可读",先排空再 EOF */ reset_all(); @@ -281,11 +281,11 @@ static void tc_420_accept_shapes(void) ch395f_fake_push_recv_len((uint8_t)fd, 1027U); addrlen = (int)sizeof(in); CHECK(net_accept(fd, sa, &addrlen) == fd, - "TC-NETSOCK-420h closed-with-readable:接受这条连接去排空(N-30 定案,反了就是 425)"); + "TC-NETSOCK-420h closed-with-readable: accept this connection to drain it (N-30, reversed yields 425)"); CHECK(g_peers.listener_req_calls == 0, - "TC-NETSOCK-420i 有残留数据时**不**登记重建(先 relisten 会把已到达的数据销毁)"); + "TC-NETSOCK-420i with leftover data present, do NOT register a rebuild (relisting first destroys arrived data)"); CHECK(g_chip.get_status_calls == 0, - "TC-NETSOCK-420j 排空判据只读 GET_RECV_LEN,不发状态查询"); + "TC-NETSOCK-420j the drain decision only reads GET_RECV_LEN, no status query"); /* 5) CLOSED + auto_relisten + RX 空 → 登记 REQ_ACCEPT 并 WOULDBLOCK */ reset_all(); @@ -295,13 +295,13 @@ static void tc_420_accept_shapes(void) s_net_socks[fd].auto_relisten = 1U; s_net_socks[fd].local_port = 21U; CHECK(net_accept(fd, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_WOULDBLOCK, - "TC-NETSOCK-420k CLOSED 且无残留 → WOULDBLOCK"); + "TC-NETSOCK-420k CLOSED with no leftover -> WOULDBLOCK"); CHECK(g_peers.listener_req_calls == 1 && g_peers.last_req_reason == (int)NET_LISTENER_REQ_ACCEPT && g_peers.last_req_fd == fd, - "TC-NETSOCK-420l 消费者撞空才登记即时重建(N-32 P2:删掉它会拉长 CLOSED 窗)"); + "TC-NETSOCK-420l only a consumer hitting empty registers an immediate rebuild (N-32 P2: removing it widens the CLOSED window)"); CHECK(g_chip.open_calls == 0 && g_chip.listen_calls == 0, - "TC-NETSOCK-420m 登记路径零芯片事务(重建动作只在 net_listener_tick 一处)"); + "TC-NETSOCK-420m the registration path costs zero chip transactions (rebuild lives only in net_listener_tick)"); /* 6) 非监听型 CLOSED(客户端)→ 不擅自登记 */ reset_all(); @@ -310,7 +310,7 @@ static void tc_420_accept_shapes(void) s_net_socks[fd].state = NET_SOCK_STATE_CLOSED; s_net_socks[fd].auto_relisten = 0U; CHECK(net_accept(fd, sa, &addrlen) == -1 && g_peers.listener_req_calls == 0, - "TC-NETSOCK-420n 客户端 fd 的 CLOSED 不登记监听重建"); + "TC-NETSOCK-420n CLOSED on a client fd registers no listener rebuild"); reset_all(); } @@ -324,14 +324,14 @@ static void tc_421_accept_public(void) bring_up(); CHECK(net_accept(-1, sa, &addrlen) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-421a 越界 → BADF"); + "TC-NETSOCK-421a out of range -> BADF"); fd = mk_established(NET_SOCK_STREAM); addrlen = 0; CHECK(net_accept(fd, sa, NULL) == fd, - "TC-NETSOCK-421b addrlen 为 NULL 仍可 accept(addr 回填被跳过,不崩)"); + "TC-NETSOCK-421b accept still works with addrlen NULL (address fill skipped, no crash)"); addrlen = (int)sizeof(in); CHECK(net_accept(fd, NULL, &addrlen) == fd, - "TC-NETSOCK-421c addr 为 NULL:只要 fd,不回填地址"); + "TC-NETSOCK-421c addr NULL: returns just the fd and fills no address"); reset_all(); } @@ -343,13 +343,13 @@ static void tc_430_connect(void) bring_up(); CHECK(net_connect(-1, NULL, 0) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-430a 越界 → BADF"); + "TC-NETSOCK-430a out of range -> BADF"); fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); CHECK(net_connect(fd, NULL, (int)sizeof(in)) == -1 && net_get_errno() == NET_ERR_INVAL, - "TC-NETSOCK-430b addr=NULL → INVAL(入队之前就把参数挡下)"); + "TC-NETSOCK-430b addr=NULL -> INVAL (arguments blocked before enqueue)"); CHECK(net_connect(fd, (struct net_sockaddr *)&in, 1) == -1 && - net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-430c addrlen 不足 → INVAL"); - CHECK(ns_rtos_q_count() == 0, "TC-NETSOCK-430d 参数非法不产生消息(不占 netTask)"); + net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-430c addrlen too small -> INVAL"); + CHECK(ns_rtos_q_count() == 0, "TC-NETSOCK-430d invalid arguments create no message (netTask is not occupied)"); /* 成功:地址簿记 + 大端顺位 + 状态 CONNECTING */ reset_all(); @@ -361,21 +361,21 @@ static void tc_430_connect(void) in.sin_addr.s_addr = net_inet_addr("192.168.1.200"); g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; CHECK(net_connect(fd, (struct net_sockaddr *)&in, (int)sizeof(in)) == 0, - "TC-NETSOCK-430e connect 命令下发成功(异步,成败由中断裁定)"); + "TC-NETSOCK-430e connect command issued (asynchronous, the interrupt decides success)"); CHECK(s_net_socks[fd].state == NET_SOCK_STATE_CONNECTING, - "TC-NETSOCK-430f 本地状态转 CONNECTING"); + "TC-NETSOCK-430f local state moves to CONNECTING"); CHECK(s_net_socks[fd].remote_port == 8888U, - "TC-NETSOCK-430g 对端端口转主机序存簿记"); + "TC-NETSOCK-430g peer port stored in bookkeeping as host order"); CHECK(g_fx.des_ip[fd][0] == 192U && g_fx.des_ip[fd][1] == 168U && g_fx.des_ip[fd][2] == 1U && g_fx.des_ip[fd][3] == 200U, - "TC-NETSOCK-430h 目的 IP 按大端数组下发(set_des_ip 要的顺位,反了就连不上)"); + "TC-NETSOCK-430h destination IP issued as a big-endian array (the order set_des_ip needs, reversed means no link)"); CHECK(g_chip.set_port_calls == 1 && g_fx.des_port[fd] == 8888U, - "TC-NETSOCK-430i 源端口下发一次(SET_SOUR_PORT),目的端口另走 SET_DES_PORT=8888"); + "TC-NETSOCK-430i source port issued once (SET_SOUR_PORT), the peer port goes via SET_DES_PORT=8888"); CHECK(g_fxchip.sock_events_calls == 1 && g_fxchip.glob_calls == 0, - "TC-NETSOCK-430j 清残留中断只清本 Socket(F-NET-7:原「再读清全局」会焊死别人)"); + "TC-NETSOCK-430j clearing stale interrupts only clears this socket (F-NET-7: the old extra global read welded others shut)"); CHECK(ch395f_fake_log_find('v') < ch395f_fake_log_find('T') || ch395f_fake_log_find('v') < 0, - "TC-NETSOCK-430k 清事件排在 TCP_CONNECT 之前(TRAP-NET-12/-18 的两级预清)"); + "TC-NETSOCK-430k clearing events precedes TCP_CONNECT (the two-stage pre-clear of TRAP-NET-12/-18)"); /* 命令级被拒(非 BUSY):必须回滚,不能停在 CONNECTING 干等 */ reset_all(); @@ -383,13 +383,13 @@ static void tc_430_connect(void) fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); g_fx.connect_rc[fd] = CH395F_ERR_VAL; CHECK(net_connect(fd, (struct net_sockaddr *)&in, (int)sizeof(in)) == -1 && - net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-430l 芯片拒命令 → -1"); + net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-430l chip refused the command -> -1"); CHECK(g_chip.close_calls == 1, - "TC-NETSOCK-430m 被拒要按手册「再次连接需从 OPEN 重开」关掉 Socket"); + "TC-NETSOCK-430m after a refusal the manual requires reopening from OPEN, so the socket is closed"); CHECK(s_net_socks[fd].session_dead == 1U && s_net_socks[fd].state == NET_SOCK_STATE_CLOSED, - "TC-NETSOCK-430n 命令级失败同样是本会话结束:置 session_dead+CLOSED(B2:否则挂起 recv 干等)"); - CHECK(g_ns_error_count >= 1, "TC-NETSOCK-430o 被拒必留 [ERR]"); + "TC-NETSOCK-430n a command-level failure also ends the session: sets session_dead and CLOSED (B2, else pending recv waits forever)"); + CHECK(g_ns_error_count >= 1, "TC-NETSOCK-430o a refusal must leave an [ERR] line"); /* BUSY 只是命令仍在执行,不得判失败 */ reset_all(); @@ -397,9 +397,9 @@ static void tc_430_connect(void) fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); g_fx.connect_rc[fd] = CH395F_ERR_BUSY; CHECK(net_connect(fd, (struct net_sockaddr *)&in, (int)sizeof(in)) == 0, - "TC-NETSOCK-430p BUSY=芯片还在执行 → 维持原行为交给中断裁定(慢芯片不该被误杀)"); + "TC-NETSOCK-430p BUSY means the chip is still executing -> keep the old behaviour and let the interrupt decide (do not kill a slow chip)"); CHECK(s_net_socks[fd].state == NET_SOCK_STATE_CONNECTING && g_chip.close_calls == 0, - "TC-NETSOCK-430q BUSY 不回滚、不关 Socket"); + "TC-NETSOCK-430q BUSY neither rolls back nor closes the socket"); /* open 三次失败 → BUSY,且不发 CONNECT */ reset_all(); @@ -407,21 +407,21 @@ static void tc_430_connect(void) fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); g_fake.open_rc[fd] = CH395F_ERR_USE; CHECK(net_connect(fd, (struct net_sockaddr *)&in, (int)sizeof(in)) == -1 && - net_get_errno() == NET_ERR_BUSY, "TC-NETSOCK-430r open 三次失败 → BUSY"); + net_get_errno() == NET_ERR_BUSY, "TC-NETSOCK-430r open failing 3 times -> BUSY"); CHECK(g_chip.open_calls == 3 && g_fxchip.connect_calls == 0, - "TC-NETSOCK-430s open 没成不发 TCP_CONNECT"); + "TC-NETSOCK-430s with no successful open, never issue TCP_CONNECT"); /* 非 TCP 流 / 未在用 → INVAL(netTask 侧再判一次) */ reset_all(); bring_up(); fd = net_socket(NET_AF_INET, NET_SOCK_DGRAM); CHECK(net_connect_locked(fd, (const struct net_sockaddr *)&in, (int)sizeof(in)) == -1 && - net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-430t UDP 槽位不走 TCP connect"); + net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-430t a UDP slot never takes the TCP connect path"); CHECK(net_connect_locked(7, (const struct net_sockaddr *)&in, (int)sizeof(in)) == -1 && net_get_errno() == NET_ERR_INVAL, - "TC-NETSOCK-430u 范围内但未在用 → INVAL(in_use 与控制块一起考;BADF 只考越界)"); + "TC-NETSOCK-430u in range but not in use -> INVAL (in_use is checked with the control block; BADF is only for range)"); CHECK(net_connect_locked(NET_MAX_SOCKETS, (const struct net_sockaddr *)&in, - (int)sizeof(in)) == -1, "TC-NETSOCK-430v 越界 → BADF"); + (int)sizeof(in)) == -1, "TC-NETSOCK-430v out of range -> BADF"); reset_all(); } @@ -437,17 +437,17 @@ static void tc_440_udp_datagram(void) bring_up_netctx(); CHECK(net_sendto(-1, "x", 1, 0, NULL, 0) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-440a sendto 越界 → BADF"); + "TC-NETSOCK-440a sendto out of range -> BADF"); CHECK(net_sendto(0, "x", 1, 0, NULL, 0) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-440b 未在用 → BADF"); + "TC-NETSOCK-440b not in use -> BADF"); CHECK(net_recvfrom(0, buf, sizeof(buf), 0, NULL, NULL) == -1 && - net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-440c recvfrom 未在用 → BADF"); + net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-440c recvfrom on an unused fd -> BADF"); fd = net_socket(NET_AF_INET, NET_SOCK_DGRAM); CHECK(net_sendto(fd, NULL, 5, 0, NULL, 0) == -1 && net_get_errno() == NET_ERR_INVAL, - "TC-NETSOCK-440d sendto 参数非法 → INVAL"); + "TC-NETSOCK-440d sendto invalid arguments -> INVAL"); CHECK(net_recvfrom(fd, NULL, 5, NET_MSG_DONTWAIT, NULL, NULL) == -1 && - net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-440e recvfrom buf 为空 → INVAL"); + net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-440e recvfrom with a NULL buf -> INVAL"); /* 带目的地址:先设 DesIP/DesPort 再写数据(不带上限的自旋实现,健康链路一次写完) */ reset_all(); @@ -457,11 +457,11 @@ static void tc_440_udp_datagram(void) in.sin_port = net_htons(8888); in.sin_addr.s_addr = net_inet_addr("192.168.1.9"); CHECK(net_sendto(fd, "hello", 5, 0, sa, (int)sizeof(in)) == 5, - "TC-NETSOCK-440f sendto 成功返回字节数"); + "TC-NETSOCK-440f sendto returns the number of bytes sent"); CHECK(g_fx.des_ip[fd][3] == 9U && g_fx.des_port[fd] == 8888U, - "TC-NETSOCK-440g 目的地址随本次发送下发(UDP 无连接,地址是每包带的)"); + "TC-NETSOCK-440g the destination address travels with this send (UDP is connectionless, address is per packet)"); CHECK(g_chip.write_calls == 1 && s_net_socks[fd].send_bytes == 5U, - "TC-NETSOCK-440h 小包一次写完 + 统计"); + "TC-NETSOCK-440h small packet written in one go plus statistics"); /* 大报分块(仍受 NET_SEND_CHUNK_MAX 上界约束) */ reset_all(); @@ -470,8 +470,8 @@ static void tc_440_udp_datagram(void) g_ns_int_pin_set = 0; ch395f_fake_push_glob((uint16_t)(1U << (fd + 4))); ch395f_fake_set_sint_sticky((uint8_t)fd, CH395F_SINT_STAT_SENBUF_FREE); - CHECK(net_sendto(fd, big, 2100, 0, NULL, 0) == 2100, "TC-NETSOCK-440i 2100B 全部交付"); - CHECK(g_chip.write_calls == 3, "TC-NETSOCK-440j UDP 也按 1024 上界分块(写穿 FIFO 的约束同 TCP)"); + CHECK(net_sendto(fd, big, 2100, 0, NULL, 0) == 2100, "TC-NETSOCK-440i all 2100 bytes delivered"); + CHECK(g_chip.write_calls == 3, "TC-NETSOCK-440j UDP also chunks at the 1024 bound (the FIFO overrun constraint matches TCP)"); /* recvfrom:前 8 字节是芯片 UDP 头(长度/srcPort/srcIP),要剥掉再交出去 */ reset_all(); @@ -481,26 +481,26 @@ static void tc_440_udp_datagram(void) addrlen = (int)sizeof(in); (void)memset(&in, 0, sizeof(in)); CHECK(net_recvfrom(fd, buf, (int)sizeof(buf), 0, sa, &addrlen) == 20, - "TC-NETSOCK-440k 返回 20:报文头 8 字节被剥掉,不把头部当数据交给应用"); + "TC-NETSOCK-440k returns 20: the 8-byte report header was stripped, the header is not handed over as data"); CHECK(addrlen == (int)sizeof(in) && in.sin_family == NET_AF_INET, - "TC-NETSOCK-440l 回填源地址结构与长度"); + "TC-NETSOCK-440l fills the source address structure and length"); /* 无数据 + 非阻塞 → WOULDBLOCK(阻塞形态是自旋无预算,本套刻意不测,见交付说明) */ reset_all(); bring_up_netctx(); fd = net_socket(NET_AF_INET, NET_SOCK_DGRAM); CHECK(net_recvfrom(fd, buf, (int)sizeof(buf), NET_MSG_DONTWAIT, NULL, NULL) == -1 && - net_get_errno() == NET_ERR_WOULDBLOCK, "TC-NETSOCK-440m 非阻塞无数据 → WOULDBLOCK"); + net_get_errno() == NET_ERR_WOULDBLOCK, "TC-NETSOCK-440m non-blocking with no data -> WOULDBLOCK"); s_net_socks[fd].blocking = 0U; CHECK(net_recvfrom(fd, buf, (int)sizeof(buf), 0, NULL, NULL) == -1 && - net_get_errno() == NET_ERR_WOULDBLOCK, "TC-NETSOCK-440n 非阻塞属性同判据生效"); + net_get_errno() == NET_ERR_WOULDBLOCK, "TC-NETSOCK-440n the non-blocking attribute follows the same decision"); /* 短于 8 字节的残包:不剥头,整包交出去(钉当前实现的边界,不猜"应该怎么算") */ reset_all(); bring_up_netctx(); fd = net_socket(NET_AF_INET, NET_SOCK_DGRAM); ch395f_fake_push_recv_len((uint8_t)fd, 5U); CHECK(net_recvfrom(fd, buf, (int)sizeof(buf), 0, NULL, NULL) == 5, - "TC-NETSOCK-440o recv_len<8 时不剥头,整包返回(当前实现)"); + "TC-NETSOCK-440o with recv_len<8 no header is stripped, the whole packet is returned (current implementation)"); reset_all(); } @@ -509,11 +509,11 @@ static void tc_450_direct_entries(void) { bring_up(); CHECK(net_send_sock(NULL, "x", 1) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-450a net_send_sock(NULL) → BADF"); + "TC-NETSOCK-450a net_send_sock(NULL) -> BADF"); CHECK(net_recv_sock(NULL, (void *)"x", 1, 0) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-450b net_recv_sock(NULL) → BADF"); + "TC-NETSOCK-450b net_recv_sock(NULL) -> BADF"); CHECK(net_close_sock(NULL) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-450c net_close_sock(NULL) → BADF"); + "TC-NETSOCK-450c net_close_sock(NULL) -> BADF"); /* netTask 内直调 send:挂起登记会被"执行者自等待"守卫拒 → 返回 -1(BUSY) */ reset_all(); @@ -525,9 +525,9 @@ static void tc_450_direct_entries(void) g_ns_cur_task = (TaskHandle_t)&g_ns_task_net; g_peers.send_register_rc = -1; /* 复刻守卫:netTask 自己发的必被拒 */ CHECK(net_send_sock(&s_net_socks[fd], "hello", 5) == -1, - "TC-NETSOCK-450d netTask 内等不到缓冲时不登记挂起(没人能替它完成)→ -1"); + "TC-NETSOCK-450d inside netTask a stalled buffer never registers pending (nobody can complete it) -> -1"); CHECK(g_peers.send_reg_calls == 1, - "TC-NETSOCK-450e 确实走到了登记调用(被拒的是登记侧,不是本层没试)"); + "TC-NETSOCK-450e the registration call really happened (the refusal came from the register side, not from us not trying)"); } reset_all(); } @@ -545,13 +545,13 @@ static void tc_460_reset_sync_timeout_bound(void) t_before = g_ns_tick; CHECK(net_close(fd) == 0, - "TC-NETSOCK-460a 芯片关不掉也照样放行 close(fd 侧簿记必须继续收口)"); + "TC-NETSOCK-460a even when the chip cannot be closed, close proceeds (fd-side bookkeeping must still close out)"); CHECK((g_ns_tick - t_before) <= 700U, - "TC-NETSOCK-460b 复位等待有 600ms 硬上限(无上限=netTask 被一颗坏芯片拖死)"); + "TC-NETSOCK-460b the reset wait has a hard 600ms ceiling (without one a bad chip drags netTask down)"); CHECK(g_ns_error_count >= 1, - "TC-NETSOCK-460c 复位超时必 [ERR]:这条 [ERR] 是唯一能发现它的信号"); + "TC-NETSOCK-460c a reset timeout must leave [ERR]: that line is the only way to ever notice it"); CHECK(s_net_socks[fd].in_use == 0U, - "TC-NETSOCK-460d 超时也照常释放槽位(不因芯片状态卡住本地 fd 表)"); + "TC-NETSOCK-460d the slot is released even on timeout (a chip state must not jam the local fd table)"); reset_all(); /* drop_conn 同一条超时线 */ @@ -563,7 +563,7 @@ static void tc_460_reset_sync_timeout_bound(void) t_before = g_ns_tick; CHECK(net_drop_conn(fd) == 0 && (g_ns_tick - t_before) <= 700U && g_ns_error_count >= 1, - "TC-NETSOCK-460e drop_conn 也走同一条有界收口并留痕"); + "TC-NETSOCK-460e drop_conn takes the same bounded close-out and logs it too"); reset_all(); } @@ -586,11 +586,11 @@ static void tc_470_send_disconnect_midway(void) rc = net_send(fd, big, 2100, 0); CHECK(rc >= 0 && rc < 2100, - "TC-NETSOCK-470a 断线只截断剩余量:按已发数返回(短写),不是 -1 也不是谎报 2100"); + "TC-NETSOCK-470a a mid-send disconnect only truncates: returns bytes already sent (a short write), not -1 and not a false 2100"); CHECK((int)s_net_socks[fd].send_bytes == rc, - "TC-NETSOCK-470b 字节统计与实际交付一致(对端已收到的不能回收)"); + "TC-NETSOCK-470b byte statistic matches what was actually delivered (what the peer got cannot be clawed back)"); CHECK(g_ns_error_count >= 1, - "TC-NETSOCK-470c 短写必 [ERR](静默截断曾让 UI 推流被对端误判为全程无字节)"); + "TC-NETSOCK-470c a short write must log [ERR] (a silent truncation once made the peer see zero bytes from a UI push)"); reset_all(); } diff --git a/test/host/net_socket/ns_s6_edges.c b/test/host/net_socket/ns_s6_edges.c index 4f8f86ea..81d92c72 100644 --- a/test/host/net_socket/ns_s6_edges.c +++ b/test/host/net_socket/ns_s6_edges.c @@ -23,25 +23,25 @@ static void tc_500_public_bounds(void) addrlen = (int)sizeof(in); CHECK(net_send(NET_MAX_SOCKETS, buf, 4, 0) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-500a net_send 越界 → BADF"); + "TC-NETSOCK-500a net_send out of range -> BADF"); CHECK(net_recv(NET_MAX_SOCKETS, buf, 4, NET_MSG_DONTWAIT) == -1 && - net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-500b net_recv 越界 → BADF"); + net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-500b net_recv out of range -> BADF"); CHECK(net_recv_to(NET_MAX_SOCKETS, buf, 4, 10U) == -1 && - net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-500c net_recv_to 越界 → BADF"); + net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-500c net_recv_to out of range -> BADF"); CHECK(net_close(NET_MAX_SOCKETS) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-500d net_close 越界 → BADF"); + "TC-NETSOCK-500d net_close out of range -> BADF"); CHECK(net_drop_conn(NET_MAX_SOCKETS) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-500e net_drop_conn 越界 → BADF"); + "TC-NETSOCK-500e net_drop_conn out of range -> BADF"); CHECK(net_accept(NET_MAX_SOCKETS, (struct net_sockaddr *)&in, &addrlen) == -1 && - net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-500f net_accept 越界 → BADF"); + net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-500f net_accept out of range -> BADF"); CHECK(net_connect(NET_MAX_SOCKETS, (struct net_sockaddr *)&in, (int)sizeof(in)) == -1 && - net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-500g net_connect 越界 → BADF"); + net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-500g net_connect out of range -> BADF"); CHECK(net_sendto(NET_MAX_SOCKETS, buf, 4, 0, NULL, 0) == -1 && - net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-500h net_sendto 越界 → BADF"); + net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-500h net_sendto out of range -> BADF"); CHECK(net_recvfrom(NET_MAX_SOCKETS, buf, 4, NET_MSG_DONTWAIT, NULL, NULL) == -1 && - net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-500i net_recvfrom 越界 → BADF"); + net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-500i net_recvfrom out of range -> BADF"); CHECK(g_ns_put_calls == 0, - "TC-NETSOCK-500j 全部越界形态零入队(入队之后才挡 = 让 netTask 处理一个没主的请求)"); + "TC-NETSOCK-500j every out-of-range shape enqueues nothing (blocking after the enqueue hands netTask an ownerless request)"); reset_all(); } @@ -57,21 +57,21 @@ static void tc_501_all_entries_busy_on_full_queue(void) ns_rtos_q_fill((int)NS_Q_CAP); CHECK(net_accept(fd, NULL, NULL) == -1 && net_get_errno() == NET_ERR_BUSY, - "TC-NETSOCK-501a net_accept 队满 → BUSY"); + "TC-NETSOCK-501a net_accept on a full queue -> BUSY"); ns_rtos_q_fill((int)NS_Q_CAP); (void)memset(&in, 0, sizeof(in)); CHECK(net_connect(fd, (struct net_sockaddr *)&in, (int)sizeof(in)) == -1 && - net_get_errno() == NET_ERR_BUSY, "TC-NETSOCK-501b net_connect 队满 → BUSY"); + net_get_errno() == NET_ERR_BUSY, "TC-NETSOCK-501b net_connect on a full queue -> BUSY"); ns_rtos_q_fill((int)NS_Q_CAP); CHECK(net_recv_to(fd, (void *)"x", 1, 20U) == -1 && net_get_errno() == NET_ERR_BUSY, - "TC-NETSOCK-501c net_recv_to 队满 → BUSY"); + "TC-NETSOCK-501c net_recv_to on a full queue -> BUSY"); ns_rtos_q_fill((int)NS_Q_CAP); CHECK(net_recv(fd, (void *)"x", 1, NET_MSG_DONTWAIT) == -1 && - net_get_errno() == NET_ERR_BUSY, "TC-NETSOCK-501d net_recv 队满 → BUSY"); + net_get_errno() == NET_ERR_BUSY, "TC-NETSOCK-501d net_recv on a full queue -> BUSY"); ns_rtos_q_fill((int)NS_Q_CAP); CHECK(net_send(fd, "x", 1, 0) == -1 && net_get_errno() == NET_ERR_BUSY, - "TC-NETSOCK-501e net_send 队满 → BUSY"); - CHECK(g_ns_notify_calls == 0, "TC-NETSOCK-501f 队满路径零通知(调用方直接拿返回值走人)"); + "TC-NETSOCK-501e net_send on a full queue -> BUSY"); + CHECK(g_ns_notify_calls == 0, "TC-NETSOCK-501f the full-queue path sends no notification (the caller leaves with the return value)"); reset_all(); } @@ -88,12 +88,12 @@ static void tc_502_socket_table_full(void) break; } } - CHECK(i == NET_MAX_SOCKETS, "TC-NETSOCK-502a 8 个槽位全部可分配"); + CHECK(i == NET_MAX_SOCKETS, "TC-NETSOCK-502a all 8 slots are allocatable"); CHECK(net_socket(NET_AF_INET, NET_SOCK_STREAM) == -1 && - net_get_errno() == NET_ERR_NOMEM, "TC-NETSOCK-502b 第 9 个 → NOMEM(不越界写表)"); + net_get_errno() == NET_ERR_NOMEM, "TC-NETSOCK-502b the ninth -> NOMEM (no out-of-range table write)"); s_net_socks[3].state = NET_SOCK_STATE_ESTABLISHED; CHECK(net_get_sock(3) != NULL && net_listener_armed(3) == 1, - "TC-NETSOCK-502c 表满不影响已在用会话(alloc 失败只回 NOMEM,不动别人的槽位)"); + "TC-NETSOCK-502c a full table does not disturb live sessions (alloc failure only returns NOMEM)"); reset_all(); } @@ -113,10 +113,10 @@ static void tc_503_zero_wait_pickup(void) rc = net_send(fd, "abcd", 4, 0); - CHECK(rc == 4, "TC-NETSOCK-503a 零等待就拾到通知值 → 直接返回结果"); - CHECK(g_ns_block_waits == 0, "TC-NETSOCK-503b 已有通知时绝不进阻塞分支"); + CHECK(rc == 4, "TC-NETSOCK-503a the zero-wait peek takes the notify value -> returns the result immediately"); + CHECK(g_ns_block_waits == 0, "TC-NETSOCK-503b with a notification already pending it never enters the blocking branch"); CHECK(g_peers.send_reg_calls == 0 && g_chip.write_calls == 0, - "TC-NETSOCK-503c 本次调用没有真的写芯片(拾到的是上一条消息的回执——这就是 实测踩过的形态)"); + "TC-NETSOCK-503c this call never touched the chip (the value peeked was the previous receipt, a shape we already hit in practice)"); reset_all(); } @@ -133,16 +133,16 @@ static void tc_504_locked_entry_branches(void) fd = net_socket(NET_AF_INET, NET_SOCK_STREAM); CHECK(net_connect_locked(fd, NULL, (int)sizeof(in)) == -1 && - net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-504a connect_locked addr=NULL → INVAL"); + net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-504a connect_locked with addr=NULL -> INVAL"); CHECK(net_connect_locked(fd, (const struct net_sockaddr *)&in, 1) == -1 && - net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-504b connect_locked addrlen 不足 → INVAL"); + net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-504b connect_locked with a short addrlen -> INVAL"); s_net_socks[fd].in_use = 1U; CHECK(net_send_locked(&s_net_socks[fd], "x", 1, NULL) == -1 && - net_get_errno() == NET_ERR_NOTCONN, "TC-NETSOCK-504c 未建立的直调 send → NOTCONN"); + net_get_errno() == NET_ERR_NOTCONN, "TC-NETSOCK-504c direct send on a not-established block -> NOTCONN"); CHECK(net_recv_locked(&s_net_socks[fd], (void *)"x", 1, NET_MSG_DONTWAIT, 0U, NULL) == -1 && - net_get_errno() == NET_ERR_WOULDBLOCK, "TC-NETSOCK-504d 直调 recv 无数据非阻塞 → WOULDBLOCK"); + net_get_errno() == NET_ERR_WOULDBLOCK, "TC-NETSOCK-504d direct recv, no data, non-blocking -> WOULDBLOCK"); CHECK(net_recv_locked(&s_net_socks[fd], NULL, 1, NET_MSG_DONTWAIT, 0U, NULL) == -1 && - net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-504e 直调 recv buf 空 → INVAL"); + net_get_errno() == NET_ERR_INVAL, "TC-NETSOCK-504e direct recv with a NULL buf -> INVAL"); reset_all(); } @@ -162,9 +162,9 @@ static void tc_505_inner_wait_and_last_chunk(void) rc = net_send_locked(&s_net_socks[fd], big, 2100, (TaskHandle_t)&g_ns_task_caller); CHECK(rc == NET_PENDING_REGISTERED, - "TC-NETSOCK-505a 内层等待(写完一块后等发完)超预算也转挂起,不留 in-place 忙等"); + "TC-NETSOCK-505a the inner wait (after writing one chunk) also converts to pending past budget, no in-place busy wait"); CHECK(g_chip.write_calls == 2 && g_peers.last_snd_sent == 2048, - "TC-NETSOCK-505b 登记的进度=已写进芯片的字节数(1024+1024=2048),已发的绝不重发"); + "TC-NETSOCK-505b registered progress = bytes written into the chip (1024+1024=2048), delivered bytes are never resent"); reset_all(); /* 末块:全部写完但芯片不回执 → 按完成返回,**不许**登记挂起 @@ -173,9 +173,9 @@ static void tc_505_inner_wait_and_last_chunk(void) fd = mk_established(NET_SOCK_STREAM); rc = net_send_locked(&s_net_socks[fd], big, 1024, (TaskHandle_t)&g_ns_task_caller); - CHECK(rc == 1024, "TC-NETSOCK-505c 单块恰好写完 → 返回 1024(完成)"); + CHECK(rc == 1024, "TC-NETSOCK-505c a single chunk finishing exactly -> returns 1024 (complete)"); CHECK(g_peers.send_reg_calls == 0, - "TC-NETSOCK-505d 末块等待不得登记挂起(sent>=len 的守卫必须挡住)"); + "TC-NETSOCK-505d the last-chunk wait must not register pending (the sent>=len guard has to hold)"); reset_all(); } @@ -195,9 +195,9 @@ static void tc_506_sendto_stall_and_short(void) g_ns_poll_tick_inc = 500U; rc = net_sendto(fd, big, 2100, 0, NULL, 0); CHECK(rc < 2100 && rc >= 0, - "TC-NETSOCK-506a sendto 停滞只拿到部分:按已发数返回(短写语义与 TCP 一致)"); + "TC-NETSOCK-506a sendto stalled returns only what went out (short-write semantics match TCP)"); CHECK(g_ns_error_count >= 2, - "TC-NETSOCK-506b 停滞 [ERR] + 短写 [ERR] 都要留(缺一就退化成静默截断)"); + "TC-NETSOCK-506b both the stall [ERR] and the short-write [ERR] must be there (missing one degrades into a silent truncation)"); reset_all(); /* 写完一块后等发完的超时出口 */ @@ -209,7 +209,7 @@ static void tc_506_sendto_stall_and_short(void) g_ns_poll_tick_inc = 500U; rc = net_sendto(fd, big, 2100, 0, NULL, 0); CHECK(rc >= 1024 && rc < 2100, - "TC-NETSOCK-506c 第一块已交付、第二块等发完超时 → 返回 1024..2099 之间的实际值"); + "TC-NETSOCK-506c first chunk delivered and the second chunk wait timed out -> a value between 1024 and 2099"); reset_all(); } @@ -231,11 +231,11 @@ static void tc_530_stall_timeout_before_spin(void) rc = net_send_locked(&s_net_socks[fd], buf, (int)sizeof(buf), (TaskHandle_t)&g_ns_task_caller); CHECK(rc == 0, - "TC-NETSOCK-530a 停滞超时按已发数 0 返回(短写形态,不是 -1)"); + "TC-NETSOCK-530a the stall timeout returns the bytes sent so far, 0 (a short write, not -1)"); CHECK(g_peers.send_reg_calls == 0, - "TC-NETSOCK-530b 停滞超时优先:不进挂起登记(判定顺序被换掉的话这里会登记)"); + "TC-NETSOCK-530b the stall timeout wins over the spin budget: no pending registration (a swapped order would register)"); CHECK(net_get_errno() == NET_ERR_TIMEDOUT, - "TC-NETSOCK-530c errno = TIMEDOUT(供调用方区分停滞与断线)"); + "TC-NETSOCK-530c errno = TIMEDOUT (lets the caller tell a stall from a disconnect)"); reset_all(); } @@ -255,10 +255,10 @@ static void tc_535_inner_timeout_after_chunk(void) rc = net_send_locked(&s_net_socks[fd], big, 2100, (TaskHandle_t)&g_ns_task_caller); - CHECK(rc == 1024, "TC-NETSOCK-535a 已交付的第一块照样交出(1024),剩余按短写处理"); + CHECK(rc == 1024, "TC-NETSOCK-535a the already delivered first chunk still counts (1024), the rest is a short write"); CHECK(g_peers.send_reg_calls == 0, - "TC-NETSOCK-535b 停滞超时收口在登记挂起**之前**(换序就会登记一条永远完不成的挂起)"); - CHECK(g_chip.write_calls == 1, "TC-NETSOCK-535c 只写了一次芯片:不得把已交付的块重发"); + "TC-NETSOCK-535b the stall timeout closes out BEFORE any pending registration (swapping the order parks a pending that never completes)"); + CHECK(g_chip.write_calls == 1, "TC-NETSOCK-535c the chip was written exactly once: a delivered chunk must never be resent"); reset_all(); } @@ -275,7 +275,7 @@ static void tc_536_recv_to_three_exits(void) ch395f_fake_push_recv_len((uint8_t)fd, 12U); g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; CHECK(net_recv_to(fd, buf, (int)sizeof(buf), 100U) == 12, - "TC-NETSOCK-536a 有数据 → 返回实际字节数(走 >=0 支)"); + "TC-NETSOCK-536a data available -> returns the actual byte count (the >=0 branch)"); /* <0 且非 TIMEDOUT:分派侧 BADF → 恢复 errno 后返回 -1 */ reset_all(); @@ -284,7 +284,7 @@ static void tc_536_recv_to_three_exits(void) g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; CHECK(net_recv_to(1, buf, (int)sizeof(buf), 100U) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-536b 真错误 → -1 且 errno 从通知值恢复(与 -2 严格区分)"); + "TC-NETSOCK-536b a real error -> -1 with errno restored from the notify value (strictly distinct from -2)"); /* ==TIMEDOUT:已在 TC-NETSOCK-224 钉过 -2;这里补一条「-2 不改写 errno」 */ reset_all(); @@ -295,7 +295,7 @@ static void tc_536_recv_to_three_exits(void) g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; CHECK(net_recv_to(fd, buf, (int)sizeof(buf), 30U) == -2 && net_get_errno() == NET_OK, - "TC-NETSOCK-536c 超时只凭返回码判定,**不改写**错误码槽(本分支刻意不设 errno)"); + "TC-NETSOCK-536c timeout is judged by the return code only and does NOT rewrite the errno slot (this branch sets none)"); reset_all(); } @@ -313,7 +313,7 @@ static void tc_537_event_callback_path(void) g_ns_int_pin_set = 0; ch395f_fake_push_glob((uint16_t)(1U << (fd + 4))); g_fake.int_status[fd] = CH395F_SINT_STAT_SEND_OK; - CHECK(net_poll() == 1, "TC-NETSOCK-537 未注册回调也照常计事件(不因空指针跳过分发)"); + CHECK(net_poll() == 1, "TC-NETSOCK-537 events are counted even with no callback registered (a null pointer never skips dispatch)"); reset_all(); } @@ -330,9 +330,9 @@ static void tc_540_negative_results(void) fd = 3; /* 范围内、未分配 */ g_ns_cur_task = (TaskHandle_t)&g_ns_task_caller; CHECK(net_close(fd) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-540a close 未分配的 fd → -1 且 errno 从通知值恢复成 BADF(不是笼统 NET_ERR)"); + "TC-NETSOCK-540a close on an unallocated fd -> -1 with errno restored to BADF from the notify value, not a generic NET_ERR"); CHECK(net_drop_conn(fd) == -1 && net_get_errno() == NET_ERR_BADF, - "TC-NETSOCK-540a2 drop_conn 同一条负值恢复支"); + "TC-NETSOCK-540a2 drop_conn takes the same negative-value restoration branch"); reset_all(); /* drop_conn 同理:用未分配 fd 走分派侧 BADF 后再由调用方恢复 */ @@ -344,7 +344,7 @@ static void tc_540_negative_results(void) (void)ns_rtos_q_put_raw(&msg); net_process_messages(); CHECK(g_ns_notify_last_val == (uint32_t)NET_ERR_BADF, - "TC-NETSOCK-540b drop_conn 分派侧 BADF 经通知值回传"); + "TC-NETSOCK-540b drop_conn BADF from the dispatch side travels back on the notify value"); /* RECV 的 BADF 支(分派侧 net_get_sock 判空) */ reset_all(); @@ -358,7 +358,7 @@ static void tc_540_negative_results(void) (void)ns_rtos_q_put_raw(&msg); net_process_messages(); CHECK(g_ns_notify_last_val == (uint32_t)NET_ERR_BADF, - "TC-NETSOCK-540c recv 分派侧 BADF 同样经通知值回传"); + "TC-NETSOCK-540c recv BADF from the dispatch side likewise travels back on the notify value"); reset_all(); } @@ -370,10 +370,10 @@ static void tc_545_local_entries_without_queue(void) reset_all(); CHECK(net_getsockname(0, (struct net_sockaddr *)&in, &addrlen) == -1 && - net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-545a 未初始化也能安全报 BADF(不崩)"); + net_get_errno() == NET_ERR_BADF, "TC-NETSOCK-545a even uninitialised it safely reports BADF (no crash)"); CHECK(net_getpeername(0, (struct net_sockaddr *)&in, &addrlen) == -1, - "TC-NETSOCK-545b getpeername 同上"); - CHECK(net_inet_addr("1.2.3.4") != 0U, "TC-NETSOCK-545c 纯函数不依赖初始化"); + "TC-NETSOCK-545b getpeername behaves the same"); + CHECK(net_inet_addr("1.2.3.4") != 0U, "TC-NETSOCK-545c pure helpers do not depend on initialisation"); reset_all(); } diff --git a/test/host/prot_set_store/prot_set_store_test.c b/test/host/prot_set_store/prot_set_store_test.c index 5996b507..fe1990bb 100644 --- a/test/host/prot_set_store/prot_set_store_test.c +++ b/test/host/prot_set_store/prot_set_store_test.c @@ -217,14 +217,14 @@ static void tc_load_triage(void) backend_reset(); g_read_rc = -1; rc = prot_set_store_load(); - CHECK(rc == 1, "TC-PROTSTOR-001 读失败归 1(按无档处理)"); + CHECK(rc == 1, "TC-PROTSTOR-001 read failure maps to 1 (treat as no file)"); backend_reset(); len = make_blob(blob, sizeof(blob)); memcpy(g_img, blob, len); stage_blob(len); rc = prot_set_store_load(); - CHECK(rc == 0, "TC-PROTSTOR-002 有效 blob 装载成功"); + CHECK(rc == 0, "TC-PROTSTOR-002 valid blob loads successfully"); /* ver 换代:magic 完好、ver 与当前固件不同 → 预期升级路径,归 2 */ backend_reset(); @@ -233,9 +233,9 @@ static void tc_load_triage(void) g_img[4] = (uint8_t)(PROT_SET_BLOB_VER + 1u); stage_blob(len); rc = prot_set_store_load(); - CHECK(rc == 2, "TC-PROTSTOR-003 ver 换代归 2(不是 -1)"); + CHECK(rc == 2, "TC-PROTSTOR-003 ver mismatch maps to 2 (not -1)"); CHECK((g_pstore_info_count == 1) && (g_pstore_error_count == 0), - "TC-PROTSTOR-004 换代只打 INFO,不误报 ERROR"); + "TC-PROTSTOR-004 version mismatch logs INFO only, no false ERROR"); /* cnt 换代:B8 定值表 32→40 项就是这个形态 */ backend_reset(); @@ -244,7 +244,7 @@ static void tc_load_triage(void) g_img[6] = (uint8_t)((uint32_t)PS_ID_COUNT + 1u); stage_blob(len); rc = prot_set_store_load(); - CHECK(rc == 2, "TC-PROTSTOR-005 cnt 换代归 2"); + CHECK(rc == 2, "TC-PROTSTOR-005 cnt mismatch maps to 2"); /* magic 坏 = 真损坏 */ backend_reset(); @@ -253,7 +253,7 @@ static void tc_load_triage(void) g_img[0] = (uint8_t)(g_img[0] ^ 0xFFu); stage_blob(len); rc = prot_set_store_load(); - CHECK((rc == -1) && (g_pstore_error_count == 0), "TC-PROTSTOR-006 magic 坏归 -1"); + CHECK((rc == -1) && (g_pstore_error_count == 0), "TC-PROTSTOR-006 broken magic maps to -1"); /* magic/ver/cnt 全好,但数据被改 → 校验不过 = 损坏 */ backend_reset(); @@ -262,7 +262,7 @@ static void tc_load_triage(void) g_img[PROT_SET_BLOB_HDR_SZ] = (uint8_t)(g_img[PROT_SET_BLOB_HDR_SZ] ^ 0x5Au); stage_blob(len); rc = prot_set_store_load(); - CHECK(rc == -1, "TC-PROTSTOR-007 数据被改(校验失败)归 -1"); + CHECK(rc == -1, "TC-PROTSTOR-007 data tampered (checksum fail) maps to -1"); /* 截断到不足头部:不得误判为换代 */ backend_reset(); @@ -270,7 +270,7 @@ static void tc_load_triage(void) memcpy(g_img, blob, len); stage_blob(PROT_SET_BLOB_HDR_SZ - 1u); rc = prot_set_store_load(); - CHECK(rc == -1, "TC-PROTSTOR-008 长度不足头部归 -1 且不误判换代"); + CHECK(rc == -1, "TC-PROTSTOR-008 length below header maps to -1 and is not misjudged as version mismatch"); backend_reset(); len = make_blob(blob, sizeof(blob)); @@ -278,7 +278,7 @@ static void tc_load_triage(void) stage_blob(len); rc = prot_set_store_load(); CHECK((rc == 0) && (g_pstore_info_count == 0), - "TC-PROTSTOR-009 成功路径不打 INFO(version change 措辞不许乱出现)"); + "TC-PROTSTOR-009 success path logs no INFO (version change wording must not appear)"); } /* ===================== 后端调用契约 ===================== */ @@ -295,9 +295,9 @@ static void tc_backend_contract(void) stage_blob(len); (void)prot_set_store_load(); CHECK(strcmp(g_read_path, "/prot_set.bin") == 0, - "TC-PROTSTOR-010 路径 = /prot_set.bin(8.3 合规)"); + "TC-PROTSTOR-010 path = /prot_set.bin (8.3 compliant)"); CHECK(g_read_cap == (size_t)PROT_SET_BLOB_SZ, - "TC-PROTSTOR-011 读取容量 = PROT_SET_BLOB_SZ(静态缓冲,不压栈)"); + "TC-PROTSTOR-011 read capacity = PROT_SET_BLOB_SZ (static buffer, not on stack)"); } /* ===================== save 与脏标志 ===================== */ @@ -311,30 +311,30 @@ static void tc_save_dirty(void) backend_reset(); dirty_clear(); rc = prot_set_store_save(); - CHECK((rc == 0) && (g_write_calls == 0), "TC-PROTSTOR-012 无脏不写盘"); + CHECK((rc == 0) && (g_write_calls == 0), "TC-PROTSTOR-012 not dirty -> no flash write"); prot_set_dirty_mark(); g_write_rc = 0; rc = prot_set_store_save(); CHECK((rc == 0) && (g_write_calls == 1) && (strcmp(g_write_path, "/prot_set.bin") == 0) && (g_write_len > 0u), - "TC-PROTSTOR-013 有脏且写成功:路径与长度正确"); + "TC-PROTSTOR-013 dirty + write ok: path and length correct"); rc = prot_set_store_save(); CHECK((rc == 0) && (g_write_calls == 1), - "TC-PROTSTOR-014 脏已消费,紧接着再调不再刷 Flash"); + "TC-PROTSTOR-014 dirty consumed, immediate second call does not flush flash again"); prot_set_dirty_mark(); g_write_rc = -1; rc = prot_set_store_save(); - CHECK((rc == -1) && (g_write_calls == 2), "TC-PROTSTOR-015 写失败返回 -1"); + CHECK((rc == -1) && (g_write_calls == 2), "TC-PROTSTOR-015 write failure returns -1"); /* 关键:失败必须把脏标志还回去,否则这一轮定值永久丢失 */ g_write_rc = 0; g_write_calls = 0; rc = prot_set_store_save(); CHECK((rc == 0) && (g_write_calls == 1), - "TC-PROTSTOR-016 上一轮写失败后下一轮仍真的再写(脏已回置)"); + "TC-PROTSTOR-016 after a failed round the next round really writes again (dirty re-armed)"); dirty_clear(); } diff --git a/test/host/sha256/sha256_test.c b/test/host/sha256/sha256_test.c index 590c43bf..d28a64bd 100644 --- a/test/host/sha256/sha256_test.c +++ b/test/host/sha256/sha256_test.c @@ -73,15 +73,15 @@ static void tc_vectors(void) sha256_calc("", 0u, d); CHECK(hex_eq_vector(d, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"), - "TC-SHA256-001 空串向量"); + "TC-SHA256-001 empty-string vector"); sha256_calc("abc", 3u, d); CHECK(hex_eq_vector(d, "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"), - "TC-SHA256-002 \"abc\" 向量"); + "TC-SHA256-002 \"abc\" vector"); sha256_calc("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56u, d); CHECK(hex_eq_vector(d, "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"), - "TC-SHA256-003 56 字节向量(补位跨分组)"); + "TC-SHA256-003 56-byte vector (padding crosses block)"); { sha256_ctx_t ctx; @@ -93,7 +93,7 @@ static void tc_vectors(void) sha256_final(&ctx, d); } CHECK(hex_eq_vector(d, "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"), - "TC-SHA256-004 1e6 × 'a' 向量(流式)"); + "TC-SHA256-004 1e6 x 'a' vector (streaming)"); } /* ===================== TC-SHA256-005:流式等价 ===================== */ @@ -111,7 +111,7 @@ static void tc_stream_equiv(void) sha256_update(&ctx, &msg[i], 1u); } sha256_final(&ctx, d2); - CHECK(memcmp(d1, d2, sizeof(d1)) == 0, "TC-SHA256-005 逐字节喂入与一次性等价"); + CHECK(memcmp(d1, d2, sizeof(d1)) == 0, "TC-SHA256-005 byte-by-byte feed equals one-shot"); } /* ===================== TC-SHA256-006..007:hex_eq ===================== */ @@ -131,11 +131,11 @@ static void tc_hex_eq(void) } upper[64] = '\0'; - CHECK(sha256_hex_eq(d, lower) == 1, "TC-SHA256-006a 小写 hex 匹配"); - CHECK(sha256_hex_eq(d, upper) == 1, "TC-SHA256-006b 大写 hex 匹配(大小写不敏感)"); + CHECK(sha256_hex_eq(d, lower) == 1, "TC-SHA256-006a lowercase hex matches"); + CHECK(sha256_hex_eq(d, upper) == 1, "TC-SHA256-006b uppercase hex matches (case-insensitive)"); lower[63] = (char)((lower[63] == '0') ? '1' : '0'); - CHECK(sha256_hex_eq(d, lower) == 0, "TC-SHA256-007a 内容不等 → 0"); + CHECK(sha256_hex_eq(d, lower) == 0, "TC-SHA256-007a content mismatch -> 0"); lower[63] = (char)((lower[63] == '0') ? '1' : '0'); /* 还原 */ { @@ -144,19 +144,19 @@ static void tc_hex_eq(void) memcpy(bad, lower, 64); bad[64] = '\0'; bad[10] = 'g'; - CHECK(sha256_hex_eq(d, bad) == 0, "TC-SHA256-007b 非法 hex 字符 → 0"); + CHECK(sha256_hex_eq(d, bad) == 0, "TC-SHA256-007b invalid hex char -> 0"); } memcpy(shortv, lower, 63); shortv[63] = '\0'; - CHECK(sha256_hex_eq(d, shortv) == 0, "TC-SHA256-007c 长度 63 → 0"); + CHECK(sha256_hex_eq(d, shortv) == 0, "TC-SHA256-007c length 63 -> 0"); memcpy(longv, lower, 64); longv[64] = 'a'; longv[65] = '\0'; - CHECK(sha256_hex_eq(d, longv) == 0, "TC-SHA256-007d 长度 65 → 0"); + CHECK(sha256_hex_eq(d, longv) == 0, "TC-SHA256-007d length 65 -> 0"); - CHECK(sha256_hex_eq(d, NULL) == 0, "TC-SHA256-007e NULL → 0"); + CHECK(sha256_hex_eq(d, NULL) == 0, "TC-SHA256-007e NULL -> 0"); } /* ===================== TC-SHA256-008:默认口令哈希钉值 ===================== */ @@ -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-SHA256-008 SHA256(\"adminadmin\") = 出厂默认 pwd_hash"); + "TC-SHA256-008 SHA256(\"adminadmin\") = factory default pwd_hash"); } /* ===================== main ===================== */ diff --git a/test/host/soe_store/soe_store_test.c b/test/host/soe_store/soe_store_test.c index 780c5714..d204d794 100644 --- a/test/host/soe_store/soe_store_test.c +++ b/test/host/soe_store/soe_store_test.c @@ -365,7 +365,7 @@ static void tc_post_side(void) uint32_t i; int ok; - printf("-- TC-SOESTORE-001..007 post 侧(零 I/O 契约)--\n"); + printf("-- TC-SOESTORE-001..007 post side (zero-IO contract) --\n"); /* 001:post 3 条只写环,绝不碰盘、绝不碰卷锁、绝不打日志 */ reset_all(); @@ -379,7 +379,7 @@ static void tc_post_side(void) } } CHECK(ok && (s_lock_waits == 0) && (g_soe_err_count == 0) && (g_soe_info_count == 0), - "TC-SOESTORE-001 post 零 FatFs / 零卷锁 / 零日志(protectTask 栈预算)"); + "TC-SOESTORE-001 post does zero FatFs / zero volume lock / zero logging (protectTask stack budget)"); /* 002:墙钟未建立 -> IV + epoch 字段 0(不造假时标) */ reset_all(); @@ -389,7 +389,7 @@ static void tc_post_side(void) ok = read_rec(0u, &out); CHECK(ok && (out.flags & SOE_FLG_IV) != 0u && (out.epoch_s == 0u) && (out.cp56[2] & 0x80u) != 0u && (out.value == 0xF0u), - "TC-SOESTORE-002 无墙钟 -> flags.IV + epoch=0 + CP56 IV 位(B9 口径)"); + "TC-SOESTORE-002 no wall clock -> flags.IV + epoch=0 + CP56 IV bit (B9 rule)"); /* 003:seq 单调;丢弃的那条也占号(真机丢号 = 主机看到的号不连续是**如实**) */ reset_all(); @@ -397,7 +397,7 @@ static void tc_post_side(void) soe_store_post((uint8_t)SOE_T_ELM_ASSERT, (uint8_t)i, i); } ok = (s_seq == 9u) && (s_drop_cnt == 1u); - CHECK(ok, "TC-SOESTORE-003 seq 单调递增,丢弃也占号(号不跳才是假象)"); + CHECK(ok, "TC-SOESTORE-003 seq increases monotonically, dropped entries still consume a number"); /* 004:环满丢弃不阻塞、不崩、**不打日志**(留痕归 drain 侧) */ reset_all(); @@ -406,7 +406,7 @@ static void tc_post_side(void) } CHECK((s_ring_head == 8u) && (s_drop_cnt == 1u) && (g_soe_err_count == 0) && (g_soe_info_count == 0), - "TC-SOESTORE-004 环满丢弃:只计数,post 侧零 DBG(栈尾链 +320B 教训)"); + "TC-SOESTORE-004 ring-full drop: count only, zero DBG on post side (lesson: +320B tail chain)"); /* 005:内核运行 + 队列已建 -> 走队列,环不再写 */ reset_all(); @@ -417,7 +417,7 @@ static void tc_post_side(void) s_ring_tail = 0u; soe_store_post((uint8_t)SOE_T_ELM_RETURN, 1u, 2u); CHECK((s_ring_head == 0u) && (s_q_cnt == 1u) && (s_q_msgsz == SOE_REC_SIZE), - "TC-SOESTORE-005 队列已建 + 内核运行 -> 条目进队列、环不再写"); + "TC-SOESTORE-005 queue created + kernel running -> entries go to the queue, ring not written"); /* 006:队列满 -> 丢弃计数(与环满同一条可观测出口) */ reset_all(); @@ -429,14 +429,14 @@ static void tc_post_side(void) soe_store_post((uint8_t)SOE_T_ELM_ASSERT, (uint8_t)i, i); } CHECK((s_q_cnt == SOE_QUEUE_MAX) && (s_drop_cnt == 2u), - "TC-SOESTORE-006 队列满 -> 丢弃并计数(soe_store_dropped 同一出口)"); + "TC-SOESTORE-006 queue full -> drop and count through the same soe_store_dropped exit"); /* 007:计数饱和不回绕 */ reset_all(); s_drop_cnt = UINT32_MAX; soe_store_post((uint8_t)SOE_T_ELM_ASSERT, 1u, 1u); CHECK((s_drop_cnt == UINT32_MAX) && (soe_store_dropped() == UINT32_MAX), - "TC-SOESTORE-007 丢弃计数饱和:UINT32_MAX 不回绕"); + "TC-SOESTORE-007 drop counter saturates at UINT32_MAX, never wraps"); } /* ===================== TC-SOESTORE-010..021:drain 落盘与故障注入 ===================== */ @@ -449,7 +449,7 @@ static void tc_drain_paths(void) int opens_before; int writes_before; - printf("-- TC-SOESTORE-010..021 drain 落盘 / 故障注入 --\n"); + printf("-- TC-SOESTORE-010..021 drain to disk / fault injection --\n"); /* 010:首次 drain 惰性建队列 + 1 条 64B 落盘且能解析回来 */ reset_all(); @@ -459,7 +459,7 @@ static void tc_drain_paths(void) && (ff_fake_size(SOE_PATH) == SOE_REC_SIZE); CHECK(ok && read_rec(0u, &out) && (out.type == (uint8_t)SOE_T_ELM_ASSERT) && (out.elm_id == 3u) && (out.value == 0xABCDu) && (out.seq == 0u), - "TC-SOESTORE-010 惰性建队列 + 64B 定长落盘 + 记录可解回"); + "TC-SOESTORE-010 lazy queue creation + fixed 64B record on disk + record decodes back"); /* 011:打开模式必须带 FA_WRITE —— 陷阱一 */ reset_all(); @@ -478,7 +478,7 @@ static void tc_drain_paths(void) { FRESULT fr3 = f_write(&probe, payload, SOE_REC_SIZE, &bw); CHECK(ok && (fr2 == FR_OK) && (fr3 == FR_DENIED) && (bw == 0u), - "TC-SOESTORE-011 模式必为 FA_WRITE|FA_OPEN_APPEND;缺写位 f_write 恒 FR_DENIED"); + "TC-SOESTORE-011 mode must be FA_WRITE|FA_OPEN_APPEND; without the write bit f_write is FR_DENIED"); } (void)f_close(&probe); } @@ -499,14 +499,14 @@ static void tc_drain_paths(void) } } } - CHECK(ok, "TC-SOESTORE-012 逐条 open/write/close(无批量合并)+ FIFO 顺序正确"); + CHECK(ok, "TC-SOESTORE-012 per-entry open/write/close (no batch merge) + correct FIFO order"); /* 013:open/close 严格配对 */ reset_all(); soe_store_post((uint8_t)SOE_T_SAMPLE_RESUME, SOE_ELM_NONE, 0u); soe_store_drain(); CHECK(g_ff_obs.calls[FF_FAKE_OP_CLOSE] == g_ff_obs.calls[FF_FAKE_OP_OPEN], - "TC-SOESTORE-013 open/close 配对(脏句柄不跨调用残留)"); + "TC-SOESTORE-013 open/close stay paired (no stale handle left across calls)"); /* 014:短写判失败 -> unlink 重建 -> 重试成功 -> 恰好 64 字节 */ reset_all(); @@ -517,7 +517,7 @@ static void tc_drain_paths(void) && (g_ff_obs.calls[FF_FAKE_OP_UNLINK] >= 1) && (g_ff_obs.last_write_bw == SOE_REC_SIZE) && (g_soe_err_count == 0), - "TC-SOESTORE-014 FR_OK+短写被当失败处理(不校验字节数就会静默收下 63B)"); + "TC-SOESTORE-014 FR_OK plus short write counts as failure (63B would pass silently without check)"); /* 015:连续**两轮** drain 都失败 -> 留痕只许 1 次(一轮 = 首写 + 自愈重试 * = 2 次 f_write,所以注入 4 次零字节短写才够撑两轮) */ @@ -528,7 +528,7 @@ static void tc_drain_paths(void) ok = (g_soe_err_count == 1) && (s_ring_tail == 0u) && (s_fault_reported == 1u); soe_store_drain(); /* 第 2 轮仍失败:不得再留痕 */ CHECK(ok && (g_soe_err_count == 1) && (s_ring_tail == 0u), - "TC-SOESTORE-015 写故障留痕去重(防串口与 selftest 被同一条故障刷屏)"); + "TC-SOESTORE-015 write-fault trace is de-duplicated (one fault must not flood UART and selftest)"); /* 015b:成功一次复位去重位,之后再失败才会重新留痕 */ /* 015b:失败(留痕1) -> 恢复(去重位复位) -> 再失败(必须留痕2)。 @@ -543,7 +543,7 @@ static void tc_drain_paths(void) soe_store_post((uint8_t)SOE_T_ELM_ASSERT, 2u, 2u); soe_store_drain(); /* 又失败 -> 留痕 2 */ CHECK(ok && (g_soe_err_count == 2) && (s_fault_reported == 1u), - "TC-SOESTORE-015b 恢复后再失败必须重新留痕(漏复位 = 永久静默)"); + "TC-SOESTORE-015b a failure after recovery must trace again (missing reset = permanent silence)"); /* 016:卷忙 -> -2:不碰 FatFs、不 release、环不推进 */ reset_all(); @@ -554,7 +554,7 @@ static void tc_drain_paths(void) CHECK(ok && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 0) && (g_ff_obs.calls[FF_FAKE_OP_WRITE] == 0) && (s_ring_tail == 0u) && (g_soe_err_count == 0), - "TC-SOESTORE-016 卷忙 = 顺延:零 FatFs、零 release、不计故障(喂狗点纪律)"); + "TC-SOESTORE-016 volume busy means defer: zero FatFs, zero release, no fault counted (feed duty)"); /* 017:写失败时环不推进 tail -> 下轮重试、既不丢也不重复 */ reset_all(); @@ -566,7 +566,7 @@ static void tc_drain_paths(void) soe_store_drain(); /* 下轮成功 */ CHECK(ok && (s_ring_tail == 1u) && (ff_fake_size(SOE_PATH) == SOE_REC_SIZE) && read_rec(0u, &out) && (out.elm_id == 5u), - "TC-SOESTORE-017 环条目写失败不推进 tail:不丢、下轮也不重复落"); + "TC-SOESTORE-017 ring write failure does not advance tail: nothing lost, no duplicate next round"); /* 018:队列条目已出队 -> 卷忙只丢当前一条,剩余留在队列(现状不对称) */ reset_all(); @@ -584,18 +584,18 @@ static void tc_drain_paths(void) && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == opens_before) && (g_ff_obs.calls[FF_FAKE_OP_WRITE] == writes_before) && (s_lock_waits >= 1) && (s_lock_seq_err == 0) && (s_q_get_calls >= 2), - "TC-SOESTORE-018 队列路径卷忙:只丢已出队那一条、本轮零 FatFs(与环路径不对称)"); + "TC-SOESTORE-018 queue path with busy volume: only the dequeued entry is lost, zero FatFs now"); /* 019:容量满 -> unlink 重建 + INFO 留痕,新文件恰好 64 字节 */ reset_all(); CHECK(ff_fake_mkfile_size(SOE_PATH, (uint32_t)SOE_STORE_MAX * SOE_REC_SIZE) == 0, - "TC-SOESTORE-019 前置:铺 1024 条(64KB)假记录"); + "TC-SOESTORE-019 setup: lay down 1024 fake records (64KB)"); soe_store_post((uint8_t)SOE_T_ELM_ASSERT, 9u, 0x99u); soe_store_drain(); CHECK((g_ff_obs.calls[FF_FAKE_OP_UNLINK] == 1) && (ff_fake_size(SOE_PATH) == SOE_REC_SIZE) && (g_soe_info_count == 1) && read_rec(0u, &out) && (out.elm_id == 9u), - "TC-SOESTORE-019 满则删除重建:新文件只剩本次这一条"); + "TC-SOESTORE-019 full file is deleted and recreated: the new file holds only this entry"); /* 020:丢弃留痕按差值上报一次,不刷屏 */ reset_all(); @@ -605,7 +605,7 @@ static void tc_drain_paths(void) soe_store_drain(); /* 差值上报 1 条 */ soe_store_drain(); /* 无新丢弃 -> 不再报 */ CHECK((s_drop_cnt == 3u) && (s_drop_logged == 3u) && (g_soe_err_count == 1), - "TC-SOESTORE-020 丢弃留痕按差值上报一次(defaultTask 侧才是日志安全区)"); + "TC-SOESTORE-020 drop trace reports the delta once (only the defaultTask side is log-safe)"); /* 021:队列创建失败 -> 条目滞留环、下轮再试、不崩 */ /* 021:osMessageQueueNew 返回 NULL —— 生产代码里环在队列**之前**排空, @@ -620,12 +620,12 @@ static void tc_drain_paths(void) && (s_ring_tail == 1u) && (ff_fake_size(SOE_PATH) == SOE_REC_SIZE); soe_store_post((uint8_t)SOE_T_ELM_ASSERT, 5u, 5u); /* 队列没建成 -> 仍进环 */ CHECK(ok && (s_q_cnt == 0u) && (s_ring_head == 2u), - "TC-SOESTORE-021 队列创建失败:环路径照常落盘不丢条目 + 留痕一次"); + "TC-SOESTORE-021 queue creation failure: ring path still writes to disk, loses nothing + one trace"); s_q_new_fail = 0; soe_store_drain(); CHECK((s_queue != NULL) && (s_ring_tail == 2u) && (ff_fake_size(SOE_PATH) == 2u * SOE_REC_SIZE) && (g_soe_err_count == 1), - "TC-SOESTORE-021b 堆恢复后队列补建、滞留条目全部落盘"); + "TC-SOESTORE-021b once the heap recovers the queue is created and all pending entries reach disk"); } /* ===================== TC-SOESTORE-022..024:陷阱二 —— 名字/参数类错误码 ===================== */ @@ -635,7 +635,7 @@ static void tc_name_error_not_volume(void) uint32_t i; int ok; - printf("-- TC-SOESTORE-022..024 名字/参数类错误码严禁升级成卷操作 --\n"); + printf("-- TC-SOESTORE-022..024 name/parameter errors must never escalate into volume operations --\n"); /* 022【D 项已修 2026-10-24:正向断言】f_open 失败(名字/参数类码) * -> 只留痕返回 -1:**绝不 unlink**、不动 /log 目录、已有记录一条不少。 @@ -692,7 +692,7 @@ static void tc_name_error_not_volume(void) && (s_ring_tail == 0u); ff_fake_inject_write_short(SOE_PATH, 0u, 0); /* 清掉不再需要的注入 */ (void)ok; - CHECK(ok, "TC-SOESTORE-023 长跑反复失败:unlink 有界(<=1/轮),绝不升级为整卷动作"); + CHECK(ok, "TC-SOESTORE-023 repeated failures: unlink stays bounded (<=1 per round), never a volume action"); /* 024:假卷严格 8.3 校验的保真自检 —— 生产路径必过、点开头必被拒 */ reset_all(); @@ -715,7 +715,7 @@ static void tc_name_error_not_volume(void) CHECK((fr_ok == FR_OK) && ((fr_dot == FR_INVALID_NAME) || (fr_dot == FR_INVALID_DRIVE)) && (fr_colon == FR_INVALID_DRIVE), - "TC-SOESTORE-024 假件保真:/log/soe.log 过 8.3,.fschk 与坏盘符被拒"); + "TC-SOESTORE-024 fake fidelity: /log/soe.log passes 8.3, .fschk and a bad drive prefix are rejected"); } /* 生产路径本身合规的正向断言:改名成非 8.3 会让上面那条保真自检变红 */ reset_all(); @@ -723,7 +723,7 @@ static void tc_name_error_not_volume(void) soe_store_drain(); CHECK((strcmp(g_ff_obs.last_open_path, "/LOG/SOE.LOG") == 0) && (g_ff_obs.last_open_rc == (int)FR_OK), - "TC-SOESTORE-024b SOE_PATH 在严格 8.3 卷上确实打得开(改名=静默写失败的防线)"); + "TC-SOESTORE-024b SOE_PATH really opens on a strict 8.3 volume (guard against silent write failure)"); } /* ===================== 入口 ===================== */ diff --git a/test/host/sys_clock/sys_clock_test.c b/test/host/sys_clock/sys_clock_test.c index ee30c53a..052f05c8 100644 --- a/test/host/sys_clock/sys_clock_test.c +++ b/test/host/sys_clock/sys_clock_test.c @@ -189,19 +189,19 @@ static void tc_000_uninitialized(void) { sd2506_time_t t; char buf[32]; - printf("TC-SYSCLK-000 未初始化语义\n"); + printf("TC-SYSCLK-000 uninitialised semantics\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"); + CHECK_EQ_U32(sys_clock_get(), UINT32_MAX, "get before init returns UINT32_MAX"); + CHECK(sys_clock_get_time(&t) == -1, "get_time before init returns -1"); memset(buf, 0, sizeof(buf)); - CHECK(sys_clock_get_str(buf, sizeof(buf)) == buf, "get_str 返回 buf 指针"); - CHECK(strcmp(buf, "----/--/-- --:--:--") == 0, "get_str 未初始化占位串"); + CHECK(sys_clock_get_str(buf, sizeof(buf)) == buf, "get_str returns the buf pointer"); + CHECK(strcmp(buf, "----/--/-- --:--:--") == 0, "get_str placeholder string before init"); } static void tc_001_init_ok(void) { int rc; - printf("TC-SYSCLK-001 init 正常(RTC 合法)\n"); + printf("TC-SYSCLK-001 init normal (valid RTC)\n"); rtc_set(2026, 8, 24, 0, 0, 0); s_rtc_read_rc = BSP_OK; s_rtc_write_rc = BSP_OK; @@ -209,60 +209,60 @@ static void tc_001_init_ok(void) { s_tick = 12345u; rc = sys_clock_init(); - CHECK(rc == 0, "RTC 合法 → init 返回 0"); + CHECK(rc == 0, "valid RTC -> init returns 0"); CHECK_EQ_U32(sys_clock_get(), ref_unix(2026, 8, 24, 0, 0, 0), - "基准 = 2026-08-24 00:00:00 的 Unix 秒"); - CHECK(s_rtc_set_calls == 0, "合法 RTC 不被写回(无校时)"); + "base = Unix seconds of 2026-08-24 00:00:00"); + CHECK(s_rtc_set_calls == 0, "valid RTC is never written back (no time correction)"); } static void tc_002_init_leap(void) { - printf("TC-SYSCLK-002 init 闰年换算\n"); + printf("TC-SYSCLK-002 init leap-year conversion\n"); /* 2024 是闰年:2/29 存在 */ rtc_set(2024, 2, 29, 12, 0, 0); s_rtc_read_rc = BSP_OK; - CHECK(sys_clock_init() == 0, "2024-02-29 合法"); + CHECK(sys_clock_init() == 0, "2024-02-29 accepted"); CHECK_EQ_U32(sys_clock_get(), ref_unix(2024, 2, 29, 12, 0, 0), - "2024-02-29 12:00:00 换算正确"); + "2024-02-29 12:00:00 converts correctly"); /* 2000 是世纪闰年:2/29 存在 */ rtc_set(2000, 2, 29, 0, 0, 0); - CHECK(sys_clock_init() == 0, "2000-02-29 合法(世纪闰年)"); + CHECK(sys_clock_init() == 0, "2000-02-29 accepted (century leap year)"); CHECK_EQ_U32(sys_clock_get(), ref_unix(2000, 2, 29, 0, 0, 0), - "2000-02-29 换算正确"); + "2000-02-29 converts correctly"); /* 3 月 1 日:验证闰年 2 月多 1 天被正确累计 */ rtc_set(2024, 3, 1, 0, 0, 0); - CHECK(sys_clock_init() == 0, "2024-03-01 合法"); + CHECK(sys_clock_init() == 0, "2024-03-01 accepted"); CHECK_EQ_U32(sys_clock_get(), ref_unix(2024, 3, 1, 0, 0, 0), - "2024-03-01 与 2024-02-29 相差恰 1 天"); + "2024-03-01 is exactly 1 day after 2024-02-29"); CHECK_EQ_U32(ref_unix(2024, 3, 1, 0, 0, 0) - ref_unix(2024, 2, 29, 0, 0, 0), - 86400u, "闰日间隔 = 86400 s"); + 86400u, "leap-day gap = 86400 s"); } static void tc_003_init_month_end(void) { - printf("TC-SYSCLK-003 init 月末边界\n"); + printf("TC-SYSCLK-003 init end-of-month boundaries\n"); rtc_set(2026, 1, 31, 0, 0, 0); s_rtc_read_rc = BSP_OK; - CHECK(sys_clock_init() == 0, "1/31 合法"); - CHECK_EQ_U32(sys_clock_get(), ref_unix(2026, 1, 31, 0, 0, 0), "1/31 换算"); + CHECK(sys_clock_init() == 0, "1/31 accepted"); + CHECK_EQ_U32(sys_clock_get(), ref_unix(2026, 1, 31, 0, 0, 0), "1/31 conversion"); rtc_set(2026, 2, 28, 23, 59, 59); s_rtc_read_rc = BSP_OK; - CHECK(sys_clock_init() == 0, "2/28 合法(平年)"); - CHECK_EQ_U32(sys_clock_get(), ref_unix(2026, 2, 28, 23, 59, 59), "2/28 末端换算"); + CHECK(sys_clock_init() == 0, "2/28 accepted (common year)"); + CHECK_EQ_U32(sys_clock_get(), ref_unix(2026, 2, 28, 23, 59, 59), "2/28 end-of-day conversion"); rtc_set(2026, 4, 30, 0, 0, 0); s_rtc_read_rc = BSP_OK; - CHECK(sys_clock_init() == 0, "4/30 合法(30 天月)"); - CHECK_EQ_U32(sys_clock_get(), ref_unix(2026, 4, 30, 0, 0, 0), "4/30 换算"); + CHECK(sys_clock_init() == 0, "4/30 accepted (30-day month)"); + CHECK_EQ_U32(sys_clock_get(), ref_unix(2026, 4, 30, 0, 0, 0), "4/30 conversion"); /* 2/28 → 3/1 间隔恰 1 天(平年) */ rtc_set(2026, 2, 28, 0, 0, 0); sys_clock_init(); uint32_t a = sys_clock_get(); rtc_set(2026, 3, 1, 0, 0, 0); sys_clock_init(); uint32_t b = sys_clock_get(); - CHECK_EQ_U32(b - a, 86400u, "平年 2/28 → 3/1 间隔 = 86400 s"); + CHECK_EQ_U32(b - a, 86400u, "common year 2/28 -> 3/1 gap = 86400 s"); } static void tc_004_init_epoch_bounds(void) { - printf("TC-SYSCLK-004 init 世纪边界(Unix 下限 / 2038 上限)\n"); + printf("TC-SYSCLK-004 init century boundaries (Unix lower bound / 2038 upper bound)\n"); /* * 注意:init 接受的 RTC 年份范围是 2000~2099(越界即判故障并自愈), * 故"Unix 0(1970-01-01)"**不可能经 init 建立**——1970 会被判越界。 @@ -270,46 +270,46 @@ static void tc_004_init_epoch_bounds(void) { * 这里验证 init 可接受的最早年月,以及 uint32 上限。 */ rtc_set(2000, 1, 1, 0, 0, 0); s_rtc_read_rc = BSP_OK; - CHECK(sys_clock_init() == 0, "2000-01-01 合法(可接受最早年)"); - CHECK_EQ_U32(sys_clock_get(), ref_unix(2000, 1, 1, 0, 0, 0), "2000-01-01 换算"); + CHECK(sys_clock_init() == 0, "2000-01-01 accepted (earliest acceptable year)"); + CHECK_EQ_U32(sys_clock_get(), ref_unix(2000, 1, 1, 0, 0, 0), "2000-01-01 conversion"); /* 2038 上限:2038-01-19 03:14:07 = 0x7FFFFFFF */ rtc_set(2038, 1, 19, 3, 14, 7); s_rtc_read_rc = BSP_OK; - CHECK(sys_clock_init() == 0, "2038-01-19 合法(uint32 上限内)"); - CHECK_EQ_U32(sys_clock_get(), 0x7FFFFFFFu, "2038-01-19 03:14:07 → 0x7FFFFFFF"); + CHECK(sys_clock_init() == 0, "2038-01-19 accepted (within uint32 limit)"); + CHECK_EQ_U32(sys_clock_get(), 0x7FFFFFFFu, "2038-01-19 03:14:07 -> 0x7FFFFFFF"); /* Unix 0 经 set 路径显式可达(与 init 的范围限制无关) */ clear_obs(); - CHECK(sys_clock_set(0u, NULL) == 0, "set(0) 合法(Unix 零点)"); - CHECK_EQ_U32(sys_clock_get(), 0u, "set(0) 后 get == 0(Unix 零点)"); + CHECK(sys_clock_set(0u, NULL) == 0, "set(0) accepted (Unix epoch)"); + CHECK_EQ_U32(sys_clock_get(), 0u, "after set(0) get == 0 (Unix epoch)"); { sd2506_time_t t; CHECK(sys_clock_get_time(&t) == 0 && t.year == 1970 && t.month == 1 && t.day == 1, - "Unix 0 → 1970-01-01(unix_to_sd2506 反向换算)"); + "Unix 0 -> 1970-01-01 (unix_to_sd2506 reverse conversion)"); } } static void tc_005_init_rtc_read_fail(void) { - printf("TC-SYSCLK-005 init RTC 读失败 → 降级默认时间并返回 -1\n"); + printf("TC-SYSCLK-005 init RTC read failure -> degrade to default time and return -1\n"); s_rtc_read_rc = BSP_ERR_IO; /* 注入读故障 */ s_rtc_write_rc = BSP_OK; clear_obs(); s_tick = 777u; int rc = sys_clock_init(); - CHECK(rc == -1, "RTC 读失败 → init 返回 -1(报告芯片故障)"); + CHECK(rc == -1, "RTC read failure -> init returns -1 (reports the chip fault)"); /* 降级基准 = 编译期默认 RTC_DEFAULT_*(2026-08-24 00:00:00) */ CHECK_EQ_U32(sys_clock_get(), ref_unix(RTC_DEFAULT_YEAR, RTC_DEFAULT_MONTH, RTC_DEFAULT_DAY, RTC_DEFAULT_HOUR, RTC_DEFAULT_MINUTE, RTC_DEFAULT_SECOND), - "降级基准 = 编译期默认时间(墙钟仍可用)"); - CHECK(g_sclk_err_count >= 1, "打了 DBG_ERROR(RTC 异常)"); + "degraded base = compile-time default time (wall clock still usable)"); + CHECK(g_sclk_err_count >= 1, "DBG_ERROR emitted (RTC abnormal)"); s_rtc_read_rc = BSP_OK; /* 复位注入 */ } static void tc_006_init_out_of_range_selfheal(void) { - printf("TC-SYSCLK-006 init RTC 越界 → 自愈写回默认时间(返回 0)\n"); + printf("TC-SYSCLK-006 init RTC out of range -> self-heal by writing back the default time (returns 0)\n"); /* * RTC_DEFAULT_INIT_ENABLE=1 且 FORCE=0 时:越界值触发"写回默认时间", * 写成功且复读合法 → rtc_ok 恢复为 1 → **返回 0**(自愈,非降级)。 @@ -319,23 +319,23 @@ static void tc_006_init_out_of_range_selfheal(void) { s_rtc_read_rc = BSP_OK; s_rtc_write_rc = BSP_OK; clear_obs(); - CHECK(sys_clock_init() == 0, "year=1999 → 自愈写回成功 → 返回 0"); - CHECK(s_rtc_set_calls == 1, "越界触发一次写回"); - CHECK(s_rtc.year == RTC_DEFAULT_YEAR, "阴影 RTC 已修正为默认年"); + CHECK(sys_clock_init() == 0, "year=1999 -> self-heal write-back ok -> returns 0"); + CHECK(s_rtc_set_calls == 1, "out-of-range triggers exactly one write-back"); + CHECK(s_rtc.year == RTC_DEFAULT_YEAR, "shadow RTC corrected to the default year"); rtc_set(2026, 13, 5, 0, 0, 0); /* month > 12 → 越界 */ clear_obs(); - CHECK(sys_clock_init() == 0, "month=13 → 自愈 → 返回 0"); - CHECK(s_rtc_set_calls == 1, "越界触发一次写回"); + CHECK(sys_clock_init() == 0, "month=13 -> self-heal -> returns 0"); + CHECK(s_rtc_set_calls == 1, "out-of-range triggers exactly one write-back"); rtc_set(2026, 5, 0, 0, 0, 0); /* day < 1 → 越界 */ clear_obs(); - CHECK(sys_clock_init() == 0, "day=0 → 自愈 → 返回 0"); - CHECK(s_rtc_set_calls == 1, "越界触发一次写回"); + CHECK(sys_clock_init() == 0, "day=0 -> self-heal -> returns 0"); + CHECK(s_rtc_set_calls == 1, "out-of-range triggers exactly one write-back"); } static void tc_020_init_selfheal_fail_degrades(void) { - printf("TC-SYSCLK-020 init 越界且写回失败 → 降级默认时间并返回 -1\n"); + printf("TC-SYSCLK-020 init out of range and write-back fails -> degrade to default time and return -1\n"); /* * 组合故障:读成功但值越界(触发写回),写回失败 → 复读仍越界 → * rtc_ok 清 0 → 走降级分支(启用默认值时建基准 + 返回 -1)。 @@ -346,81 +346,81 @@ static void tc_020_init_selfheal_fail_degrades(void) { clear_obs(); s_tick = 42u; int rc = sys_clock_init(); - CHECK(rc == -1, "越界 + 写回失败 → init 返回 -1"); - CHECK(s_rtc_set_calls == 1, "尝试写回一次(失败)"); - CHECK(g_sclk_err_count >= 1, "打了 DBG_ERROR"); + CHECK(rc == -1, "out of range + write-back failure -> init returns -1"); + CHECK(s_rtc_set_calls == 1, "write-back attempted once (failed)"); + CHECK(g_sclk_err_count >= 1, "DBG_ERROR emitted"); CHECK_EQ_U32(sys_clock_get(), ref_unix(RTC_DEFAULT_YEAR, RTC_DEFAULT_MONTH, RTC_DEFAULT_DAY, 0, 0, 0), - "降级基准 = 编译期默认时间(墙钟仍可用)"); + "degraded base = compile-time default time (wall clock still usable)"); s_rtc_write_rc = BSP_OK; } static void tc_007_init_corrects_rtc(void) { - printf("TC-SYSCLK-007 init 越界 → 自动写回默认时间并复验\n"); + printf("TC-SYSCLK-007 init out of range -> auto write-back of default time and re-verify\n"); rtc_set(1999, 1, 1, 0, 0, 0); /* 越界,触发校时写回 */ s_rtc_read_rc = BSP_OK; s_rtc_write_rc = BSP_OK; clear_obs(); int rc = sys_clock_init(); - CHECK(s_rtc_set_calls == 1, "越界 → 写回 RTC 一次"); - CHECK(rc == 0, "写回成功 + 复读合法 → 返回 0(自愈成功,非降级)"); + CHECK(s_rtc_set_calls == 1, "out of range -> RTC written back once"); + CHECK(rc == 0, "write-back ok + re-read valid -> returns 0 (self-heal succeeded, not a degrade)"); CHECK(s_rtc.year == RTC_DEFAULT_YEAR && s_rtc.month == RTC_DEFAULT_MONTH - && s_rtc.day == RTC_DEFAULT_DAY, "阴影 RTC 已被写入默认时间"); + && s_rtc.day == RTC_DEFAULT_DAY, "shadow RTC was written with the default time"); CHECK_EQ_U32(sys_clock_get(), ref_unix(RTC_DEFAULT_YEAR, RTC_DEFAULT_MONTH, RTC_DEFAULT_DAY, 0, 0, 0), - "基准 = 修正后的默认时间"); + "base = the corrected default time"); } static void tc_008_get_advance(void) { - printf("TC-SYSCLK-008 get 正常推进(含亚秒截断)\n"); + printf("TC-SYSCLK-008 get advances normally (sub-second truncation included)\n"); base_at(1000000u, 5000u); - CHECK_EQ_U32(sys_clock_get(), 1000000u, "基准时刻 = 基准值"); + CHECK_EQ_U32(sys_clock_get(), 1000000u, "at the base instant the value equals the base"); tick_advance(999u); - CHECK_EQ_U32(sys_clock_get(), 1000000u, "999ms 未满 1s → 不变(截断)"); + CHECK_EQ_U32(sys_clock_get(), 1000000u, "999ms is under 1 s -> unchanged (truncated)"); tick_advance(1u); - CHECK_EQ_U32(sys_clock_get(), 1000001u, "累计 1000ms → +1s"); + CHECK_EQ_U32(sys_clock_get(), 1000001u, "accumulated 1000ms -> +1 s"); tick_advance(2500u); - CHECK_EQ_U32(sys_clock_get(), 1000003u, "再 +2500ms → 共 +3s(余 500ms 截断)"); + CHECK_EQ_U32(sys_clock_get(), 1000003u, "another +2500ms -> +3 s total (remaining 500 ms truncated)"); } static void tc_009_get_no_rebase_below_threshold(void) { - printf("TC-SYSCLK-009 未达 30 天阈值不触发再基准化\n"); + printf("TC-SYSCLK-009 below the 30-day threshold no re-baselining\n"); base_at(2000000u, 0u); /* 29 天 < 30 天阈值:线性推进,基准不动 */ tick_advance(29u * 24u * 3600u * 1000u); CHECK_EQ_U32(sys_clock_get(), 2000000u + 29u * 24u * 3600u, - "29 天线性推进正确(未再基准化)"); + "29 days advance linearly and correctly (no re-baselining)"); } static void tc_010_get_rebase_at_threshold(void) { - printf("TC-SYSCLK-010 30 天惰性再基准化(窗口清零、值无损、余数结转)\n"); + printf("TC-SYSCLK-010 30-day lazy re-baselining (window cleared, value lossless, remainder carried over)\n"); base_at(3000000u, 0u); /* 推进恰好 30 天 + 1500ms(余数 500ms 应结转到新窗) */ tick_advance(30u * 24u * 3600u * 1000u + 1500u); uint32_t expect = 3000000u + 30u * 24u * 3600u + 1u; /* 1500ms → +1s,余 500ms */ - CHECK_EQ_U32(sys_clock_get(), expect, "再基准化后墙钟值无损(+30 天 1 秒)"); + CHECK_EQ_U32(sys_clock_get(), expect, "after re-baselining the wall clock value is lossless (+30 days 1 second)"); /* 再推 500ms:结转的余数正好补足,再多 1 秒 */ tick_advance(500u); - CHECK_EQ_U32(sys_clock_get(), expect + 1u, "亚秒余数已结转(+500ms 补足 1 秒)"); + CHECK_EQ_U32(sys_clock_get(), expect + 1u, "sub-second remainder carried over (+500 ms completes 1 second)"); /* 再推一整天:仍线性 */ tick_advance(24u * 3600u * 1000u); - CHECK_EQ_U32(sys_clock_get(), expect + 1u + 86400u, "再基准化后继续线性推进"); + CHECK_EQ_U32(sys_clock_get(), expect + 1u + 86400u, "keeps advancing linearly after re-baselining"); } static void tc_011_get_tick_wrap(void) { - printf("TC-SYSCLK-011 tick 回绕(无符号差)安全\n"); + printf("TC-SYSCLK-011 tick wraparound (unsigned diff) is safe\n"); /* 基准设在接近 2^32 处 */ base_at(4000000u, 0xFFFFF000u); /* 推进 0x2000 ms(跨越 2^32 回绕):差 = 0x2000 = 8192ms → +8s */ tick_advance(0x2000u); - CHECK_EQ_U32(sys_clock_get(), 4000000u + 8u, "跨 tick 回绕后差值正确"); + CHECK_EQ_U32(sys_clock_get(), 4000000u + 8u, "diff is correct across the tick wraparound"); } static void tc_012_get_long_run_no_drift(void) { - printf("TC-SYSCLK-012 多轮再基准化长期不漂移\n"); + printf("TC-SYSCLK-012 many re-baselining rounds do not drift over time\n"); base_at(5000000u, 0u); /* * 惰性再基准化的**正确用法**:周期性调用 get() 让差值窗口始终 < 30 天。 @@ -434,44 +434,44 @@ static void tc_012_get_long_run_no_drift(void) { for (i = 1u; i <= 9u; i++) { tick_advance(10u * 86400u * 1000u); /* 每次 +10 天(< 30 天阈值) */ CHECK_EQ_U32(sys_clock_get(), base + i * 10u * 86400u, - "10 天步进(含 3 轮再基准)线性无漂移"); + "10-day steps (with 3 re-baseline rounds) stay linear with no drift"); } } static void tc_013_get_str(void) { - printf("TC-SYSCLK-013 get_str 格式化\n"); + printf("TC-SYSCLK-013 get_str formatting\n"); char buf[32]; base_at(ref_unix(2026, 10, 2, 13, 4, 5), 0u); memset(buf, 0, sizeof(buf)); sys_clock_get_str(buf, sizeof(buf)); - CHECK(strcmp(buf, "2026-10-02 13:04:05") == 0, "格式化 YYYY-MM-DD HH:MM:SS"); + CHECK(strcmp(buf, "2026-10-02 13:04:05") == 0, "formatted as YYYY-MM-DD HH:MM:SS"); base_at(ref_unix(2000, 1, 1, 0, 0, 0), 0u); memset(buf, 0, sizeof(buf)); sys_clock_get_str(buf, sizeof(buf)); - CHECK(strcmp(buf, "2000-01-01 00:00:00") == 0, "零点补零格式正确"); + CHECK(strcmp(buf, "2000-01-01 00:00:00") == 0, "zero-padded midnight format is correct"); } static void tc_014_get_time_fields(void) { - printf("TC-SYSCLK-014 get_time 日历字段\n"); + printf("TC-SYSCLK-014 get_time calendar fields\n"); sd2506_time_t t; /* 2026-10-02 是周五(已知) */ base_at(ref_unix(2026, 10, 2, 8, 9, 10), 0u); - CHECK(sys_clock_get_time(&t) == 0, "get_time 返回 0"); + CHECK(sys_clock_get_time(&t) == 0, "get_time returns 0"); CHECK(t.year == 2026 && t.month == 10 && t.day == 2, - "年月日正确"); - CHECK(t.hour == 8 && t.minute == 9 && t.second == 10, "时分秒正确"); - CHECK(t.week == 5, "2026-10-02 星期五(week==5,0=周日)"); + "year/month/day correct"); + CHECK(t.hour == 8 && t.minute == 9 && t.second == 10, "hour/minute/second correct"); + CHECK(t.week == 5, "2026-10-02 is Friday (week==5, 0=Sunday)"); } static void tc_015_get_time_null(void) { - printf("TC-SYSCLK-015 get_time NULL 参数被拒\n"); + printf("TC-SYSCLK-015 get_time rejects a NULL argument\n"); base_at(6000000u, 0u); - CHECK(sys_clock_get_time(NULL) == -1, "p_time == NULL → 返回 -1"); + CHECK(sys_clock_get_time(NULL) == -1, "p_time == NULL -> returns -1"); } static void tc_016_set_writes_rtc(void) { - printf("TC-SYSCLK-016 set 更新基准 + 写回 RTC\n"); + printf("TC-SYSCLK-016 set updates the base + writes back RTC\n"); sd2506_time_t sd; memset(&sd, 0, sizeof(sd)); sd.year = 2027; sd.month = 3; sd.day = 15; @@ -480,48 +480,48 @@ static void tc_016_set_writes_rtc(void) { s_rtc_write_rc = BSP_OK; clear_obs(); s_tick = 100u; - CHECK(sys_clock_set(7000000u, &sd) == 0, "set 返回 0"); - CHECK_EQ_U32(sys_clock_get(), 7000000u, "基准已更新"); - CHECK(s_rtc_set_calls == 1, "sd_time != NULL → 写回 RTC 一次"); + CHECK(sys_clock_set(7000000u, &sd) == 0, "set returns 0"); + CHECK_EQ_U32(sys_clock_get(), 7000000u, "base has been updated"); + CHECK(s_rtc_set_calls == 1, "sd_time != NULL -> RTC written back once"); CHECK(s_rtc.year == 2027 && s_rtc.month == 3 && s_rtc.day == 15 && s_rtc.hour == 6 && s_rtc.minute == 7 && s_rtc.second == 8, - "RTC 写入内容与传入一致"); + "RTC written content equals what was passed in"); /* 写失败:基准仍更新,但打错误日志 */ clear_obs(); s_rtc_write_rc = BSP_ERR_IO; sys_clock_set(7000001u, &sd); - CHECK_EQ_U32(sys_clock_get(), 7000001u, "RTC 写失败仍更新基准"); - CHECK(g_sclk_err_count >= 1, "RTC 写失败打 DBG_ERROR"); + CHECK_EQ_U32(sys_clock_get(), 7000001u, "base is still updated when the RTC write fails"); + CHECK(g_sclk_err_count >= 1, "DBG_ERROR emitted when the RTC write fails"); s_rtc_write_rc = BSP_OK; } static void tc_017_set_no_rtc(void) { - printf("TC-SYSCLK-017 set sd_time=NULL 不碰 RTC\n"); + printf("TC-SYSCLK-017 set sd_time=NULL never touches the RTC\n"); clear_obs(); - CHECK(sys_clock_set(8000000u, NULL) == 0, "set(NULL) 返回 0"); - CHECK(s_rtc_set_calls == 0, "sd_time == NULL → 不写 RTC"); - CHECK_EQ_U32(sys_clock_get(), 8000000u, "基准更新"); + CHECK(sys_clock_set(8000000u, NULL) == 0, "set(NULL) returns 0"); + CHECK(s_rtc_set_calls == 0, "sd_time == NULL -> RTC not written"); + CHECK_EQ_U32(sys_clock_get(), 8000000u, "base updated"); } static void tc_018_set_unix_fields(void) { - printf("TC-SYSCLK-018 set_unix 写回 RTC 且字段正确\n"); + printf("TC-SYSCLK-018 set_unix writes back the RTC with correct fields\n"); sd2506_time_t expect_week; uint32_t u = ref_unix(2026, 10, 2, 15, 30, 45); clear_obs(); s_rtc_write_rc = BSP_OK; s_tick = 0u; - CHECK(sys_clock_set_unix(u) == 0, "set_unix 返回 0"); - CHECK(s_rtc_set_calls == 1, "写回 RTC 一次"); + CHECK(sys_clock_set_unix(u) == 0, "set_unix returns 0"); + CHECK(s_rtc_set_calls == 1, "RTC written back once"); CHECK(s_rtc.year == 2026 && s_rtc.month == 10 && s_rtc.day == 2 && s_rtc.hour == 15 && s_rtc.minute == 30 && s_rtc.second == 45, - "RTC 日历字段与 Unix 秒一致"); - CHECK(s_rtc.week == 5, "RTC 星期字段 = 5(2026-10-02 周五)"); + "RTC calendar fields match the Unix seconds"); + CHECK(s_rtc.week == 5, "RTC weekday field = 5 (2026-10-02 is Friday)"); (void)expect_week; } static void tc_019_week_known_dates(void) { - printf("TC-SYSCLK-019 星期(Zeller)已知日期穷举\n"); + printf("TC-SYSCLK-019 weekday (Zeller) exhaustive check against known dates\n"); /* 期望值经 Python datetime 独立核对(0=周日); * 覆盖 1/2 月(Zeller 需上调为上年 13/14 月的分支)与 3~12 月(2026-10-02 * 修正前全部错误),以及世纪闰年、非闰世纪、范围首尾。*/ @@ -554,14 +554,14 @@ static void tc_019_week_known_dates(void) { cases[i].y, cases[i].m, cases[i].d, cases[i].w); CHECK(t.week == cases[i].w, nm); } else { - CHECK(0, "get_time 失败(用例数据问题)"); + CHECK(0, "get_time failed (bad test data)"); } } } int main(void) { - printf("=== System Clock 主机侧单元测试 ===\n"); - printf("被测:App/util/sys_clock.c(时间换算 + 墙钟基准)\n\n"); + printf("=== System Clock host-side unit tests ===\n"); + printf("Target: App/util/sys_clock.c (time conversion + wall-clock base)\n\n"); /* tc_000 必须最先(依赖"刚上电"的静态态) */ tc_000_uninitialized(); diff --git a/test/host/sys_log_mcu/sys_log_mcu_test.c b/test/host/sys_log_mcu/sys_log_mcu_test.c index efea41e1..08e03393 100644 --- a/test/host/sys_log_mcu/sys_log_mcu_test.c +++ b/test/host/sys_log_mcu/sys_log_mcu_test.c @@ -538,7 +538,7 @@ static void tc_format(void) int ok; uint32_t i; - printf("-- TC-SYSLOG-001..004 记录格式(64B 定长)--\n"); + printf("-- TC-SYSLOG-001..004 record format (fixed 64B) --\n"); /* 001 布局 */ reset_all(); @@ -551,14 +551,14 @@ static void tc_format(void) && (rec[SYSLOG_EPOCH_OFFS - 1u] == ' ') && (memcmp(rec + SYSLOG_DESC_OFFS, "hello", 5u) == 0) && (rec[SYSLOG_DESC_OFFS + 5u] == '\0'); - CHECK(ok, "TC-SYSLOG-001 [0..18]ts / [19]空格 / [20..29]epoch / [30]空格 / [31..]desc"); + CHECK(ok, "TC-SYSLOG-001 [0..18]ts / [19]space / [20..29]epoch / [30]space / [31..]desc"); ok = 1; for (i = SYSLOG_DESC_OFFS + 6u; i < SYSLOG_REC_SIZE; i++) { if (rec[i] != 0u) { ok = 0; } } - CHECK(ok, "TC-SYSLOG-001b 尾部 NUL 填充到 64B(定长解析的地基)"); + CHECK(ok, "TC-SYSLOG-001b tail padded with NUL to 64B (basis of fixed-length parsing)"); /* 002 描述截断 */ reset_all(); @@ -575,7 +575,7 @@ static void tc_format(void) } CHECK(ok && (rec[SYSLOG_DESC_OFFS + SYSLOG_DESC_MAX] == 0u) && (rec[SYSLOG_REC_SIZE - 1u] == 0u), - "TC-SYSLOG-002 超长描述截到 28B,不越 64B 边界"); + "TC-SYSLOG-002 over-long desc truncated to 28B, never crossing the 64B boundary"); } /* 003 墙钟未建立 */ @@ -584,7 +584,7 @@ static void tc_format(void) s_format_rec(SYSLOG_RUN, "x", rec); CHECK((memcmp(rec, "1970-01-01 08:00:00", SYSLOG_TS_LEN) == 0) && (memcmp(rec + SYSLOG_EPOCH_OFFS, "0000000000", SYSLOG_EPOCH_LEN) == 0), - "TC-SYSLOG-003 无墙钟 -> 占位时间戳 + epoch 全 0(不造假时标)"); + "TC-SYSLOG-003 no wall clock -> placeholder timestamp + epoch all zero (never fake a time stamp)"); /* 004 单条 vs 批量逐字节相同 */ reset_all(); @@ -594,7 +594,7 @@ static void tc_format(void) (void)memset(b, 0, sizeof(b)); s_format_rec(SYSLOG_RUN, "same-content", b); CHECK(memcmp(rec, b, SYSLOG_REC_SIZE) == 0, - "TC-SYSLOG-004 同一输入两次格式化逐字节一致(UI 定长偏移解析的前提)"); + "TC-SYSLOG-004 same input formats byte-identical twice (premise of UI fixed-offset parsing)"); reset_all(); s_now = 1700000000u; ready_only(); @@ -606,7 +606,7 @@ static void tc_format(void) s_format_rec(SYSLOG_RUN, "ab", batch + SYSLOG_REC_SIZE); CHECK((memcmp(rec, batch, SYSLOG_REC_SIZE) == 0) && (memcmp(rec, batch + SYSLOG_REC_SIZE, SYSLOG_REC_SIZE) == 0), - "TC-SYSLOG-004b 批量路径复用同一 s_format_rec(两条都等于单条)"); + "TC-SYSLOG-004b batch path reuses the same s_format_rec (both equal the single-record result)"); } } @@ -617,7 +617,7 @@ static void tc_write_single(void) uint8_t rec[SYSLOG_REC_SIZE]; int ok; - printf("-- TC-SYSLOG-010..019 单条写路径 --\n"); + printf("-- TC-SYSLOG-010..019 single-record write path --\n"); /* 010 成功 + 打开模式 */ reset_all(); @@ -630,7 +630,7 @@ static void tc_write_single(void) && (g_ff_obs.calls[FF_FAKE_OP_CLOSE] == 1) && (s_lock_releases == 1) && (s_lock_seq_err == 0) && (g_sys_err_count == 0); - CHECK(ok, "TC-SYSLOG-010 单条落盘成功:模式带写位 + open/write/close 各一次 + 放锁"); + CHECK(ok, "TC-SYSLOG-010 single write ok: mode carries the write bit + open/write/close once each + lock released"); /* 011 陷阱一保真对照 */ reset_all(); @@ -644,7 +644,7 @@ static void tc_write_single(void) fr2 = f_write(&probe, rec, SYSLOG_REC_SIZE, &bw); (void)f_close(&probe); CHECK((fr1 == FR_OK) && (fr2 == FR_DENIED) && (bw == 0u), - "TC-SYSLOG-011 只给 FA_OPEN_APPEND -> f_write 恒 FR_DENIED(2026-09-20 真根因)"); + "TC-SYSLOG-011 FA_OPEN_APPEND alone -> f_write is always FR_DENIED (real root cause 2026-09-20)"); } /* 012 卷忙 */ @@ -655,7 +655,7 @@ static void tc_write_single(void) CHECK(ok && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 0) && (g_ff_obs.calls[FF_FAKE_OP_WRITE] == 0) && (s_lock_releases == 0) && (s_lock_seq_err == 0) && (g_sys_err_count == 0), - "TC-SYSLOG-012 卷忙 = 顺延:不碰盘、不 release、不计故障(喂狗点绝不阻塞)"); + "TC-SYSLOG-012 volume busy means defer: no disk touch, no release, no fault counted (feed point never blocks)"); /* 013 短写 -> 自愈 */ reset_all(); @@ -665,7 +665,7 @@ static void tc_write_single(void) CHECK(ok && (ff_fake_size(P_RUN) == SYSLOG_REC_SIZE) && (g_ff_obs.calls[FF_FAKE_OP_UNLINK] == 1) && (g_ff_obs.last_write_bw == SYSLOG_REC_SIZE), - "TC-SYSLOG-013 FR_OK+短写 63B 被判失败 -> unlink 重建 -> 恰好 64 字节"); + "TC-SYSLOG-013 FR_OK + short write 63B treated as failure -> unlink and rebuild -> exactly 64 bytes"); /* 014 容量满 -> 删除重建 */ reset_all(); @@ -675,7 +675,7 @@ static void tc_write_single(void) CHECK(ok && (g_ff_obs.calls[FF_FAKE_OP_UNLINK] == 1) && (ff_fake_size(P_RUN) == SYSLOG_REC_SIZE) && (syslog_count(SYSLOG_RUN) == 1u), - "TC-SYSLOG-014 满 1024 条 -> 先 unlink 再写,新文件只剩本次一条"); + "TC-SYSLOG-014 at 1024 records -> unlink first then write, new file holds only this record"); /* 015 满 + unlink 真失败 */ reset_all(); @@ -685,7 +685,7 @@ static void tc_write_single(void) ok = (s_append(SYSLOG_RUN, "x") == -1); CHECK(ok && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 0) && (s_lock_releases == 1) && (s_lock_seq_err == 0), - "TC-SYSLOG-015 容量轮转时 unlink 失败 -> 返回 -1 且**已释放卷锁**(漏放 = FTP 永久拿不到卷)"); + "TC-SYSLOG-015 unlink failure during rotation -> -1 and **the volume lock is released** (leak = FTP never gets the volume)"); /* 016 满 + unlink 返 FR_NO_FILE 无害 */ reset_all(); @@ -698,7 +698,7 @@ static void tc_write_single(void) ok = (s_append(SYSLOG_RUN, "gone") == 0); CHECK(ok && (g_ff_obs.calls[FF_FAKE_OP_UNLINK] == 1) && (g_ff_obs.calls[FF_FAKE_OP_WRITE] == 1) && (g_sys_err_count == 0), - "TC-SYSLOG-016 unlink 返 FR_NO_FILE 被当无害:不进错误分支、不留痕、继续写"); + "TC-SYSLOG-016 unlink returning FR_NO_FILE is harmless: no error branch, no trace, write continues"); /* 017 入参守卫 */ reset_all(); @@ -708,7 +708,7 @@ static void tc_write_single(void) && (s_append(SYSLOG_RUN, NULL) == -1) && (s_append_rec((syslog_id_t)9u, rec) == -1); CHECK(ok && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 0), - "TC-SYSLOG-017 id 越界 / 空 rec / 空 desc -> -1 且不碰卷锁与盘"); + "TC-SYSLOG-017 id out of range / empty rec / empty desc -> -1 without touching the lock or the disk"); /* 018 写成功 -> 读侧代数自增 */ reset_all(); @@ -717,7 +717,7 @@ static void tc_write_single(void) ok = (s_rd_gen[SYSLOG_RUN] == 1u) && (s_rd_gen[SYSLOG_SELFTEST] == 0u); (void)s_append(SYSLOG_SELFTEST, "b"); CHECK(ok && (s_rd_gen[SYSLOG_SELFTEST] == 1u), - "TC-SYSLOG-018 每次落盘只自增本 id 的代数(另一文件的窗口不被误失效)"); + "TC-SYSLOG-018 each write bumps only this id's generation (the other file's window stays valid)"); /* 019 留痕去重 */ reset_all(); @@ -730,7 +730,7 @@ static void tc_write_single(void) ff_fake_inject_write_short(P_RUN, 0u, 2); (void)s_append(SYSLOG_RUN, "e3"); /* 再失败 -> 再留痕 */ CHECK(ok && (g_sys_err_count == 2), - "TC-SYSLOG-019 持续故障只报第一次;恢复后再失败必须重新留痕"); + "TC-SYSLOG-019 a persistent fault reports once; a failure after recovery must trace again"); } static void tc_write_many(void) @@ -739,7 +739,7 @@ static void tc_write_many(void) uint32_t i; int ok; - printf("-- TC-SYSLOG-020..024 批量写路径(N-24)--\n"); + printf("-- TC-SYSLOG-020..024 batch write path (N-24) --\n"); /* 020 8 条一次 I/O */ reset_all(); @@ -752,7 +752,7 @@ static void tc_write_many(void) && (g_ff_obs.last_write_btw == SYSLOG_BATCH_MAX * SYSLOG_REC_SIZE) && (g_ff_obs.last_write_bw == SYSLOG_BATCH_MAX * SYSLOG_REC_SIZE) && (g_ff_obs.calls[FF_FAKE_OP_CLOSE] == 1), - "TC-SYSLOG-020 一批 8 条 = 一次 open + 一次 512B write + 一次 close(旧实现 8 轮)"); + "TC-SYSLOG-020 a batch of 8 = one open + one 512B write + one close (old code needed 8 rounds)"); /* 021 入参守卫 */ reset_all(); @@ -762,7 +762,7 @@ static void tc_write_many(void) && (s_append_many(SYSLOG_RUN, NULL, 1u) == -1) && (s_append_many((syslog_id_t)SYSLOG_COUNT, batch, 1u) == -1); CHECK(ok && (s_lock_waits == 0) && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 0), - "TC-SYSLOG-021 批量入参守卫在**取卷锁之前**(越界 n 不占用卷)"); + "TC-SYSLOG-021 batch argument guards run **before taking the volume lock** (bad n never occupies it)"); /* 022 容量不足 -> -3 且不 unlink */ reset_all(); @@ -773,7 +773,7 @@ static void tc_write_many(void) && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 0) && (s_lock_releases == 1) && (s_lock_seq_err == 0) && (ff_fake_size(P_RUN) == ((uint32_t)SYSLOG_RUN_MAX - 3u) * SYSLOG_REC_SIZE), - "TC-SYSLOG-022 装不下一批 -> -3 交回慢路径;批量路径**绝不**自己 unlink 重建"); + "TC-SYSLOG-022 batch does not fit -> -3 back to the slow path; the batch path **never** unlinks itself"); /* 023 批量卷忙 / 短写自愈 */ reset_all(); @@ -785,7 +785,7 @@ static void tc_write_many(void) CHECK(ok && (ff_fake_size(P_RUN) == 4u * SYSLOG_REC_SIZE) && (g_ff_obs.calls[FF_FAKE_OP_UNLINK] == 1) && (g_sys_err_count == 0), - "TC-SYSLOG-023 批量卷忙 -> -2;短写(256 只回 100)-> 自愈重建后整批落全"); + "TC-SYSLOG-023 batch with busy volume -> -2; short write (256 asked, 100 back) -> rebuild, whole batch lands"); /* 024 批量持续失败 + 去重 */ reset_all(); @@ -794,7 +794,7 @@ static void tc_write_many(void) ok = (s_append_many(SYSLOG_RUN, batch, 2u) == -1); (void)s_append_many(SYSLOG_RUN, batch, 2u); CHECK(ok && (g_sys_err_count == 1) && (s_rd_gen[SYSLOG_RUN] == 2u), - "TC-SYSLOG-024 批量持续失败留痕去重;代数照样自增(宁多失效一轮也不读脏窗)"); + "TC-SYSLOG-024 batch failure trace de-duplicated; generation still bumps (invalidate a window rather than read stale)"); (void)i; } @@ -806,7 +806,7 @@ static void tc_drain(void) uint32_t i; int ok; - printf("-- TC-SYSLOG-030..041 syslog_drain 排空 --\n"); + printf("-- TC-SYSLOG-030..041 syslog_drain --\n"); /* 030 卷未就绪:条目滞留 preboot,drain 直接返回。 * 注意两条容易被读漏的事实: @@ -821,7 +821,7 @@ static void tc_drain(void) syslog_drain(); CHECK(ok && (s_q_new_calls == 1) && (s_preboot_cnt == 1u) && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 0) && (s_soe_drain_calls == 0), - "TC-SYSLOG-030 卷未就绪 -> 队列先建成、条目滞留 preboot、不落盘也不调 SOE"); + "TC-SYSLOG-030 volume not ready -> queue created, entries stay in preboot, nothing written and no SOE call"); /* 031 惰性建队列 */ reset_all(); @@ -829,7 +829,7 @@ static void tc_drain(void) ok = (s_queue == NULL); syslog_drain(); CHECK(ok && (s_queue != NULL) && (s_q_new_calls == 1) && (s_q_msgsz == sizeof(syslog_entry_t)), - "TC-SYSLOG-031 队列在**首次 drain**(defaultTask 上下文)才创建(内核前建对象 = 启动失败)"); + "TC-SYSLOG-031 the queue is created at the **first drain** (defaultTask context); creating objects pre-kernel kills boot"); /* 032 preboot 8 条一批落 */ reset_all(); @@ -837,12 +837,12 @@ static void tc_drain(void) for (i = 0u; i < SYSLOG_QUEUE_MAX; i++) { syslog_post(SYSLOG_RUN, "pre"); } - CHECK(s_preboot_cnt == SYSLOG_QUEUE_MAX, "TC-SYSLOG-032a 内核未运行:8 条全进 preboot 数组"); + CHECK(s_preboot_cnt == SYSLOG_QUEUE_MAX, "TC-SYSLOG-032a kernel not running: all 8 entries go to the preboot array"); syslog_drain(); ok = (s_preboot_cnt == 0u) && (syslog_count(SYSLOG_RUN) == SYSLOG_BATCH_MAX) && (g_ff_obs.calls[FF_FAKE_OP_WRITE] == 1) && (g_ff_obs.last_write_btw == SYSLOG_BATCH_MAX * SYSLOG_REC_SIZE); - CHECK(ok, "TC-SYSLOG-032b preboot 8 条同文件 -> 一次 512B 合并写(数组下标看而不删)"); + CHECK(ok, "TC-SYSLOG-032b 8 preboot entries of one file -> one merged 512B write (index inspected, not deleted)"); /* 033 + 034 两文件混排:换文件那条不消耗 */ reset_all(); @@ -864,7 +864,7 @@ static void tc_drain(void) CHECK(ok && (s_preboot_cnt == 0u) && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 3) && (g_ff_obs.calls[FF_FAKE_OP_WRITE] == 3), - "TC-SYSLOG-033/034 换文件即分批(run 被切成两批 = 共 3 轮 I/O)+ 顺序不乱"); + "TC-SYSLOG-033/034 a file change splits the batch (run split in two = 3 I/O rounds) + order preserved"); /* 035【A 项已修 2026-10-24:正向断言】卷忙 -> **整批回投队列**,一条不丢。 * 生产侧修法:syslog_drain 批量路径补 else if (rc == -2) { done = 0u; }, @@ -913,7 +913,7 @@ static void tc_drain(void) syslog_drain(); CHECK((s_q_cnt == 3u) && (syslog_count(SYSLOG_RUN) == SYSLOG_RUN_MAX - 1u) && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 0), - "TC-SYSLOG-035b 慢路径遇卷忙 -> 3 条**整批回投**(同一码在两条路径上行为相反)"); + "TC-SYSLOG-035b slow path meets busy volume -> all 3 **requeued whole** (same code, opposite behaviour per path)"); /* 035c 一整批(8 条)在卷忙时全部回投,不是只保住一条 */ reset_all(); @@ -966,7 +966,7 @@ static void tc_drain(void) syslog_drain(); CHECK(ok && (s_q_cnt == SYSLOG_QUEUE_MAX) && (s_preboot_cnt == 0u) && (g_sys_err_count == 1 + 5 + 1), - "TC-SYSLOG-036 回投装不下 -> 5 次 hold-over drop + drop/wfail 各 1 条留痕"); + "TC-SYSLOG-036 requeue does not fit -> 5 hold-over drops + one drop trace and one wfail trace"); /* 037 -3 退回慢路径:容量轮转只发生一次 */ reset_all(); @@ -982,7 +982,7 @@ static void tc_drain(void) && (g_ff_obs.calls[FF_FAKE_OP_UNLINK] == 1) && (g_ff_obs.calls[FF_FAKE_OP_WRITE] >= 4); CHECK(ok && (s_q_cnt == 0u), - "TC-SYSLOG-037 -3 -> 逐条慢路径:装满剩位 -> 满 -> unlink 重建 -> 继续,全程 unlink 恰一次"); + "TC-SYSLOG-037 -3 -> per-record slow path: fill the rest -> full -> unlink rebuild -> continue, unlink exactly once"); /* 038 慢路径中途写失败 -> 该条丢 + 尾部回投 */ reset_all(); @@ -999,7 +999,7 @@ static void tc_drain(void) ok = (s_q_cnt == 2u) && (ff_fake_size(P_RUN) == 0u) && (g_sys_err_count >= 2); syslog_drain(); /* 之后成功 */ CHECK(ok && (s_q_cnt == 0u) && (syslog_count(SYSLOG_RUN) == 2u), - "TC-SYSLOG-038 慢路径写失败:只丢**当前那一条**,尾部 2 条下轮补齐"); + "TC-SYSLOG-038 slow-path write failure: only **that one record** is lost, the last 2 land next round"); /* 039【B 项已修 2026-10-24:正向断言】rc == -1:整批回投 + 留痕文案如实 * (旧版这里打 "drop %lu entries" 但一条没丢,文案与行为相反)。 @@ -1038,7 +1038,7 @@ static void tc_drain(void) ok = (s_soe_drain_calls == 1); syslog_drain(); CHECK(ok && (s_soe_drain_calls == 2), - "TC-SYSLOG-040 drain 尾部必调 soe_store_drain(同写者、同卷就绪门)"); + "TC-SYSLOG-040 drain must call soe_store_drain (same writer, same volume-ready gate)"); /* 041 post 分流与守卫 */ reset_all(); @@ -1046,7 +1046,7 @@ static void tc_drain(void) syslog_post((syslog_id_t)SYSLOG_COUNT, "bad-id"); syslog_post(SYSLOG_RUN, NULL); CHECK((s_preboot_cnt == 0u) && (s_q_cnt == 0u), - "TC-SYSLOG-041a id 越界 / NULL 描述 -> 静默丢弃(不占待发位)"); + "TC-SYSLOG-041a id out of range / NULL desc -> silently dropped (does not occupy a pending slot)"); reset_all(); ready_only(); for (i = 0u; i < SYSLOG_QUEUE_MAX + 2u; i++) { @@ -1087,7 +1087,7 @@ static void tc_drain(void) syslog_post(SYSLOG_RUN, "q2"); syslog_post(SYSLOG_RUN, "q3"); CHECK((s_q_cnt == 2u) && (g_sys_err_count == 1), - "TC-SYSLOG-041c 内核运行 -> 走队列;队列满丢弃 + 留痕"); + "TC-SYSLOG-041c kernel running -> queue path; queue full drops with a trace"); } /* ===================== D 读侧 ===================== */ @@ -1100,17 +1100,17 @@ static void tc_read(void) uint32_t i; int ok; - printf("-- TC-SYSLOG-050..058 读侧(N-24 滑动窗口)--\n"); + printf("-- TC-SYSLOG-050..058 read side (N-24 sliding window) --\n"); /* 050 count */ reset_all(); ready_only(); - CHECK(syslog_count(SYSLOG_RUN) == 0u, "TC-SYSLOG-050a 文件缺失 -> count 0"); + CHECK(syslog_count(SYSLOG_RUN) == 0u, "TC-SYSLOG-050a missing file -> count 0"); for (i = 0u; i < 3u; i++) { (void)s_append(SYSLOG_RUN, "c"); } ok = (syslog_count(SYSLOG_RUN) == 3u) && (syslog_count((syslog_id_t)7u) == 0u); - CHECK(ok, "TC-SYSLOG-050b count = filesize/64(O(1),不读盘内容);id 越界 -> 0"); + CHECK(ok, "TC-SYSLOG-050b count = filesize/64 (O(1), no content read); id out of range -> 0"); /* 051 窗口命中零 I/O */ reset_all(); @@ -1131,7 +1131,7 @@ static void tc_read(void) && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == opens_after) /* 命中 -> 零 I/O */ && (g_ff_obs.calls[FF_FAKE_OP_READ] == reads_base + 1); } - CHECK(ok, "TC-SYSLOG-051 窗口命中 -> 第二次读**零 FatFs 调用**(UI 翻页不再逐条开合)"); + CHECK(ok, "TC-SYSLOG-051 window hit -> the second read makes **zero FatFs calls** (UI paging no longer opens per record)"); /* 052 写者代数失效 */ reset_all(); @@ -1142,7 +1142,7 @@ static void tc_read(void) (void)s_append(SYSLOG_RUN, "new"); /* 代数 +1 -> 窗口必须重填 */ ok = ok && (syslog_get_record(SYSLOG_RUN, 1u, ts, sizeof(ts), desc, sizeof(desc)) == 0) && (strcmp(desc, "new") == 0); - CHECK(ok, "TC-SYSLOG-052 写者一落地代数就变 -> 窗口重填,绝不返回陈旧内容"); + CHECK(ok, "TC-SYSLOG-052 once the writer lands the generation changes -> window refills, never returns stale content"); /* 053 跨窗口 */ reset_all(); @@ -1158,7 +1158,7 @@ static void tc_read(void) && (g_ff_obs.last_lseek_ofs == (FSIZE_t)(SYSLOG_RD_WINDOW * SYSLOG_REC_SIZE)) && (g_ff_obs.last_read_btr == SYSLOG_REC_SIZE); } - CHECK(ok, "TC-SYSLOG-053 idx=8 跨窗 -> 一次 open + lseek(8*64) + read(1 条)(窗口按 8 对齐)"); + CHECK(ok, "TC-SYSLOG-053 idx=8 crosses the window -> one open + lseek(8*64) + read(1 record) (window aligned to 8)"); /* 054 越界 */ reset_all(); @@ -1169,7 +1169,7 @@ static void tc_read(void) reset_all(); ready_only(); ok = ok && (syslog_get_record(SYSLOG_RUN, 0u, ts, sizeof(ts), desc, sizeof(desc)) == -1); - CHECK(ok, "TC-SYSLOG-054 越界 idx / 空文件 -> -1(等锁前后各校验一次 count)"); + CHECK(ok, "TC-SYSLOG-054 out-of-range idx / empty file -> -1 (count checked before and after taking the lock)"); /* 055 读时卷忙 */ reset_all(); @@ -1181,7 +1181,7 @@ static void tc_read(void) lock_busy_next(1); ok = (syslog_get_record(SYSLOG_SELFTEST, 0u, ts, sizeof(ts), desc, sizeof(desc)) == -1) && (g_ff_obs.calls[FF_FAKE_OP_OPEN] >= 1) && (s_lock_seq_err == 0); - CHECK(ok, "TC-SYSLOG-055 读时卷忙 -> -1(读窗口 try 语义:uiTask 也绝不阻塞等锁,下轮刷新重读)"); + CHECK(ok, "TC-SYSLOG-055 busy volume while reading -> -1 (try semantics: uiTask never blocks for the lock, retry next refresh)"); /* 056 短读作废窗口 */ reset_all(); @@ -1193,7 +1193,7 @@ static void tc_read(void) ff_fake_inject_read_short(P_RUN, 1u, 1); ok = (s_read_raw(SYSLOG_RUN, 0u, (uint8_t *)desc) == -1) && (s_rd_win_cnt == 0u) && (s_rd_win_id == -1); - CHECK(ok, "TC-SYSLOG-056 短读 -> 窗口作废(半窗当有效命中 = UI 显示半条脏记录)"); + CHECK(ok, "TC-SYSLOG-056 short read -> window invalidated (a half window treated as valid = UI shows half a stale record)"); /* 057 get_record 守卫与截断 */ reset_all(); @@ -1213,7 +1213,7 @@ static void tc_read(void) * 整 28 字符而不是截断结果 —— 即"传刚够的缓冲会被拒、传更小的也被拒, * 从来没有截断"。登记为死分支,见文件头"本套照出的现状"。 */ && (strlen(desc) == (size_t)SYSLOG_DESC_MAX); - CHECK(ok, "TC-SYSLOG-057 守卫:ts_len<=19 或 desc_len<=28 一律 -1;29 才读得到整 28 字符"); + CHECK(ok, "TC-SYSLOG-057 guards: ts_len<=19 or desc_len<=28 always -1; only 29 reads the full 28 characters"); /* C 项整改(2026-10-24):容量不足一律拒绝,且**不得**碰调用方缓冲—— * 上面每次被拒的调用都用了同一对缓冲,哨兵还在就说明没写进去 */ reset_all(); @@ -1243,7 +1243,7 @@ static void tc_read(void) s_now = 1700000123u; (void)s_append(SYSLOG_RUN, "e"); ok = ok && (syslog_last_epoch(SYSLOG_RUN, &epoch) == 0) && (epoch == 1700000123u); - CHECK(ok, "TC-SYSLOG-058 last_epoch:无记录 -1;有记录解析 10 位 ASCII"); + CHECK(ok, "TC-SYSLOG-058 last_epoch: no record -> -1; with a record parse the 10 ASCII digits"); } /* ===================== E mounted / 上电重启分类 ===================== */ @@ -1253,7 +1253,7 @@ static void tc_mounted(void) uint8_t rec[SYSLOG_REC_SIZE]; int ok; - printf("-- TC-SYSLOG-060..064 挂载后处理(挂载幂等 + 上电/重启分类)--\n"); + printf("-- TC-SYSLOG-060..064 post-mount handling (idempotent mount + power/reboot classification) --\n"); /* 060 /log 不在 -> 建目录 + 写上电记录;第二次调用完全静默 */ reset_all(); @@ -1264,7 +1264,7 @@ static void tc_mounted(void) syslog_mcu_mounted(); ok = ok && (s_fs_ready == 1u) && (syslog_count(SYSLOG_RUN) == 1u); CHECK(ok && (g_ff_obs.calls[FF_FAKE_OP_MKDIR] == 0) && (g_sys_err_count == 0), - "TC-SYSLOG-060a /log 已存在 -> 只写上电/重启记录一条"); + "TC-SYSLOG-060a /log exists -> write only the one power/reboot record"); /* 060b 幂等:再来一次既不建目录也不写第二条 */ reset_all(); s_fs_ready = 0u; @@ -1275,7 +1275,7 @@ static void tc_mounted(void) syslog_mcu_mounted(); /* 第二次:应完全静默 */ CHECK((s_fs_ready == 1u) && (syslog_count(SYSLOG_RUN) == cnt1) && (g_ff_obs.calls[FF_FAKE_OP_MKDIR] == mkdirs1), - "TC-SYSLOG-060b 幂等再调用:不再建目录、不再写上电记录(2s 复查不刷屏)"); + "TC-SYSLOG-060b idempotent re-entry: no mkdir, no second power-on record (the 2s recheck must not flood)"); } (void)rec; @@ -1291,7 +1291,7 @@ static void tc_mounted(void) ok = ok && (g_sys_err_count == 1) && (s_lock_releases == 2) && (s_lock_seq_err == 0); syslog_mcu_mounted(); /* 注入耗尽 -> 成功 */ CHECK(ok && (s_fs_ready == 1u) && (s_mount_fail_reported == 0u), - "TC-SYSLOG-061 mkdir 失败:不就绪、留痕一次(防 2s 刷屏)、第三轮自愈并复位标志"); + "TC-SYSLOG-061 mkdir failure: not ready, trace once (no 2s flooding), third round self-heals and resets the flag"); /* 062 卷忙:本轮顺延,不置就绪、不碰盘 */ reset_all(); @@ -1300,7 +1300,7 @@ static void tc_mounted(void) syslog_mcu_mounted(); CHECK((s_fs_ready == 0u) && (g_ff_obs.calls[FF_FAKE_OP_STAT] == 0) && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 0) && (s_lock_releases == 0), - "TC-SYSLOG-062 卷忙 -> 直接返回(try 失败不 release,下轮 2s 后再试)"); + "TC-SYSLOG-062 busy volume -> return at once (a failed try must not release; retry after the next 2s)"); /* 063 上电 / 重启分类:阈值 SYSLOG_REBOOT_WINDOW_S 两侧 + 墙钟无效 */ reset_all(); @@ -1320,7 +1320,7 @@ static void tc_mounted(void) syslog_mcu_mounted(); ok = raw_at(P_RUN, 1u, rec) && (memcmp(rec + SYSLOG_DESC_OFFS, "reboot", 6u) == 0) && (rec[SYSLOG_DESC_OFFS + 6u] == '\0'); - CHECK(ok, "TC-SYSLOG-063a 末条 epoch 距 now 300s(<600) -> 描述落 \"reboot\""); + CHECK(ok, "TC-SYSLOG-063a last epoch 300s(<600) before now -> desc is \"reboot\""); reset_all(); s_fs_ready = 0u; @@ -1335,7 +1335,7 @@ static void tc_mounted(void) } syslog_mcu_mounted(); ok = raw_at(P_RUN, 1u, rec) && (memcmp(rec + SYSLOG_DESC_OFFS, "power on", 8u) == 0); - CHECK(ok, "TC-SYSLOG-063b 间隔 >=600s -> \"power on\"(掉电超过 10 分钟算重新上电)"); + CHECK(ok, "TC-SYSLOG-063b gap >=600s -> \"power on\" (over ten minutes off counts as a fresh power-up)"); reset_all(); s_fs_ready = 0u; @@ -1348,14 +1348,14 @@ static void tc_mounted(void) } syslog_mcu_mounted(); ok = raw_at(P_RUN, 1u, rec) && (memcmp(rec + SYSLOG_DESC_OFFS, "power on", 8u) == 0); - CHECK(ok, "TC-SYSLOG-063c 墙钟无效(UINT32_MAX)-> 保守判 \"power on\",不拿假差值判重启"); + CHECK(ok, "TC-SYSLOG-063c wall clock invalid (UINT32_MAX) -> conservatively \"power on\", never judge a reboot from a fake delta"); /* 064 幂等靠 stat,不靠状态位:/log 已在就不再 mkdir */ reset_all(); s_fs_ready = 0u; syslog_mcu_mounted(); ok = (g_ff_obs.calls[FF_FAKE_OP_MKDIR] == 0) && (g_ff_obs.calls[FF_FAKE_OP_STAT] >= 1); - CHECK(ok, "TC-SYSLOG-064 /log 已存在时靠 f_stat 短路,f_mkdir 一次都不调"); + CHECK(ok, "TC-SYSLOG-064 with /log present f_stat short-circuits, f_mkdir is never called"); } /* ===================== F 取证通道 sys_log_evidence ===================== */ @@ -1365,7 +1365,7 @@ static void tc_evidence(void) uint8_t raw[8u * SYSLOG_REC_SIZE]; int ok; - printf("-- TC-SYSLOG-070..074 sys_log_evidence(wdev.log 取证通道)--\n"); + printf("-- TC-SYSLOG-070..074 sys_log_evidence (wdev.log forensics channel) --\n"); /* 070 变长行 + 第二条 run.log */ reset_all(); @@ -1379,14 +1379,14 @@ static void tc_evidence(void) && raw_at(P_RUN, 0u, raw) && (memcmp(raw + SYSLOG_DESC_OFFS, "wd stall declared", 17u) == 0); } - CHECK(ok, "TC-SYSLOG-070 wdev.log 写变长行(带 CRLF),并补一条 run.log 独立证据"); + CHECK(ok, "TC-SYSLOG-070 wdev.log writes a variable-length line (with CRLF) plus a separate run.log evidence record"); /* 071 卷锁顺序:第二条写必须在释放之后(非递归锁,反了 = 自死锁) */ reset_all(); (void)sys_log_evidence("order probe"); CHECK((s_lock_waits == 2) && (s_lock_releases == 2) && (s_lock_seq_err == 0) && (s_lock_held == 0), - "TC-SYSLOG-071 取锁两次各放一次(在持锁状态下调 s_append 会永远拿不到锁)"); + "TC-SYSLOG-071 the lock is taken twice and released twice (calling s_append while holding it would deadlock)"); /* 072 >8192B 护栏 */ reset_all(); @@ -1394,7 +1394,7 @@ static void tc_evidence(void) ok = (sys_log_evidence("after rotate") == 0); CHECK(ok && (g_ff_obs.calls[FF_FAKE_OP_UNLINK] == 1) && (ff_fake_size(P_WDEV) > 0u) && (ff_fake_size(P_WDEV) < 200u), - "TC-SYSLOG-072 超过 8KB -> 先 unlink 再写(长跑不被无界撑爆)"); + "TC-SYSLOG-072 beyond 8KB -> unlink first then write (a long run must not grow without bound)"); /* 073 卷忙 */ reset_all(); @@ -1402,14 +1402,14 @@ static void tc_evidence(void) ok = (sys_log_evidence("busy probe") == -1); CHECK(ok && (ff_fake_exists(P_WDEV) == 0) && (syslog_count(SYSLOG_RUN) == 0u) && (s_lock_releases == 0) && (s_lock_seq_err == 0), - "TC-SYSLOG-073 卷忙 -> -1 且**两条写都没发生**(喂狗点绝不阻塞等锁)"); + "TC-SYSLOG-073 busy volume -> -1 and **neither write happened** (feed point never blocks for the lock)"); /* 074 wdev 写失败:返回 -1,但第二条仍写("独立证据"语义) */ reset_all(); ff_fake_inject_rc(P_WDEV, FF_FAKE_OP_OPEN, FR_DISK_ERR, 1); ok = (sys_log_evidence("second write still") == -1); CHECK(ok && (syslog_count(SYSLOG_RUN) == 1u) && (g_sys_err_count == 0), - "TC-SYSLOG-074 wdev 写失败不阻断第二条 run.log(多一条独立证据的原始意图)"); + "TC-SYSLOG-074 a wdev write failure does not block the second run.log record (the intent of extra evidence)"); } /* ===================== G 陷阱二:名字/参数类错误码严禁升级成卷操作 ===================== */ @@ -1425,7 +1425,7 @@ static void tc_name_rules(void) int ok; uint32_t i; - printf("-- TC-SYSLOG-080..082 陷阱二分档与「绝不升级」 --\n"); + printf("-- TC-SYSLOG-080..082 name class split and never escalate --\n"); /* 080 短名违规**分档**:每条都落到 FR_INVALID_NAME;':' 落到 FR_INVALID_DRIVE */ reset_all(); @@ -1442,7 +1442,7 @@ static void tc_name_rules(void) CHECK((fr_body == FR_INVALID_NAME) && (fr_ext == FR_INVALID_NAME) && (fr_bad == FR_INVALID_NAME) && (fr_dot == FR_INVALID_NAME) && (fr_colon == FR_INVALID_DRIVE), - "TC-SYSLOG-080 分档:体>8 / 扩展>3 / 非法字符 / 点开头 -> FR_INVALID_NAME;':' -> FR_INVALID_DRIVE"); + "TC-SYSLOG-080 classes: body>8 / ext>3 / bad char / leading dot -> FR_INVALID_NAME; ':' -> FR_INVALID_DRIVE"); /* 081 生产实际用的每个名字都必须过严格 8.3(改名 = 静默写失败的第一道防线) */ reset_all(); @@ -1452,7 +1452,7 @@ static void tc_name_rules(void) ok = ok && (f_open(&probe, P_WDEV, FA_WRITE | FA_OPEN_APPEND) == FR_OK) && (f_close(&probe) == FR_OK); ok = ok && (f_stat("/log", NULL) == FR_OK); - CHECK(ok, "TC-SYSLOG-081 生产路径 /log、run.log、selftest.log、wdev.log 全部 8.3 合规"); + CHECK(ok, "TC-SYSLOG-081 production paths /log, run.log, selftest.log, wdev.log are all valid 8.3 names"); /* 082 名字类错误码不得升级成卷操作:反复失败也只动自己的文件 */ reset_all(); @@ -1485,7 +1485,7 @@ static void tc_extra_branches(void) uint32_t i; int ok; - printf("-- TC-SYSLOG-090..100 补齐分支 --\n"); + printf("-- TC-SYSLOG-090..100 remaining branch coverage --\n"); /* 090 批量路径的 L1 自愈:open 失败一次 -> unlink + 重开 -> 整批照常落盘 * (这条钉的是 s_append_many 里那段"和单条同一份自愈表";漏了它, @@ -1502,7 +1502,7 @@ static void tc_extra_branches(void) CHECK(ok && (g_ff_obs.calls[FF_FAKE_OP_UNLINK] == 1) && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 3) /* 单条 1 + 批量首开 1 + 自愈重开 1 */ && (ff_fake_size(P_RUN) == 2u * SYSLOG_REC_SIZE) && (g_sys_err_count == 0), - "TC-SYSLOG-090 批量 open 失败一次 -> unlink 重开 -> 整批 2 条落全、不留痕"); + "TC-SYSLOG-090 one batch open failure -> unlink and reopen -> whole batch of 2 lands, no trace"); /* 091 批量 open 永久失败 -> -1(走的是"打开失败"那条 else,不是写失败) */ reset_all(); @@ -1514,7 +1514,7 @@ static void tc_extra_branches(void) } CHECK(ok && (ff_fake_exists(P_RUN) == 0) && (g_sys_err_count == 1) && (s_lock_releases == 1) && (s_lock_seq_err == 0), - "TC-SYSLOG-091 批量打开持续失败 -> -1 + 留痕一次 + 已释放卷锁"); + "TC-SYSLOG-091 batch open keeps failing -> -1 + one trace + the volume lock released"); /* 092 取锁后二次校验:等锁期间写者可能已把文件删掉(容量轮转/取证重建) * -> 释放锁再返回 -1,绝不能拿锁前的旧 total 去 lseek */ @@ -1527,7 +1527,7 @@ static void tc_extra_branches(void) ok = ok && (s_read_raw(SYSLOG_RUN, 0u, raw) == -1) && (s_lock_releases == 2) && (s_lock_seq_err == 0); CHECK(ok && (s_rd_win_cnt == 0u), - "TC-SYSLOG-092 锁后二次 count 失败 -> 放锁返回 -1(漏放 = FTP 永久等不到卷)"); + "TC-SYSLOG-092 second count after the lock fails -> release the lock and return -1 (leak = FTP waits forever)"); /* 093 读时 f_open 失败 -> 放锁返回 -1(另一条提前退出路径) */ reset_all(); @@ -1540,7 +1540,7 @@ static void tc_extra_branches(void) && (s_lock_releases == 2) && (s_lock_seq_err == 0); /* 第二次读(注入耗尽)应成功,证明窗口没被留在半初始化状态 */ ok = ok && (s_read_raw(SYSLOG_RUN, 0u, raw) == 0) && (s_rd_win_cnt == 1u); - CHECK(ok, "TC-SYSLOG-093 读打开失败 -> 放锁 -1;下轮恢复后窗口正常重填"); + CHECK(ok, "TC-SYSLOG-093 read open failure -> release lock and -1; next round refills the window after recovery"); /* 094 墙钟未建立时 evidence 用占位时标(不得写半截或未初始化缓冲) */ reset_all(); @@ -1550,7 +1550,7 @@ static void tc_extra_branches(void) (void)ff_fake_fetch(P_WDEV, raw, 0u, SYSLOG_TS_LEN); ok = (memcmp(raw, "1970-01-01 08:00:00", SYSLOG_TS_LEN) == 0); } - CHECK(ok, "TC-SYSLOG-094 无墙钟 -> wdev.log 落占位时标(取证行也必须可解析)"); + CHECK(ok, "TC-SYSLOG-094 no wall clock -> wdev.log gets a placeholder timestamp (forensic lines must stay parseable)"); /* 095 wdev 短写:FR_OK + 字节数不足 -> -1,但第二条 run.log 照写 */ reset_all(); @@ -1558,7 +1558,7 @@ static void tc_extra_branches(void) ok = (sys_log_evidence("short line") == -1); CHECK(ok && (ff_fake_size(P_WDEV) == 3u) && (syslog_count(SYSLOG_RUN) == 1u) && (g_sys_err_count == 0), - "TC-SYSLOG-095 wdev 短写判失败返回 -1,第二条独立证据仍落 run.log"); + "TC-SYSLOG-095 a wdev short write fails with -1 while the second run.log evidence record still lands"); /* 096 队列创建失败:条目滞留 preboot、留痕一次、下轮建成后排空 */ reset_all(); @@ -1573,7 +1573,7 @@ static void tc_extra_branches(void) syslog_drain(); CHECK(ok && (s_queue != NULL) && (syslog_count(SYSLOG_RUN) == 1u) && (s_preboot_cnt == 0u) && (s_soe_drain_calls == 1), - "TC-SYSLOG-096 队列没建成 -> 一条都不排(不静默丢),堆恢复后排空并接上 SOE"); + "TC-SYSLOG-096 queue not created -> nothing is drained (no silent loss); after the heap recovers it empties into SOE"); /* 097 换文件那条来自队列 -> 原样回投队列(不是 preboot 下标回退) * 队列里 RUN/SELFTEST/RUN 交替:三条必须全落且各自文件内顺序不乱 */ @@ -1594,7 +1594,7 @@ static void tc_extra_branches(void) && (s_q_cnt == 0u); } CHECK(ok && (g_ff_obs.calls[FF_FAKE_OP_OPEN] == 3), - "TC-SYSLOG-097 队列侧换文件回投:三条全落、各文件内顺序不乱(回投不是丢弃)"); + "TC-SYSLOG-097 queue-side file change requeues: all three land, order inside each file kept (requeue is not a drop)"); /* 098【C 项已修 2026-10-24】原来的 "if (dl >= desc_len) dl = desc_len - 1" * 是永不可达的死分支(守卫已挡掉 desc_len <= SYSLOG_DESC_MAX,而 dl 恒 * <= SYSLOG_DESC_MAX),已从生产码删除。本条改为正向钉住"读侧不再截断": @@ -1617,7 +1617,7 @@ static void tc_extra_branches(void) && (syslog_get_record(SYSLOG_RUN, 0u, ts, sizeof(ts), desc, sizeof(desc)) == 0) && (sys_log_evidence(NULL) == -1); CHECK(ok && (s_lock_seq_err == 0), - "TC-SYSLOG-099 p_rec / p_desc 空指针守卫(守卫顺序在取锁之前,不放锁)"); + "TC-SYSLOG-099 p_rec / p_desc NULL guards (guards run before taking the lock, so nothing is released)"); /* 100 last_epoch:有记录但读失败 -> -1 且把 *p_epoch 清 0 * (调用方 syslog_mcu_mounted 直接拿这个值判上电/重启,留旧值就会误判) */ @@ -1629,7 +1629,7 @@ static void tc_extra_branches(void) epoch = 0xA5A5A5A5u; ff_fake_inject_rc(P_RUN, FF_FAKE_OP_OPEN, FR_DISK_ERR, 1); ok = (syslog_last_epoch(SYSLOG_RUN, &epoch) == -1) && (epoch == 0u); - CHECK(ok, "TC-SYSLOG-100 last_epoch 读失败 -> -1 且 *p_epoch 清零(不留调用方旧值)"); + CHECK(ok, "TC-SYSLOG-100 last_epoch read failure -> -1 and *p_epoch cleared (never leave the caller's old value)"); (void)i; } diff --git a/test/host/task_prof/task_prof_test.c b/test/host/task_prof/task_prof_test.c index b4a34215..4cee2e76 100644 --- a/test/host/task_prof/task_prof_test.c +++ b/test/host/task_prof/task_prof_test.c @@ -178,26 +178,26 @@ static void tc_sample_gate(void) CHECK((s_prof[TASK_PROF_UI_PERIOD].count == 1u) && (s_prof[TASK_PROF_UI_PERIOD].last == 500u) && (s_prof[TASK_PROF_UI_PERIOD].max == 500u), - "TC-TASKPROF-001 有效样本记 count/last/max"); + "TC-TASKPROF-001 valid sample records count/last/max"); task_prof_sample(TASK_PROF_UI_PERIOD, 300u); CHECK((s_prof[TASK_PROF_UI_PERIOD].max == 500u) && (s_prof[TASK_PROF_UI_PERIOD].last == 300u) && (s_prof[TASK_PROF_UI_PERIOD].count == 2u), - "TC-TASKPROF-002 更小样本不改 max"); + "TC-TASKPROF-002 smaller sample does not change max"); reset_all(); task_prof_sample(TASK_PROF_UI_PERIOD, 0u); CHECK((s_prof[TASK_PROF_UI_PERIOD].glitch == 1u) && (s_prof[TASK_PROF_UI_PERIOD].count == 0u) && (s_prof[TASK_PROF_UI_PERIOD].max == 0u), - "TC-TASKPROF-003 cyc=0 只累加 glitch(DWT 复位防线)"); + "TC-TASKPROF-003 cyc=0 only accumulates glitch (DWT reset defence)"); reset_all(); task_prof_sample(TASK_PROF_UI_PERIOD, SystemCoreClock * 10u); CHECK((s_prof[TASK_PROF_UI_PERIOD].glitch == 1u) && (s_prof[TASK_PROF_UI_PERIOD].count == 0u), - "TC-TASKPROF-004 超上界样本只累加 glitch"); + "TC-TASKPROF-004 over-upper-bound sample only accumulates glitch"); reset_all(); task_prof_sample((task_prof_id_t)TASK_PROF_ID_COUNT, 100u); @@ -205,7 +205,7 @@ static void tc_sample_gate(void) task_prof_enter((task_prof_id_t)TASK_PROF_ID_COUNT); task_prof_exit((task_prof_id_t)TASK_PROF_ID_COUNT); CHECK((s_prof[0].count == 0u) && (s_prof[TASK_PROF_ID_COUNT - 1].count == 0u), - "TC-TASKPROF-005 id 越界安全返回,不碰任何槽"); + "TC-TASKPROF-005 out-of-range id returns safely, touches no slot"); } /* ===================== 时基与 enter/exit 配对 ===================== */ @@ -219,27 +219,27 @@ static void tc_enter_exit(void) CHECK(((g_coredebug.DEMCR & CoreDebug_DEMCR_TRCENA_Msk) != 0u) && ((g_dwt.CTRL & DWT_CTRL_CYCCNTENA_Msk) != 0u) && (s_dwt_ok == 1u), - "TC-TASKPROF-006 首次取时基即惰性使能 DWT"); + "TC-TASKPROF-006 first timebase read lazily enables DWT"); reset_all(); set_cyc(2000u); task_prof_enter(TASK_PROF_UI_WORK); CHECK((s_prof[TASK_PROF_UI_WORK].in_seg == 1u) && (s_prof[TASK_PROF_UI_WORK].t_start == 2000u), - "TC-TASKPROF-007 enter 置 in_seg 并记起点"); + "TC-TASKPROF-007 enter sets in_seg and records the start point"); set_cyc(2640u); task_prof_exit(TASK_PROF_UI_WORK); CHECK((s_prof[TASK_PROF_UI_WORK].in_seg == 0u) && (s_prof[TASK_PROF_UI_WORK].last == 640u) && (s_prof[TASK_PROF_UI_WORK].count == 1u), - "TC-TASKPROF-008 exit 结算 Δ 并清 in_seg"); + "TC-TASKPROF-008 exit settles the delta and clears in_seg"); reset_all(); task_prof_exit(TASK_PROF_ADC_BEAT); CHECK((s_prof[TASK_PROF_ADC_BEAT].count == 0u) && (s_prof[TASK_PROF_ADC_BEAT].glitch == 0u), - "TC-TASKPROF-009 未 enter 直接 exit 不记账(防 0 起点假超大样本)"); + "TC-TASKPROF-009 exit without enter records nothing (guards fake huge sample from 0 start)"); reset_all(); set_cyc(100u); @@ -247,7 +247,7 @@ static void tc_enter_exit(void) set_cyc(150u); task_prof_exit(TASK_PROF_NET_POLL); task_prof_exit(TASK_PROF_NET_POLL); - CHECK(s_prof[TASK_PROF_NET_POLL].count == 1u, "TC-TASKPROF-010 重复 exit 不重复记账"); + CHECK(s_prof[TASK_PROF_NET_POLL].count == 1u, "TC-TASKPROF-010 repeated exit does not double count"); } /* ===================== 上报节流与通道 ===================== */ @@ -258,26 +258,26 @@ static void tc_report_throttle(void) reset_all(); g_tick = 4999u; task_prof_report(); - CHECK((g_line_calls == 0) && (g_raw_calls == 0), "TC-TASKPROF-011 首 5 s 前不发"); + CHECK((g_line_calls == 0) && (g_raw_calls == 0), "TC-TASKPROF-011 nothing sent before the first 5 s"); g_tick = 5000u; task_prof_report(); CHECK((g_line_calls == 2) && (g_raw_calls == 0), - "TC-TASKPROF-012 到点发两行走环形缓冲"); + "TC-TASKPROF-012 on schedule: sends two lines via the ring buffer"); g_tick = 6999u; task_prof_report(); - CHECK(g_line_calls == 2, "TC-TASKPROF-013 不足 2 s 不发"); + CHECK(g_line_calls == 2, "TC-TASKPROF-013 less than 2 s apart sends nothing"); g_tick = 7000u; task_prof_report(); - CHECK(g_line_calls == 4, "TC-TASKPROF-014 满 2 s 再发两行"); + CHECK(g_line_calls == 4, "TC-TASKPROF-014 after a full 2 s sends two lines again"); g_line_calls = 0; g_raw_calls = 0; task_prof_report_raw(); CHECK((g_raw_calls == 2) && (g_line_calls == 0), - "TC-TASKPROF-015 report_raw 无视节流且走裸发通道"); + "TC-TASKPROF-015 report_raw ignores throttling and uses the raw channel"); } /* ===================== 行内容与换算 ===================== */ @@ -293,11 +293,11 @@ static void tc_line_format(void) CHECK((g_line_calls == 2) && (strncmp(g_line[0], "[PROF] ", 7) == 0) && (strncmp(g_line[1], "[PROF2] ", 8) == 0), - "TC-TASKPROF-016 两行行首分别是 [PROF] / [PROF2]"); + "TC-TASKPROF-016 the two lines start with [PROF] / [PROF2] respectively"); CHECK((strstr(g_line[0], "\r\n") != NULL) && (strstr(g_line[1], "\r\n") != NULL), - "TC-TASKPROF-016b 两行都以 CRLF 结尾"); - CHECK(field_of(0, "uip=") == 0L, "TC-TASKPROF-016c 未采样的槽打印 0"); + "TC-TASKPROF-016b both lines end with CRLF"); + CHECK(field_of(0, "uip=") == 0L, "TC-TASKPROF-016c an unsampled slot prints 0"); /* 017:打印的是**微秒**,分母是 SystemCoreClock —— 断言落在打印字段上 */ reset_all(); @@ -306,14 +306,14 @@ static void tc_line_format(void) g_tick = 5000u; task_prof_report(); CHECK(field_of(0, "uip=") == 10L, - "TC-TASKPROF-017 168 MHz:1680 周期的 max 打印成 uip=10"); + "TC-TASKPROF-017 168 MHz: max of 1680 cycles prints as uip=10"); CHECK(field_of(0, "adcm=") == 20L, - "TC-TASKPROF-017b 同频:3360 周期的 max 打印成 adcm=20"); + "TC-TASKPROF-017b same clock: max of 3360 cycles prints as adcm=20"); SystemCoreClock = 84000000u; /* 改时钟树而忘了同步 → 整表偏移,这里必须显式跟着变 */ g_tick = 7000u; task_prof_report(); CHECK(field_of(2, "uip=") == 20L, - "TC-TASKPROF-017c 84 MHz 下同一批周期数打印成 20"); + "TC-TASKPROF-017c at 84 MHz the same cycle counts print as 20"); SystemCoreClock = 168000000u; /* 018:gl= 是**所有槽**的 glitch 汇总,不是当前槽 */ @@ -323,7 +323,7 @@ static void tc_line_format(void) task_prof_sample(TASK_PROF_NET_POLL, 0u); g_tick = 5000u; task_prof_report(); - CHECK(field_of(0, "gl=") == 3L, "TC-TASKPROF-018 gl= 汇总所有槽的 glitch"); + CHECK(field_of(0, "gl=") == 3L, "TC-TASKPROF-018 gl= sums the glitch of all slots"); /* 019:段未结算时,"此刻已在段内多久"要看得见(uipn / netn 两个字段) */ /* 字段口径 = 上报时刻的 CYCCNT 减去各自的进段时刻(**不是**样本值): @@ -338,13 +338,13 @@ static void tc_line_format(void) g_tick = 5000u; task_prof_report(); CHECK(field_of(0, "uipn=") == 301L, - "TC-TASKPROF-019 UI_PERIOD 段内:uipn= 上报此刻已停留的 us"); + "TC-TASKPROF-019 inside UI_PERIOD segment: uip= reports the us elapsed so far"); CHECK(field_of(1, "netn=") == 248L, - "TC-TASKPROF-019b NET_POLL 段内:[PROF2] 的 netn= 同步可见"); + "TC-TASKPROF-019b inside NET_POLL segment: netn= of [PROF2] is visible too"); CHECK(field_of(0, "adcn=") == 0L, - "TC-TASKPROF-019c 未进段的 ADC_BEAT 打印 0(不串用别的槽)"); + "TC-TASKPROF-019c ADC_BEAT not in segment prints 0 (no cross-slot leakage)"); CHECK(s_prof[TASK_PROF_UI_PERIOD].in_seg == 1u, - "TC-TASKPROF-019d 上报不消费段状态(只观测)"); + "TC-TASKPROF-019d reporting does not consume segment state (observe only)"); /* 020:count 是累计量,两轮上报之间不能清零 */ reset_all(); @@ -355,7 +355,7 @@ static void tc_line_format(void) task_prof_report(); CHECK((s_prof[TASK_PROF_UI_WORK].count == 1u) && (field_of(2, "uic=") == 0L) && (field_of(0, "uic=") == 0L), - "TC-TASKPROF-020 上报不清零(UI_WORK 不在 uic= 字段,仍为累计 1)"); + "TC-TASKPROF-020 reporting does not clear counters (UI_WORK not in uic= field, still cumulative 1)"); } diff --git a/test/host/time_sync/time_sync_test.c b/test/host/time_sync/time_sync_test.c index 32a3fbfb..e4abe860 100644 --- a/test/host/time_sync/time_sync_test.c +++ b/test/host/time_sync/time_sync_test.c @@ -418,31 +418,31 @@ static int delays_all(uint32_t v, int n) { static void tc_delay_fed(void) { fakes_reset(); time_sync_delay_fed(0U); - CHECK((s_beat_calls == 0) && (s_delay_calls == 0), "TC-TIMESYNC-001 delay_fed(0) 不睡眠不喂狗"); + CHECK((s_beat_calls == 0) && (s_delay_calls == 0), "TC-TIMESYNC-001 delay_fed(0) neither sleeps nor beats"); fakes_reset(); time_sync_delay_fed(50U); CHECK((s_beat_calls == 1) && (s_delay_calls == 1) && (s_delays[0] == 50U), - "TC-TIMESYNC-002 delay_fed(50) = 1 片 50ms + 1 次心跳"); + "TC-TIMESYNC-002 delay_fed(50) = one 50 ms slice + 1 beat"); fakes_reset(); time_sync_delay_fed(120U); - CHECK((s_beat_calls == 3) && (s_delay_calls == 3), "TC-TIMESYNC-003 delay_fed(120) 切成 3 片"); + CHECK((s_beat_calls == 3) && (s_delay_calls == 3), "TC-TIMESYNC-003 delay_fed(120) splits into 3 slices"); CHECK((s_delays[0] == 50U) && (s_delays[1] == 50U) && (s_delays[2] == 20U), - "TC-TIMESYNC-003b 片长 50/50/20(末片为余数)"); + "TC-TIMESYNC-003b slice lengths 50/50/20 (last slice is the remainder)"); fakes_reset(); time_sync_delay_fed(2000U); CHECK((s_delay_calls == 40) && (s_beat_calls == 40) && delays_all(50U, 40), - "TC-TIMESYNC-004 delay_fed(2000) = 40 片 × 50ms,每片喂一次心跳"); + "TC-TIMESYNC-004 delay_fed(2000) = 40 slices x 50 ms, one beat per slice"); fakes_reset(); time_sync_delay_fed(49U); - CHECK((s_beat_calls == 1) && (s_delays[0] == 49U), "TC-TIMESYNC-005 不足一片(49ms)单片处理"); + CHECK((s_beat_calls == 1) && (s_delays[0] == 49U), "TC-TIMESYNC-005 less than one slice (49 ms) handled as a single slice"); fakes_reset(); time_sync_delay_fed(30000U); - CHECK(s_delay_calls == 600, "TC-TIMESYNC-006 总预算 30s = 600 片(片长上限恒 50ms)"); + CHECK(s_delay_calls == 600, "TC-TIMESYNC-006 total budget 30 s = 600 slices (slice cap is always 50 ms)"); } /* ===================== TC-TIMESYNC-010..015:open_listener ===================== */ @@ -451,13 +451,13 @@ static void tc_open_listener(void) { fakes_reset(); { int s = time_sync_open_listener(); - CHECK(s == 5, "TC-TIMESYNC-010 open_listener 成功返回 socket 描述符"); + CHECK(s == 5, "TC-TIMESYNC-010 open_listener success returns the socket descriptor"); CHECK((s_socket_calls == 1) && (s_bind_calls == 1) && (s_listen_calls == 1), - "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 为网络序"); + "TC-TIMESYNC-010b socket / bind / listen called once each"); + CHECK(s_htons_last == (uint16_t)TIME_SYNC_PORT, "TC-TIMESYNC-010c port goes through net_htons(8888)"); + CHECK(s_bind_port == net_htons((uint16_t)TIME_SYNC_PORT), "TC-TIMESYNC-010d sin_port is in network byte order"); 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 成功路径无退避延时"); + CHECK(s_delay_calls == 0, "TC-TIMESYNC-010f no backoff delay on the success path"); } 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-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"); + CHECK(s == 5, "TC-TIMESYNC-011 bind succeeds on retry after one failure"); + CHECK((s_close_calls == 1) && (s_close_socks[0] == 5), "TC-TIMESYNC-011b bind failure closes that socket"); + CHECK(s_delay_calls == 40, "TC-TIMESYNC-011c bind failure backs off 2000 ms (40 slices)"); + CHECK(g_tstest_err_count == 1, "TC-TIMESYNC-011d bind failure leaves a DBG_ERROR trace"); } 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-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"); + CHECK(s == 5, "TC-TIMESYNC-012 listen succeeds on retry after one failure"); + CHECK((s_close_calls == 1) && (s_close_socks[0] == 5), "TC-TIMESYNC-012b listen failure closes that socket"); + CHECK(s_delay_calls == 40, "TC-TIMESYNC-012c listen failure backs off 2000 ms"); } fakes_reset(); s_socket_default = -1; { int s = time_sync_open_listener(); - 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 片)"); + CHECK(s == -1, "TC-TIMESYNC-013 socket keeps failing -> returns -1"); + CHECK(s_socket_calls == 5, "TC-TIMESYNC-013b retry cap is 5 attempts"); + CHECK(g_tstest_err_count == 5, "TC-TIMESYNC-013c every failure leaves its own trace (5 DBG_ERROR lines)"); + CHECK(s_delay_calls == 50, "TC-TIMESYNC-013d every failure backs off 500 ms (5 x 10 slices)"); } fakes_reset(); @@ -498,16 +498,16 @@ static void tc_open_listener(void) { s_socket_seq_n = 3; { int s = time_sync_open_listener(); - 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"); + CHECK(s == 9, "TC-TIMESYNC-014 3rd retry succeeds and returns the new descriptor"); + CHECK(s_socket_calls == 3, "TC-TIMESYNC-014b exactly 3 attempts"); + CHECK(s_delay_calls == 20, "TC-TIMESYNC-014c two failures back off 500 ms x 2"); } fakes_reset(); s_socket_default = -1; (void)time_sync_open_listener(); - CHECK(s_beat_calls == 55, "TC-TIMESYNC-015 每轮重试(5) + 每片延时(50) 各喂一次心跳"); - CHECK(s_beat_id_bad == 0, "TC-TIMESYNC-015b 心跳位恒为 TASK_WD_TIMESYNC"); + CHECK(s_beat_calls == 55, "TC-TIMESYNC-015 every retry round (5) + every delay slice (50) beats once"); + CHECK(s_beat_id_bad == 0, "TC-TIMESYNC-015b the beat bit is always TASK_WD_TIMESYNC"); } /* ===================== TC-TIMESYNC-020..029:handle_conn ===================== @@ -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-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"); + CHECK(s_set_unix_calls == 1, "TC-TIMESYNC-020 TIME packet in one shot -> wall clock updated once"); + CHECK(s_set_unix_last == 0x12345678u, "TC-TIMESYNC-020b epoch parsed big-endian"); + CHECK((s_recv_calls == 1) && (s_recv_len_log[0] == 16), "TC-TIMESYNC-020c the first request asks for 16 bytes"); + CHECK(s_recv_to_log[0] == 50U, "TC-TIMESYNC-020d single wait slice length = 50 ms"); + CHECK(s_close_calls == 0, "TC-TIMESYNC-020e after handling, the connection is **not** closed (close is the outer conn!=ls branch job)"); + CHECK(s_drop_calls == 0, "TC-TIMESYNC-020g a successful session is not torn down (drop is only for give-up paths)"); + CHECK(g_tstest_info_count == 1, "TC-TIMESYNC-020f leaves the wall clock updated trace"); /* 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-TIMESYNC-021 分段送达累积后解析正确"); - CHECK(s_recv_calls == 2, "TC-TIMESYNC-021b 读了两次"); + CHECK((s_set_unix_calls == 1) && (s_set_unix_last == 10u), "TC-TIMESYNC-021 pieces accumulate and then parse correctly"); + CHECK(s_recv_calls == 2, "TC-TIMESYNC-021b read twice"); CHECK((s_recv_len_log[0] == 16) && (s_recv_len_log[1] == 12), - "TC-TIMESYNC-021c 第二次只请求剩余 12 字节"); - CHECK((s_recv_to_log[0] == 50U) && (s_recv_to_log[1] == 50U), "TC-TIMESYNC-021d 每片 50ms(预算充裕)"); + "TC-TIMESYNC-021c the second request asks only for the remaining 12 bytes"); + CHECK((s_recv_to_log[0] == 50U) && (s_recv_to_log[1] == 50U), "TC-TIMESYNC-021d 50 ms per slice (budget is ample)"); /* 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-TIMESYNC-022 超长包只取前 8 字节"); - CHECK(s_recv_calls == 1, "TC-TIMESYNC-022b 一次读够即停"); + CHECK((s_set_unix_calls == 1) && (s_set_unix_last == 5u), "TC-TIMESYNC-022 an over-long packet only takes the first 8 bytes"); + CHECK(s_recv_calls == 1, "TC-TIMESYNC-022b stops as soon as one read is enough"); /* 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-TIMESYNC-023 非 TIME 前缀不更新墙钟"); - CHECK(s_close_calls == 0, "TC-TIMESYNC-023b 非 TIME 前缀也不关闭连接"); + CHECK(s_set_unix_calls == 0, "TC-TIMESYNC-023 a non-TIME prefix does not update the wall clock"); + CHECK(s_close_calls == 0, "TC-TIMESYNC-023b a non-TIME prefix also does not close the connection"); /* 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-TIMESYNC-024 对端关闭(EOF)立即退出不解析"); - CHECK(s_close_calls == 0, "TC-TIMESYNC-024b EOF 也不关闭连接(net 层 auto_relisten 收口监听)"); + CHECK((s_set_unix_calls == 0) && (s_recv_calls == 1), "TC-TIMESYNC-024 peer close (EOF) exits immediately without parsing"); + CHECK(s_close_calls == 0, "TC-TIMESYNC-024b EOF also does not close the connection (net-layer auto_relisten re-arms the listener)"); /* 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-TIMESYNC-025 真错误立即退出不解析"); + CHECK((s_recv_calls == 1) && (s_set_unix_calls == 0), "TC-TIMESYNC-025 a real error exits immediately without parsing"); /* 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-TIMESYNC-026 不足 8 字节不解析"); - CHECK(s_recv_calls == 2, "TC-TIMESYNC-026b 继续等待后续字节"); + CHECK(s_set_unix_calls == 0, "TC-TIMESYNC-026 fewer than 8 bytes are not parsed"); + CHECK(s_recv_calls == 2, "TC-TIMESYNC-026b keeps waiting for the remaining bytes"); /* 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-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 拆连接保监听)"); + CHECK(s_recv_calls == 1, "TC-TIMESYNC-027 no more reads once the budget is exhausted (only 1 read)"); + CHECK(g_tstest_info_count == 1, "TC-TIMESYNC-027b leaves the no TIME packet in 30s, drop conn trace"); + CHECK(s_close_calls == 0, "TC-TIMESYNC-027c budget exhausted still does not close the connection"); + CHECK(s_drop_calls == 1, "TC-TIMESYNC-027d budget exhausted drops the session on purpose (E-02 wrap-up: net_drop_conn kills the connection, keeps the listener)"); /* 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-TIMESYNC-028 两次等待后结束"); + CHECK(s_recv_calls == 2, "TC-TIMESYNC-028 ends after two waits"); CHECK((s_recv_to_log[0] == 50U) && (s_recv_to_log[1] == 20U), - "TC-TIMESYNC-028b 第二次片长 = 剩余 20ms"); + "TC-TIMESYNC-028b second slice length = the remaining 20 ms"); /* 10) 32 位 tick 回绕 */ fakes_reset(); @@ -623,7 +623,7 @@ 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-TIMESYNC-029 32 位 tick 回绕后预算计算仍正确"); + "TC-TIMESYNC-029 after a 32-bit tick wraparound the budget math is still correct"); } /* ===================== TC-TIMESYNC-040..044:time_sync_task ===================== */ @@ -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-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 位"); + "TC-TIMESYNC-040 task entry registers the watchdog beat bit (task_wd_bind once)"); + CHECK(s_evt_calls == 0, "TC-TIMESYNC-040b skips the readiness barrier when sys_evtHandle==NULL"); + CHECK(s_accept_calls == 3, "TC-TIMESYNC-040c accept polled 3 times (2 with no connection + 1 success)"); + CHECK((s_set_unix_calls == 1) && (s_set_unix_last == 9u), "TC-TIMESYNC-040d the time packet arrived and the wall clock was updated"); + CHECK(s_close_calls == 1, "TC-TIMESYNC-040e the connection is closed once"); + CHECK(s_delay_calls == 9, "TC-TIMESYNC-040f delay slice count = 4+4+1 (200+200+50 ms)"); + CHECK(delays_all(50U, 9), "TC-TIMESYNC-040g every delay is sliced at 50 ms"); + CHECK(s_beat_calls == 13, "TC-TIMESYNC-040h beat count = main loop 1 + backoff 8 + accepted connection 1 + wrap-up 1 + next round 1"); + CHECK(s_beat_id_bad == 0, "TC-TIMESYNC-040i every beat sets the TIMESYNC bit"); /* 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-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 仍先登记心跳路由"); + CHECK(s_evt_calls == 3, "TC-TIMESYNC-041 readiness barrier polled 3 times (2 not ready + 1 ready)"); + CHECK(s_evt_last_timeout == 100U, "TC-TIMESYNC-041b barrier waits are sliced at 100 ms"); + CHECK(s_evt_last_flags == SYS_EVT_NET_READY, "TC-TIMESYNC-041c waits for the NET_READY bit"); + CHECK(s_evt_last_options == (osFlagsWaitAny | osFlagsNoClear), "TC-TIMESYNC-041d the ready bit is not consumed"); + CHECK(s_beat_calls == 3, "TC-TIMESYNC-041e the two not-ready rounds each beat once (+ 1 in the main loop)"); + CHECK(s_wd_bind_calls == 1, "TC-TIMESYNC-041f still registers the beat routing first"); /* 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-TIMESYNC-042 屏障等待 4 次均未就绪(循环未挂死)"); - CHECK(s_beat_calls == 3, "TC-TIMESYNC-042b 每次未就绪后各喂一次心跳(第 4 次跳出前)"); + CHECK(s_evt_calls == 4, "TC-TIMESYNC-042 barrier waited 4 times, none ready (loop did not hang)"); + CHECK(s_beat_calls == 3, "TC-TIMESYNC-042b beats once after each not-ready round (before the 4th breaks out)"); /* 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-TIMESYNC-043 代次变化时关闭旧监听"); + CHECK((s_close_calls == 1) && (s_close_socks[0] == 5), "TC-TIMESYNC-043 closes the old listener when the network generation changes"); /* INFO 三条:两次 open_listener 成功各一条 "TCP listen on" + 一条 "network re-init, relisten" */ - 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(g_tstest_info_count == 3, "TC-TIMESYNC-043b leaves the network re-init, relisten trace (plus 2 listen-success lines)"); + CHECK(s_accept_calls == 2, "TC-TIMESYNC-043c polls accept only once per loop then gives up"); CHECK((s_socket_calls == 2) && (s_bind_calls == 2) && (s_listen_calls == 2), - "TC-TIMESYNC-043d 第二次循环重建了监听"); + "TC-TIMESYNC-043d the second loop rebuilt the listener"); /* 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-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 位"); + CHECK(s_socket_calls == 5, "TC-TIMESYNC-044 open_listener gives up after 5 internal retries"); + CHECK(g_tstest_err_count == 6, "TC-TIMESYNC-044b 5 net_socket FAIL lines + 1 retry later line"); + CHECK(s_delay_calls == 90, "TC-TIMESYNC-044c backoff 5x500 ms + 2000 ms = 90 slices"); + CHECK(s_beat_calls == 97, "TC-TIMESYNC-044d beat count = 2 + 5 + 50 + 40"); + CHECK(s_beat_id_bad == 0, "TC-TIMESYNC-044e every beat sets the TIMESYNC bit"); } /* ===================== main ===================== */ diff --git a/test/host/vol_lock/vol_lock_test.c b/test/host/vol_lock/vol_lock_test.c index d2f74c3a..436d3d8b 100644 --- a/test/host/vol_lock/vol_lock_test.c +++ b/test/host/vol_lock/vol_lock_test.c @@ -114,21 +114,21 @@ static void fakes_reset(void) { static void tc_init(void) { fakes_reset(); - 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-VOLLOCK-001 first init call returns 0"); + CHECK(s_new_calls == 1, "TC-VOLLOCK-001b init creates the mutex exactly once (osMutexNew)"); + CHECK(s_lock != NULL, "TC-VOLLOCK-001c module static state holds the handle"); - CHECK(vol_lock_init() == 0, "TC-VOLLOCK-002 init 重复调用仍返回 0(幂等)"); - CHECK(s_new_calls == 1, "TC-VOLLOCK-002b 幂等:不再创建第二个互斥量"); + CHECK(vol_lock_init() == 0, "TC-VOLLOCK-002 repeated init still returns 0 (idempotent)"); + CHECK(s_new_calls == 1, "TC-VOLLOCK-002b idempotent: no second mutex created"); fakes_reset(); s_new_fail = 1; - CHECK(vol_lock_init() == -1, "TC-VOLLOCK-003 osMutexNew 失败 -> init 返回 -1"); - CHECK(s_lock == NULL, "TC-VOLLOCK-003b 失败时不留下半初始化句柄"); + CHECK(vol_lock_init() == -1, "TC-VOLLOCK-003 osMutexNew failure -> init returns -1"); + CHECK(s_lock == NULL, "TC-VOLLOCK-003b failure leaves no half-initialized handle"); s_new_fail = 0; - CHECK(vol_lock_init() == 0, "TC-VOLLOCK-004 失败后重试可成功(返回 0)"); - CHECK(s_new_calls == 2, "TC-VOLLOCK-004b 重试确实再次调用 osMutexNew"); + CHECK(vol_lock_init() == 0, "TC-VOLLOCK-004 retry after failure can succeed (returns 0)"); + CHECK(s_new_calls == 2, "TC-VOLLOCK-004b retry really calls osMutexNew again"); } /* ===================== TC-VOLLOCK-005..010:vol_lock_wait ===================== */ @@ -137,46 +137,46 @@ static void tc_wait(void) { /* --- 已创建:超时值原样透传 --- */ fakes_reset(); (void)vol_lock_init(); - 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"); + CHECK(vol_lock_wait(100U) == 1, "TC-VOLLOCK-005 wait returns 1 on acquire success"); + CHECK(s_wait_calls == 1, "TC-VOLLOCK-005b osMutexWait called once"); + CHECK(s_last_timeout == 100U, "TC-VOLLOCK-005c timeout passed through to osMutexWait unchanged"); fakes_reset(); (void)vol_lock_init(); - 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"); + CHECK(vol_lock_wait(0U) == 1, "TC-VOLLOCK-014 wait(0) returns 1 on acquire (try semantics)"); + CHECK(s_last_timeout == 0U, "TC-VOLLOCK-014b wait(0) timeout passes through as 0"); /* --- 超时:osMutexWait != osOK -> 返回 0 --- */ fakes_reset(); (void)vol_lock_init(); s_wait_ok = 0; - CHECK(vol_lock_wait(50U) == 0, "TC-VOLLOCK-006 osMutexWait 非 osOK -> wait 返回 0"); - CHECK(s_wait_calls == 1, "TC-VOLLOCK-006b 超时路径确实尝试过等待"); + CHECK(vol_lock_wait(50U) == 0, "TC-VOLLOCK-006 osMutexWait not osOK -> wait returns 0"); + CHECK(s_wait_calls == 1, "TC-VOLLOCK-006b timeout path really attempted the wait"); /* --- 锁未创建:自动 init 后正常获取 --- */ fakes_reset(); - 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 随后执行了一次等待"); + CHECK(vol_lock_wait(10U) == 1, "TC-VOLLOCK-007 wait auto-inits and acquires when no lock exists"); + CHECK(s_new_calls == 1, "TC-VOLLOCK-007b auto init created the mutex"); + CHECK(s_wait_calls == 1, "TC-VOLLOCK-007c then performed one wait"); /* --- ⭐ fail-open:创建失败必须返回 1 且绝不阻塞 --- */ fakes_reset(); s_new_fail = 1; - 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 后仍无句柄"); + CHECK(vol_lock_wait(0U) == 1, "TC-VOLLOCK-008 fail-open: returns 1 even if lock creation fails (never blocks a feed point)"); + CHECK(s_wait_calls == 0, "TC-VOLLOCK-008b fail-open **does not call** osMutexWait (zero blocking)"); + CHECK(s_lock == NULL, "TC-VOLLOCK-008c still no handle after fail-open"); /* --- fail-open 之后 release 无害 --- */ vol_lock_release(); - CHECK(s_release_calls == 0, "TC-VOLLOCK-009 fail-open 后 release 不调用 osMutexRelease(判空静默)"); + CHECK(s_release_calls == 0, "TC-VOLLOCK-009 after fail-open release does not call osMutexRelease (NULL guard, silent)"); /* --- 已创建时 wait 不再创建 --- */ fakes_reset(); (void)vol_lock_init(); (void)vol_lock_wait(0U); (void)vol_lock_wait(0U); - CHECK(s_new_calls == 1, "TC-VOLLOCK-010 多次 wait 不重复创建互斥量"); - CHECK(s_wait_calls == 2, "TC-VOLLOCK-010b 每次 wait 各等待一次"); + CHECK(s_new_calls == 1, "TC-VOLLOCK-010 repeated wait does not recreate the mutex"); + CHECK(s_wait_calls == 2, "TC-VOLLOCK-010b each wait performs one wait call"); } /* ===================== TC-VOLLOCK-011..013:vol_lock_release ===================== */ @@ -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-VOLLOCK-011 已持锁时 release 调用 osMutexRelease 一次"); + CHECK(s_release_calls == 1, "TC-VOLLOCK-011 release while holding the lock calls osMutexRelease once"); /* --- 锁未创建:静默返回 --- */ fakes_reset(); vol_lock_release(); - CHECK(s_release_calls == 0, "TC-VOLLOCK-012 锁未创建时 release 静默返回(不调用、不崩溃)"); + CHECK(s_release_calls == 0, "TC-VOLLOCK-012 release with no lock returns silently (no call, no crash)"); /* --- 完整周期 --- */ fakes_reset(); - CHECK(vol_lock_init() == 0, "TC-VOLLOCK-013 周期:init -> 0"); - CHECK(vol_lock_wait(0U) == 1, "TC-VOLLOCK-013b 周期:wait -> 1"); + CHECK(vol_lock_init() == 0, "TC-VOLLOCK-013 cycle: init -> 0"); + CHECK(vol_lock_wait(0U) == 1, "TC-VOLLOCK-013b cycle: wait -> 1"); vol_lock_release(); - CHECK(vol_lock_wait(100U) == 1, "TC-VOLLOCK-013c 周期:再 wait -> 1(可重复获取)"); + CHECK(vol_lock_wait(100U) == 1, "TC-VOLLOCK-013c cycle: wait again -> 1 (re-acquirable)"); vol_lock_release(); - 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 透传正确"); + CHECK(s_new_calls == 1, "TC-VOLLOCK-013d cycle: only one mutex created overall"); + CHECK(s_release_calls == 2, "TC-VOLLOCK-013e cycle: released twice"); + CHECK(s_last_timeout == 100U, "TC-VOLLOCK-013f cycle: second wait timeout passes through correctly"); } /* ===================== main ===================== */ diff --git a/test/host/watchdog/watchdog_test.c b/test/host/watchdog/watchdog_test.c index 5755408b..4ab32208 100644 --- a/test/host/watchdog/watchdog_test.c +++ b/test/host/watchdog/watchdog_test.c @@ -131,44 +131,44 @@ static void beat_all(void) { /* ===================== 用例 ===================== */ static void tc_001_not_armed(void) { - printf("TC-WATCHDOG-001 未启动时 poll 不做判定\n"); + printf("TC-WATCHDOG-001 poll makes no decision before start\n"); beat_all(); poll_advance(1000); - CHECK(s_feed_count == 0, "未启动时 poll 不喂狗"); - CHECK(task_wd_is_armed() == 0, "is_armed == 0(未启动)"); + CHECK(s_feed_count == 0, "poll does not feed before start"); + CHECK(task_wd_is_armed() == 0, "is_armed == 0 (not started)"); } static void tc_002_throttle(void) { - printf("TC-WATCHDOG-002 节流:< 100ms 直接返回\n"); + printf("TC-WATCHDOG-002 throttle: < 100ms returns directly\n"); start_and_clear(); beat_all(); poll_advance(50); /* 50ms < 100ms → 不抽样 */ - CHECK(s_feed_count == 0, "50ms 内 poll 不喂狗"); + CHECK(s_feed_count == 0, "poll within 50ms does not feed"); poll_advance(50); /* 累计 100ms → 抽样 */ - CHECK(s_feed_count == 1, "累计 100ms 后喂狗 1 次"); + CHECK(s_feed_count == 1, "after 100ms accumulated, fed exactly once"); } static void tc_003_all_beat_feeds(void) { - printf("TC-WATCHDOG-003 全员到位 → 喂狗一次\n"); + printf("TC-WATCHDOG-003 all tasks present -> feed once\n"); start_and_clear(); beat_all(); poll_advance(100); - CHECK(s_feed_count == 1, "全员到位喂狗 1 次"); - CHECK(task_wd_last_mask() == 0x1F7u, "last_mask == 0x1F7(bit0|1|2|4|5|6|7|8)"); + CHECK(s_feed_count == 1, "all present feeds exactly once"); + CHECK(task_wd_last_mask() == 0x1F7u, "last_mask == 0x1F7 (bit0|1|2|4|5|6|7|8)"); } static void tc_004_take_and_clear(void) { - printf("TC-WATCHDOG-004 取走清零:旧位不残留\n"); + printf("TC-WATCHDOG-004 take-and-clear: no stale bits left\n"); start_and_clear(); beat_all(); poll_advance(100); /* 消费位图并喂狗 */ - CHECK(s_feed_count == 1, "第一轮喂狗"); + CHECK(s_feed_count == 1, "first round fed"); poll_advance(100); /* 不重新置位 */ - CHECK(s_feed_count == 1, "未重新置位 → 第二轮不喂狗(位图已取走清零)"); + CHECK(s_feed_count == 1, "no re-set -> second round does not feed (bitmap already taken and cleared)"); } static void tc_005_mask_required(void) { - printf("TC-WATCHDOG-005 掩码判定:缺任一位不喂\n"); + printf("TC-WATCHDOG-005 mask check: missing any bit -> no feed\n"); start_and_clear(); /* 故意缺 UI(bit4) */ task_wd_beat(TASK_WD_DEFAULT); @@ -179,31 +179,31 @@ static void tc_005_mask_required(void) { task_wd_beat(TASK_WD_IEC104); task_wd_beat(TASK_WD_PROTECT); poll_advance(100); - CHECK(s_feed_count == 0, "缺 UI 位 → 不喂狗"); + CHECK(s_feed_count == 0, "UI bit missing -> no feed"); CHECK(task_wd_last_mask() == (0x1F7u & ~(1u << TASK_WD_UI)), - "last_mask 精确记录缺失位"); + "last_mask records the missing bit exactly"); } static void tc_006_stall_8(void) { - printf("TC-WATCHDOG-006 连续 8 次缺席 → 打 stall 并停喂\n"); + printf("TC-WATCHDOG-006 8 consecutive misses -> print stall and stop feeding\n"); start_and_clear(); beat_all(); poll_advance(100); /* streak 清零 */ int err0 = g_wdtest_err_count; for (int i = 1; i <= 7; i++) { poll_advance(100); - CHECK(g_wdtest_err_count == err0, "第 1..7 次缺席不报 stall"); + CHECK(g_wdtest_err_count == err0, "misses 1..7 do not report stall"); } poll_advance(100); /* 第 8 次 */ - CHECK(g_wdtest_err_count == err0 + 1, "第 8 次缺席打 [WD] task stall"); - CHECK(s_feed_count == 1, "全程仅在开始时喂过 1 次(缺席期间未喂)"); + CHECK(g_wdtest_err_count == err0 + 1, "8th miss prints [WD] task stall"); + CHECK(s_feed_count == 1, "fed exactly once at the start only (nothing fed during the missing period)"); } static void tc_007_stall_repeats_until_reset(void) { - printf("TC-WATCHDOG-007 停喂后 stall 日志持续复报(当前设计:每 100ms 一条)\n"); + printf("TC-WATCHDOG-007 after feeding stops the stall log keeps repeating (current design: one per 100ms)\n"); start_and_clear(); for (int i = 0; i < 8; i++) poll_advance(100); /* 第 8 次触发 */ int err8 = g_wdtest_err_count; - CHECK(err8 == 1, "第 8 次缺席后已报 1 条 stall"); + CHECK(err8 == 1, "after the 8th miss exactly 1 stall line was reported"); poll_advance(100); /* 第 9 次 */ poll_advance(100); /* 第 10 次 */ /* @@ -213,89 +213,89 @@ static void tc_007_stall_repeats_until_reset(void) { * 代价是日志冗余(约 9 条/停顿周期)。若改为"每停顿周期仅报一次", * 需加一个 s_stall_reported 标志,见文档"已知可优化点"。 */ - CHECK(g_wdtest_err_count == err8 + 2, "停喂后每次抽样都复报 stall(现状)"); + CHECK(g_wdtest_err_count == err8 + 2, "after feeding stops every sample re-reports stall (current behaviour)"); } static void tc_008_recover(void) { - printf("TC-WATCHDOG-008 恢复:重新全员到位 → 喂狗 + streak 归零\n"); + printf("TC-WATCHDOG-008 recovery: all present again -> feed + streak reset\n"); start_and_clear(); for (int i = 0; i < 8; i++) poll_advance(100); /* 触发 stall */ beat_all(); poll_advance(100); - CHECK(s_feed_count == 1, "恢复后立即喂狗"); + CHECK(s_feed_count == 1, "feeds immediately after recovery"); int err0 = g_wdtest_err_count; poll_advance(100); /* 再缺一次 */ - CHECK(g_wdtest_err_count == err0, "streak 已归零:单次缺席不报 stall"); + CHECK(g_wdtest_err_count == err0, "streak already reset: a single miss does not report stall"); } static void tc_009_throttle_boundary(void) { - printf("TC-WATCHDOG-009 节流窗口边界 99/100/199/200\n"); + printf("TC-WATCHDOG-009 throttle window edges 99/100/199/200\n"); start_and_clear(); beat_all(); - poll_advance(99); CHECK(s_feed_count == 0, "99ms 不判"); - poll_advance(1); CHECK(s_feed_count == 1, "100ms 判(喂狗)"); + poll_advance(99); CHECK(s_feed_count == 0, "99ms: no decision"); + poll_advance(1); CHECK(s_feed_count == 1, "100ms: decides (feed)"); beat_all(); - poll_advance(99); CHECK(s_feed_count == 1, "再 99ms 不判"); - poll_advance(1); CHECK(s_feed_count == 2, "累计 100ms 判"); + poll_advance(99); CHECK(s_feed_count == 1, "another 99ms: no decision"); + poll_advance(1); CHECK(s_feed_count == 2, "accumulated 100ms: decides"); } static void tc_010_tick_wrap(void) { - printf("TC-WATCHDOG-010 tick 回绕安全\n"); + printf("TC-WATCHDOG-010 tick wraparound is safe\n"); start_and_clear(); s_tick = 0xFFFFFF00u; /* 推到接近 2^32 回绕 */ task_wd_poll(); /* 建立基线(此处可能不判,取决节流) */ beat_all(); s_feed_count = 0; poll_advance(0x100u); /* 跨越回绕:0xFFFFFF00 + 0x100 = 0 */ - CHECK(s_feed_count == 1, "回绕处 100ms 仍正确判(无符号差)"); + CHECK(s_feed_count == 1, "across the wraparound 100ms still decides correctly (unsigned diff)"); } static void tc_011_observers(void) { - printf("TC-WATCHDOG-011 观测接口语义\n"); + printf("TC-WATCHDOG-011 observation API semantics\n"); start_and_clear(); - CHECK(task_wd_is_armed() == 1, "is_armed == 1(已启动)"); + CHECK(task_wd_is_armed() == 1, "is_armed == 1 (started)"); beat_all(); poll_advance(100); - CHECK(task_wd_last_mask() == 0x1F7u, "last_mask 反映最近一次抽样"); - CHECK(task_wd_miss_count() == 0u, "全程达标 → miss_count == 0"); + CHECK(task_wd_last_mask() == 0x1F7u, "last_mask reflects the most recent sample"); + CHECK(task_wd_miss_count() == 0u, "all rounds met -> miss_count == 0"); } static void tc_013_bad_id(void) { - printf("TC-WATCHDOG-013 非法任务 ID 被忽略\n"); + printf("TC-WATCHDOG-013 invalid task id is ignored\n"); start_and_clear(); task_wd_beat((task_wd_id_t)(TASK_WD_ID_MAX + 3)); /* 非法:应被忽略 */ poll_advance(100); - CHECK(s_feed_count == 0, "非法 ID 未污染位图(必需位全缺 → 不喂)"); - CHECK(task_wd_last_mask() == 0u, "位图保持 0(非法位未置)"); + CHECK(s_feed_count == 0, "invalid id does not pollute the bitmap (all required bits missing -> no feed)"); + CHECK(task_wd_last_mask() == 0u, "bitmap stays 0 (invalid bit never set)"); } static void tc_014_start_idempotent(void) { - printf("TC-WATCHDOG-014 start 幂等\n"); + printf("TC-WATCHDOG-014 start is idempotent\n"); task_wd_start(); task_wd_start(); - CHECK(s_start_count == 1, "重复 start 只启动 IWDG 一次"); + CHECK(s_start_count == 1, "repeated start launches IWDG only once"); CHECK(task_wd_is_armed() == 1, "is_armed == 1"); } static void tc_015_start_feeds_once(void) { - printf("TC-WATCHDOG-015 start 先喂一次(首个窗口从启动时刻起算)\n"); + printf("TC-WATCHDOG-015 start feeds once first (first window counted from the start instant)\n"); task_wd_start(); - CHECK(s_start_count == 1, "start 启动 IWDG 一次"); - CHECK(s_feed_count == 1, "start 内部先喂狗一次(避免启动即超时)"); + CHECK(s_start_count == 1, "start launches IWDG once"); + CHECK(s_feed_count == 1, "start feeds once internally (avoids a timeout right at boot)"); } static void tc_016_stall_not_armed_no_feed(void) { - printf("TC-WATCHDOG-016 未启动时即便全员到位也不喂\n"); + printf("TC-WATCHDOG-016 even with all tasks present, nothing feeds before start\n"); /* 未 start:poll 直接返回 */ beat_all(); poll_advance(500); - CHECK(s_feed_count == 0, "未启动 → 不喂狗(无论位图)"); - CHECK(task_wd_last_mask() == 0u, "未启动 → 不更新 last_mask"); + CHECK(s_feed_count == 0, "not started -> no feed (whatever the bitmap)"); + CHECK(task_wd_last_mask() == 0u, "not started -> last_mask not updated"); } int main(void) { - printf("=== Task Watchdog 主机侧单元测试 ===\n"); - printf("被测:App/util/task_watchdog.c(判定状态机)\n\n"); + printf("=== Task Watchdog host-side unit tests ===\n"); + printf("Target: App/util/task_watchdog.c (decision state machine)\n\n"); fresh(); tc_001_not_armed(); fresh(); tc_016_stall_not_armed_no_feed();