adc_input: 失败拍清 s_stm32_valid,杜绝超时沿用上一拍旧值(单测 70->79)
缺陷(真机实测发现):本层只有一份 s_stm32_raw[],有效标志此前只在成功时 置 1、失败时从不清零 -> 超时拍消费侧照样取数、照样压入采样环(且超时前 几个 Rank 已写本拍新值、后面几个是上一拍旧值 = 半新半旧混合帧),直接污 染 20 点 DFT 相量窗;adc_input_poll() 返回值只由 TPAFE 决定,s_frames_skip 也抓不到它。 修复:stm32_scan() 两条失败支路(HAL_ADC_Start 失败 / 轮询超时)都清 s_stm32_valid -> 本拍 adc_input_raw() 对 STM32 语义通道返 -2 -> adc_task 走既有 skip 整帧跳过路径;下一拍扫描成功自动置回 1(自愈)。 测试:新增 TC-AI-070..078(70 -> 79 用例)。旧用例 TC-AI-034/039b 都是 init 后立刻失败(valid 本就是 0),照不出成功过之后再失败这条路径,故新 用例先成功一拍进入有效态再注入失败。**反向验证已做**:把支路改回旧行为 -> TC-AI-039b/073/074 立即 FAIL(76/79),证明用例有效。 验证:主机单测 79/79 PASS;@build 0 错 0 警(Code 256868 -> 256872); @test PASS(本轮无超时:adc1_err=0、skip=0、idle=0、frames=20001); 18 钩子全绿。文档同步 4 处(停摆分析 4.4 / ADC采样节拍 10.4 / ADC输入层 单测说明 / test-host README)。 遗留:2 ms 忙等本身未消(硬化 2 = DMA,方案 B2 待 CubeMX 配置)。
This commit is contained in:
+1
-1
@@ -46,7 +46,7 @@
|
||||
| `cfg_file/stub/` | 桩头文件(`dbg_log.h`),覆盖 MCU 版以在 PC 上编译 |
|
||||
| `phasor/run_unit_test.py` | **相量层(L2)单测**:离线编译真实 `App/algo/phasor.c` + `sample_ring.c`(**无需任何桩**,纯算法),57 用例覆盖傅氏系数表 / 幅值·相位 / 谐波抑制与提取 / 频偏 / 采样环 / 双区原子交换 |
|
||||
| `phasor/phasor_test.c` | 测试单元本体(`#include` 两个生产源码 + 合成任意波形) |
|
||||
| `adc_input/run_unit_test.py` | **ADC 输入层(L1)单测**:离线编译真实 `App/algo/adc_input.c`,70 用例给每个 Rank 注入互异码值**逐通道钉死映射**,并覆盖 HAL 启动失败 / 转换超时 / 参数错等真机难复现分支 |
|
||||
| `adc_input/run_unit_test.py` | **ADC 输入层(L1)单测**:离线编译真实 `App/algo/adc_input.c`,79 用例给每个 Rank 注入互异码值**逐通道钉死映射**,并覆盖 HAL 启动失败 / 转换超时 / **失败拍陈旧帧** / 参数错等真机难复现分支 |
|
||||
| `adc_input/adc_input_test.c` | 测试单元本体(`#include` 生产源码 + HAL / TPAFE 可注入桩) |
|
||||
| `adc_input/stub/` | 桩头文件(`adc.h` / `tpafe5160.h`) |
|
||||
| `vol_lock/run_unit_test.py` | **卷锁单测**:离线编译真实 `App/fs/vol_lock.c`,33 断言点覆盖创建 / 获取 / 释放契约(**fail-open 不变量**:创建失败仍返回 1 且零阻塞)/ 幂等 / 超时透传 |
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
* TC-AI-019/01A 越界(ADC_SEM_COUNT)与负数语义 -> NULL
|
||||
* —— map_check(TC-AI-020)——
|
||||
* TC-AI-020 真实映射表自洽(反向路径结构上不可达,见文件末说明)
|
||||
* —— stm32_scan(TC-AI-021..03A)——
|
||||
* —— stm32_scan(TC-AI-021..078)——
|
||||
* TC-AI-021..025 全通道成功:返回 0 / 状态码 / 不计失败 / Start-Stop 各一次 / 轮询 9 次
|
||||
* TC-AI-026..02B **Rank -> 通道号映射**:UB->CH14(rank9) / UC->CH3(rank4) /
|
||||
* IB->CH6(rank7) / IC->CH1(rank2) / IN->CH2(rank3) / TEMP->CH5(rank6)
|
||||
@@ -37,6 +37,11 @@
|
||||
* TC-AI-030..034 HAL_ADC_Start 失败:返回 -1 / 状态码 RC_START / 计数 +1 / 不调 Stop
|
||||
* TC-AI-035..039 轮询超时:返回 -2 / 状态码 RC_TIMEOUT / 计数 +1 / 调 Stop 收尾 / 立即退出
|
||||
* TC-AI-03A 失败计数跨次单调累计
|
||||
* TC-AI-070..078 **失败拍不得沿用上一拍旧值**(2026-10-10 补,真机实测发现的
|
||||
* 正确性缺陷):先成功一拍让 STM32 侧进入有效态,再注入超时拍 /
|
||||
* Start 失败拍 -> adc_input_raw() 必须返 -2(而非上一拍的值);
|
||||
* 恢复拍重新置有效。TC-AI-034/039b 只覆盖"冷启动即失败",
|
||||
* 照不出"成功过之后失败 → 静默沿用旧值",故单独立一组。
|
||||
* —— adc_input_raw(TC-AI-040..04B)——
|
||||
* TC-AI-040..043 参数守卫:out=NULL / 越界 / 负数 -> -1,且不写 out
|
||||
* TC-AI-044/045 无有效数据 -> -2(两来源分别)
|
||||
@@ -318,6 +323,40 @@ static void tc_scan_timeout(void) {
|
||||
CHECK(adc_input_stm32_errs() == 2u, "TC-AI-03A 失败计数跨次单调累计 = 2");
|
||||
}
|
||||
|
||||
/* ============ TC-AI-070..077:失败拍不得沿用上一拍旧值(陈旧帧) ============
|
||||
* 背景(2026-10-10 真机实测发现):本层只有一份 s_stm32_raw[],超时拍里"超时前
|
||||
* 几个 Rank 已写本拍新值、后面几个还是上一拍旧值",而 s_stm32_valid 此前只在
|
||||
* 成功时置 1、失败时**从不清零** → 消费侧照样取数、照样压入采样环,
|
||||
* s_frames_skip 抓不到。TC-AI-034/039b 都是"init 后立刻失败"(valid 本就是 0),
|
||||
* 因此照不出这条路径——必须先成功一拍。 */
|
||||
|
||||
static void tc_scan_stale(void) {
|
||||
int32_t v = 0;
|
||||
|
||||
/* --- 超时支路:成功拍 -> 超时拍 -> 恢复拍 --- */
|
||||
fakes_reset();
|
||||
(void)adc_input_init();
|
||||
CHECK(stm32_scan() == ADC_INPUT_RC_OK, "TC-AI-070 前置:首拍成功");
|
||||
CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 108), "TC-AI-071 前置:UB 取到 108(有效态)");
|
||||
|
||||
s_poll_fail_at = 4; /* 第 5 个 Rank 超时(前 4 个已写新值) */
|
||||
CHECK(stm32_scan() == ADC_INPUT_RC_TIMEOUT, "TC-AI-072 第二拍轮询超时");
|
||||
CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-AI-073 超时拍不得沿用上一拍值 -> -2");
|
||||
CHECK(adc_input_raw(ADC_SEM_UC, &v) == -2, "TC-AI-074 超时拍连本拍已写入的 Rank 也不得出数");
|
||||
|
||||
s_poll_fail_at = -1;
|
||||
CHECK(stm32_scan() == ADC_INPUT_RC_OK, "TC-AI-075 第三拍恢复成功");
|
||||
CHECK((adc_input_raw(ADC_SEM_UB, &v) == 0) && (v == 108), "TC-AI-076 恢复拍重新可取数(自愈)");
|
||||
|
||||
/* --- 启动失败支路:同样不得沿用 --- */
|
||||
fakes_reset();
|
||||
(void)adc_input_init();
|
||||
(void)stm32_scan(); /* 先成功一拍 */
|
||||
s_start_rc = HAL_ERROR;
|
||||
CHECK(stm32_scan() == ADC_INPUT_RC_START, "TC-AI-077 Start 失败拍");
|
||||
CHECK(adc_input_raw(ADC_SEM_UB, &v) == -2, "TC-AI-078 Start 失败拍不得沿用上一拍值 -> -2");
|
||||
}
|
||||
|
||||
/* ===================== TC-AI-040..045:raw 参数守卫与无数据 ===================== */
|
||||
|
||||
static void tc_raw_guards(void) {
|
||||
@@ -448,6 +487,8 @@ int main(void) {
|
||||
tc_scan_start_fail();
|
||||
printf("-- stm32 scan: poll timeout --\n");
|
||||
tc_scan_timeout();
|
||||
printf("-- stm32 scan: stale frame on failure beat --\n");
|
||||
tc_scan_stale();
|
||||
printf("-- raw: guards / no-data --\n");
|
||||
tc_raw_guards();
|
||||
printf("-- raw: tpafe index + two's complement --\n");
|
||||
|
||||
Reference in New Issue
Block a user