TPAFE驱动闭环E-44/E-45/E-58取数契约,固化E-59门禁,adc_task挂进Keil工程
This commit is contained in:
@@ -444,10 +444,10 @@ sequenceDiagram
|
||||
### 5.9 ADC 采集(FR-ADC)⬜ 待实现
|
||||
|
||||
- **需求(待产品定义确认)**:周期采集 TPAFE5160 多通道模拟量并转发。
|
||||
- **现状**:`tpafe5160_init()` 与 `tpafe5160_start_conv_irq()` 在启动序列调用一次;**全仓库无周期性 CONVST 重触发**;`data_ready`/`get_buf` 无消费者(`adc_task.c` 为空桩,且未在 `freertos.c` 创建)。
|
||||
- **现状**:`tpafe5160_init()` 与 `tpafe5160_start_conv_irq()` 在启动序列调用一次;**全仓库无周期性 CONVST 重触发**;`tpafe5160_snapshot()` 无消费者(`adc_task.c` 为空桩——2026-10-10 起已挂进 `uvprojx`,仍未在 `freertos.c` 创建);STM32 侧 ADC1 已生成但**全仓库无 `HAL_ADC_Start`**。
|
||||
- **后果**:上电后仅采集 1 个样本,此后数据永久陈旧。
|
||||
- **待确认(阻塞项 B0)**:① 采集是否持续 ② 采样率/通道 ③ 转发目标 ④ `APP_ADC_ENABLE` 语义。
|
||||
- **实现约束**(见 §9):周期 CONVST 重触发 + `adc_task` 消费;**先修原子快照 API**(否则接入即撕裂);栈预算核算;V0.1 通道映射已固化 → `docs/硬件平台/ADC通道映射说明.md`(13/17 路置换;语义 UA/UB/UC/UN、IA/IB/IC/IN、V_ZL2=温度,其余备用;网名 ADC17 = PC4 用 `ADC_CHANNEL_14`,**不是** `ADC_CHANNEL_12`)。⚠ **8 路电气量分属 TPAFE / STM32 两片转换器属 V0.1 硬件缺陷**(跨转换器无同一时刻性、精度与量程不一致,登记簿 N-18,V0.2 改版要求全部走 TPAFE)→ 在 V0.1 上主板侧只做**逐通道独立监视**,功率 / 功率因数 / 相角 / 矢量类量一律取子板计量模块结果,不得由主板混算。
|
||||
- **实现约束**(见 §9):周期 CONVST 重触发 + `adc_task` 消费 `tpafe5160_snapshot()`;**原子快照 API 已就位**(2026-10-10 修 E-44 / E-45 / E-58,旧的 `get_buf` / `data_ready` / `clear_ready` 已删 → 取数不再撕裂、重触发不再丢帧、芯片不驱动总线会被 `init()` 首帧自检抓到);栈预算核算;V0.1 通道映射已固化 → `docs/硬件平台/ADC通道映射说明.md`(13/17 路置换;语义 UA/UB/UC/UN、IA/IB/IC/IN、V_ZL2=温度,其余备用;网名 ADC17 = PC4 用 `ADC_CHANNEL_14`,**不是** `ADC_CHANNEL_12`)。⚠ **8 路电气量分属 TPAFE / STM32 两片转换器属 V0.1 硬件缺陷**(跨转换器无同一时刻性、精度与量程不一致,登记簿 N-18,V0.2 改版要求全部走 TPAFE)→ 在 V0.1 上主板侧只做**逐通道独立监视**,功率 / 功率因数 / 相角 / 矢量类量一律取子板计量模块结果,不得由主板混算。
|
||||
|
||||
### 5.10 RS-485 采集(FR-RS485)⬜ 待实现
|
||||
|
||||
@@ -768,7 +768,7 @@ cfg-file-unit-test、test-suite-switch、gitlint。
|
||||
|
||||
| 缺口 | 现状 | 影响 |
|
||||
|---|---|---|
|
||||
| **ADC 采集链路** | `adc_task.c` 空桩;无周期 CONVST 重触发;`data_ready`/`get_buf` 无消费者 | 上电后仅采 1 个样本 |
|
||||
| **ADC 采集链路** | `adc_task.c` 空桩(已挂进 `uvprojx`、未建任务);无周期 CONVST 重触发;`tpafe5160_snapshot()` 无消费者;STM32 侧无 `HAL_ADC_Start` | 上电后仅采 1 个样本(驱动取数契约已于 2026-10-10 修好,接消费者不再有撕裂/丢样风险) |
|
||||
| **RS-485 采集链路** | `rs485_task.c` 空桩;`App/protocol/` 仅 README | 无 RS-485 数据收发 |
|
||||
| **DTU 核心转发职责** | 未定义 | 采集到数据后无处转发 |
|
||||
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
<!-- MEM_SNAPSHOT:BEGIN generated by scripts/check_mem_numbers.py -->
|
||||
| 区域 | 用量 | 容量 | 占比 |
|
||||
|---|---|---|---|
|
||||
| ER_IROM1 | 267,820 B (261.54 KB) | 1,048,576 B (1024 KB) | 25.5% |
|
||||
| RW_IRAM1 | 85,032 B (83.04 KB) | 131,072 B (128 KB) | 64.9% |
|
||||
| ER_IROM1 | 268,128 B (261.84 KB) | 1,048,576 B (1024 KB) | 25.6% |
|
||||
| RW_IRAM1 | 85,040 B (83.05 KB) | 131,072 B (128 KB) | 64.9% |
|
||||
| RW_CCM | 49,184 B (48.03 KB) | 65,280 B (64 KB) | 75.3% |
|
||||
| **Flash (ROM 合计)** | **268,560 B (262.3 KB)** | 1,048,576 B (1024 KB) | **25.6%** |
|
||||
| **Flash (ROM 合计)** | **268,876 B (262.6 KB)** | 1,048,576 B (1024 KB) | **25.6%** |
|
||||
<!-- MEM_SNAPSHOT:END -->
|
||||
|
||||
各区的容量与常量来源:
|
||||
|
||||
@@ -256,7 +256,7 @@ Forbidden:`FAIL`/`ERROR`/`HardFault`。
|
||||
| O1 | 断电 <10min 的"上电/重启"歧义 | §5.3 阈值折中,文档声明;如需精确可后续加掉电标志(PVD) |
|
||||
| O2 | 故障"已复归"/持续监测(mockup 语义) | v2:周期自检 + 活动故障状态机 + 恢复记录 |
|
||||
| O3 | "清除记录"菜单项(node 27 #P,现为空框) | v2:UI 动作 = 删除/重建 log 文件(与满时策略同路径) |
|
||||
| O4 | 待机页电流值接实时数据 | 待交流量标定管线(AC 页占位数据替换)落地后接入 `tpafe5160_get_buf()` |
|
||||
| O4 | 待机页电流值接实时数据 | 待交流量标定管线(AC 页占位数据替换)落地后接入 `tpafe5160_snapshot()`(原子快照;旧 `tpafe5160_get_buf()` 已于 2026-10-10 删除,见 `AGENTS.md`) |
|
||||
| R-1 | FAT32 小追加簇开销 | §3 调研结论:写频率极低可接受;容量上限约束增长 |
|
||||
| R-2 | UI 读与落盘并发 | 只读既有内容 + EOF 追加 + FatFS 系统锁,无互斥需求(§4.4) |
|
||||
|
||||
|
||||
+10
-7
@@ -65,16 +65,18 @@
|
||||
### 2.1 阶段 B:核心功能补齐(产品价值最高,需产品定义确认)
|
||||
|
||||
> 目标:让 DTU 真正采到数——这是当前**最大的功能空洞**,**当前最高优先级**。
|
||||
> 一旦 B0 产品定义明确,即可与 B3(纪律门禁)并行启动。
|
||||
> **B3(纪律门禁)已于 2026-10-10 固化进 `AGENTS.md` 并销项**;同日 TPAFE 侧前置缺陷
|
||||
> **E-44 / E-45 / E-58 全部修复** → **B1 现在只欠 B0 的产品定义 + 栈预算**;
|
||||
> B2 仍欠 **E-50 / E-49**(RS485 驱动契约未修,门禁仍挡着)。
|
||||
|
||||
| 序 | 任务 | 前置 | 说明 |
|
||||
|---|---|---|---|
|
||||
| **B0** | **产品定义确认**(阻塞项) | — | 需甲方明确:① 采集是否持续 ② 采样率(**通道语义已于 2026-10-09 确认并固化 → `docs/硬件平台/ADC通道映射说明.md`**:UA/UB/UC/UN=`AIN1~4`、IA/IB/IC/IN=`AIN8~11`、V_ZL2=温度、其余 8 路备用;主板只做监视/辅助测量,计量在子板。**注意:8 路电气量分属 TPAFE/STM32 两片转换器属 V0.1 硬件缺陷 → N-18**,主板侧不得做跨转换器的相位/功率类运算) ③ 转发目标(MODBUS RTU?上行 TCP?)④ `APP_ADC_ENABLE`/`APP_RS485_ENABLE` 语义。**B1/B2 的规模完全取决于此** |
|
||||
| **B1** | **ADC 采集链路实现**(消化 P1-1、E-58) | B0 + **E-59 门禁** | 周期 CONVST 重触发 + `adc_task` 消费 `get_buf`;**先修 E-58**(原子快照 API,否则接入即撕裂);栈预算核算(两任务未入 `freertos.c` 栈表);**取数必须按 `docs/硬件平台/ADC通道映射说明.md`**(TPAFE `buf[2]=IA`/`buf[5]=UN`/`buf[6]=UA`;STM32 侧 ADC1 **已于 2026-10-09 生成**:`hadc1` + `MX_ADC1_Init()`、9 通道 Rank1~9、144 cycles、ADCCLK=21 MHz、软件触发,网名 ADC17=PC4 用 `ADC_CHANNEL_14`;剩活只剩消费者与 `adc_task` 建任务) |
|
||||
| **B2** | **RS-485 采集链路实现**(消化 E-50、E-49) | B0 + **E-59 门禁** | 双缓冲 + 序号(防包撕裂)+ DE 收尾(超时路径等 TC)+ 协议状态机(`App/protocol/` 正是为此预留) |
|
||||
| **B3** | **E-59 门禁固化入 `AGENTS.md`** | — | 把"接消费者前必须先修 E-36/E-44/E-45/E-58 + 栈预算"写成强制门禁,与"改栈前跑 `stack_report.py`"同级。**这是防止 B1/B2 带缺陷上线的关键** |
|
||||
| **B1** | **ADC 采集链路实现**(消化 P1-1;E-58 已闭环) | B0 + **E-59 门禁**(TPAFE 侧已满足) | 周期 CONVST 重触发 + `adc_task` 消费 **`tpafe5160_snapshot()`**(**2026-10-10 驱动契约已修**:E-44 FRSTDATA 有效性校验 + `init()` 首帧自检返 `-3`、E-45 帧序号取代就绪电平标志、E-58 临界区原子快照;旧 `get_buf`/`data_ready`/`clear_ready` **已删**,删除前零调用者);`adc_task.c` **已挂进 `uvprojx`**(此前 Keil/模拟器两边都不注册 = 永不编译;simulator 无任务层,只挂 Keil);**仍欠**:栈预算核算(两任务未入 `freertos.c` 栈表,建任务前后各跑 `stack_report.py`;先处理 S-1)+ 消费者本体 + 建任务走 **L1(`.ioc` 的 `FREERTOS.Tasks01`)**;**取数必须按 `docs/硬件平台/ADC通道映射说明.md`**(TPAFE `buf[2]=IA`/`buf[5]=UN`/`buf[6]=UA`;STM32 侧 ADC1 **已于 2026-10-09 生成**:`hadc1` + `MX_ADC1_Init()`、9 通道 Rank1~9、144 cycles、ADCCLK=21 MHz、软件触发,网名 ADC17=PC4 用 `ADC_CHANNEL_14`;⚠ 全仓库至今**无 `HAL_ADC_Start`** → STM32 侧一路未跑) |
|
||||
| **B2** | **RS-485 采集链路实现**(消化 E-50、E-49) | B0 + **E-59 门禁**(**尚未满足**:E-50 / E-49 未修) | 双缓冲 + 序号(防包撕裂)+ DE 收尾(超时路径等 TC)+ 协议状态机(`App/protocol/` 正是为此预留) |
|
||||
|
||||
**建议**:B3 与 B0 并行推进(前者是纪律,后者问甲方);**E-58 修复应在 B1 动消费者之前完成**。
|
||||
**建议**:驱动契约与编译接线已在 2026-10-10 铺完 → B1 的下一步是**栈预算 + 建任务(L1)**,
|
||||
再谈消费者与节拍;B2 之前必须先修 E-50 / E-49。
|
||||
|
||||
### 2.2 阶段 C:结构债清理(二期)+ 存储侧健壮性
|
||||
|
||||
@@ -114,9 +116,10 @@
|
||||
|
||||
#### P1-1 ADC 采样数据路径产品构建中死亡
|
||||
- **位置**:`App/app/app_main.c`(`tpafe5160_start_conv_irq()` 仅启动时调用一次)+ `Drivers/BSP/TPAFE5160/tpafe5160.c`
|
||||
- **证据**:启动序列调用一次 `tpafe5160_start_conv_irq()`;全仓库无周期性 CONVST 重触发;`data_ready` / `get_buf` 无任何消费者(`adc_task.c` 是空桩)。
|
||||
- **证据**:启动序列调用一次 `tpafe5160_start_conv_irq()`;全仓库无周期性 CONVST 重触发;`tpafe5160_snapshot()` 无任何消费者(`adc_task.c` 是空桩——2026-10-10 起已挂进 `uvprojx`,但仍未在 `freertos.c` 建任务);STM32 侧 ADC1 已生成却**全仓库无 `HAL_ADC_Start`**(一路彻底未跑)。
|
||||
- **影响**:上电后仅采集 1 个样本,此后数据永久陈旧;且 `APP_ADC_ENABLE` 为未接线占位(已如实标注,不再冒充开关),形成"看似启用实则失效"的假象。
|
||||
- **修复建议**:周期 CONVST 重触发(定时器或任务)+ 数据消费任务;若基线版本有意不实现采集,应删除启动调用并以 `APP_ADC_ENABLE` 真实门控。
|
||||
- **进展**(2026-10-10):**驱动侧取数契约已修**(E-44 FRSTDATA 有效性校验 + `init()` 首帧自检、E-45 帧序号、E-58 原子快照,索引见 `docs/问题记录/错误码传播审计.md` §2.2)→ 接消费者不再有"撕裂 / 重触发丢样 / 芯片静默死亡"三类风险。本条剩余 = **周期重触发 + 消费者 + 建任务**。
|
||||
- **修复建议**:周期 CONVST 重触发(定时器或任务)+ `adc_task` 消费 `tpafe5160_snapshot()`;建任务走 **L1(`.ioc` 的 `FREERTOS.Tasks01`)** 并做栈预算;若基线版本有意不实现采集,应删除启动调用并以 `APP_ADC_ENABLE` 真实门控。
|
||||
- **置信度**:high(代码级确证);P0/P1 定级取决于产品定义(见 §4 待确认)。
|
||||
|
||||
#### P1-10 测试固件静态 RAM 预算(基线已重建、测试缓冲已瘦身,剩构建实测闭环)
|
||||
|
||||
@@ -131,11 +131,11 @@ STM32(U17)为 LQFP144 脚号。
|
||||
| **通道归属(硬件缺陷)** | 8 路电气量分属两片转换器:UA/UN/IA → TPAFE,UB/UC/IB/IC/IN → STM32 ADC | **V0.1 硬件缺陷**(非有意分配,理由见 §1)→ V0.1 上禁止跨转换器做相位/功率/功率因数/矢量类运算;**V0.2 改版要求 8 路电气量全部走 TPAFE**(登记簿 N-18) |
|
||||
| STM32 ADC 外设 | **已生成(2026-10-09,CubeMX 6.17 + FW_F4)**:`Src/adc.c`/`Inc/adc.h` 已入库并挂进 `MDK-ARM/*.uvprojx`;`Inc/stm32f4xx_hal_conf.h` 的 `HAL_ADC_MODULE_ENABLED` 已生效;HAL `stm32f4xx_hal_adc.c/_ex.c` + `stm32f4xx_ll_adc.h` 已补入仓库(HAL 原本是裁剪子集);`Src/main.c` 里 `MX_ADC1_Init()` 排在 `MX_IWDG_Init()` 之后。生成配置核对无误:9 通道 / Rank 1~9 / 全部 144 cycles / `ScanConvMode=ENABLE` / `ContinuousConvMode=DISABLE` / `ExternalTrigConv=ADC_SOFTWARE_START` + `EDGE_NONE` / `EOCSelection=ADC_EOC_SINGLE_CONV` / `DataAlign=RIGHT` / 12 位;`HAL_ADC_MspInit()` 已把 PA0~PA7+PC4 配成 `GPIO_MODE_ANALOG` | 硬件通路已打通(`hadc1` 可用);**仍无消费者**——见下面两行 |
|
||||
| ADC 时钟 | CubeMX 的 F4 ADC 面板**有** Clock Prescaler 一项(此前"面板没有该项、固定 DIV2"的判断有误),已选 **PCLK2/4 → ADCCLK = 21 MHz** ✓。面板里 **DIV2 是灰的、选不到**:DB 里 `FadcConstraint Max=36000000`,APB2 = 84 MHz → DIV2 = 42 MHz 超限,该候选值被 `Action="DISABLE"` 禁掉,超规值进不来 | **不设额外防护(2026-10-09 决定)**:约束已由 CubeMX 把关;`.ioc` 虽不保存 `ADC1.ClockPrescaler` 键,重生成也只会回落到约束允许的值。按 144+12 cycles 算 ≈ 7.4 µs/通道、9 通道一轮 ≈ 67 µs |
|
||||
| `adc_task` | **空桩**:`App/task/adc_task.c` 只 `osDelay(1000)`,且任务未在 `Src/freertos.c` 创建 | 无消费者,数据路径死(登记簿 P1-1) |
|
||||
| `adc_task` | **空桩**:`App/task/adc_task.c` 只 `osDelay(1000)`;**2026-10-10 起已挂进 `MDK-ARM/*.uvprojx`**(此前 Keil/模拟器两边都不注册 = 永不编译,改它不生效;simulator 无任务层故只挂 Keil),任务仍未在 `Src/freertos.c` 创建 | 无消费者,数据路径死(登记簿 P1-1) |
|
||||
| TPAFE 采样触发 | `tpafe5160_start_conv_irq()` 仅在 `app_main_init` 调一次,**无周期 CONVST 重触发** | 只采到一帧,无连续波形 |
|
||||
| 前端偏置 | 每路 1k 串联 + 1k 到 `*_GND` + 滤波 C,**无中点偏置** | STM32 侧只能测 **0~3.3 V 单极性**,交流量负半周被削顶;主板侧只做监视可接受,若要算 RMS/功率需硬件补偏置或明确算法口径 |
|
||||
| TPAFE 量程 | 默认 ±5 V(RANGE 接 GND),16 位二进制补码,LSB ≈ 152.59 µV | 用 `tpafe5160_to_voltage()` 换算 |
|
||||
| 双缓冲撕裂 | 审计项 **E-58**(`docs/问题记录/错误码传播审计.md`):`get_buf` 换缓冲 + 任务抢占 → 8 通道可能失去同一性 | 实现消费者时必须处理(一次帧内原子取用) |
|
||||
| 取数契约(**2026-10-10 已修**,E-44 / E-45 / E-58 闭环) | 旧的 `get_buf` / `data_ready` / `clear_ready` **已删除**(删除前确认全仓库零调用者):`get_buf` 只给指针、任务再拷 → 被 BUSY EXTI 抢占就是**两帧混合**;`s_ready` 电平标志被 `start_conv_irq` 触发前清 0 → **重触发即丢未消费帧**;`read_all` 从不看 FRSTDATA(宏有定义、代码零引用)→ 芯片死亡时返回 OK + 常量垃圾。现口径:**`tpafe5160_snapshot(dst, count)`**(临界区原子拷贝,返回 1/0/-1,**仅任务上下文**)+ **`tpafe5160_frame_seq()`**(帧序号只增不清)+ **`tpafe5160_frstdata_err()`**(无跳变帧计数);`tpafe5160_init()` 增**首帧自检**——一帧读下来 FRSTDATA 无跳变(芯片不驱动并行总线;板上 R24 4.7k 上拉会把它钉死为高)→ 返回 `-3` + `[ERR]` | 消费者**只能**用 `snapshot()` 取数(`AGENTS.md` 已立为铁律);真机实测开机 `[ADC] Init OK` 现只在自检帧通过后才打印 → 判据在本板成立、非空转 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
+54
-44
@@ -17,7 +17,13 @@
|
||||
|
||||
## 0. 结论速览
|
||||
|
||||
**当前未闭环 17 项:P1×2、P2×15。无 P0。**
|
||||
**当前未闭环 16 项:P1×1、P2×15。无 P0。**
|
||||
|
||||
> **2026-10-10 追记(E-59 门禁的 TPAFE 前置项全部闭环)**:**E-44 / E-45 / E-58** 已修复并经真机验证
|
||||
> (`tpafe5160` 驱动:FRSTDATA 数据有效性校验 + 帧序号取代就绪电平标志 + 原子快照 API;
|
||||
> 旧的 `get_buf`/`data_ready`/`clear_ready` **删除**,全仓库零调用者)。未闭环 17 → **16**(P1 2→1),
|
||||
> 已闭环索引 41 → **44**(§2.2)。门禁本身已固化进 `AGENTS.md`;**E-59 仍未闭环**(消费者仍是空桩,
|
||||
> 且 RS485 侧 E-50 / E-49 未修、两任务栈预算未做)。
|
||||
|
||||
> **2026-10-04 订正(计数同步)**:2026-10-03 的 **E-34 / E-04**(第一档)与
|
||||
> **GD5F 错误通道统一(E-10 / E-42 / E-53 / E-56 / E-57,第二档 #1)** 已修复并台架验证,
|
||||
@@ -32,23 +38,22 @@
|
||||
> 主机侧单测(S1-b)首跑抓出,已修复并通过 `@build` 0/0。**已闭环**,
|
||||
> 明细见 §2.1。
|
||||
|
||||
首版 59 项中 **41 项已闭环**(索引见 §2),其中 **4 项 P0 全部修复并在位**;**17 项未闭环**
|
||||
首版 59 项中 **44 项已闭环**(索引见 §2),其中 **4 项 P0 全部修复并在位**;**16 项未闭环**
|
||||
(见 §3),另 **1 项回归监督**(E-62,无需改动、仅防后人误改)。剩余问题分三类:
|
||||
|
||||
| 类别 | 数量 | 性质 | 处置 |
|
||||
|---|---|---|---|
|
||||
| **A. 待处理的实质缺陷** | 5 | 有明确后果,需改代码 | §3.1,第一 / 二档 |
|
||||
| **A. 待处理的实质缺陷** | 4 | 有明确后果,需改代码 | §3.1,第一 / 二档 |
|
||||
| **B. 契约缺口(随消费者接入触发)** | 7 | 当前调用者"恰好不会踩",但契约没写死 | §3.2,接消费者前必修 |
|
||||
| **C. 一致性 / 可维护性** | 5 | 无功能影响或影响极小 | §3.3,第三档 |
|
||||
|
||||
**最值得先动的两件事**(2026-10-04 更新——原列的 **E-34 / E-04 已闭环**,见 §2.2):
|
||||
**最值得先动的两件事**(2026-10-10 更新——原列的 **E-58 已闭环**,**E-34 / E-04 已闭环**,见 §2.2):
|
||||
|
||||
1. **E-59(P1,元发现)**——`adc_task` / `rs485_task` 均为空桩,驱动层多项缺陷
|
||||
(E-58 / E-50 / E-44 / E-45)**当前全部不可触发**;一旦接入真实消费者便会同时上线。
|
||||
处置:把"接消费者前先修驱动契约 + 栈预算"固化为**强制门禁**(§5 第三档)。
|
||||
2. **E-58(P1)**——TPAFE 双缓冲角色互换 + 任务抢占 → 8 通道失去同一性,
|
||||
且**没有任何错误指示**;现因 `adc_task` 空桩而休眠,**接入消费者之日即触发**,
|
||||
属"接消费者前必修"(§5 第三档前置条件)。
|
||||
1. **E-59(P1,元发现)**——`adc_task` / `rs485_task` 均为空桩。TPAFE 侧契约缺陷
|
||||
(**E-44 / E-45 / E-58**)已于 2026-10-10 **全部修复**,RS485 侧 **E-50 / E-49 仍未修**;
|
||||
门禁已固化进 `AGENTS.md`,接消费者前仍欠"栈预算 + RS485 双缓冲/序号"。
|
||||
2. **E-50(P2)**——RS485 单缓冲无 ISR/任务同步 → 读出跨两帧拼接的数据;与 E-59 同族,
|
||||
属"接 RS485 消费者前必修"(§5 第三档前置条件)。
|
||||
|
||||
> **2026-09-25 变更**:**E-03 已修复**(错误码改按任务隔离,见 §3.1)。
|
||||
> 它是本次审计中唯一"并发条件下会说谎"的通道,且 pending 二期不覆盖它,故独立小修先行。
|
||||
@@ -110,7 +115,7 @@
|
||||
|
||||
---
|
||||
|
||||
## 2. 已闭环总览(41 项)
|
||||
## 2. 已闭环总览(44 项)
|
||||
|
||||
只列索引与闭环依据,明细不再展开(首版明细可从 git 历史取回)。
|
||||
|
||||
@@ -123,7 +128,7 @@
|
||||
| **E-02** | `net_socket.c` / `lftpd` / `time_sync` | 一条空闲 FTP 控制连接把 netTask 独占 30s → **全体消费者队列停摆**(实测冻结远端显示 17.7s) | `f8d6e90`+`4a1605b`(分片)→ `a45c0cb`(L3 pending 化,结构性消灭) |
|
||||
| **E-63** | `App/cfg/cfg_file.c` | 外科手术保存 3 处 `s_encode(...) == 0` 判定恒假(函数成功返回**文本长度**)→ 受管值改写为**死码**:对已存在 `/config.ini` 保存时受管键从不改写(**静默不落盘**,`net_cfg_save` 仍报 OK) | **2026-10-02**(L0.5 `cfg_file` 单测首跑抓出)——判据由 `== 0` 改 `>= 0`;见 [`../测试说明/配置文件单元测试说明.md`](../测试说明/配置文件单元测试说明.md) §5 |
|
||||
|
||||
### 2.2 P1 十八项
|
||||
### 2.2 P1 二十一项
|
||||
|
||||
E-05(net 建链 API 队列化)、E-06 / E-20 / E-21 的**主要分量**(随 E-02 pending 化落地)、
|
||||
E-09(UI 页面局部副本 + 显式提交)、E-17(RECONFIG 原子消费)、
|
||||
@@ -131,7 +136,16 @@ E-32(SD2506 充电器寄存器回读校验)、E-33(CH395F DMA 错误通道
|
||||
E-36 / E-37(RS485 契约与 init 返回码)、E-38(SD2506 负温度解码)、
|
||||
E-39 / E-51(SD2506 写允许窗口 / `set_alarm` 读-改-写)、E-40(FTL erase/prog 错误分类)、
|
||||
E-43(GD5F erase 容量边界)、**E-03(错误码按任务隔离,2026-09-25)**、
|
||||
**E-34(CH395F 字节命令有限超时,2026-10-03)**、**E-04(`remo_send` 返回值校验,2026-10-03)**。
|
||||
**E-34(CH395F 字节命令有限超时,2026-10-03)**、**E-04(`remo_send` 返回值校验,2026-10-03)**、
|
||||
**E-44(TPAFE `read_all` 无数据有效性校验:FRSTDATA 宏有定义、代码零引用,芯片死亡时返回 OK + 常量垃圾;
|
||||
现 `read_channels` 要求"一帧内 FRSTDATA 必须跳变"、`init()` 首帧自检返 `-3`,2026-10-10)**、
|
||||
**E-45(TPAFE `s_ready` 三写者、重触发即清掉未消费帧;改帧序号 `frame_seq()` 只增不清,2026-10-10)**、
|
||||
**E-58(TPAFE `get_buf` 取指针 + 任务侧拷贝被 ISR 抢占 → 两帧混合;删 `get_buf`/`data_ready`/`clear_ready`,
|
||||
改临界区原子快照 `snapshot()`,2026-10-10)**。
|
||||
|
||||
> 注:**E-44 / E-45 在 2026-09-25 重写时只留在首版 P1 速览表、未展开正文条目**(正文只余 E-59 的引用),
|
||||
> 本次闭环直接进索引;实现口径与陷阱见 `AGENTS.md`「ADC 取数只用 `tpafe5160_snapshot()`」条与
|
||||
> `Drivers/BSP/TPAFE5160/README.md`。
|
||||
|
||||
> 注:E-05 已闭环(建链 API 并入队列),但**同族的 `net_getsockname` 残留通道**
|
||||
> 在 §3.1-E-24 重新入册。
|
||||
@@ -148,13 +162,13 @@ E-57(`int` / `int32_t` 混用)、**E-10 / E-42 / E-56(GD5F init / BBT / ra
|
||||
|
||||
---
|
||||
|
||||
## 3. 未闭环发现(17 项)
|
||||
## 3. 未闭环发现(16 项)
|
||||
|
||||
每项字段统一为:**位置 → 机制 → 后果 → 当前状态 → 建议**。
|
||||
"当前状态"是本轮(2026-09-25)回到代码实测的结论;**2026-10-03 已修复的条目
|
||||
(E-04 / E-10 / E-42 / E-53 / E-56)与 2026-09-25 的 E-03 保留为留档**(标 ✅),不计入未闭环数。
|
||||
|
||||
### 3.1 A 类:待处理的实质缺陷(未闭环 5 项)
|
||||
### 3.1 A 类:待处理的实质缺陷(未闭环 4 项)
|
||||
|
||||
> **本类已闭环留档**:E-03(2026-09-25)、E-04 / E-10 / E-42 / E-53 / E-56(2026-10-03)——
|
||||
> 见下方各条目的 ✅ 标记与 §2 索引;此处保留详细条目仅作背景留档。
|
||||
@@ -292,23 +306,6 @@ E-57(`int` / `int32_t` 混用)、**E-10 / E-42 / E-56(GD5F init / BBT / ra
|
||||
|
||||
---
|
||||
|
||||
#### E-58 TPAFE 双缓冲角色互换 + 任务抢占 → 撕裂帧 — **P1** | 模式 P7
|
||||
|
||||
- **位置**:`Drivers/BSP/TPAFE5160/tpafe5160.c:322-324`(`get_buf` 换缓冲)、
|
||||
`:343` / `:354`(ISR 与任务侧)
|
||||
- **机制**:`get_buf` 交换双缓冲指针后,任务侧才逐通道 `memcpy`;若在这两步之间
|
||||
被 ISR 抢占且跨过一个整帧周期,任务拷贝的就是**混合了两帧**的 8 通道数据。
|
||||
- **后果**:8 通道失去同一性(同一时刻的 8 路值互相错位)——对外是"数据跳变",
|
||||
且**没有任何错误指示**。
|
||||
- **当前状态(复核)**:**仍然存在,属"休眠缺陷"**。当前 `adc_task.c:37-43` 是空桩
|
||||
(`osDelay` 循环),没有任何消费者调用 `get_buf`。**接入消费者之日即触发**。
|
||||
- **建议**:提供**原子快照 API**(临界区短锁 + `memcpy`,把"取指针"与"拷数据"合并为
|
||||
一个不可分割动作),或在文档中明确"必须关中断后拷贝"并落成强制约定。
|
||||
属"接消费者前必修"(§5 第三档前置条件)。
|
||||
- **关联**:E-59(消费者接入前置清单)
|
||||
|
||||
---
|
||||
|
||||
#### E-49 RS485 TX 超时立即拉低 DE — **P2** | 模式 P9
|
||||
|
||||
- **位置**:`Drivers/BSP/RS485/rs485.c:70-93`
|
||||
@@ -340,12 +337,14 @@ E-57(`int` / `int32_t` 混用)、**E-10 / E-42 / E-56(GD5F init / BBT / ra
|
||||
- **机制**:两个任务的函数体都是 `osDelay` 空循环,谁都不调驱动层的 `get_buf` / `on_rx`。
|
||||
- **后果**:**首版列出的多项驱动层 P1(E-36 / E-44 / E-45 / E-58)当前全部不可触发。**
|
||||
这意味着"审计通过"是假的——一旦接入真实消费者,这些缺陷会同时上线。
|
||||
- **当前状态(复核)**:**仍然存在,且是本轮最应强调的一条**。
|
||||
本条不是某个具体 bug,而是一个**风险闸门**:它决定了 §3.2 那一整类"契约缺口"
|
||||
是"暂时无害"还是"即将爆炸"。
|
||||
- **建议**:把"接消费者前必须先修驱动契约"写成**强制门禁**(建议入 `AGENTS.md`,
|
||||
与"改栈前跑 `stack_report.py`"同级)。前置清单 = E-36 / E-44 / E-45 / E-58,
|
||||
另加栈预算核算(`adc_task` / `rs485_task` 尚未纳入 `Src/freertos.c` 栈表)。
|
||||
- **当前状态(复核 2026-10-10)**:**仍然存在**(消费者仍未接入),但**闸门已经半开**:
|
||||
① 前置清单里 TPAFE 三项 **E-44 / E-45 / E-58 已修复**(原子快照 API + 帧序号取代
|
||||
就绪标志 + FRSTDATA 数据有效性校验,索引见 §2.2);RS485 侧 **E-36 / E-37 早已闭环**,
|
||||
但 **E-50(单缓冲无同步)与 E-49(超时路径拉 DE)仍未修** → RS485 消费者仍被挡住。
|
||||
② 门禁本身已固化进 `AGENTS.md`(与"改栈前跑 `stack_report.py`"同级)。
|
||||
③ 栈预算**仍未做**:两任务尚未纳入 `Src/freertos.c` 栈表。
|
||||
- **建议**:接 **ADC** 消费者现在只欠"栈预算 + 产品定义(采样率 / 数据出口)";
|
||||
接 **RS485** 消费者前还必须先修 E-50 / E-49。
|
||||
|
||||
---
|
||||
|
||||
@@ -480,7 +479,7 @@ E-57(`int` / `int32_t` 混用)、**E-10 / E-42 / E-56(GD5F init / BBT / ra
|
||||
|
||||
**读法提示**:三处"空白带"(事件标志、syslog、配置引擎的大部分行)不是没审,
|
||||
而是首版查出的问题已闭环。**GD5F 列的项已于 2026-10-03 全部闭环**(矩阵该列已清空),
|
||||
当前未闭环项集中在 **RS485/TPAFE 驱动(E-49 / E-50 / E-58)、net 层全局状态
|
||||
当前未闭环项集中在 **RS485 驱动(E-49 / E-50)、net 层全局状态
|
||||
(E-24 / E-25 / E-26 / E-27 / E-28)、配置引擎(E-16)与测试基础设施(E-23 / E-30)。**
|
||||
|
||||
---
|
||||
@@ -511,11 +510,12 @@ E-57(`int` / `int32_t` 混用)、**E-10 / E-42 / E-56(GD5F init / BBT / ra
|
||||
|
||||
### 第三档:长期 / 前置门禁
|
||||
|
||||
- **E-59 门禁**:`adc_task` / `rs485_task` 接入消费者**之前**,必须先完成
|
||||
**E-36 / E-44 / E-45 / E-58**(驱动契约修复)+ 栈预算核算
|
||||
(两任务尚未纳入 `Src/freertos.c` 栈表)。建议写入 `AGENTS.md`,
|
||||
与"改栈前跑 `stack_report.py`"同级。
|
||||
- **E-50**:RS485 双缓冲 + 序号(随 E-59 门禁)
|
||||
- **E-59 门禁**(**已固化进 `AGENTS.md`,2026-10-10**):`adc_task` / `rs485_task` 接入消费者
|
||||
**之前**必须先完成驱动契约修复 + 栈预算核算(两任务尚未纳入 `Src/freertos.c` 栈表),
|
||||
与"改栈前跑 `stack_report.py`"同级。清单现状:**E-36 / E-37 ✅(早前)**、
|
||||
**E-44 / E-45 / E-58 ✅(2026-10-10)**、**E-50 / E-49 ❌(RS485 未修)**
|
||||
→ **ADC 侧只欠"栈预算 + 产品定义",RS485 侧仍被挡住**
|
||||
- **E-50**:RS485 双缓冲 + 序号(随 E-59 门禁,**接 RS485 消费者前必修**)
|
||||
- **E-12**:`FF_FS_LOCK` 或固化"单写者纪律"(`AGENTS.md`)
|
||||
- **E-31 后续 / E-62**:卷自愈触发集的回归监督(纪律已固化,需防后人误改)
|
||||
- **E-47 / E-48**:驱动健壮性长尾(独立超时码 / WARN 留痕)
|
||||
@@ -622,3 +622,13 @@ cppcheck 无告警、`git diff --check` 干净、编码无 `U+FFFD` 且 BOM 状
|
||||
与 **E-60** 闭环结果——**§0 未闭环 25 → 17**(P1 5→2、P2 20→15),**§2 已闭环 33 → 41**
|
||||
(P0 3→4、P1 15→18、P2 15→19),§3 各类计数(A 10→5、C 8→5)与 §4 矩阵(清空 GD5F 列)
|
||||
同步更新。本次订正**仅改计数与索引,未改动任何审计结论**。*
|
||||
|
||||
*2026-10-10 闭环(E-59 门禁的 TPAFE 前置三项,`Drivers/BSP/TPAFE5160/`):**E-44**——
|
||||
`read_channels()` 要求"一帧读下来 FRSTDATA 必须发生跳变"(板上 R24 4.7k 上拉,芯片死亡则钉死为高),
|
||||
`tpafe5160_init()` 增**首帧自检**,不满足即返回 `-3` + `[ERR]`;**E-45**——`s_ready` 电平标志改
|
||||
`s_frame_seq` 帧序号(只增不清),`start_conv_irq` 不再清标志;**E-58**——删 `get_buf` / `data_ready` /
|
||||
`clear_ready`(删除前确认全仓库**零调用者**),新增临界区原子快照 `tpafe5160_snapshot()` 与
|
||||
`tpafe5160_frstdata_err()`。`@build` 0 错误 0 警告;真机 `@test` PASS + 烧录回读 `No difference found`;
|
||||
开机日志 `[ADC] Init OK` 现只在自检帧通过后才打印 → 证明 FRSTDATA 在本板确实跳变、判据不是空转。
|
||||
**§0 未闭环 17 → 16**(P1 2→1)、**§2 已闭环 41 → 44**(P1 18→21)、§3.1 A 类 5→4、§4 矩阵去掉 E-58。
|
||||
门禁本身已写入 `AGENTS.md`(与"改栈前跑 `stack_report.py`"同级)。*
|
||||
|
||||
Reference in New Issue
Block a user