wandering1
78248a1cdf
feat(S-5): 收编 SD2506/TPAFE 并给 dhara 失败分类,门禁基线 19→17
...
前一笔立契约与门禁(`Drivers/BSP/bsp_err.h` + `bsp-err` 钩子 + RS485 试点);这一笔按用户
指定顺序 C3 → C1 → C2 把三个模块真正收编,并让存储失败第一次变得可读、可分类。
**C3 · SD2506 整模块(11 个公共 API + 6 个内部 helper)**:三枚私有宏 `SD2506_OK`/
`SD2506_ERROR`/`SD2506_I2C_ERROR` **删除而不是留别名**——留别名等于新代码还能用旧形状,
把迁移洗掉;编译器替我们找全所有调用点。新增 `sd2506_err_from_hal()`,**把 I2C 超时从
"和没人应答共用一个 −2"里拆出来归成 `BSP_ERR_TIMEOUT`(可重试)**——SD2506 是启动链第一站、
I2C1 上电时序敏感,这是本波唯一真正的语义改善,不是改名。`sd2506_init` 的 charge 寄存器
**回读校验不符**原返参数类错误,改归 `BSP_ERR_IO`(那不是调用方的错)。
**C1 · 同形两义**:`GD5F_BUSY_TIMEOUT` → `GD5F_WAIT_EXPIRED`(**值 −2 不变**,纯消"名字叫
TIMEOUT 其实是返回码")。**GD5F 私有码集整体收编刻意没做**:169 处引用里 48 处在板级套件、
还要动 Trap 记录用词,属另一波带真机+套件回归的工作,不夹带。TPAFE5160 收编 23 处:
`BUSY_TIMEOUT → BSP_ERR_TIMEOUT`、`ERROR → BSP_ERR_PARAM`(**同值 −1,行为零变化**)、
`FRSTDATA_ERR → BSP_ERR_NO_DEVICE`(E-44 的本义就是"芯片没驱动 DB 总线",归到器件无响应比
私有 −3 有用,且避开与 `BSP_ERR_TIMEOUT` 撞值)。实测 `tpafe5160.o`/`gd5f2gq5ue.o` 的 Code
增量为 **0**——改名不产生一条指令。
⚠ **`tpafe5160_snapshot()` 刻意不套成败码**:它是 1=有新帧 / 0=无新帧 / −1=参数错 的三态
**状态**返回,0 不是错误而是"这一拍没有新数据",强行收编会把慢消费者的正常路径变成失败。
顺带订正我上一版在 `bsp_err.h` 的断言——"本层只有 `net_*` 把数量与错误挤同一返回值"是错的,
`snapshot`/`adc_input_poll` 就是第二族;两族现都已写明并各注保留理由。
**C2 · FTL 坍缩点分类**:`ftl_flush_cache`/`ftl_read_page` 不再把 dhara 失败压成
`GD5F_ERROR`,
按**处置差异**分三类,并在最早同时知道 LPN 与原始码的位置就地打印:`ECC`/`TOO_BAD` →
`BSP_ERR_CRC`(页级,重试或换页,不代表卷坏);`JOURNAL_FULL`/`MAP_FULL` →
`BSP_ERR_NO_SPACE`(介质健康但块池/日志见底,此时重格式化只是把问题推回去);
`BAD_BLOCK`/`RECOVER`/`CORRUPT_MAP`/越界 → `BSP_ERR_IO`(完整性故障,保卷 + 上报,不许自愈
重格式化)。这与 **E-31** 是同一条纪律的两端。可读名用自建短表:**本仓 dhara 没有编
`error.c`,用 `dhara_strerror()` 会直接链接失败**。`disk_read`/`disk_write` 仍回
`RES_ERROR`
(FatFs 契约);要让 defaultTask 卷健康探针按类分支还差跨调用存活的快照 → C4 待还。
**两次靠核实拦住的自我错误**:① 我一度认定 `DBG_ERROR("... err=%d", err)` 是把结构体塞进
varargs 的格式 bug——核 `Lib/dhara/error.h` 后确认 `dhara_error_t` 是 `enum`(标量),那行日志
本来合法,改了反而是引入错误;② `bsp-err` 一次 `replace_all` 越界把 8 处 **GD5F 码空间**的
判据改成 `!= BSP_OK`(数值同为 0、无行为变化),但那正是"把两个码空间混起来",已逐一还原。
`cppcheck` 亦抓到 `cls` 声明作用域过宽,已收进失败分支。
**验证**:`@build` 0 错 0 警告(`Code` 213,648、RO 18,860、`ER_IROM1` 232,508 B /
22.2%、
`ROM 合计` 233,696;**RAM 三项零增量**);`@test` PASS(692 ms,烧入戳 `Oct 23 01:35:32`)
且逐条读到被改模块的锚点:`SD2506 init: OK (ret=0)` 与 ID/时间/温度/电池四条读回正常、
`ADC init: OK`、`NAND init: OK`、`Map resumed: 14094/97504`、`adc=` 帧计数持续递增(证明
snapshot 三态未被改坏)、`[ERR]`/Fault/FAIL 0 条。主机单测:系统时钟 100/100、dhara NAND
移植层 149/149(两者都因本次改动需补 `Drivers/BSP` include 路径,补后在钩子内实跑 Passed)。
`pre-commit run` 全量 RC=0(20 个实跑钩子 Passed);`bsp-err` 基线 **19 → 17**(还掉两个
`*_BUSY_TIMEOUT = -2`)、`--prune` 干净;`doc-links --all --sections-strict` 147 篇
0 问题;
`id-check --strict`、`layer-deps`、`mem-numbers`、`mem-budget`、`ui-golden` 全过;33
个文件
字节卫生 0 异常(无 CR / 无 U+FFFD / 无行尾空格 / 均有尾换行)。
**口径与数字联动**:新增 `docs/架构设计/STM32F4-Base存储架构说明.md` §10.4(三类码与处置
理由);`pre-commit使用说明.md` §2.27 与 `AGENTS.md` 基线计数 19 → 17;TPAFE README、
GD5F 测试指南与 Trap 记录均**保留旧名留痕**以便对旧日志;配图桶按 .map 对象级增量重算
(`dhara/FTL` 10,931 → 11,222,+291 全部落在 `nand_ftl.o`;应用代码/UI +36 落在
`app_main.o`;其余散量入"其他"7,557;桶和 = Code+RO 断言通过、文本溢出 0);
`ram_baseline --update/--write`、`ram_report_20261023.md` 快照、报告 §1.3/§5.1/§5.4
与
部署文档 §3.3 数字全部同步;报告 §0.4/§9 的 S-5 状态改为 🟡 主体已落地。
2026-10-23 07:42:02 +08:00
wandering1
36a3c3449c
refactor(task): 19 处任务句柄裸 extern 收拢为 task_handles.h 引用契约
...
推荐清单第 3 步(结构债 S-2 剩余面),用户批准"按你推荐做"。
新建 `App/task/task_handles.h`——**只有声明、没有 `.c`**:头文件不需要双端注册,
且 `../App/task` 本来就在 uvprojx 的 `<IncludePath>` 里,所以这一步零构建面。
- `App/task/default_task.c:52-69` 的 18 行局部 extern(9 个句柄 + 9 个 attributes)
删除,改 include;栈水位观测用的任务清单表本体仍留在该文件
- `App/task/adc_task.c:125` 的 1 行同法收口
- `Src/main.c` 函数内的 `extern volatile uint32_t g_rcc_csr_latched;` 移进
`App/app/app_main.h`(`main.c` 本来就 include 它),USER CODE 区内只留"读
RCC_CSR → 写 RMVF 清除"两句,顺序约束的原注释保留
为什么值得做:原先每加一个任务都得记得往 `default_task.c` 再抄两行 extern,抄
漏一行 = 读别人的栈(静默,无报错)。现在只有一个改动点;而且 CubeMX 若把句柄
改名,报错会落在链接期而不是静默通过。
**镜像逐项体积不变**:`Code=213,188 RO-data=18,580 RW-data=1,184
ZI-data=131,504`,`@build` 0 错 0 警告 → 行为中性。
`check_cubemx_survival.py` 对这次有意的 USER CODE 区改动报"漂移",已按其文档流程
`--write` 重建基线(`.cubemx_survival_baseline.json` 仅 1 个指纹变化;顺手把该脚本
写文件带来的 CRLF 归一回 LF,符合 `* text=auto eol=lf`),`--check` 复跑通过、易失
清单 29 项全部到位。
报告 §0.4/§9 的 S-2 口径同时改成**精确分类**:该修的手写跨模块裸 extern **24 处,
今天已消 22 处,只剩 2 处**(`ch395f.c:177` 的 `g_spi1_dma_done` 与 `net_socket.c:77`
的 `netMsgQueueHandle`);`stm32f4xx_it.c:241-256` 那 16 条是 CubeMX「External
variables」生成块(删了会被重生成写回来,**不算债**),`:183/195/207/220` 那 4 条
是手写在 `__asm` Handler 里引用汇编标签(ARMCC `__asm` 取不到 C 数据符号,
**合法例外**)。上一版写的"25 处"把这三类混在一起了,一并更正。另更正 §0.4 的
S-1 一格:不是"运行时属主纪律被破"(UI 只投递 `net_cfg_save_request()`,写盘在
defaultTask),也不是"进不了主机侧单测"(模拟器已跑整条链),要修的只是静态分层
方向。
门禁:`@build` 0/0;`cubemx-survival --check` 通过;`check_doc_links.py --all
--sections-strict` 146 文档 0 问题;`check_ids.py --strict` 增量拦截通过、可判定
82.83%;`mem-numbers` 0。字节卫生:新增头文件与各改动文件 BOM 无 / CR 0 /
U+FFFD 0。未推送。
2026-10-22 19:09:20 +08:00
wandering1
67fbdd9897
refactor(结构债): S-4 删零消费点占位宏;S-2 消两处与 Inc 重复的 extern
...
用户批准「先只跑 1+2」(报告 §0.4 结构债三项 S-1/S-2/S-4 的评估结论)。
**S-4 闭环**:删除 `App/app/app_cfg.h` 里 4 个**全库零消费点**的宏
(`APP_NET_ENABLE` / `APP_ADC_ENABLE` / `APP_RS485_ENABLE` /
`APP_SYS_TIME_SRC`),文件降格为「决策占位说明」——修改记录 v1.2 写明为什么删、
将来在真实初始化点接入门控时怎么接回;同时去掉 `app_main.c` 里只为它存在的
include。留「看着能裁剪、其实不生效」的宏比不留更糟:它不产生任何编译期效果,
却会让评审误信模块可裁剪——此前为了对冲这个误解,AGENTS 之外还得在 6 处文档各
写一句「未接线占位,别当开关用」。
**文档口径同步 17 处**:`App/app/README.md`、`App/README.md`、根 `README.md`、
`项目架构总览.md`、`项目部署环境要求.md`(§3.2 两行 + 配置表一行)、`产品需求
设计文档.md`(B0 结论 + 配置表)、`基线与待确认.md`、`排期详述.md` C5、`登记簿
.md` N-23 残余、`RAM使用分析与优化方案.md` 三处。
**顺带纠出另一个「文档里有、代码里从来没有」的东西**:`RAM使用分析与优化方案
.md` 把 `APP_CCM_ENABLE` 写成「加在 `App/app/app_cfg.h`」,全库只有那篇文档提
到它,从未落地——已就地标注「未实现,重开本簇时一起落地」,免得下一个读者以为
CCM 有回退开关。
**S-2 第一步**:删 `gd5f2gq5ue.c:47`、`sd2506.c:20` 两处与 `Inc/spi.h` /
`Inc/i2c.h` 重复的 `extern`;GD5F 改 `#include "spi.h"`(沿用 `ch395f.c:22`
的既有做法)。
**镜像体积逐项不变**:`Code=213,188 RO-data=18,580 RW-data=1,184
ZI-data=131,504` 与改动前完全相同,`@build` 0 错 0 警告 → 两步均为行为中性。
报告 §0.4/§9 同步为实测口径并**认错**:S-2 不是旧写的「4 处」而是 **25 处**
(`App/task/default_task.c:52-69` 一次就 18 行任务句柄/属性 extern;
`stm32f4xx_it.c` 的 `fault_entry_hard` 属 ARMCC `__asm` 合法例外,不该「
修」);S-1 不是「语义层错位」而是**真实的 BSP→App 反向依赖**(NETCFG 10 处
include `App/cfg/cfg_file.h` + UI 3 个文件)。这两个旧数字是 v3.0 重写时沿用
未测所致。
途中被自家门禁正确拦下一次:在 .c 注释里写「S-2a」→ `+1 [校验1] 未登记编号
`,改成平实语言后转绿(正合既有纪律「代码注释禁用不可检索的内部编号」)。
门禁:`@build` 0/0;`check_ids.py --strict` 增量拦截通过、存量债 650 → 640、
可判定比例 82.83%(地板 82.6%+0.1pp);`check_doc_links.py --all
--sections-strict` 146 文档 0 问题;`pre-commit` 相关文件全 Passed;字节卫生 15
个文件 BOM/CR/U+FFFD/行尾空格全清(`end-of-file-fixer` 修掉 app_cfg.h 的一个
多余空行)。未推送。
2026-10-22 18:22:58 +08:00
wandering1
d4867ddbe2
fix(algo): Q10 定值宏改单精度;收口 Flash 优化簇并更正审查报告三处误判
...
影响面:一个头文件宏(App/algo/prot_set.h)+ 七份文档口径;固件行为逐位
等价,无功能变化。门禁全绿后提交,未推送。
验证链
- @build:0 错 0 警;Code 213,520 → 213,188(−332 B),RO/RW/ZI 不变。
- 真机 @test PASS:戳 fw build: Oct 22 2026 10:36:15 suite=NONE;无
[ERR]/ERROR/FAIL/Fault;708 ms 到 net init: OK;protect task start、
i104: listening on 2404、[STACK] 三面水位齐。
- 主机单测:prot_set 90/90、prot_elm 47/47、iec104 97/97。
- 等价性穷举:宏内 42 个字面量;int32 全域 ÷1024 往返 4,494,305 例零
差异;×1024 方向 20 万随机 float 零差异(×/÷1024 是 2^10 指数平移,
不产生尾数舍入)→ 定值默认值/上下限、校验和、104 上送值全部不变。
F-6 双精度软浮点(已落地)
- 两个 Q10 宏去掉显式 (double)、1024.0 → 1024.0f:保护判据每 20 ms 每
元件 3 次定值读取改走 F407 单精度 FPU,不再软件模拟。
- .map 里 dflti/d2f/f2d/dfixi/fepilogue 共 300 B 消失;自研侧对双精度
helper 的引用归零。
- 更正报告归因:全库 0 处 %f(扫 App/Src/Inc/Drivers 共 173 个 .c/.h),
剩下 dadd/dmul/ddiv/depilogue/dfixul = 1,018 B 由 MicroLIB printfa.o 的
_printf_core → _fp_digits 无条件引用,只要还用 snprintf 就删不掉;
报告"把 %f 改整数刻度"没有可执行对象。
F-4 LVGL 死代码(判定不做)
- 报告列的五项字节数逐字节仍准(合计 10,060 B),但没有一项有开关:
根因是 lv_draw_sw.c 的 execute_drawing() 无条件 switch 引用全部 task
类型,链接器 --remove 无从下手。
- 唯一总开关 LV_DRAW_SW_COMPLEX 被 ui_deco.c 的"浅 V"3 px 粗斜腿依赖
(斜段与其所需 mask 核心都在该开关内);2026-09-03 已实测失败并把两端
=1 固化 → UI_设计架构.md §1.4 第 7 条。
- 报告原"mask/grad 是文字与矩形绘制必经路径"证伪:字形走 blend 层
mask_buf,不经 lv_draw_sw_mask_*。
- 剩余路线需给 Lib/lvgl 打本地补丁(上限 ≈16 KB),而 Flash 仅占 22.1%、
无 OTA/双镜像预算 → 收益不抵代价;图片链同理不打补丁。
F-5 uvprojx 空 TU(降级为观察项)
- 实测 326 个 .c / LVGL 201 个 / .map 零产出 127 个;但增量构建 4~5 s、
空 TU 只在全量重建或改 lv_conf.h 时才重编,且远程 CI 刻意不跑 @build。
- 报告原"编译时长 −40%"无基线记录,不复述;真要做用 Keil 原生
<IncludeInBuild>0</IncludeInBuild>,且排在任何 lv_conf.h 改动之后。
文档与台账
- 审查报告 §0.1/§0.4/§1/注册表/§5.1/§5.4/§6.4/W4 行按实测更正,补
2026-10-22 变更记录行与 F-4/F-6 记录去处行;登记簿 N-28 改写为"三项
已判定、仅剩 F-5 观察项"。
- 更正 FTL 写回缓存旧口径(sys_log_mcu.c 注释、运行与自检记录设计说明
§4.4、实机测试实施指南 §9.1):f_close 经 sync_fs → CTRL_SYNC →
ftl_flush_cache 已落盘,"写另一个文件逼出脏页"不是必要条件;2026-10-02
那次"复位后写入整段丢失"根因是 dhara resume 锚错 checkpoint。
- 部署环境要求 §3.3 资源预算由 2026-09-11 快照刷新为 2026-10-22 实测,
并补 CCM 红线行(旧"SRAM 95.4%/极度紧张"的说法早已失效)。
- ram_baseline.py --update/--write、check_mem_numbers.py --write 已回填:
mem-budget(SRAM1 57.4% / CCM 87.9%,阈值 92%)与 mem-numbers 转绿。
2026-10-22 11:03:05 +08:00
wandering1
790e153cd6
fix(adc_input): 丢帧计数改按帧点数累计,与 TPAFE 侧 tgap 同单位
...
读码确认的口径缺陷:两片转换器的丢帧计数单位不一致——TPAFE 侧
adc_health_tpafe_gaps() 按 (d-1) 加权记「帧点数」,STM32 侧
adc_input_stm32_gaps() 每次事件只 +1 记「次数」。两者都被当作心跳字段
并排打印(adc1_gap / tgap),一次跨多帧时数值就分叉:同样丢 3 帧,
一边记 2、一边记 1。跨字段对比或做除法会得出错误结论。
选 A(改代码,真对称)而不是只改字段名:
- 单拍超一帧(d=2)时两者数值相同,历史上绝大多数样本本来就等价,
换单位对既有判读习惯冲击很小;
- 只在一次跨 ≥2 帧时分叉,而那正是心跳日志突发期最常见的形态,
留在文档里当"注意点"迟早还会读错一次。
改动:
- adc_input.c:s_stm32_gaps += (d - 1u)(d = seq - s_dma_seq_seen,
顺带把已算过的差值提成局部变量 d,不再重复算一遍)
- adc_input.h / adc_input.c 函数头:单位写明「Σ 每次前进的超出部分」,
并点名 2026-10-21 之前固件该字段是次数口径,跨版本日志不可直接对比
- 用例:原两档只跨 1 帧(前进 2 记 1),钉不出单位;补第二档——连投
3 帧不消费(一次跨 2 帧)必须记 2 点、累计 1+2=3。补充断言沿用所属
用例覆盖点,不另立新编号,也不在文档外复制用例号(编号门禁按文件内
实例数比对台账豁免,多写一处即被判新债)
- 文档同步:ADC采样节拍设计说明 §8/§9 字段口径与稳态基线、采集与算法
层设计说明 §3/§4、采样有效性校验设计说明 §6.2/§10/§11(并把"两车道
单位不同"从观测盲区降级为"历史日志口径差异")、ADC输入层单元测试
说明用例表该行;两张配图生成器文案同步
实测:
- @build 0 错 0 警;Program Size 与上一提交**逐字节相同**(Code=213520
RW=1184 ZI=131504)——编译器早已为半区推导算过同一差值并复用,
故本次净增 0 B,不产生新的台账漂移
- 主机单测:ADC 输入层 103/103、ADC 有效性 45/45
- stack_report:adcTask 1320 B / protectTask 872 B 均不变
- 字节卫生:BOM 无 / CR 0 / U+FFFD 0 / 文件尾换行齐
- id-check:Passed(曾因新增用例号实例触发"台账之外 +2",已按不复制
用例号的方式消除,未动 id_known_backlog.json 台账)
gate: only mem-budget/mem-numbers pending lead ledger backfill
pre-commit run --all-files 失败仅这两条,漂移量来自上一条提交 6f90600
(+96 B Code / +24 B ZI);本条自身 0 B。按并行分支约定本分支不跑
--write,台账由 Lead 合并后统一回填。
2026-10-22 00:43:32 +08:00
wandering1
9f826dbb4d
fix(protect): 采样陈旧时独立闭锁保护(判定层失明的兜底门)
...
问题:L5-4 闭锁读的 adc_health_flags() 只有 adcTask 每拍跑
adc_health_check() 才可能置位。TIM3 一停,adcTask 就永久阻塞在
osThreadFlagsWait(刻意的 fail-safe),check() 不再执行 → stall 位
永远是 0,而 protectTask 仍每 20 ms 拿冻在最后一帧的相量继续判据。
窗口最坏约 800 ms(停喂阈值)+ 2498 ms(IWDG 标称)≈ 3.3 s。
方案:保护侧建一条与消费者存活完全解耦的兜底新鲜度门。
- adc_health.c/h 新增 adc_health_age_stale():无模块状态的纯判据,
参照系 adc_health_age_t 由调用方自存。故意不让 protectTask 去调
adc_health_check()——那是「每拍一次、单写者」的契约,两个上下文
同写会互相刷新差值基线,把现有判定层一起弄坏。
- 新增 ADC_HF_STALE = bit8(与判定层 bit0..bit7 位段错开)。本位
不由判定层写、不进 sticky、不进编排层 logged 位图。
- protect_task.c 用自己的时基直接读两个**中断侧递增**的计数器
(tpafe5160_frame_seq / adc_input_stm32_seq),并入掩码。两条车道
各自一份 primed:共用会让先观测的那条把标志置 1,另一条首拍拿
adv_ms = 0 算年龄 → 开机即误锁保护。
- 门限 PROT_STALE_AGE_MS = 100 + 20 = 120 ms,买的是时序阶梯:
判定层活着时它先报 0x1/0x2(带日志与自检留痕),死了只出现
0x100。闭锁最迟 140 ms,仍远小于最小动作延时(默认 1000 ms)。
实测:
- @build 0 错 0 警:Code 213424 → 213520(+96 B);ZI 131480 →
131504(+24 B = 两份 age 结构);RW-data 1184 不变
- stack_report:protectTask 静态最坏链 872 B 不变(余 1176 B / 57%)、
adcTask 1320 B 不变——新判据无日志,不进最坏链
- 主机单测 45/45(新增 TC-ADCHEALTH-012..017 共 14 条断言:首拍只建
基线 / 超拍不判老 / 门限含等号 / 跨 tick 回绕 / 倒退按分工不判老 /
双观察者互不污染 / 空参数不判老)
- 台架注入(一次性停 TIM3 300 ms 探针,验完已撤;探针固件与最终
固件 Program Size 逐字节相同):
[+5462ms] [ERR][PROT] sampling FAULT -> protection blocked (hf=0x00000100)
[+5757ms] [PROT] sampling recovered -> protection resumed
同次开机 [ADC_TASK] health: 出现 0 次;MISS 快照缺的正是 bit6
(0x1F7 - 0x1B7 = 0x40,实证 adcTask 当时确实阻塞,不是"在跑但没报");
reset cause: 仅 1 次(300 ms 被 800 ms 容忍吸收,闭锁不靠复位)
证据 docs/测试说明/boot_log_data/20261021_probe_stale_gate_boot_log.txt
- 字节卫生:BOM 无 / CR 0 / U+FFFD 0;新增行无非法字面量
gate: only mem-budget/mem-numbers pending lead ledger backfill
pre-commit run --all-files 失败仅这两条(台账受管快照与本树 .map 的
Flash/RAM 水位漂移,即本次 +96 B Code、+24 B ZI)。按并行分支约定
本分支不跑 --write,台账由 Lead 合并后统一回填。
文档同步:设计说明新增 §15(原相关文档改 §16),§7 位表加 bit8 行、
§8 责任矩阵与「已知窗口」段改写为已闭合、§10 盲区第 3 条、§11 用例
表、§12 判读手册、§14 改前清单全部跟上;位图配图补 bit8 列,并修掉
生成器把列数硬编码成 8 列导致新列被备注框盖住的问题。
2026-10-22 00:43:32 +08:00
wandering1
60a650c175
fix(adc_task): 接上从未被调用的任务初始化入口(含判定层参照系)
...
问题:adc_task_func 函数头写「限定条件:adc_task_init() 已调用」,但
adc_task_init() 全库无调用点;同类空壳 net_task_init()(体内只有一条
DBG_INFO,函数头却写「创建 TCP Server 监听 Socket」)同样无人调用。
判定层为什么今天还没坏:状态全在 .bss(复位即 0),且 adc_health 的
首拍只建基线、不判定,所以漏调 init 只是「少清一次」。但假契约会让
下一个接手者照它推理,故必须修在成灾之前。
改动:
- adc_task_func 进入循环之前(开闸 s_consumer_ready 之前)自己调用
adc_task_init(),不依赖外部接线;init 与首拍之间无抢占窗口
- adc_task_init() 去掉 DBG_INFO 并在函数头标注禁止加日志:它落在
adcTask 静态最坏调用链上,每条 DBG_* 约 216 B 栈,而这条启动行
无诊断价值(存活由首帧日志与 TASK_WD_ADC 心跳证明)
- 删除 net_task.c/.h 里的空壳 net_task_init()(声明 + 定义 + 误述)
- docs/算法/采样有效性校验设计说明.md §14 与变更记录同步改写:
原来登记的「init 不在产品路径」事实已修复,不留过时结论
实测(任务工作树 adc-health,构建 + 静态分析):
- @build 0 错 0 警;Code 213356 → 213424(+68 B)
- RW-data 1184 / ZI-data 131480 逐字节不变 ⇒ RAM 零增量
- stack_report:adcTask 静态最坏链 1320 B → 1320 B 不变,
余 1240 B / 48% 仍 PASS(netTask 1912 B、protectTask 872 B 不变)
- ADC 有效性单测 31/31 通过(钩子按 adc_task.c 自动触发)
- 字节卫生自查:BOM 无 / CR 0 / U+FFFD 0,字符串字面量纯 ASCII
(中文只在注释里),新增行无非 ASCII 字面量
gate: only mem-budget/mem-numbers pending lead ledger backfill
pre-commit run --all-files = 33 Passed / 2 Failed,失败仅这两条,
均为台账受管区与本树 .map 的 Flash 差异(233,120 → 233,188,即本次
+68 B);RW_IRAM1 75,240 与 RW_CCM 57,376 与台账完全一致。按并行
分支约定本分支不跑 --write,台账由 Lead 合并后统一回填。
另记一处门禁缺口(非本次引入):ui-golden 的黄金参考 simulator/
tests/ref/ 被 .gitignore 排除、从未入库,新工作树里必然失败;本树
用 check_content_pages.py --update 生成 11 页基线后 ui-golden Passed
(即本次改动对 UI 像素中性)。是否让基线入库待裁。
2026-10-22 00:43:31 +08:00
wandering1
5a9988b557
chore(注释): 清掉源码里不可检索的过程编码
...
清掉的(读者无从解析、且所指文档已不存在)
- 已删任务文档的编号:Task #32、其内部 §5 / §4.3、P1-5、P0-2、P1-4a、
"方案 a"、"Lead 批准 2026-10-12"
- 正文里当代词用的文件版本号:"(v2.7 起为 AboveNormal)""已随 v2.0 事件
驱动改造删除""(v2.0:DMA 消费)""见文件头 v1.3 说明"等 → 改写成陈述现状
- 测试与脚本同类:adc_input 桩头"v2.0:DMA 模型"、stub/adc.h 的 v2.0、
check_cubemx_survival.py 段头的"2026-10-10 v2.8"、run_all_suites.py 的"方案 A"
刻意保留
- 可检索登记簿锚点:P-AUDIT 真条目(P0-1/P1-8/P2-1/P2-9/P3-11)、S6/S11、
E-31/E-44、N-18/N-23/N-32、B1/B5/B7/B8、L1-x~L5-x 功能号
- 文件头修改记录块内的 vN.M(规范 V1.0 §2.1/§2.2 要求保留该块;块内编号
在本文件内自洽可读)
顺带纠正注释与代码已经不一致的过时事实
- 仍把 TIM6 写成现行节拍源:Src/main.c 的 include 注释与回调注释、
Src/freertos.c 的 adcTask 块 → 改 TIM3;adc_input.h 修订条目里"ADC1 只认
TIM2/TIM3/TIM8 的 TRGO"不准确 → 换成指向判据(ADC采样节拍设计说明 §3.2)
- App/algo/phasor.c 双区注释称"唯一消费者是 adcTask、为后续保护任务预留",
实际 protectTask 已跨上下文读(prot_elm_run -> phasor_get)→ 改为"读者跨
adcTask 心跳与 protectTask 判据两个上下文,勿改加锁、勿取消双区",并同步
修正 docs/算法/采集与算法层设计说明.md 同一句
- adc_tick_irq_notify() 的"拒绝 ISR 内计算"理由仍写"内含 2 ms 忙等"(DMA 化
后已无忙等)→ 换成三条真实理由:任务级共享数据 / 计算量 / 生成区回调
- 裸 §5(指代不明)与"规划 §1.6 / 规划 §4"昵称式 → 写成完整路径紧邻式
字节卫生(Edit 会静默剥 BOM)
- App/task/ui_task.c 与 Drivers/BSP/UI/ui_net_sink.c 被剥掉 BOM 两次,均按
3 字节 EF BB BF 前缀补回并复验;全部 20 个文件 CR=0、U+FFFD=0、无行尾空白
门禁
- @build 0 错误 0 警告,且 Program Size 与清理前逐项相同
(Code=213356 RO=18580 RW=1184 ZI=131480)→ 纯注释改动、中文未被误重编码
- ui-golden 首跑红:新工作树缺被 gitignore 的黄金参考 simulator/tests/ref/
(不入库、只在主工作树生成过);从主工作树复制该基线后复跑通过 → 注释改动
零像素影响
- 全套 pre-commit 在这 20 个文件上 Passed(coding-standard / cppcheck /
6 个主机单测 / doc-links / task-table / mem-numbers / cubemx-survival /
registration-check / mem-budget / font-charset / ui-golden / id-check)
- id-check 可判定比例 82.71% -> 82.88%(删掉的是"形似 P-AUDIT 但查无定义"的
假锚点),悬空引用 863 -> 854
2026-10-21 11:39:53 +08:00
wandering1
64d8b052b1
docs(algo): App/algo/README 缩成目录索引,详细设计迁入 docs/算法
...
拆分层级
- 新建 docs/算法/采集与算法层设计说明.md(413 行、13 节)承接机制、契约、
判据与设计理由:定位与边界 / 数据流与初始化落点 / adc_input / adc_health /
sample_ring / phasor / freq(7.1 为什么自适应窗、7.2 判据 J1~J6)/
prot_set / prot_elm / 关键约定与禁令 / 资源足迹 / 验证与判读 / 相关文档
- App/algo/README.md 360 -> 128 行:只留文件清单、依赖、逐文件"改代码必须
知道"的红线、构建与测试入口、新增模块动作;深挖改成逐条指针
- README 保留 §3.1-§3.7 原编号,既有"§3.7"引用不失效
索引与引用同步
- 索引:docs/README.md §5.2 新增行;项目架构总览主题表拆成"设计与判据 /
目录索引"两行;AGENTS.md 与 App/README.md 指向(后者原文还写着 L1/L2)
- 按内容重指(编号仍在但内容已搬走,只核编号会静默指错):App/algo/freq.h、
test/host/freq/freq_test.c、run_unit_test.py、继电保护规划 L2-4 行、
pre-commit使用说明 J4 行 -> 指向设计说明
- ADC采样节拍设计说明的两处指向同步改到新文档
修 README 内过时事实
- 挂载写"八个 .c",实际 uvprojx 内 7 个
- SIM_EXEMPT 写"prot_set / freq 才登记豁免",实际七个全在表内
- freq-unit-test 标"待登记",实际已在 .pre-commit-config.yaml
- 定值项数一处 31->40、一处 32->40;blob 144->176 B 证明是 32->40
- 用例与判据数字不再三处复制:属主是 test/host/<模块>/ 与 docs/测试说明/
门禁
- doc-links --all 无新增问题;--sections-strict 覆盖 10 篇文档通过
- id-check 可判定 82.65%(基线 82.6,容差 0.1);TC 双向追溯差异 124 处不变
- registration-check PASS(1 条已知 WARN);freq 单测 46/46;@build 0 错 0 警
- 全部改动文件无 BOM、无 CR、U+FFFD = 0
2026-10-21 11:39:53 +08:00
wandering1
0f0d002afc
docs(ADC): 采样节拍设计说明只留现状,历史决策与台架记录移出
...
删除(已确定的决策与过程记录,无现状信息量)
- §2 方案选型(方案 A 推荐 / 方案 B 备选与结论)
- §9 变更记录整表(9 行"已实现 / 已验收 / 已落地 / 复核修正"叙事)
- §7.1、§10.3、§11.5 三张台架实测对照表 + 反向验证记录 + boot_log 证据行
- 用户决策与过程编号(Task #32 P1-5 方案 a、B1、P0-1/P0-2、v2.0/v2.2/v2.7/v2.8、
"规划未预见""原规划写错了"更正叙事)
- §4 代码改造清单(改造已完成)与 §8 / §10.5 的后续规划口吻
保留并补齐现状
- 链路总览(新增 TIM3 同源 Mermaid)· 实现落点表 · TIM3 配置与"为什么是 TIM3"
(F4 触发清单是硬约束)· ADC1 + DMA 四条硬约束与半区无竞态推导 · 上电自校准
· TPAFE 侧契约与原子快照 · 就绪门与节拍缺失 fail-safe · 单周期时序
· 心跳计数逐个判读(含相位伪影为何阈值取 2)· 性能与资源特征
· 设计边界与已知代价(N-18 无同刻性、滞后一拍、TPAFE 未 DMA 化的前提未定、
调频能力现状)· 设计铁律
- 468 -> 344 行
顺带修掉文档自相矛盾
- 原 §3 / §4 仍在教人配 TIM6(§11 已改 TIM3)-> 全文统一 TIM3
- 上位需求引用写成 继电保护功能复现规划.md §3.2,实际 L1-1 在 §3.1
连带引用同步(7 文件 8 处)
- App/algo/adc_input.c -> §8;App/task/adc_task.c -> §6;Src/main.c -> §3.3;
Src/freertos.c -> §9 与 §10(顺带纠正已失效的"ADC 2 ms 忙等"表述,DMA 化后
单拍取数已零忙等)
- 看门狗设计说明 §6 与 §9 / §4.4;ADC通道映射说明 §4 与 §6;
继电保护功能复现规划 §3.2
- 其中 2 处活断链 doc-links --all 抓不到(整行含"已消""已实现"状态词被豁免),
另写脚本按「文档名 + 章节号」全库扫出后修复
门禁
- doc-links --all(非 SDL2 问题 0,可判定 57% -> 58%)与 --sections-strict 通过
- no-mojibake / trailing-whitespace / end-of-file-fixer / id-check 通过;
task-table / mem-numbers 一致;@build 0 错误 0 警告
- 改动文件均无 BOM、无 CR、U+FFFD = 0;CubeMX 文件的注释改动都落在 USER CODE 区
2026-10-21 11:39:52 +08:00
wandering1
bda7ab2b50
refactor(编号): 16 个测试模块码单词化 + 门禁识别面连带放宽
...
批 2(用户授权改名 + 「新名要一眼看懂」裁定)
- 16 个有歧义模块码单词化,共 1,146 处随 scripts/rename_ids.py 改写:
AI→ADCIN、AH→ADCHEALTH、PS→PROTSET、PE→PROTELEM、PH→PHASOR、
TS→TIMESYNC、VL→VOLLOCK、NP→NANDPORT、CFG→CONFIG、CLK→SYSCLK、
WD→WATCHDOG、STO→STORAGE、SH→SHA256、FA→FTPAUTH、FR→FREQ、104→IEC104
- 不动 NET/GD5F/RTC/SOE/UI/ADC/LOG/RS485/TOOL(已是单词、芯片名或业界通用词,
改了纯属 churn)
- 别名按全局登记:这批字面量已完全限定(TC-<码>-<nnn>),不存在裸形多义
- 映射表存档 scripts/rename_maps/batch2.json 作审计轨迹;§6 模块码表同步
连带修门禁(关键教训)
- 模块码涨到 9 位(ADCHEALTH/WATCHDOG)后,候选正则与族正则的 {0,4} 上界
会让改名后的号**整批从门禁眼里消失**:实测编号字面量从 8271 掉到 7315、
悬空假降 490 处。已放宽到 {0,9} 并写进 §6 注记
- 结论:改名批次必须连带复核识别面,只改数据不改判据 = 静默放行;
这次是靠「可判定比例跌破基线即失败」那条线拦下来的
现状与遗留
- 校验 1 未登记前缀 0 处;可判定比例 82.71%(基线 82.6%,只涨不跌成立)
- 遗留:7 个模块的「单元测试说明.md」仍缺(PROTSET 116、NANDPORT 109、
PROTELEM 65、FREQ 48、FTPAUTH 45、SHA256 25、SOE 14 处悬空)——改名不解决
缺文档,处置方式待议
- 遗留:T-2/T-3/T-4/T-6 历史任务号悬空(别名表未收全,属本工具批次漏项)
- 未改任何 C/H 可编译语义(仅注释与宏名内的编号),故不需 @build
2026-10-21 09:53:28 +08:00
wandering1
dafc18f5ed
feat(UI): W6 第一波——设计令牌层、页面注册表生成器与 UI 门禁补强
...
启动 docs/任务规划/README.md 的 W6 UI 扩展簇(用户裁定,覆盖 2026-10-11
的"本轮不排期")。四个工作包,全部验证通过。
## U1 设计令牌层(零行为变化)
新建 Drivers/BSP/UI/ui_tokens.h(20 个宏),框架 + 7 个页面 + App/task/
ui_task.c 全部接入。屏幕几何**复用 ui_port.h 既有 UI_SCREEN_W/H**,不重复
定义;令牌头自身只 include ui_port.h,不把 LVGL 拖进全部消费者。
补收了报告没列但代码里真重复的量:UI_TEXT_BAND_H 15(7 次)、列表左右边界
与每页行数(各 4 个页面逐字复制)、推流协议几何与显示几何同源(此前硬编码
3200 且注释写着"须与 UI_FB_SIZE 一致"——典型漂移隐患)、UI_TASK_TICK_MS
(ui_port_step 与 osDelay 必须同值,原先靠注释维系)。
故意不收页面私有几何与"同形不同义"的值(device_info 的 pitch=15 与列表
UI_ROW_PITCH=14 合并即改像素)。
## U3 页面注册表与生成器(删手工分发)
ui_page_registry.{c,h} 由生成器产出,**手工 menu_content_page_for() 已删
除**(仓库内仅存 2 处历史说明注释)。密码页按代码实况**单独出口**
(ui_page_registry_password())——它非节点绑定,任何 #P 叶子进同一页。
顺带落地此前判定"U1 阶段做不了"的共享 flat 样式 ui_style.{c,h}。
生成器除产注册表外**自动把新 .c 写进 uvprojx 与 CMakeLists.txt**,且
**双向对账**:加页打印 registered、删页打印 pruned,不留死条目;并双向
校验(#page 找不到实例报错、实例未被任何 #page 引用也报错)。
## U4 门禁补强(35 个钩子)
新增 font-charset 钩子(scripts/check_font_charset.py):复用
tools/font_gen 的同一套提取与 cmap 解析规则(importlib 直载,零第二套
规则),A 段查源码在用 vs 字符集、B 段查字符集 vs 字体 cmap。
registration-check 补第 ④ 类:实测原规则对"进了两端构建但没接描述符表"
的页面**全绿**——desc 被链接器剥离、编译链接全过、菜单永远打不开的死代码。
仍照不出的两项已如实写进文档(枚举漏加归 @build、菜单树漏挂归 golden)。
## 字体子集瘦身(D 案,4 留 3 删)
ui_cn_chars.txt 122→119 字(恰删 上/电/重,零新增)。异/常/片/芯 进
KEEP_EXTRA 带理由白名单:它们曾在 9eb1bd63 被写进中文自检描述落盘
/log/selftest.log(定长 64B 记录跨固件持久),删字形会使历史故障记录
渲染空白且不可逆。保留字按**必需**处理,反向有牙——谁只跑 extract_cn
把它们静默洗掉,钩子直接 FAIL 并逐字打印理由。
--strict 口径为"未知冗余 = 0"而非"冗余 = 0"。
## 验证
@build 0 错 0 警;ER_IROM1 232,052 B(较 HEAD −228 B)、RW_IRAM1
75,232 B **零增量**、RW_CCM 87.9% 未变。golden:菜单 8 状态全像素一致 +
内容页 11 页逐字节一致,**参考图 sha256 差异 0 条**(未用 --update 刷
基线);池水位菜单基线 5368 B、开页-关页往返 5448 B 与 U1 时相同。
38 个在途修改文件逐个核对 BOM/CRLF/U+FFFD 全部与 HEAD 一致。
L0 33 钩子 + L0.5 16 runner / 1104 断言全绿;check_doc_links --all
142 篇、无法判定 0;mem-budget / mem-numbers 已回填。
## 单位成本实测(U5 排期依据)
临时页 zzprobe 绑到"遥信量"叶子 → 只跑生成器 → 带页 @build 0/0 →
注册表出现 {5u, &ui_page_zzprobe_desc} → 回滚后 6 个产出文件 zzprobe
残留计数均 0、重编回基线。
**结论:新增一页 = 3 处人工(新 .c + 新 .h + 菜单树那一行加
#page=<名>)+ 1 条生成器命令,手工编辑注册文件 0 处。**
据此修正报告原口径"8 处降到 1 处"——那个 1 只在"1 处对既有文件的修改"
意义下成立,页面自身 2 个文件本就要写,真实处数是 3。
## 文档同步与两处自我修正
§0.1 UI 行 B → B+;§6.1「内容页」「设计令牌」两行按实况回填;§6.5 U1/U3
状态更新;§6 顶部加"建议栏不可照抄"总警示(本轮四次证伪:ui_port.h 已有
同名宏、LV_COLOR_BLACK/WHITE 不存在且极性反了、27 页实为目标页数现存 7
个、生成器草图漏密码页非节点绑定)。
两处改口:① §6.5 U4 从我上一版**误写的 3/3 改回 2/3**——"golden 脚本早已
存在"不等于"已进自动门禁",两个 golden 脚本至今未挂 pre-commit,该缺口
单列为待办;② 原计划"分三笔提交"**作废**,U1 与 U3 改同一批文件、文件内
交叠,硬切会产生不可编译的中间态,故整波一笔。
2026-10-20 21:14:14 +08:00
wandering1
720f841494
fix(storage): dhara 移植层 is_free 整页精度 + HAL 越界守卫;日志读写批量化
...
登记簿 N-21(报告 N-12/N-13)与 N-24(报告 N-16)两项未闭环问题修复并销项。
N-12:dhara_nand_is_free() 旧实现只读页首 64 B 判全 0xFF,会把"页首
0xFF、后段有数据"的已编程页误判空闲,dhara 遂往已编程页再编程 = 位碰撞、
journal/map 指向垃圾且不报任何错。改整页扫描(栈上 64 B 分块、页首命中即
早退,故"已编程且页首有数据"的绝大多数页成本与旧实现同价)。
N-13:报告原建议经核对不成立——本仓裁剪版 dhara 既无 DHARA_NO_PAGE(哨兵
实为 DHARA_PAGE_NONE,journal.h:46)也无 DHARA_E_UNSUPPORTED(error.h 枚举
里没有,照抄直接编译失败),且 map.c 三处 dhara_journal_copy 调用点各自已
挡掉哨兵。真风险是移植层零上界校验:越界页号被芯片地址位截断成某个真实页
→ 静默读写错页。改为六个 HAL 入口统一几何上界守卫 + DHARA_E_CORRUPT_MAP。
错误码选择是刻意的:BAD_BLOCK 会让 journal.c:904 标坏无辜好块,RECOVER 会
让 map.c:275 启动回收;无错误通道的 is_free/is_bad/mark_bad 一律取保守值。
N-16 写侧:一次排空合并成"每文件一次 open/write/close"(≤8 条 = 512 B
静态缓冲)。掉电语义不变——批次仍在同一次 drain 调用内 close,而 close
回写目录项这个不同 LPN 会把 FTL 单页写回缓存逼出到 NAND;失败尾部回投
队列,条目不丢(旧实现 -2 卷忙会直接丢掉那一条)。容量轮转仍只在按条慢
路径做,批量路径发现装不下一批就返回 -3 退回。
N-16 读侧:s_read_raw() 加 8 条滑动读窗口 + 写者代数失效,API 与 UI 零改动。
验证:@build 0 错 0 警(Code 213,540 / ER_IROM1 232,280 B = 22.2%,
RW_IRAM1 75,232 B = 57.4%,ZI +1,640 B 全为静态缓冲、不吃任务栈);
@test PASS,且台架 journal 恢复点与修复前同轨——连续四次启动 sectors used
恒 14,094、Map head 每轮 +128 单调推进、epoch 稳定 3 → 整页 is_free 未
改变恢复语义、无双编程、无回退;stack_report 9 个任务全 PASS(defaultTask
静态最坏链 3,024 B / 余 40%,实测峰值 2,164 B / 余 57%)。
新增主机侧移植层单测 test/host/nand_port/(第 16 个 -unit-test 钩子):
RAM 假芯片 + 真实 dhara map/journal 源,149 断言,含"旧算法只看页首 64 B"
对照用例(将来有人把 is_free 改回去会立刻红)与 dhara 级 resume 双编程计数
为 0 的场景。L0.5 由 15 runner / 955 断言 → 16 runner / 1,104 断言。
文档:存储架构说明 §5.3 加移植层两条硬约束;运行与自检记录设计说明
§4.4/§4.5 写批量化与读窗口;GD5F Trap Records 新增 Trap 07(含三条遗留
代价与一条待办编译期断言);登记簿 N-21/N-24 删行销项并同步 README
§1/§2.0/§2.1、排期详述 C3、报告 §0.1/§0.2/§0.4/§4.x/§7 与去处表;
钩子计数 33→34、主机侧单测 15→16 全库同步。
2026-10-15 12:34:39 +08:00
wandering1
506eccc68f
docs: 错误码传播审计收口并删除该文档(E-xx 转历史编号族)
...
本次会话先后销项与关闭:
- E-61 SD2506 清 INTAF:原实现只读取 CTR1,而按手册 ARST=0 时读操作
不清标志,属空操作;改为读-改-写 CTR1,并按手册订正 CTR1 位宏
(INTAF/INTDF/BLF 位置,ARST 归 CTR3)
- E-16 cfg_file:新增 CFG_FILE_MAX_NAME_LEN(段名/键名 ≤15),注册时
拒绝超长键名;s_gen_document 两处 snprintf 改检查式;补 TC-CFG-024
用例(主机单测 149→151 PASSED)
- E-23 TC704:PHASE7_MULTI_COUNT 8→5(并发上限 = 8 − 3 个常驻监听),
accept 失败分支加网络代次检查(网络重建即重建监听)
- E-26(UDP)按“保留 API + 文档定案”关闭;E-30 评估为不必要后关闭;
N-4(ACCEPT 决定不实施)关闭
审计文档剩余 5 项 P2 + 2 项监督,经用户裁定“都不重要”后整体删除:
- 删除 docs/问题记录/错误码传播审计.md(634 行)
- 九类缺陷模式表迁入 docs/编号规范.md §4.2.1(PAT-01~09)
- E-xx 转为纯历史编号族:编号规范 §4.1 属主改“无(原属主已删除)”,
§4.3 保持冻结;全仓 26 处引用按“保留编号、去悬空文档名”处理
- 顺带修正 N-4 收口遗留:排期详述 C1 才是 E-25/E-27/E-28 的承载处
(审计 §4 曾误写为登记簿);README 两处 C1 旧名改回“net 层跨上下文收口”
一并提交此前遗留的体系层评审报告 2026-10-14 复核 WIP(六维评分复核、
未闭环 Top 5→3、三区水位实测刷新)。
校验:Keil 构建 0 错误 0 警告(Code=212344);check_doc_links
--sections-strict 与 --all(142 文档)通过;内存双台账刷新后均 PASS。
2026-10-15 07:39:38 +08:00
wandering1
d770e36c7c
refactor(NET): 源码注释去阶段化 + 网络两份文档重构 + 不稳根因图更新
...
- 源码注释:删去自愈收敛阶段
1/1.5/3等 scaffolding 称谓,改为语义引用
(E-02 收口 / F-NET-2/3/4 / docs/网络/网络自愈架构设计.md §5.2 E13);
涉及 net_socket/.h、net_events、net_listener、net_pending、net_types、
net_config、ch395f、time_sync、iec104_serv、ui_net_sink、lftpd、
simulator/sim/net_socket_sim、board/host 测试与探针
- 文档重构:网络自愈架构设计.md 与 Net层阻塞模型架构设计.md 改为现状口径
(删历史节与阶段叙事),NET/README.md、docs/README.md 同步
- 工具与配图:gen_net_instability_svg.py 与
docs/images/网络不稳根因总览.svg 随源码口径一并更新
- 门禁:@build 0 错误 0 警告
2026-10-14 22:05:53 +08:00
wandering1
a12367981d
fix(N34): E14 丢中断复核——芯片不丢事件;listen 排事件挪至 LISTEN 前+全局读收口+全库归因更正
...
48 轮直读 SINT 矩阵(8 周期×6 变体)复核历史"丢中断"说法:芯片侧事件
丢失 = 0。归类:drain 读清消费 3/48(drain-int 探针现场抓获)、门控
竞态 2/48、主机同步 1/48、幽灵态 0/48 未复现。
根除性修复:net_listen_locked / net_listener_try 的排事件读清从
listen 后挪至 LISTEN 命令之前——新连接 CONNECT 落进该窗即被本方读清
吞掉,即"数据被吞"的生产侧自伤机制(台架 3/48 为同形态放大版)。
全局读收口:全局中断寄存器唯一读者 = net_poll(I7);生产/测试/台架
游离全局读全部删除,ch395f.h 声明处加护栏注释。
归因更正:17 文件约 40 处"丢中断"措辞改为"事件未收到/读清消费竞态"
(机制全部保留,仅归因更正);设计文档 §5.2 新增 E14 锚点;Trap
Records TRAP-NET-17/-20/B3 归因更正段;配图生成器与 SVG 重生成。
台架:事件未收到复核探针保留(drain-int / SINT 补读×3 / 超时归类),
下次跑矩阵自动归类;实验注册(main.c/uvprojx)已完全还原。
验证:@build 0 错误 0 警告;ci_local L0 32/0 + gitlint + L0.5
953/953;doc-links --all --sections-strict 通过;@test PASS(无
[ERR],net init 619ms);回归 :7003 300ms×10 = 10/10、:21 n30×50 =
0/50 失败。
2026-10-14 02:48:50 +08:00
wandering1
6394853fef
feat(N34): 阶段3 net层收敛——单一reconciler+忙等统一+镜像降级+E-02收口
...
实施方案 docs/网络/N34-自愈审计/实施方案.md §5 项1/2/3/5(项4 U15受E6暂缓):
- 3a 合并reconciler:net_listener_pump删除,与net_reconcile_tick合并为
单一100ms tick;判据读驱动状态缓存(唯一刷新点=net_poll每轮全量刷新,
E2背书18.1us);去抖分级②=1/③④⑤=2/①=4轮(M3让位窗400ms保留)+冷却1s;
链路态订阅留痕(F-DRV-13);探针去抖删除(F-MS-9)
- 3b 忙等统一(P2b):listen/connect open重试与close排空循环改
net_sock_reset_sync(驱动sock_reset:读空RX→CLOSE→排空事件→等
byte0=00H,内置LISTEN态二段CLOSE补发);close不再读清全局中断寄存器
(F-NET-7);net_poll每轮步进活跃复位状态机(驱动契约,防搁浅)
- 3c 镜像降级:net_sock_state_t声明为本层会话投影,芯片事实源=驱动缓存
- E-02收口:新API net_drop_conn(拆会话保监听,QUARANTINE语义,幂等;
模拟器双端实现;timeSync 30s预算耗尽接入;主机单测TC-TS-027d)
定案:CH395F close无RST,对内核存活不close的对端停FIN_WAIT_2,
监听恢复受限于对端close(Trap 07补充),兜底=E13 keepalive/TIMEOUT
台架全绿(Code=211348 RW=1104 ZI=154232):@test PASS;[STACK] net
1116/3840;Trap22 :7003 50/50+:21三档各50/50;Trap23 RST10/10+FIN5/5;
Trap25 n30 11/11;E-02双PASS;iec104 18/18;对时跨会话连续;
ftp_regression 11/11;integrity 15/15 SHA;ci_local L0+L0.5全过。
2026-10-13 15:09:58 +08:00
wandering1
d346e4ee84
feat(NET): N34 阶段 1.5 recv 语义主流化——无限默认+具名非阻塞+模式属性
...
核心语义(实施方案 §3.5):
- net_recv 默认无限阻塞:删除 NET_RECV_TIMEOUT_MS(30s 隐藏默认预算),
超时归调用方策略;唤醒源=数据/EOF/close/网络重建(CONNRESET),
会话死亡由对账① ~400ms 判死兜底,无"对端消失永久挂死"窗口
- 新增 net_recv_nb(NET_MSG_DONTWAIT 路径转正具名)与
net_setblocking(fd,on)(阻塞模式挂控制块属性,对齐 O_NONBLOCK/
Python setblocking;直写单字节,net_set_event_cb 先例)
- net_types.h net_sock_t 新增 blocking 属性;net_socket() 默认置 1
(close memset 清零后显式重置,同 released_abnormal 纪律)
- 原 1s 强制了结看门狗降级为 60s tripwire:只 [ERR] 留痕一次,
绝不伪造 TIMEDOUT 返回值(旧实现掩盖完成路径缺陷)
- net_recvfrom 删 30s 自旋超时、同判据对齐(零生产调用者,注释警示)
- 文档契约:IWDG required_mask 内任务禁止无限阻塞 recv(BSD 指南
§3.5/§10.1 + net_socket.h 注释)
调用点审计(§3.5.5):零生产调用点采用无限默认——iec104_serv/
ui_net_sink 转 net_recv_nb(受监控任务逐位等价);lftpd/time_sync
已是显式预算 net_recv_to 不动;32 轮盲收兜底未动(阶段 3 E6 门禁)
模拟器双端镜像 net_recv_nb/net_recv_to/net_setblocking(包装层
Sleep(1) 轮询模拟阻塞);差距清单 N-3/N-6 登记义务已履行
门禁与台架:
- @build 0/0:Code 209580→209780(+200B) ZI +32B;RAM 受管区官方
脚本同步;ci_local L0 32/32 + L0.5 951/951
- 台架全回归:relisten :7003 50/50、iec104 18/18、对时正常、
ftp_regression 11/11、Trap23 RST 5/5+FIN 5/5、ftp_integrity
20/20 字节一致、n30 0/10、@test PASS
- 模拟器 build_sim OK + check_remo_sink 黄金参考 0/25600 位差
队友 p15-recv-semantics 实施,Lead 全量审阅 + 独立复跑门禁与回归
2026-10-13 11:23:19 +08:00
wandering1
b8c6a3dab0
refactor(net)!: N34 阶段1 API 面收敛(对账⑤ + 删 3 个手动自愈 API)
...
BREAKING CHANGE: 删除公开 API net_relisten / net_resync_listen /
net_can_accept 与消息类型 NET_MSG_RESYNC_LISTEN / NET_MSG_RELISTEN。
生产调用者为零(仅看门狗文档与 iec104 门控),应用侧无迁移成本;
如有外部消费者须改用对账/pump 自动机制(见下)。
1. 对账①扩展为①②⑤(F-NET-2 缺口,先补缺口再删 API)
net_reconcile_tick 新增 bad=5:本层 ESTABLISHED 且芯片 0x05/0x01
(Socket OPEN + TCP LISTEN,静默回收回监听、不发 DISCONNECT)
→ RESYNC 语义只修本层(state→LISTENING + last_peer_port 转登 +
lost_conn_seen 清零 + 取消挂起 recv),**不发任何芯片命令**
(纪律同 pump③ U11,run8 实证重下发会 170s 永拒)。
原判据①要求 TCP==CLOSED、②要求本层 LISTENING,均不命中此形态
——此前生产无人认领(仅手动 API 能修)。
2. 删 net_relisten(net_socket.c 函数 + 消息分派 + 头文件声明)
footgun:对健康监听器无条件 open→USE→close 自毁 ~1s(原注释自认);
与 pump(100ms)/D10(30ms) 完全重叠。
3. 删 net_resync_listen(同上;语义并入第 1 条)
4. 删 net_can_accept(net_socket.c + net_socket.h + sim 三处)
只认 ESTABLISHED 的旧门控把"监听器在服役、待 CONNECT"窗口全挡掉,
:2404 丢 CONNECT 探针因此从不运行;iec104 门控迁 net_listener_armed。
5. timeSync :8888 会话收尾不再 net_close(同 fd 续 accept,监听跨会话
常驻;原 close→重建每会话一个 Trap 09 沉降窗)。server 脚本注释同步
新契约(PC 侧 2s 宽限后自行关闭)。
6. lftpd 应用层阻塞重试退役:lftpd_inet_listen 5 轮(500ms/2000ms,最坏
10s 阻塞 ftpTask) → 单次 + 失败即 425;cmd_pasv 3×200ms 同删。
就绪屏障已消除 Trap 09 启动形态,客户端自带传输重试语义。
台架实证修正(本提交内二次修复,务必留痕):
- net_listener_armed 补齐 **ESTABLISHED 放行**。首版迁移只放行
LISTENING/CLOSED+残留,漏了 ESTABLISHED=单连接模型的"待 accept"电平
→ iec104 200ms 任务周期抢不过对账② 的 ~400ms 去抖,对账②先 standalone
accept 转 ESTABLISHED 后 armed=0 → 应用整场不 accept,18/18 检查全 FAIL
(设备日志证据:sock1 standalone accept 后无 i104 accepted,直至对端 FIN
才由 closed-with-data 救回)。补放行后 18/18 PASS,且耗时 127s→8.3s。
该态 accept 必返 fd,无 RPC 风暴风险。
- 期间顺带验证 M3 无辜:sock1 suspect DISCONNECT on live conn 命中后
defer→对账①→closed-with-data accept 把未 accept 的 RX 数据救回,
正是 M3 设计意图(资产门保护)。
验证(全绿):@build 0/0(Code=209580;含 CH395F 套件+Phase13 全量重编
0/0 的编译验证);@test PASS(回读无差异);iec104 18/18(8.3s);
n30 0/50;:21 @0ms 50/50 p50=512;:7003 50/50 p50=517;ftp_regression
11/11;Trap23 RST 5/5 + FIN 5/5;time_sync :8888 连续推送正常(RTC 更新、
无 [ERR])。文档同步:BSD 指南(§3.3/3.6/10.1/10.2/12 + 变更记录)、
函数调用关系、监听生命周期设计说明、IEC104 上行设计说明、模拟器差距
清单、链路延迟测试说明。
门禁说明:doc-links 工作树 junction 伪影按既定口径 SKIP;mem-budget
分支 .map 漂移同前;cppcheck/coding-standard 手跑 Passed。
2026-10-13 06:44:26 +08:00
wandering1
1d96fc9f87
feat(soe): B9 动作记录 + 时标 SOE(L4-4/L4-5)+ 104 M_SP_TB_1 自发
...
- 新增 App/log/soe_rec.{c,h}:64B 定长 SOE 记录纯编解码(CP56Time2a
时标 + 类型 + 元件号 + 单调序号 + 值 + sum8 撕裂校验),零 I/O 零 OS
依赖,主机 L0.5 覆盖(32 断言,含与 iec104 CP56 解码器交叉互证)
- 新增 App/log/soe_store.{c,h}:protectTask 边沿投递(取时标 + 组记录 +
SPSC 待发环/消息队列,零文件系统);defaultTask 经 syslog_drain 尾部
排空落 /log/soe.log(卷锁 try / FA_WRITE|FA_OPEN_APPEND / 校验字节数 /
容量满 unlink 重建,全套照 run.log 实证纪律;无卷损坏归类路径)
- protect_task.c:元件动作/返回、软压板投退、采样闭锁/恢复六类边沿
→ soe_store_post;post 内禁 DBG_*(protect 静态最坏链 872 B 不变,
改前/改后 stack_report 九任务逐字节一致),丢弃留痕挪 drain 侧
- iec104:单点 YX 自发改 M_SP_TB_1(30) 带 CP56 时标(总召/周期保持
M_SP_NA_1,单测两种都断言);link cfg 新增 epoch_ms 时标源回调
(NULL/无效 → IV 位如实置位);serv 绑 sys_clock(秒域时基,
ms 域 = 秒×1000,不造假亚秒)
- 主机单测:test/host/soe/(32 断言)+ iec104 94→97(TB 时标/IV);
iec104_master.py 解析 type 30(B6/B7 流不回归);decode_soe.py
台架解码断言工具(seq 单调/校验和/UTC 交叉)
- 注册:uvprojx + check_registration SIM_EXEMPT 点名(MCU-only 胶水)
- 文档(我方属主区):`App/log/README.md` 增 soe 节(64B 记录/单写者/
post 禁 DBG/UTC 交叉坑);`docs/子系统设计/IEC104上行设计说明.md`
§1 范围行 + §3.2 时标注 + §7 台架行 + §8 第 2 条销项 + 变更记录行
台架腿(bench 锁 B9,release --bench-pass):run_boot_test PASS;
--b7-pre 21/21、--b7-post 13/13(B6/B7 回归 + 确定性动作边沿);
自发 YX 上送 M_SP_TB_1 带 ts(11:00:51 动作 / 11:00:53 复归);
FTP 下载 /log/soe.log 30 条记录 decode PASS(seq 0..28 单调、
ELM_ASSERT 14 条、UTC 交叉一致);定值/压板已恢复默认。
台账 +1088 B(SPSC 环 512 + 静态 FIL 528 + 计数器)随合并由 Lead
回填(ram_baseline --write + check_mem_numbers --write)。
gate: only mem-budget/mem-numbers pending lead ledger backfill
(pre-commit --all-files: 29 Passed / 2 Failed / 0 Skipped;
hygiene self-check OK: no BOM/CRLF/mojibake/trailws/non-ASCII literal)
sync 追平 v2-on-ui(B8 freq + N33 抬栈)后复跑:@build 0/0
(Code=209492 RW=1104 ZI=154184);stack_report 九任务全 PASS、
protectTask 872 B/57% 不变;ci_local L0.5 15 runner 951/951
(freq 46 / soe 32 / iec104 97 / prot_set 90 / prot_elm 47)。
顺带修 protect_task.c 陈旧注释:定值巡检 31 项 → 40 项(B8 后)。
2026-10-12 19:38:13 +08:00
wandering1
0264b49489
feat(algo): B8 频率测量层 + 过频/低频保护(L3-5)
...
新增 App/algo/freq.c/h:由 L2 基波相量导出系统频率。相邻两拍共轭
乘积 P=Z(m)·conj(Z(m-1)) 取角 = 每拍相位增量(免显式解缠绕),再按
自适应窗长 K_eff=round(8·Fs/(2·f_hat))(45~55 Hz 段 73~89 拍)做滑动
平均。定长窗受 20 点矩形窗负序泄漏纹波限制(实测扫频最坏 0.317 Hz;
60 拍 Kay 复数和 0.197 Hz,交叉项和角不按 1/K^2 衰减),自适应窗使
窗长恰为纹波周期 fs/(2f) 整数倍 -> 最坏 0.0101 Hz。推导与两轮弯路
写在 freq.c 文件头。
假值钳制带取 35~65 Hz,刻意宽于系统合理带 40.5~60.5:单拍相位差本身
带 ±5 Hz 泄漏纹波,贴边钳制会非对称丢弃纹波半周 -> 均值偏置(实测
45 Hz 点 +0.16 Hz)。系统合理带由 OF/UF 定值范围在消费侧把关。
幅值门 FREQ_AMP_MIN=50 码(拟定,待 L1-5 标定复核):低于门判无有效
波形,停更新、valid 清零、读数保持 -> 浮空/PT 断线不发散。源优先级
UA(C02)->IA(C01),按名前缀解析、每拍动态回退,切换即废相位基准。
prot_set:尾追加 8 项(PS_ID_COUNT 32->40,编号不回收)
OF_EN/OF_HZ/OF_DLY/UF_EN/UF_HZ/UF_DLY/RET_OF/RET_UF。OF/UF 逐项通讯
地址不在本仓库 -> 全部 comm_addr=0 本地项(104 C_SE 不可寻址,待对照
参考表补)。频率返回系数独立(0.99/1.01),勿与电气量 0.95/1.05 共用。
bad_mask 随项数扩为 uint64_t。PROT_SET_BLOB_VER 1->2。
prot_set_store:换代与损坏分流。load 返回 2 = 版本/项数换代(本文件
打 INFO "prot set blob version change, defaults in use"),-1 = 真损坏
(defaultTask 按 CORRUPT 报 ERROR + 自检留痕)。B7 旧档(ver=1/32 项)
升级首启属预期路径,不得报成损坏。语义分流收在属主文件内,
default_task.c 不动。
prot_elm:实例表加 src 字段(0=phasor rms,1=freq),PE_OF/PE_UF 尾
追加(PE_COUNT 7->9)。freq 无有效读数按方向填"必不启动"值(过量 0 /
欠量 1e30 -> 滞回比较恒假 -> 元件复位),不整拍跳过——频率源缺失不得
饿死电流/电压类元件(B5 行为不回归)。OF/UF 暂未映射独立 104 遥信点,
动作只经 YX15 保护总聚合可见(送检点表 = B10)。
板端接线:adcTask 在 phasor_run() 之后同拍调 freq_run();心跳/首拍日志
追加 freq(<tag>): f=%ld valid=%u (x0.01)(MicroLIB 无 %f)。app_main
内核前 freq_init()。
主机单测:freq 46 用例(J1 扫频 45~55 Hz <=0.02 Hz 实测最坏 0.0101;
J2 噪声 1% <=0.10 实测 0.0160;J3 启动收敛 <=40 ms 实测 20;J4 阶跃
50->51 <=120 ms 实测 98;J5 浮空 valid=0 不发散;J6 跳变 60 ms 内回
±0.05;另直流 8000 码 / 3-5 次谐波 20%/10% / UA->IA 回退)。
prot_set 90(+TC-PS-011 OF/UF 行 + 64 位 bad_mask bit39 + 旧档拒绝)、
prot_elm 47(+OF/UF 滞回与方向隔离 + run() 测频接线)。回归:phasor
57、iec104 94 全绿。
J4=120 ms 是"精度优先于响应"的显式取舍(Lead 批准):4 周波窗换
0.317->0.0101 Hz,测频响应 98 ms << OF/UF 定时限默认 1000 ms(占
总动作时间 <10%),暂态另有 J6 <=60 ms 兜底。
注册:freq.c 入 uvprojx algo 组 + check_registration.py SIM_EXEMPT
(纯算法、模拟器无消费路径,照 prot_set.c 先例)。
@build 0 错误 0 警告(Code=207468 RO=18304 RW=1068 ZI=153084)。
RAM:RW_IRAM1 96096->96728 B(+632 B,73.3%->73.8%)、RW_CCM 不变
57376 B(87.9%)、Flash 224596->226840 B(+2244 B,21.4%->21.6%);
台账随合并由 Lead 回填。stack_report:adcTask 静态最坏链 1320 B /
余量 1240 B(48%)改前后完全不变(freq_run 帧未进最坏链,无需抬栈);
protectTask 链 872 B / 余 1176 B(57%)同样不变。
gate: only mem-budget/mem-numbers pending lead ledger backfill
--------------------------------------------------------------
门禁实跑(pre-commit run --all-files,Lead 批准 --no-verify 提交):
28 Passed / 2 Failed,失败仅 mem-numbers 与 mem-budget 两条——均为
docs/内存管理 受管快照与本 .map 不一致(台账由 Lead 每次合并后
--write 回填,避免多分支同改受管表冲突)。其余含 doc-links /
coding-standard / no-mojibake / cppcheck / registration-check /
13 条主机单测钩子全 Passed(gitlint 属 commit-msg 阶段,不在该次
--all-files 内)。ci_local L0.5 全绿(freq 46/46 等)。
字节卫生自查(--no-verify 跳过卫生钩子,故手工核):17 个暂存文件
全部 BOM=无 / CR=0(纯 LF)/ U+FFFD=0;自研 .c/.h 去注释后字符串
字面量 100% ASCII(唯一非 ASCII 字面量在 test/host/iec104/iec104_test.c
的既有用例名,非本次改动行;test/ 不在 coding-standard 钩子范围)。
2026-10-12 19:16:37 +08:00
wandering1
dafcf8098b
test(b6): 台架 @test 闭环复测收口 + 启动行门控修复 + PC 104 主站
...
B6 台架 @test 闭环复测(B4/B5 验收窗口)完成,DoD 全判据过。
门控修复(首跑 FAIL 实锤的 B5 遗留竞态):
- 现象:protect task start 锚点行字节级交错损坏
(st[art: cycle=220ms elm=70,两次开机同形复现)
- 根因:启动行在控制台写者注册前打印走无锁裸发,与
defaultTask 启动日志交错——违反 2026-10-10 门控纪律
(控制台单写者日志设计说明.md §3.4,adcTask 同款先例)
- 修复:启动锚点行改 dbg_console_writer_ready() 首拍补打
台架与工具:
- .serialtest/config.json:Required 增 protect task start /
i104 listening on 2404 / [STACK] protect|iec104|heap
- test/host/iec104_master.py:纯标准库 104 主站客户端
(STARTDT→总召四组+actterm→C_SE 两段写触发 YX15/16 变位
COT=3→恢复复归→YK11 两段正答→C_RD 读回),往返 18/18
PASS(d3107f3 与 B7+fix 两版固件)
- 复测 @test PASS:锚点完好 +577ms、9/9 Required、零 [ERR]、
回读一致;protect free_min 1220(59%)、iec104 2136(83%)、
新 56KB 堆 min_ever=10000(N-33 抬栈背书就绪)
证据与文档回填:
- boot_log_data 四份快照(含缺陷复现 MISS 件)+ README 登记
- 保护规划 §7 B6 行(B5 台架遗留闭环);控制台单写者 §3.4
纪律示例 + §11 变更记录;IEC104 §7/§8 主站工具就绪;
W1 卡 B6 ✅ + N-33 背书 + B7 台架腿注;登记簿 N-33
- 内存台账:+16 B 构建后 ram_baseline/check_mem_numbers 回填
验证:@build 0 错 0 警(Code=205516);ci_local 全绿
(L0 30 钩子 + L0.5 13 套件 826 断言)。
2026-10-12 16:31:33 +08:00
wandering1
1fe163ba7b
feat(protect): B7 定值持久化 + 全局软压板 + L5-1 竞态收口(W1 代码腿完成)
...
- prot_set:新增 PS_GLOBAL_EN(枚举尾追加);值区双缓冲 + 单字交换,
prot_set_set_sealed 原子写+封存;selfcheck 改 seqlock 式复核
(提交撞见 = 本轮跳过)→ 收口 B5 登记的 µs 级误锁窗口
- 持久化:新增 App/cfg/prot_set_store.c/h,/prot_set.bin blob
(magic+版本+计数+值区+sum32 正/反码对,144 B)走 cfg_store_write_atomic;
uvprojx 注册 + 模拟器豁免点名(check_registration 同步)
- 写路径:C_SE/YK12 执行段置脏 → iec104Task 投递 SYS_EVT_PROT_SET_SAVE
(事件位 bit7)→ defaultTask(配置引擎属主)落盘,写失败脏回置 = 天然
重试;装载 = STORAGE_READY 屏障前整表原子 parse(损坏保出厂默认 +
自检留痕 prot set corrupt;文件缺失 = 首启静默)
- YK12 转真:两段式(选择段校验 DPC / 执行段 set_sealed),protectTask
下一拍读退出态 → 复位元件 + 停判据(global plate OUT/IN 边沿日志);
本地定值项 comm_addr=0 显式不可寻址(防 IOA=0 误命中首个本地项)
- 单测:prot_set 63 断言(+33:软压板/原子写/脏握手/blob 往返/损坏拒绝/
伪造自洽越界对抗样本)、iec104 94 断言(+7:YK12 两段转真/置脏/本地项
C_RD EVI)
- 文档:IEC104 设计说明 §3.3/§3.4/§7、保护规划 §3.5 L5-1/§7 P4/变更记录、
App/algo 与 App/cfg README、W1 任务卡 B7→🟦 (台架腿 🔴 待窗口,随 B6 同窗)
- 验证:@build 0 错 0 警(Code=205500,ZI +280 = 双缓冲+blob 缓冲);
ci_local 全绿(L0 27 钩子 + L0.5 13 套件 826 断言);ram_baseline 台账
受管区与内存快照已同步;19 个改动文件无 BOM / LF / 零乱码
2026-10-12 15:01:49 +08:00
wandering1
d3107f374f
docs: 待处理内容.md 解耦为 docs/任务规划/ 文件夹(README 排序权威 + 6 个职责单一文件)
...
- rename_ref.py 搬迁:git mv + 全库引用改写 33 文件 82 处
- README.md 保留 §0 编号空间 / §1 未闭环一览 / §2 推进顺序权威 / §3 维护约定
- 拆出 6 文件:W1-采集保护收尾(任务卡五字段)、排期详述、暂缓-RS485、
登记簿、测试与架构专项、基线与待确认
- 外部引用重定位 ~50 处:裸「登记簿 §X」、§5.1→基线与待确认 §2.1、
§2.4→暂缓-RS485、§6→基线与待确认 §3、脚本注释 T-x/N-x→登记簿
- 新增并行写纪律:任务分支不改本文件夹,状态列由 Lead 主工作树更新
- 验证:doc-links 141 文档全绿;mem-numbers 一致;refgraph 重生成;
@build 0 错误 0 警告;新文件无 BOM / LF / 零乱码
2026-10-12 13:42:47 +08:00
wandering1
90db528032
W1 功能主线完成:内存台账三件套(W1-0) + IEC104 上行(B4) + protectTask 板端接线(B5)
...
W1-0 台账三件套:scripts/ram_baseline.py(四模式)+ ram_baseline.tsv 趋势 +
docs/内存管理/RAM预算台账.md + pre-commit mem-budget 钩子(RW_IRAM1/RW_CCM >92%
即 FAIL + Top-10 附表);审查报告 §5.5 三条闭环。
B4 IEC 60870-5-104 上行(被控站,TCP 2404):App/protocol/iec104/ 三模块
(asdu 编解码 / pts 点表+数据源 vtable / link APCI+FSM,纯逻辑零 I/O)+
App/task/iec104_serv.c(iec104Task,NET_READY 屏障 100ms 分片喂位)。
82 断言 L0.5 全绿 + iec104-unit-test 钩子(第 31 钩子);
设计说明 docs/子系统设计/IEC104上行设计说明.md 全量回填。
B5 protectTask(L3 板端接线):App/task/protect_task.c——20ms 判据节拍
prot_elm_run + L5-4 采样故障闭锁(adc_health 电平位→元件复位)+ L5-1 定值
校验和巡检;新增 prot_elm_request_reset() 收口跨上下文复归(104 YK11 落请求、
eval 头部消费);定值/元件初始化移入 app_main_init(内核前)。TC-PE-010
(prot_elm 28 用例)。
门禁与内存:TASK_WD_PROTECT=8 入 required_mask(产品 0x77→0x1F7、HW 层
0x1F5,看门狗单测 39 断言同步);FreeRTOS 堆 48→56KB(.ioc L1 参数 +
FreeRTOSConfig.h 同步,RAM预算台账 §6 登记配额 48→56KB)。
ZI 144,008→152,204(+8,196 B = 堆 +8KB,B5 扩容);Code=204,348。
stack_report:protectTask 512 words 静态链 872 B/余 57%、iec104Task
640 words 1456 B/余 43% 均 PASS;RW_IRAM1 73.1% / RW_CCM 87.9%(<92%)。
验证:@build 0 错 0 警;ci_local 全绿(31 钩子 + 13 主机侧单测);
doc-links 135 文档 PASS。登记簿 B4/B5 销项、W1 波次完成;保护规划/看门狗
说明/AGENTS(9 任务)/RAM 三文档全部同步。
遗留(验收窗口,非代码空洞):台架第三方 104 主站往返(送检窗口)、
标准源注入动作判据、@test PROT 锚点 + protect 栈水位 + 新堆 min_ever 复测。
2026-10-12 12:36:23 +08:00
wandering1
c5227291bd
test(fw-stamp): 身份戳覆盖测试宏——头依赖 + suite/dstr 变体串
...
问题:__DATE__/__TIME__ 只在所属 TU 被重编时才刷新,而 app_main.c 不依赖
test/board/test_config.h → 只切套件宏的增量构建不重编它,测试镜像与产品
镜像顶着同一个 fw build: 戳,@test 的戳校验对"两种构建互换"完全失明
(2026-10-11 N-31 复测实测:两者戳同为 Oct 11 2026 14:44:11,只有
-CmpFile 回读才发现镜像不同)。
修复(App/app/app_main.c,两条防线):
- #include "test_config.h" 建立头依赖 → 改 TEST_SUITE_* /
ENABLE_DESTRUCTIVE_TESTS 必重编本 TU,戳必刷新(根因修复)
- 戳串追加 FW_BUILD_VARIANT = " suite=<TEST_SUITE_NAME> dstr=<on|off>"
→ 戳内容本身区分构建,时间撞车也能分辨
实测:产品 20:36:11 suite=NONE dstr=off ↔ 测试 20:36:40 suite=CH395F
dstr=on ↔ 还原宏后 20:36:55 suite=NONE dstr=off(时间戳每次都变 = 头依赖
真的生效)。@test 全闭环 PASS:戳匹配 + 回读 No difference found +
锚点 x1 + 零 [ERR]。run_boot_test.py 无需改动(戳按"标记后连续可打印
ASCII"抠取,天然吃下新后缀)。
代价:Code 196764 → 196788(+24 B),@build 0 错 0 警。
文档:自动化测试流程.md 补「戳覆盖构建配置」小节与变更记录行;失败模式
表新增一行——戳命中但 suite= 与要跑的套件不符 = 烧的是产品镜像。
门禁:mem-numbers 钩子拦下「RAM 文档快照与 .map 不一致」→ 用
check_mem_numbers.py --write 刷新生成区(ER_IROM1 213,256 → 213,396 B)。
2026-10-11 20:45:09 +08:00
wandering1
d1e6bb4ba7
W5波+N-19收口:FTP鉴权落地、Trap25三连定案修复(N-30)、N-20/N-23/N-26
...
N-19 FTP 鉴权:
- lftpd_auth(USER/PASS 状态机 + 连续5次失败锁60s)+ SHA-256
(user||pwd) 口令哈希;config.ini [ftp] 段 user/pwd_hash/write,
出厂 admin/admin 在用有启动告警;lftpd_log.c 删除并入 lftpd_auth
- ftp_cfg 配置读写;台架 ftp_auth_bench.py 13/13
N-30 / Trap 25(CH395F_Trap_Records.md 四次定案全记录):
- 修复1 closed-with-data accept:客户端发完正常 FIN 后芯片按
FUN_PARA(0x09) §5.52② 保留 Socket+RX 缓冲,旧代码把 CLOSED 一律
relisten 自毁缓冲 → STOR 必挂 425;改为接受"已关但可读"连接排空
- 修复2 丢 CONNECT 中断探针 net_lost_connect_probe + last_peer_port
幽灵甄别(拆链窗口握手完成但中断丢失,双信源去抖补 accept)
- 修复3 send_list/send_nlst 批量单发:背靠背 ~60B 小段毒化芯片 TX
(芯片报 SEND_OK 但对端全丢),整份目录一次性写入
- 证伪存档:固定沉降/Socket 轮换冷却/listen 门控(台架 v7 矩阵)
- 台架工具 test/board/ch395f_reuse_bench.{c,h} + host 脚本存档
(不注册编译;实验分支 n30-chip-bench 保留)
N-20:Error_Handler 死循环降级(记录+复位路径)
N-23:scripts/check_registration.py 双端注册反向校验(pre-commit)
N-26:GD5F NAND 直 DMA 调用方缓冲窗口断言
验证:BUILD_OK 0/0;ftp_regression 连跑 4 轮 11/11(修复前
LIST#4/#7 100% 挂、STOR#2 曾 100% 425);ftp_auth_bench 13/13;
@test 启动标记 PASS;ci_local L0+L0.5 全过;doc-links 通过。
登记簿 N-30 已销项。
2026-10-11 18:50:24 +08:00
wandering1
c936441c83
门禁扩容:新增 lv-conf-sync、simulator/ 纳入全部钩子;含 L3 定值/元件框架落地
...
本轮把"自研代码落在门禁之外"的口子收掉,同时落地 LVGL 特性裁剪与
L3 保护定值/元件框架。
门禁(.pre-commit-config.yaml,26 个钩子)
- 新增 scripts/check_lv_conf_sync.py + 钩子 lv-conf-sync:比对两份
lv_conf.h 的**生效值**(未定义则取 lv_conf_internal.h 兜底默认),
抓 MISMATCH / LVGL 不认的宏名 / 同文件重复定义
- 顶层 exclude 删掉 simulator/:其下 21 个 tracked 文件全是本项目自研
代码,生成物(build/、SDL2/、tests/ref/、shot*)已在 .gitignore;
doc-links 的 exclude 同步删除
- lv-conf-sync 的 files: 覆盖两端配置 → 只改 simulator/lv_conf.h 也触发
(pre-commit 4.x 已移除 always: true,实测只告警并跳过,无兜底开关)
- 新增 prot-set-unit-test / prot-elm-unit-test 两个主机侧单测钩子
- S11(2.3.5) 判定细化:禁的是"用路径找文件",尖括号系统头带子目录
(如 <sys/stat.h>)不再误报;全仓库复核仅 2 处项目代码判定变化
模拟器代码整改(纳入钩子后暴露,全部修代码而非豁免)
- cppcheck 4 处:sim_syslog.c 判空分支内解引用 p_epoch(真实 bug)、
2 处 struct tm 未初始化、1 处指针可加 const
- coding-standard 61 处:44 处函数左大括号并到右括号同行、8 处补函数
注释、3 处补文件头注释块、2 处 __ 前缀保护宏改 XXX_H、2 处 sprintf
改 snprintf(写入字节数与原来完全一致)
LVGL 特性裁剪(F-1/F-2/F-3)
- 两端 lv_conf.h 对齐同一特性子集:删 26 个 LVGL 9.3 不存在的选项名、
3 处重复定义,10 项靠默认值隐式生效的改为显式固化
- 实测对镜像体积中性;价值在防漂移,且模拟器 golden 回归跑的正是固件
实际编译的配置
L3 软件侧
- App/algo/prot_set.* Q10 定值模型(范围校验 / 整表 all-or-nothing /
校验和封存-自检-闭锁)+ prot_elm.* 通用"滞回+定时限"元件框架 7 实例
- test/host/prot_set、test/host/prot_elm 主机侧单测;uvprojx 挂载两处
文档同步
- pre-commit使用说明:§2.8 S11 口径、§2.15 lv-conf-sync 详解、新增 §5.5
复盘(教训:exclude 只写真正不该进钩子的路径)
- AGENTS.md、UI_设计架构 §1.4 第 10 条、RAM 分析、审查报告刷新与销项
验证
- @build BUILD_OK 0/0(Code=194276 RO=15872 RW=876 ZI=139892)
- 模拟器重建:菜单 8 状态像素逐字节一致(池 5368 B)、11 内容页黄金参考
全过(往返 5448 B)、remo sink 0/25600 位差异、--logtest/--cfgtest PASS
- 全仓库 cppcheck / coding-standard / no-mojibake --all-files 全过
- check_doc_links --all 129/0;check_mem_numbers --check 内存数字一致
- 端到端:往 simulator/lv_conf.h 注入一行漂移 → 钩子 FAIL(exit 1)
2026-10-11 08:48:49 +08:00
wandering1
13a4e61c27
L1-6 采样有效性校验:adc_health 判定层 + 告警编排 + 31 用例单测 + 台架闭环
...
新增 App/algo/adc_health.c/h(纯逻辑判定层,零平台依赖免桩单测):
- 静默:两侧帧序号连续 >=100ms 无前进(电平位可自愈,flags() 为 L5-4 闭锁预留)
- 丢帧:TPAFE 序号一次前进 >1 计 tgap(与 STM32 侧 adc1_gap 对称,边沿事件)
- 单调性:序号倒退锁存位;tick/计数差值法 (int32_t)(a-b) 回绕安全
- 错误增量:FRSTDATA / HAL 错误 / STM32 停摆计数增量,事件位与锁存位编号对齐,
消费者按位图做"每类每次开机留痕一次"编排
adc_task.c v2.9 告警编排(判定与编排分离):严重事件/电平上升沿 DBG_ERROR +
SYSLOG_SELFTEST(每类每次开机一次防刷屏),下降沿 DBG_INFO 恢复;gap 不告警
(消费者超拍是已知现象,告警会淹没真故障);心跳行增 tgap 观测字段。
主机单测 test/host/adc_health/ 31 用例全绿(100ms 门限两侧 / 边沿语义 /
倒退锁存 / tick 回绕 / NULL 守卫 / init 幂等),登记 adc-health-unit-test 钩子。
台架 @test PASS:零 [ERR](健康不误报)、tgap=1->2 与 adc1_gap 同步可见、
frames 1000.0 Hz;证据 boot_log_data/20261011_prod_adc_health_boot_log.txt。
抬栈:adc_health_report->syslog_post 控制台回显尾使 adcTask 静态最坏链
832->1080 B(512 words 余 968 B < 1024 B ISR 底线)-> 512->640 words,
复测余 1480 B / 57%,堆 min_ever 7152->6640 B(-512 B 符合预算)。
AGENTS/README 任务表、RAM 方案 §2.3、规划文档 §3.1 L1-6 已同步置完成。
2026-10-11 01:28:20 +08:00
wandering1
54d6d2d5d5
docs: 删除 Task #32 停摆分析(已结案),可复用结论并入看门狗设计说明 §11
...
按登记簿"完成即销项"规则删除 docs/问题记录/UI任务看门狗停摆分析.md
(560 行)。结案依据:累计 38 次上板启动 0 复现(原 L2 基线 3/10),
P0/P1-4a/P1-5/P2/方案 A 全部落地,方案 B 已评估决定不做。
并入 docs/子系统设计/看门狗设计说明.md 新增 §11(只留可复用部分):
- §11.1 三条易误读的判读口径:启动期 MISS start 0x67 是良性 episode;
miss= 是累计不是连续(连续数饱和在 WD_MISS_TOLERANCE=8);
reset cause 不能区分 IWDG 溢出与台架软件复位
- §11.2 诊断四步:先看掩码缺几位(只缺 1 位 = 定点打击,多位 = 全局
饥饿)→ 逐项量化占空比(实测 10%~13%,否掉"CPU 饱和"直觉)→
用计数速率反证空转(ring 恰好 1000/s)→ 用 [PROF] 指认占用者
- §11.3 三条结构性脆弱点(uiTask 唯一 BelowNormal/心跳曾依赖 netTask
往返/自定截止期不可恢复)+ 两个顺带修掉的正确性缺陷(无新帧仍压环
≈3% 频率失配、失败拍静默沿用旧值)
- §11.4 [PROF]/[PROF2] 全字段语义 + v2.8 实测基线(netp=0 是真实值、
adcm 峰值来自心跳日志、uip 地板 = LVGL 帧周期)与三机理判读口诀
- §11.5 三条教训:门控类优化必须保留低频兜底;门控会顺手消灭暴露路径;
事件驱动要核对节拍源启动时刻 vs 消费者创建时刻
- §11.6 明确不做的四条及理由(提 uiTask 优先级会掩盖真缺陷、net_* 有界
等待版会串回执、推流搬出 uiTask、推流塞进 netTask)
UI 推流门控与方案 B 否决理由收进 RemoDispBus 协议说明 §3(该处原本已有
摘要,改为自洽不再回指);就绪门控 API 的约束已在 BSD Socket 指南 §10.1。
引用改指 12 处:ui_task.c、task_prof.c/.h、ui_net_sink.c/.h、docs/README、
RemoDispBus、看门狗设计说明 R7 行、ADC 采样节拍设计说明、BSD Socket 指南
×2、项目审查报告 N-10 ×2。
⚠ ui_task.c / ui_net_sink.c / ui_net_sink.h 是带 BOM 文件,Edit 剥掉了
BOM,已按原样补回 3 字节 EF BB BF(未整文件重写)。
验证:check_doc_links --all 通过(127 个文档,无悬空引用);
@build 0 错 0 警,Code=257660 与删除前一字不差(纯注释改动)。
2026-10-11 00:38:50 +08:00
wandering1
9bbe117f97
adc: 节拍源 TIM6->TIM3 + ADC1 走 DMA 乒乓双缓冲,消除 2 ms 忙等(P1-5 单拍硬上界办结)
...
用户选定最彻底方案(B2):DMA + 定时器 TRGO 硬件触发 + 消费上一拍
已完成的半区。对应 P1-5 拆出的"单拍硬上界",现已办结。
硬件事实更正(查 CubeMX 器件库 + 本仓 HAL 头证实):F4 上 ADC1 的
外部触发清单里没有 TIM6/TIM7 TRGO(只接 DAC)。故 1 kHz 节拍源由
TIM6 改为 TIM3(PSC 83 / ARR 999,TRGO=UPDATE),同一个更新事件
同时 ① ISR 脉冲 TPAFE CONVST ② 经 TRGO 触发 ADC1 一轮 9 通道
③ 置位 ADC_WAKE_FLAG 唤醒 adcTask。TIM6 从 .ioc 整体移除。
代码:
- Src/tim.c/h:新增 MX_TIM3_Init(含 MasterSlaveMode),删 htim6
- Src/adc.c:ExternalTrigConv=T3_TRGO + EDGE_RISING +
DMAContinuousRequests=ENABLE;MspInit 挂 hdma_adc1(DMA2_Stream4
循环模式)。DDS 位关掉 = 一轮只发一次请求,静默丢 8 路
- Src/dma.c:DMA2_Stream4 NVIC 优先级 6(CubeMX 换流会把它重置为 0,
优先级 0 会抢占 FreeRTOS 临界区,违反"外设中断 ≥5")
- Src/main.c:周期回调加 TIM3 分支;stm32f4xx_it.c 向量同步
- App/algo/adc_input.c:stm32_scan() → stm32_take(),逐通道
PollForConversion 全删;乒乓半区由完成计数奇偶推出(只读一个
32 位量 → 与 ISR 无竞态);STM32 侧数据固定滞后 1 拍
- App/task/adc_task.c:心跳日志拆出四类计数
观测性:adc1_seq(完成计数)/ adc1_gap(seq 前进 >1 = 丢帧)/
adc1_err(连续 ≥2 拍无新帧 = 停摆)/ adc1_hw(HAL 错误回调)。
单拍无新帧是消费者相位伪影(DMA 完成落在唤醒后 ≈67 µs),不计故障。
验证:
- 主机单测 79 → 101 全绿;反向验证四连均咬(半区奇偶取反 11 条、
停摆拍置 valid 4 条、STALL_RUN_MAX 改 1 为 6 条、gap 阈值 1 条)
- @build 0 错 0 警,Code 256872 → 257660
- @test PASS:adcp 122 µs → 8 µs、adc1_err=0、adc1_hw=0、
adc1_gap=27/20002 拍、adc1_seq 与 seq 恒定偏移 2
- stack_report 7/7 PASS,adcTask 832 B / 余 59%(不变)
- cubemx-survival 新增 5 项审计(TIM3 分支 / T3_TRGO / DDS /
DMA 挂载 / 流优先级),28 通过 0 失败
文档:ADC 采样节拍设计说明新增 §11;看门狗停摆分析 §4.4 与 §8 收口;
算法规划 L1-1/L1-3、通道映射、测试说明、各 README 同步。
2026-10-11 00:31:33 +08:00
wandering1
dd8210867a
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 配置)。
2026-10-10 23:08:01 +08:00
wandering1
9231a3c22c
adcTask 事件驱动消费(P1-5 方案 a)+ 补 F4 ADC 上电自校准 + 修正 2 ms 忙等过期表述
...
P1-5 方案 a(事件驱动消费,Task #32):
- TIM6 1 kHz ISR 除触发 CONVST 外再调 adc_tick_irq_notify(),置位
ADC_WAKE_FLAG;adcTask 循环尾改 osThreadFlagsWait(osWaitForever),
删除 ADC_TASK_BEAT_MS 定时轮询
- adcTask 优先级 Normal(24) -> AboveNormal(32)(Src/freertos.c USER CODE 区)
- 补消费者就绪门(规划未预见):TIM6 在 app_main_init 就启动,比调度器
早约 100 ms,未就绪时 ISR 不得 osThreadFlagsSet
- 实测 6 次上板:idle 由 1~649 降到 0/20000 拍,frames 1000.0 Hz,
seq-frames=7 正是就绪窗口;UI 侧 uip/uiw/uis 无退化
补 STM32F4 ADC 上电自校准(此前项目从未做过):
- 核查证实裁剪版 HAL 无 HAL_ADCEx_Calibration_Start、裁剪版 CMSIS 头无
ADC_CR2_CAL -> 按 RM0090 13.3.6 在 Src/adc.c 的 USER CODE 区手写
adc1_calibrate(),MX_ADC1_Init() 末尾调用
- 新增 cubemx-survival 审计项 adc1-calibration-call / -impl(清单 21->23)
- 实测校准前后同一拍 STM32 侧 6 路同向偏移 +10~+63 LSB,TPAFE 侧不变
修正两处过期表述(实测反证):
- 原文 9 通道全超时最坏 = 18 ms 连占 有误:stm32_scan() 在首个超时处即
Stop+return,单拍上界 = 一次超时约 2~3 ms
- adcm 约 2.1 ms 的峰值归因由 ADC 采集改判为每 10 s 一次的心跳日志;
6 次对照 adcp = 122 us(无超时)/ 2209 us(超时 1 次)
- 同步修正 adc_task.c 两处过期注释;新发现超时拍 STM32 侧静默沿用
上一拍值的正确性代价,硬化排序记入 4.4 / 10.4(未实施)
验证:@build 0 错 0 警(Code 256728 -> 256868);@test 6/6 PASS;
stack_report 7 任务全 PASS(adcTask 832 B / 余 59%);18 钩子全绿
2026-10-10 22:41:19 +08:00
wandering1
3b1d0308d8
fix(ui): Task #32 P0/P1/P2 — 解耦 UI 心跳、修 adc 压环与截止期、加测量探针
...
Task #32 UI 看门狗停摆(docs/问题记录/UI任务看门狗停摆分析.md)
P0 adc_task.c(已上板验证):
- 仅 r==1 才压环+重算;上板印证 ring==frames(修前 ring=frames+idle)
- osDelayUntil 返回值重同步,落后拉回基准,解除永久空转死锁
P1-4a ui_task.c v1.3: task_wd_beat 提到 ui_net_sink_poll 之前
→ 心跳测"UI 活着"而非"netTask 响应",解开 §4.2 心跳依赖
→ 未上 P1-3(提优先级会掩盖 §4.2/§4.4);P1-5 暂缓
P2 新增 App/util/task_prof.c/.h: DWT 常开探针,测各任务周期/耗时/
推流往返/ADC 轮询/控制台排空/syslog 落盘/net_poll 最坏值;心跳位图
1→0 边沿裸 UART 直发 [PROF]/[PROF2] 快照;uvprojx 已登记
doc: 分析 doc §7 补良性启动 episode 与复位非诊断项;§8 加处置落地
验证: P0+P1 累计 32 次上板启动 0/32 复现(原 L2 基线 3/10),构建 0/0
2026-10-10 19:06:06 +08:00
wandering1
317e97fca6
docs(algo): App/algo/README.md 补齐为详版(分层/数据流/接口/测试/扩展)
...
- 该文件此前仅 27 行(仅"现有模块"表 + 约定 + 相关文档),本次补齐为 168 行
详版:文件清单、1 ms 数据流图、逐文件 API 表与要点、关键约定、静态足迹、
构建与测试(含两个主机单测钩子)、新增算法模块的固定动作。
- 内容已逐项对照当前源码核验:相量实例 5 行 / 环容量 2×20 点 / 9 个语义通道 /
Rank 映射(CH0..CH7 + CH14)/ 所引文档、脚本与 skill 均存在。
- 与 L1/L2 现状一致:adc_input(L1)、sample_ring + phasor(L2)三模块。
2026-10-10 18:04:51 +08:00
wandering1
3762c03bb4
L2 相量层:采样环缓冲 + 全周傅氏 + 主机单测(台架间歇复位待查)
...
新增(均已通过主机侧单测与构建,**台架存在未定位的间歇性回归,见下**):
- App/algo/sample_ring.c/h:按语义通道的采样环缓冲(2 周波 = 40 点),
整帧压入 + 帧计数,供 L2 按窗取数。
- App/algo/phasor.c/h:全周傅氏相量层,覆盖规划 §3.2 的 L2-1/2/3/6/7——
系数表按 docs/算法/傅氏算法详解.md §2.3 预乘 √2/N(fAmSQ 直接即有效值);
5 个数据驱动实例(IA/UA/UN 基波 + IA 二/五次谐波);暴力滑动窗;
计算区/使用区双区原子切换。
- test/host/phasor/:主机侧单测(52/52 PASSED,无需桩)——系数表逐项复核、
幅值/有效值/相位、直流与谐波抑制、任意次谐波提取、频率敏感性(±2Hz≤3%)、
环缓冲时序与回绕、实例层与双区交换。
- 集成:adc_task 每拍压帧 + 重算(v2.4);app_main 调 phasor_init();
Keil 工程挂 phasor.c/sample_ring.c(App/algo 已在 IncludePath)。
验证:
- 主机单测 52/52 PASSED。
- @build 0 错误 0 警告;内存快照已刷新(RW_IRAM1 89,320→90,936 B)。
- 台架:L2 链路数据正常(ring=10001、skip=0、回读一致、相量日志可见),
但 10 次运行中 3 次出现 UI 任务看门狗停喂(mask=0x67 缺 TASK_WD_UI)
→ IWDG 复位;改动前基线 6 次运行 0 次。属**未定位的间歇性回归**。
未完成:定位并修复该间歇性复位;L2 文档状态与登记簿条目尚未按结论更新。
2026-10-10 17:39:37 +08:00
wandering1
d59c2198eb
feat(adc): L1 采集层落地——STM32 ADC1 扫描 + 语义通道映射
...
新增 App/algo/adc_input.c/h(L1 采集与预处理层,落实 L1-3/L1-4):
- L1-4 语义通道映射表 k_adc_map[]:UA/UN/IA → TPAFE buf[6]/[5]/[2];
UB/UC/IB/IC/IN/TEMP → STM32 ADC1 CH14/3/6/1/2/5。消费侧一律经
adc_input_raw() 按语义取数,不写死下标(V0.2 改版只改表内容)。
- L1-3 STM32 ADC1 9 通道软件触发顺序扫描:HAL_ADC_Start + 逐通道
PollForConversion/GetValue(EOC_SINGLE_CONV + 无 DMA,可逐通道轮询)。
- adc_input_poll() 统一"TPAFE 原子快照 + STM32 扫描";
adc_input_init() 做映射自检(STM32 映射通道必落在扫描序列内,否则
返回 -1),挡住"映射到不扫描的通道 → 恒读陈旧值"的静默错。
集成:
- adc_task.c 取数改走 L1 层(首帧日志补全 8 路 + 温度;心跳增
adc1_rc/adc1_err 观测 STM32 侧健康度)。
- app_main.c 在 tpafe5160_init() 之后调 adc_input_init(),失败记
SYSLOG_SELFTEST("ADC map fault")。
- Keil 工程挂 adc_input.c 并加 ../App/algo 包含路径。
- 文档同步:继电保护规划 §1.2/§3.1(L1-3/L1-4 改 ✅ )、ADC通道映射说明
§7/§8/§9、产品需求 §5.9/§9、架构总览 §7、AGENTS.md、App/README.md、
App/task/README.md、新增 App/algo/README.md、boot_log_data 清单。
验证:
- @build 0 错 0 警;镜像无源文件新于 hex。
- 台架 @test PASS:ADC input layer init OK、adc1_rc=0/adc1_err=0
(30 s ≈27 万次转换零超时)、seq 仍 1000.0 Hz、adc 栈峰值
528→584 B(余 71%)、回读一致、零 [ERR]/HardFault。
证据 docs/测试说明/boot_log_data/20261010_prod_adc_l1_boot_log.txt
- 内存快照已刷新(Flash 269,404→270,712 B)。
2026-10-10 16:06:31 +08:00
wandering1
970e574433
feat(adc): 1 kHz 采样节拍改由 TIM6 硬件定时器触发
...
- CubeMX 加 TIM6(PSC=83 / ARR=999 / ARR 预装载 / NVIC 抢占优先级 6)
- Src/main.c 回调加 TIM6 分支触发 CONVST(USER CODE 区)
- app_main.c 用 HAL_TIM_Base_Start_IT(&htim6) 替换单次触发
- adc_task.c 退化为纯消费者(1 ms 轮询仅作消费节奏)
- @build 0 错 0 警;台架 @test 验收待做
- 同步 ADC采样节拍设计说明 / 继电保护复现规划 / AGENTS / TPAFE README
2026-10-10 15:24:02 +08:00
wandering1
da66c500ea
fix(console): gate adcTask logs on console-writer readiness
...
B1 on-board closed loop surfaced a byte-level console interleave: before
the console writer (defaultTask) registers, con_append() routes to
dbg_console_write_raw() -> con_tx_bounded(), which is register-level
polling with no mutual exclusion. adcTask logged every 1 ms, so its
first-frame line collided with defaultTask's [NAND_FTL] init line and
the required marker spanned two interleaved lines -> false FAIL.
- console_log: add dbg_console_writer_ready() (returns s_con_writer_up)
- adc_task: gate first-frame and 10 s stats logs on writer readiness;
defer the first-frame report until the writer is up
- docs: close B1/P1-1 in the registry; flip stale "remaining @test"
notes; correct the console doc's obsolete "drop-only, no interleave"
claim (that held for HAL gState, not register-level raw send)
Bench (run_boot_test.py): VERDICT PASS, readback OK. adcTask
frames/seq +10000 per 10 s = 1000 Hz, idle=0, frst_err=0; stack
496/2048 (75%). @build 0/0.
2026-10-10 14:53:36 +08:00
wandering1
883c9dd0cc
feat(adc): B1 实现 ADC 采集链路(adcTask + 看门狗)
...
B1(ADC 采集链路)落地,消化 P1-1:
- adc_task.c:空桩 -> 真实消费者。每 1ms 触发一次 CONVST,
用 tpafe5160_snapshot() 原子取数(AGENTS 铁律)+ 帧统计 +
每 10s 心跳日志。只取数,不做保护运算。
- Src/freertos.c:手工创建 adcTask(512 words / Normal,落
USER CODE 保护区,同 timeSyncTask 先例)。
- task_watchdog:新增 TASK_WD_ADC;required_mask 产品 0x37 ->
0x77、ENABLE_HW_LAYER_TESTS 0x35 -> 0x75。
- default_task.c:栈水位探针增列 adcTask(extern + 表项)。
- 脚本:stack_report.py 增 ROOTS/RUNTIME_ALIAS;gen_task_table
增 adcTask(README/AGENTS 任务表已 --write)。
- 单测:watchdog_test.c beat_all/掩码断言同步(39 断言全绿)。
- 文档:待处理内容/看门狗设计/RAM 方案/继保规划 同步。
验证:@build 0 错 0 警;stack_report 静态最坏链 504B(余 75%);
pre-commit 全绿。剩 @test 实机闭环。
2026-10-10 14:33:32 +08:00
wandering1
e89fe54a97
重写看门狗设计说明为现状说明:删立项前旧描述、补FTL心跳路由与取证机制、修掩码与复位归因
2026-10-10 10:57:31 +08:00
wandering1
0779d3a075
栈整改不抬栈:删旧档迁移、FIL静态化、日志行缓冲按模块收紧、钩子脱离HAL,defaultTask链5312→2776B
2026-10-10 10:17:00 +08:00
wandering1
5c978465c9
TPAFE驱动闭环E-44/E-45/E-58取数契约,固化E-59门禁,adc_task挂进Keil工程
2026-10-10 03:46:50 +08:00
wandering1
fccf99bc90
测试闭环补固件身份戳、烧录回读校验与启动锚点计数,并修cmd引号解析与flash-cmd预检缺陷
2026-10-10 02:54:33 +08:00
wandering1
29df7bf8fb
4 个 Fault Handler 迁入 USER CODE BEGIN 0(L3→L2):生成区恢复 CubeMX 原样,重生成零 diff
CI / L0 静态门禁 (pre-commit) (push) Has been cancelled
CI / L0.5 主机侧单测 (MSVC) (push) Has been cancelled
2026-10-10 02:02:58 +08:00
wandering1
e2e1d0fd42
IWDG 延后启动改走宏改名(L3→L2):生成调用变空操作,重生成后不再需要手工删
2026-10-10 01:30:47 +08:00
wandering1
ad0fd53389
阶段 D 收口:P3 卫生六项 + S-2 boot_log 存档流程 + 登记簿销项
...
阶段 D(验证与卫生)离线可完成项收口;台架依赖项 D2/D5/D6 保留登记。
- D4 P3 卫生六项:
- P3-1 cfg_file.c s_encode:STR 型 len==0 回绕(p_key->len - 1u)直接拒绝
- P3-2 cfg_file_store_mcu.c:原子写临时名由 p_path 同目录推导(s_build_tmp_path)
- P3-4 rs485.c:模块描述订正为实际实现(HAL_Delay(1),非 DWT µs)
- P3-6 ch395f_get_socket_status:补 p_status NULL 检查
- P3-8 build.md:退出码契约订正为 0/1/2 三档
- P3-11 adc_task/rs485_task:注明"预留桩(未启用)"
- D3 S-2:新增 docs/测试说明/boot_log_data/(快照存档目录 + 流程),
并在 测试开发标准流程.md §7.3 登记沉淀约定
- 登记簿销项:删 P3-1/2/4/6/8/11、S-2;阶段 D 表移除 D3/D4;
§1 计数更新(P3 6→0、登记簿 10→9);§3 章节重排
(登记簿→§3.2、专项→§3.3);清理 App/cfg/README.md 等对已销编号的引用
- 同步刷新内存快照:Flash 266,632 B / ROM 合计 267,372 B
验证:@build 0 错 0 警;cfg_file 主机单测 149/149;
pre-commit --all-files 17/17 通过。
2026-10-05 10:15:53 +08:00
wandering1
e0b02d397c
修复 P2 全部 10 项:错误传播/竞态/门控/文档失真
...
待办池 docs/待处理内容.md §3.2 的 10 个 P2 全部闭环;逐项落代码 + 注释说明。
P2-1 cfg_file: 受管键行超 CFG_LINE_TEST_MAX 拒绝保存(防重复键行)
P2-2 ch395f: DMA 失败传播状态 + 锁存通道故障 + 读不拷不可信数据
P2-7 net_select: LISTENING 不再恒判可读(消除 select 忙轮询地雷)
P2-8 time_sync: 核实 L3 pending 改写已闭环(net_recv_to 分片 + 总预算)
P2-9 sys_log: 挂载改幂等 + 卷锁,defaultTask 2s 重试建 /log
P2-10 sys_log: s_read_raw 纳入卷锁 try(读者/写者 unlink 互斥)
P2-11 net_task: RECONFIG 改 osEventFlagsWait 原子取走 + 清除
P2-12 app_cfg: APP_*_ENABLE 如实标注为未接线占位,删“开关”说法
P2-13 freertos: 产品构建 vTaskDelete(testTask) 回收 8KB CCM 栈
P2-15 download.bat: 先删旧日志 + 增“未产出日志”判定
P2-13 用 USER CODE 区回收而非生成区 #if 门控:生成区改动会被 CubeMX
重生成覆盖,本方案重生成不丢。P2-12 因产品定义 B0 未定、APP_NET_ENABLE
无单一接线点,按修复建议备选(删“开关”说法)处理。
验证:@build 0 错 0 警;主机单测 watchdog 39/39 + sys_clock 100/100 +
cfg_file 149/149(新增 TC-CFG-044);pre-commit --all-files 17/17。
2026-10-04 08:30:30 +08:00
wandering1
f4fea70749
docs: 合并 4 份待办文档为统一登记簿 待处理内容.md
...
合并 docs/待处理内容.md(N/S/T-x)、审查记录/项目审计改进清单.md(P-x)、
审查记录/下一步任务规划.md(阶段与基线)、审查记录/测试与架构改进建议.md
(S1x/A-x)为单一《待处理内容(统一待办登记簿)》。
- 结构:编号空间与来源 / 未闭环一览 / 任务排序(阶段 A~D)/
逐条详述 / 待验证与待确认 / 设计基线 / 诊断基线 / 内存预算 / 维护约定。
- 编号沿用且不回收;E-xx 仍由 错误码传播审计.md 独立维护。
- 删除 3 份被合并文档;重定向下游引用:README、AGENTS、审查报告、
实机测试实施指南、Net 层架构、NET/cfg 模块 README、脚本注释。
- 同步订正计数:P1=2(+1 收尾) / P2=10 / P3=6。
pre-commit 17/17 Passed。
2026-10-04 02:28:52 +08:00
wandering1
029437be89
台架执行《实机测试实施指南》步骤 3~7 并闭环
...
步骤 3/4(IWDG V2/V4/V5 + 堆低水位 S11):
- V2 任务饿死 stall 后 ≤2.5s IWDG 复位;V4 关中断死循环 ~4.9s 稳定复位;
V5 30min 120×FTP 全 PASS、零 IWDG 复位。堆告警全程未触发(min_ever=4728B)。
- task_watchdog.c:stall 证据写盘会经 nand_ftl_wd_feed 喂狗 → 增 s_stall_evidenced
每次 stall 仅取一次证据,避免"取证据"本身阻止复位。
- default_task.c:堆低水位告警(HEAP_LOW_WATER_B=3072)。
步骤 5(GD5F 错误通道 S9):gd5f2gq5ue.c/.h + nand_ftl.c 错误码统一为 int32_t 并
全量检查返回值;套件回归 16/16 PASSED。
- test/run_all_suites.py:--forbidden 改为按套件覆盖(GD5F 用 "HardFault;assert")——
TC-GD5F-704 故意触发 [ERR] 回落轮询,统一默认值会误判 FAIL。
步骤 6(网络稳定性):7.1 正常路径 ✅ (V5 证据);7.2 N-2 丢弃可观测性代码已具备、
49s 静默在 V5 未复现(降级低风险观察项);7.3 N-3 待 PC peer。
步骤 7(工程卫生):
- S5:新增 test-cppcheck 钩子(仅 warning,排除模拟器桩)。
- S4:新增 scripts/check_test_traceability.py(默认仅告警)。
- 待核实项 TEST_SUITE_SELECTED 实机核实 = 死代码(无使用点);RTC 套件实际正常执行,
真缺口 = 缺套件级汇总行 → sd2506_test_task.c 补 === RTC Tests: N/M PASSED === 并
修正 Phase 级汇总累计问题;test_config.h 补齐 RTC 并注释"当前无引用"。
验证:产品 @build 0/0;pre-commit --all-files 17/17 Passed;
run_all_suites.py --suites RTC → PASS。
文档:实机测试实施指南 / SD2506_Test_Guide / 待处理内容 / 测试与架构改进建议 同步。
2026-10-04 00:35:06 +08:00