28 Commits

Author SHA1 Message Date
wandering1 06baf7a531 Merge pull request 'docs(hw): ④ 段变比定死入通道映射——电压族 606.06:1、电流族 29.4118 A/V,eng 保持 0(#41)' (#92) from write-ratio-41-fba44d301c82 into master
Reviewed-on: #92
2026-11-06 19:41:56 +08:00
wandering1 8a24c7ac85 Merge branch 'master' into write-ratio-41-fba44d301c82 2026-11-06 19:41:42 +08:00
wandering1 2ed715f6d5 Merge pull request 'docs(故障录波): 第二幕尾步坏段/空态画面板级闭环入档(#68)' (#91) from remote-shoot-68-274d2d56da74 into master
Reviewed-on: #91
2026-11-06 19:40:06 +08:00
super_agent_bot 2e4c167bfb docs(hw): ④ 段变比定死入通道映射——电压族 606.06:1、电流族 29.4118 A/V,eng 保持 0
用户在 Issue #41 现场报子板参数:PT 2mA/2mA、输入侧 200 kΩ、输出侧 330 Ω;
CT 5A/2.5mA、输出侧负担 68 Ω。先复核算术后入库:

- 200000 ÷ 330 = 606.060606… V/V ✓;5 ÷ (2.5mA × 68Ω) = 5 ÷ 0.17 =
  29.41176470… A/V(= 匝比 2000 ÷ 68)✓,两数与报参口径一致,未发现算误。
- 电流族"变比"实为带单位的 A/V(I端子 ÷ UAINn),与 V/V 不可混写,文档分注。

改动全在 docs/硬件平台/ADC通道映射说明.md(#41 口径:本卡不动代码、
ROM、登记簿):

- §7.1 链路分段表 ④ 行由"仍待实测确认"改"定死(参数算定)",给出两族数值;
  引文与可评审结论 1/3/4 同步收口。
- 新增 §7.2 登记:算式与额定点(400 V→0.66 V、5 A→0.17 V)、②×③×④ 端到端
  标称系数表(92.48 / 488.28 mV/码、4.488 / 23.70 mA/码)、复核口径——铭牌
  参数非本板实测,数值确认归两点标定;`eng` 判定:④ 到手满足第一条件,
  电气 8 路 ADC_CAL_F_VALID 未置位,eng 保持 0,两点标定转为可开工。
- 移交两点标定卡的两道存储题:电压族端子域标称 k 越 int32 Q16 µV/码上限
  32767,且合法带基准读 ROM 出厂表(引脚域)——写入端子域系数前存储单位
  与出厂表须一并换血。

验证:check_doc_links.py --all 与 no-mojibake 实跑通过;docs-only,
/keil-build 不适用。
2026-11-06 19:10:21 +08:00
super_agent_bot c40fd24c1a docs(故障录波): 第二幕尾步坏段/空态画面板级闭环入档(#68)
同号翻位覆盖列内段 WAVE06 → 回放页显式「该段不可读」(零波形元素,
判据「绝不许画直线」过);全删段 → 「无录波段」空态 + 串口
open fail fr=4 互证。证据目录 wave_shot_20261106:三态 PNG 与原始
帧、坏样本与原件、PC 侧 wave_read REJECT 实录、串口摘录、sha256
清单。收工:板上九件原件逐件 sha 复验恢复、坏样本不留板(§7 二
选一取删除),UI 停 STANDBY。发现 F1(STOR 新文件不进钉表,需同
号顶当前段或手动录波触发重扫)与 F2(数据 CRC 判废串口静默、画
面自证)记 §10。同步销项:手册第二幕状态与现场记录表第 3 行、
设计说明 §10「回放页坏段/空态画面闭环记录」、任务规划 README
§2.0 独立行。本轮不改代码。关联 #68 #38。
2026-11-06 18:35:40 +08:00
wandering1 c2a946f993 Merge pull request 'docs(ui): Issue #53 台架轮复核销项——六页真机判据上板复核完成(RESTARTED 标不可验)' (#90) from bench-verify-ui-pages-f9c1662bf18b into master
Reviewed-on: #90
2026-11-06 09:37:18 +08:00
super_agent_bot 3da3936ffe chore(sync): 空合并提交触发 PR #90 可合并性复测(master@8772420 已在 e1476e1 中合入,内容零变化) 2026-11-06 08:41:40 +08:00
wandering1 e1476e12c1 Merge branch 'master' into bench-verify-ui-pages-f9c1662bf18b 2026-11-06 08:21:23 +08:00
wandering1 87724205c9 Merge pull request 'docs: #39 收尾——子项 A 收口审计 + 子项 B 台架重验证据写入模块文档' (#89) from queue-issue-39-d318f32c6528 into master
Reviewed-on: http://100.123.83.113:3001/wandering1/STM32F4-Base/pulls/89
2026-11-06 08:18:27 +08:00
super_agent_bot 416e92f109 docs(ui): Issue #53 台架轮复核销项——六页真机判据上板复核完成(RESTARTED 标不可验)
CI / 静态门禁 (pre-commit) (push) Failing after 3m10s
CI / 主机侧单测 (MSVC) (push) Failing after 44s
CI / 静态门禁 (pre-commit) (pull_request) Failing after 47s
CI / 主机侧单测 (MSVC) (pull_request) Failing after 44s
台架轮(2026-11-06,实机 192.168.31.100 生产固件,boot 187–193,
ST-LINK + RemoDispBus 7003 按键注入/抓帧 + FTP 取证,全程持 bench 锁):

- 判据1 真记录翻页与保持:oper 73 条 19 页 / yk 34 条 9 页 / start 2 条
  1 页实机翻页连续,页数与盘上条数交叉吻合;跨 188–193 六次重启
  (IWDG/NRST/系统复位,RAM 每次全清)YK/START/WDEV md5 逐字节不变,
  RUN/SOE/OPER/SELFTEST 纯追加、旧记录区零改写。
- 判据2 清除记录后对应页归零:oper 73→0、start 2→0、yk 34→0(页显
  「无记录」+ NAND 对应文件消失);告警行空类清除幂等;RUN/SOE/
  SELFTEST 清除前后逐字节一致(逐行独立清除证实);OPER 由后续写入
  自动重建且恰含三条清类留痕、清 oper 自身不留痕(留痕契约证实)。
- 判据3 上电一次 boot_count +1:187→193 六连号无跳变,电池域 SRAM
  保持+回写正常;本机无市电开关,以系统复位代理完整上电(覆盖
  SRAM 存储语义),真·拔电 POR 计数差额留人工一眼补验。
- 判据4 拔 RTC 电池落 RESTARTED:台架不可验(用户裁定 2026-11-05),
  销项不挂账;seq_state 四态判定归主机单测 test/host/boot_stats/ 覆盖。
- 判据5 IWDG 复位落「独立看门狗」:SWD 热插拔现场收窄看门狗窗口
  (PR=0/RLR=2,窗口 ≈0.37ms ≪ 100ms 喂狗节拍)触发真实计数器溢出
  → rst_cause=独立看门狗;咬后 wd_platform_start 自愈回 PR=4/RLR=1249。
  调试停机(DBGMCU_APB1_FZ 实读 0)与 NRST 硬脉冲两条不咬路径的
  归因已记台架台账(Issue #53 评论)。
- 判据6 主站接入一次 conn_up +1:75s 静默窗(前后帧逐字节相同)后
  单次 STARTDT 连接恰好 +1,发送帧数 +1、接收字节 +6B 交叉印证。

销项:六页文件头「台架待补」段改为「台架复核已完成」(模拟器口径
保留);模拟器差距清单 §2.3 开机账本行更新复核口径;登记簿 §7
「UI 六页真机判据」行删除(工单授权),交叉引用同步(任务规划
README、产品需求 FR-SOE-3)。清除动作是判据 2 本体,清前全量
NAND 记录已备份(PC 侧),留证于 Issue #53 台架轮评论。

门禁:check_doc_links --all 213 文档过;主机侧单测 48 runner
4257 断言全过;ARMCC 全量构建 0 Error 0 Warning
(Code=254820 RO=30896 RW=2072 ZI=150104);ui-golden 菜单 8 状态
+ 内容页 74 张黄金参考一致(本机按部署文档第 3 步补装 SDL2 SDK)。
附带:内存数字两文档随 .map 同步——RAM 台账受管区 3 行 +
RAM 使用分析快照 3 行(mem-budget / mem-numbers 门禁随本票
Drivers/BSP staged 触发的 HEAD 既有漂移修正:#73/#79 合入后未跑
--write;285,716 B 与体积凭证一致,全部 PASS/参考,无红线变动)。
体积凭证指纹陈旧同为 HEAD 既有(488f6fb 起),本票纯注释/文档
不动体积面,不越权刷新。
2026-11-06 03:49:18 +08:00
super_agent_bot 685e3b58f5 docs: #39 收尾——子项 A 收口审计 + 子项 B 台架重验证据写入模块文档
CI / 静态门禁 (pre-commit) (push) Failing after 7m23s
CI / 主机侧单测 (MSVC) (push) Successful in 31s
- docs/网络/网络自愈架构设计.md:新增 2026-11-06 台架重验条目(子项 B 完成判据达成)
- docs/子系统设计/看门狗设计说明.md:新增 2026-11-06 变更记录(uiTask ≥800ms 饿死签名新负载下不复现)
- docs/任务规划/README.md §2.0:第 2 行 net 层跨上下文收口 → ✅ 2026-11-06 闭环
- docs/任务规划/登记簿.md §6:第 1 项销项并重新编号

Closes #39
2026-11-06 02:11:24 +08:00
wandering1 829c2580bb Merge pull request 'build(mdk): Keil 可逆排除 126 个零产出 LVGL 编译单元,全量重建 21.5→18.3 s(-14.6%,#46)' (#87) from execute-issue-46-214251580469 into master
CI / 静态门禁 (pre-commit) (push) Failing after 4m36s
CI / 主机侧单测 (MSVC) (push) Successful in 32s
Reviewed-on: http://100.123.83.113:3001/wandering1/STM32F4-Base/pulls/87
2026-11-06 01:04:31 +08:00
wandering1 0f2aec8850 Merge pull request 'docs(storage): #45 复核结论——卷锁无第二写者,全序列卷锁项关闭(销项)' (#86) from execute-issue-45-262ec492e96a into master
Reviewed-on: #86
2026-11-06 00:05:47 +08:00
super_agent_bot 488f6fbf21 build(mdk): Keil 可逆排除 126 个零产出 LVGL 编译单元,全量重建 21.5→18.3 s(-14.6%,#46)
CI / 静态门禁 (pre-commit) (push) Failing after 44s
CI / 主机侧单测 (MSVC) (push) Failing after 44s
CI / 静态门禁 (pre-commit) (pull_request) Failing after 45s
CI / 主机侧单测 (MSVC) (pull_request) Failing after 45s
按 #46 判据「有实测收益才保留改动」执行,证据(同机同基线 c487ce42,UV4 -r 墙钟):

- 基线 4 次全量重建均值 21.46 s → 排除态 4 次均值 18.33 s,-3.13 s(-14.6%);
  增量最坏对照(touch lvgl.h 后 -b)9.66 s/83 单元 → 8.06 s/45 单元(-16.6%)。
- 影像等价:Program Size 四项全同(Code=254820 RO=30896 RW=2072 ZI=150104);
  .hex 286,084 字节两两比对仅差 0x08007C6B–6F 的 fw 时间戳横幅(基线之间同差);
  .map 符号表逐行比对,基线独有 126 行恰为被排除单元的 ABSOLUTE 文件记录。
- 零产出认定:3 次基线 .map 的 Image component sizes 中 Code/RO/RW/ZI 全 0,
  名单一致(121 空 TU + 6 仅调试记录)。Cross Reference Table 不动点收敛得可安全
  排除集:lv_circle_buf.c 因被保留的 lv_iter.o 静态引用而保留(armlink 先解析
  后死删,127 全排实测 L6218E×9);净排除 126 个。
- 形态:仅加每文件 <FileOption><IncludeInBuild>0</IncludeInBuild>,不删条目,
  GUI 可逐项恢复,revert 单笔整体回滚;FilePath 集合不变(registration-check 过)。
- 本机构建对工程文件零抖动;最终一次全量构建(18.20 s,0E0W)跑在提交字节上。
- sim/CMake 不涉及;LVGL 源码零改动。台架回归不需要:镜像与已验收基线逐字节
  等价(除时间戳)。

Issue: http://100.123.83.113:3001/wandering1/STM32F4-Base/issues/46
2026-11-06 00:03:33 +08:00
super_agent_bot 84f46b5660 docs(storage): #45 复核结论——卷锁无第二写者,全序列卷锁项关闭(销项)
登记簿 §2「可选全序列卷锁」按其判据(无第二写者则关闭)销项:
master c487ce4 枚举全部生产卷访问点——写者 syslog/soe/cfg/prot_set、
录波段、lftpd,读者 UI 两径,空闲 sync——全部持卷锁或走屏障;
启动期卷写由 STORAGE_READY 屏障门控(default_task.c bring-up)。
「存储侧喂狗饥饿」2026-10-02 后无新台架证据:F2/F3(10-25)、
录波枚举(11-02)、PR #82 补验 soak(11-05)均无该签名;dhara
try_recover 自旋有界(8 次 restart 定案 TOO_BAD)且 FTL 入口
nand_ftl_wd_feed() 直接喂 IWDG,观察行留存并更新现状字段。

覆盖面审计沉淀进 存储架构说明 §10.5;登记簿 §6 第 3 项销项、
uvprojx 观察行升 3;项目架构总览 fs/ 行旧「三条路径」口径更正。

评估过程与逐条证据:Gitea issue #45。
2026-11-05 23:51:23 +08:00
wandering1 c487ce4225 Merge pull request 'fix(cfg): 热重载读侧三点一致性校验——掐断打回出厂与保存吞段(#73)' (#82) from fix-config-reload-03ecc431fc5e into master
CI / 静态门禁 (pre-commit) (push) Failing after 5m15s
CI / 主机侧单测 (MSVC) (push) Failing after 45s
Reviewed-on: #82
2026-11-05 18:26:56 +08:00
super_agent_bot b66fcc4d87 docs(cfg): HELD 日志行“两数相等”语义注记(内容判据命中)(#73)
CI / 静态门禁 (pre-commit) (pull_request) Failing after 44s
CI / 主机侧单测 (MSVC) (pull_request) Successful in 49s
台架实录中出现 `poll: view 1064B != stat 1064B, HELD`:两数相等是
设计使然——同尺寸旧映射块命中内容判据(s_view_bad),并非空读/
短读。首读该日志易误判为格式串错误,在 §5.3 守卫条目补一句语义
注记。纯文档改动,不影响代码指纹与体积门禁。
2026-11-05 17:27:34 +08:00
super_agent_bot 1a2ca0467d fix(cfg): 视图守卫补内容判据——同尺寸全 0 旧映射块也能拦(#73)
CI / 静态门禁 (pre-commit) (pull_request) Failing after 6m33s
CI / 主机侧单测 (MSVC) (pull_request) Successful in 35s
CI / 静态门禁 (pre-commit) (push) Failing after 5m7s
CI / 主机侧单测 (MSVC) (push) Failing after 43s
台架(PR #82 head d9303e05,常授权烧写验证)在三点校验版守卫上继续复现
出打回形态:卷层给出的旧映射块与目标文件恰好同长(1064B)且整块全 0,
读长 == st.size 与读前后复 stat 全部通过,解析零错误、RAM 照样打回默认
(15:21 决定性轮:盘文件 RETR 校验七段完好,重载窗口内 s_sntp 三字节段
全 0)。纯令牌层校验对"内容坏"是盲的,必须补内容判据。

处置(引擎侧,与三点校验同族):
- 新增 s_view_bad:重载/保存读到的视图若为空读、或 [0,len) 内任意偏移
  含 NUL 字节即判坏——INI UTF-8 文本约定下任何偏移都不得含 0x00;解析
  器按行切分遇 NUL 即断行,零块之后的内容本就不可达(静默截断同源故障),
  拒之不误伤任何可解析文档。不要求首字节 ';'(手写文档可直接段名起始)。
- poll:坏内容 = 与长度/令牌不符同处置——拒绝应用,RAM 与基线不动,2s
  重试自愈,首次 ERROR + 自检留痕,每 30 趟一条 WARN(限速)。
- save:坏内容同族拒存返回 -1,原文件一字节不动,调用方 dirty 保留重试。
- 边界如实保留:内容合法但陈旧的整卷视图(长度/令牌/内容三者皆一致滞后)
  引擎层无法检出,属卷层(dhara/FTL)课题,重启必然收敛;"改过配置后
  重启一次"在卷层根治前仍是最稳口径。

测试:
- TC-CONFIG-061(poll 同尺寸全 0 块 HELD + 视图刷新自愈 + 零回调)、
  TC-CONFIG-062(save 遇全 0 块拒存、文件字节/写次数不动、追平后重试
  成功);桩新增 vfs_mark_stale_zeros() 注入同长全 0 旧视图。
- cfg_file 套件 259/259;iec104 179/179、run_par 67/67、adc_cal 117/117、
  sntp 98/98、cfg_file_store_mcu 34/34 复跑全绿。
- /keil-build 0 错 0 警:Code 254,784 -> 254,820 B(+36 B);台账与同码
  凭证已同步。台架实录见 PR #82 评论:NUL 注入块实机 HELD(16:55:46)
  + WARN 节拍 30/60 趟命中(16:56:42/16:57:41)+ 视图转新鲜后重载自动
  追平;残余打回事件均为"内容合法但陈旧"整卷视图(15:19:30/16:34:59/
  16:58:38),属已声明守卫边界,盘文件全程未吞段,重启收敛实机确认
  (17:04 RAM 回文件值)。

文档:
- 《配置文件设计说明》§4-(3)/§5.3 守卫描述补内容判据与 15:21 实证形态、
  风险表行更新、变更记录 v1.17 行同步;
- 《配置文件单元测试说明》TC-CONFIG-061/062 行 + 当前结果 259/259 +
  扩展指南补 vfs_mark_stale_zeros()。
2026-11-05 17:08:25 +08:00
super_agent_bot d9303e05a4 fix(cfg): 热重载读侧三点一致性校验——掐断打回出厂与保存吞段(#73)
CI / 静态门禁 (pre-commit) (push) Failing after 8m2s
CI / 主机侧单测 (MSVC) (push) Successful in 40s
CI / 静态门禁 (pre-commit) (pull_request) Failing after 5m10s
CI / 主机侧单测 (MSVC) (pull_request) Successful in 37s
真机 #73:运行中改配置触发热重载,卷层(dhara)偶发返回旧/短
视图时,引擎把该视图当成文件全文:逐段按缺省解析后整盘打回
出厂默认且不自愈;此后任何一次保存又按缩小的视图做手术式
重写,文件越写越小(台架 1066B→986B,[sntp] 段整体丢失),
即真机对时静默 10.5 小时的元凶。

处置(引擎侧根因无关防御;卷层回滚归 #79/#81 已合并的 FTL
修复域):
- poll:读完加三点校验(读长==stat.size、读前后 re-stat 的
  size/mtime 一致),判为旧/短视图则 RAM 不动、基线不刷新、
  每 2 拍自动重试自愈;首次拒绝留 1 条 DBG_ERROR+syslog,
  之后每 30 拍一条 WARN 提示重启收敛。
- save:同型三点校验,视图与 stat 不符返回 -1 且文件不动,
  调用方保留 dirty 下拍重试,吞段链在第一次保存即被掐断。
- 边界:「一致但陈旧」的整卷回滚引擎层无法区分,靠重启
  收敛,已写入设计说明风险表与文档口径。

测试:新增 TC-CONFIG-058/059/060(旧视图保持 RAM、保存短
视图拒写、读中改写拒绝+日志限速)。cfg_file 239/239;
iec104 179、run_par 67、adc_cal 117、sntp 98、
cfg_file_store_mcu 34、net_cfg 48、ftp_cfg 16、prot_set 90、
prot_dim 38 全绿;/keil-build 0 Error 0 Warning。

文档:配置文件设计说明 §(3)/§5.3/风险表/变更记录 v1.17;
单元测试说明 058–060 行;网络配置说明与产品需求 FR-CFG-3
同步口径;台账随新鲜 .map 由 ram_baseline --update 回填。
2026-11-05 12:35:46 +08:00
wandering1 0d5cd1c8d1 chore(skills): 删除 template-skill 占位模板(零引用出厂噪音) 2026-11-05 10:11:35 +08:00
wandering1 c44f985afb docs: 谐波B行按板端前端真实衰减关闭——结论现状化与登记
CI / 静态门禁 (pre-commit) (push) Failing after 5m19s
CI / 主机侧单测 (MSVC) (push) Failing after 44s
- 执行手册:用户裁定删除 §8.6–§8.10 尾部(顺序/分诊/还原/归档节);
  谐波 B 行结论只留现状(删万用表分诊、三点拟合、嫌疑解除等过程叙述)
- 定案:250 Hz 读数 −4.4 % = IA 前端差分滤波(C35 100 nF + R19/R21
  各 1 k,一阶低通 fc ≈ 796 Hz)真实衰减,板端读数忠实、量算皆对;
  工频 50 Hz 仅 −0.2 % 不受影响;选择性成立;谐波产品化需板改
- 通道映射 §8.2 新增前端 RC 段:逐阶外推(21 次 −39.6 %,改 10 nF
  后 −0.9 %)、改板优先于软件修正的理由、证伪条件(250 Hz 附加滞后 ≈17°)
- 数据可信.md:§2.7 谐波行同步;任务卡打勾保留并标注四项未闭合
  (叠加轮/削顶低频档/测频改码档/模型仪器证伪);README 顺位表 ✅
- 登记簿 §3 新增「IA 前端差分滤波限制谐波带宽」条目(语义标识)
- 证据:ia_rc_model.py 输出归档 boot_log_data 并入 manifest(LF 重算
  md5);速查图生成器脚注同步并重跑(脚本与产物同笔)
- check_doc_links --all 通过(3206 处、无法判定 0)
2026-11-05 09:34:27 +08:00
wandering1 dc09217834 docs: 六轮动态验证收尾——削顶低频档按裁定关闭、记录回填与证据归档
- 削顶步 2(UB 注 DC −1.00 V)2026-11-04 已做:唯一 [ERR] rail edge=0x2
  sticky=0x2、UB 钉 0 码、撤注后 rail=0x002 恒持 ≥30 min = sticky 锁存实证
- 步 3(2.0 Hz 低频档)与复位复核经用户裁定 2026-11-04 关闭:直流档已闭合
  判据链,sticky 唯一清除路径 = adc_health_rail_init()(实现背书,不占台架)
- 相位 0°/90° 段 WAVE09 录波 fft 重算 Δφ = 90.05° PASS(判据 ≤2°);
  测频 332 行复证「如实报不可测」;谐波 A/C 过、B 行 −4.4 % 待万用表分诊
- 执行手册 ADC前端注入验证流程.md 各轮记录表回填 + 削顶卡步 3 行关闭注;
  实测结论新开 ADC通道映射说明.md §8.2(§8.1 静态轮加澄清句)
- 数据可信.md §2.7 / §4.6 / §5 任务卡现状化(削顶转 ✅、未闭合仅剩谐波 B)
- 证据归档 boot_log_data:6 份 txt 摘录 + 3 份录波段原件(*.BIN 被全局
  gitignore 挡,段原件是相位判据本体,force-add 入库)+ md5 清单
2026-11-04 22:16:35 +08:00
wandering1 87fa0276ad docs: 六轮验证文档剔除104读数通道+字母编号黑话清扫
CI / 静态门禁 (pre-commit) (push) Failing after 3m46s
CI / 主机侧单测 (MSVC) (push) Successful in 29s
注入流程/数据可信/故障录波设计说明三份文档与速查图
全部剔除104作为量测工具(YC交叉、0x401D/0x4012观察项、
§8.6第7步整行;总耗时150改135 min);104仍是固件消费者
与送检参照,架构表述保留。

注入流程全文清扫:A档/B档/定量档/定性档/段档/标量档等
字母编号与黑话清零;波形轮注简化为三句;通用动作段重写
为编号四步。

数据可信属主同步:§4.6前提表、§4.6.2三行判据、§4.6.3
读数点对比表、DoD证据归档口径。

内存内容分配策略.md:22修复编号改名事故(STM32L4被误替换
成「出口与记录」),按git原文恢复。

速查图生成器gen_ac_rounds_svg.py三处文案+脚注同步改并重跑,
脚本与产物同笔提交。
2026-11-04 19:04:31 +08:00
wandering1 740bcbcc37 Merge pull request 'fix(nand-ftl): 传输失败不再误标坏块 + format 不再被脏缓存挡死(#79)' (#81) from fix/nand-ftl-format-deadlock into master
CI / 静态门禁 (pre-commit) (push) Has been cancelled
CI / 主机侧单测 (MSVC) (push) Has been cancelled
Reviewed-on: #81
2026-11-04 19:01:36 +08:00
super_agent_bot 5538af829b fix(nand-ftl): 传输失败不再误标坏块 + format 不再被脏缓存挡死(#79)
CI / 静态门禁 (pre-commit) (push) Failing after 43s
CI / 主机侧单测 (MSVC) (push) Failing after 45s
CI / 静态门禁 (pre-commit) (pull_request) Failing after 44s
CI / 主机侧单测 (MSVC) (pull_request) Failing after 43s
根因(真机定案,问题 #79):旧 dhara_nand_erase/prog() 把一切失败一律
mark_bad,而 mark_block_bad 每次**立即持久化**板级 BBT(不可撤销)——
一次传输层/等忙抖动就把好块永久记成坏块。台架 129 个好块(1016–1142
连续段)被固化,journal prepare_head() 连续 8 次撞 is_bad → TOO_BAD →
Cache flush FAIL → reformat 又被同一页挡住 → 整卷禁用、重启不恢复。

- 修复①:只有芯片明确回 E_FAIL/P_FAIL(状态位证据)才标坏;
  传输/超时失败只报 DHARA_E_BAD_BLOCK 让 dhara 重试,不标坏
- 修复②:nand_ftl_format() 尽力刷一次脏缓存,失败即丢弃并继续
  dhara_map_clear()(格式化语义本就是销毁映射;旧实现第一步返回,
  恢复动作在同一页死锁,f_mkfs 全在旧映射上必失败)
- C4 还债:新增跨调用失败类快照 nand_ftl_fault_get/clear(20 B,
  resume/读/刷/同步四点位记账);defaultTask 探针按类分流,
  BSP_ERR_NO_SPACE 跳过重格式化(容量问题不该用 mkfs 解)
- 哨兵与诊断:init 解锁块保护(A0h)后补回读校验(与 B0h ECC 同族
  缺口,实测本板 A0h=0,非本次根因,留作哨兵);gd5f_bbt_load()
  合并后坏块数 > 出厂扫描时打「BBT after merge」,现场可区分
  真坏与误标固化
- 测试:主机单测 149→178 全绿;新增 format 死锁(TC-NANDPORT-800..
  813b)、传输失败不标坏(207 语义翻转 + 208/505);牙齿检查过——
  把修复回退即见红
- 真机:恢复动作 A 重建 BBT 清除已固化误标(3/3 PASSED,BBT
  version=71);产品镜像复烧 [FS] FATFS mounted、配置出厂模板
  落盘、0 条 flush FAIL——#79 真机闭环(旧卷内容随 map clear
  作废,台架卷为可弃数据)
- 文档:存储架构说明 §10.4 口径修正 + 新增 §10.4.1/§10.4.2(页级
  失败升级链与误标持久化机理),存储维护与容量恢复 §2 补板级 BBT
  独立持久化注记 + §2.1(动作 A 此前静默失效),登记簿 C4 销项
- Keil 0 错 0 警(Code=255552,与烧录验证镜像一致);doc-links 213
  文档通过
2026-11-04 18:58:13 +08:00
wandering1 1f94015434 Merge pull request 'refactor(time_sync)!: 退役 TCP :8888 对时任务,timeSyncTask 转纯 SNTP 校时节拍宿主(#78)' (#80) from remove-8888-timesync-a6657322808f into master
CI / 静态门禁 (pre-commit) (push) Failing after 5m15s
CI / 主机侧单测 (MSVC) (push) Successful in 39s
Reviewed-on: #80
2026-11-04 18:26:40 +08:00
super_agent_bot 3a2f9b21fb refactor(time_sync)!: 退役 TCP :8888 对时任务,timeSyncTask 转纯 SNTP 校时节拍宿主(#78)
CI / 静态门禁 (pre-commit) (push) Failing after 43s
CI / 主机侧单测 (MSVC) (push) Failing after 45s
CI / 静态门禁 (pre-commit) (pull_request) Failing after 45s
CI / 主机侧单测 (MSVC) (pull_request) Failing after 45s
SNTP 客户端已随 #73/PR #77 上线合入(merge 2b848c4a),用户裁定
8888 对时任务退出历史舞台(gitea:77 线程原话,跟踪 Issue #78)。

生产侧(App/sync/time_sync.c v2.0,任务入口名不变,freertos.c 零改动):
- 删除 :8888 监听、TIME 包重组、sys_clock 写入、OPER 落痕、
  net_drop_conn 队头自救整条链(TIME_SYNC_PORT 宏随退役删除)
- 任务体收敛为:就绪屏障(100ms 分片、osFlagsNoClear)→
  200ms 校时节拍 task_wd_beat → time_sntp_run(net_get_generation())
  → 分片延时;喂狗节奏(TASK_WD_TIMESYNC=5,required_mask)不变
- 时钟写入口自此 = SNTP / UI 手工 / 104 C_CS,双写竞态(后写者赢)
  随之消失(墙钟说明 §15 退役公告、§16 现势口径)

工具与测试:
- 删除 test/host/time_sync_server.py(对时源)与 e02_probe.py
  (队头阻塞探针,载体随监听退役;判据脚本 v5_log_gap_report.py
  保留供旧日志解读)
- time_sync 主机单测重写 v2.0:33 断言覆盖分片延时 / 屏障 /
  SNTP 节拍与网络代次当轮交接 / 未出网守门;stub 的
  net_socket.h 裁剪至 net_get_generation 作编译期绊线
- 覆盖率基线 --update-baseline 收口(time_sync.c 101→20 行为刻意
  缩减,全仓 48/48 套绿)

文档与图:墙钟说明 §15 改退役公告(教训保留:CH395F FIN 丢未读
缓冲)、§16 单一网络来源;产品需求 FR-TIME-2 退役注记、§6.3 重写;
架构总览 / 软件架构规格 / 网络配置 / 网络自愈 §9.3 / BSD 指南 /
看门狗说明心跳与白名单行 / 实机测试指南 / 部署环境 / 继保规划 /
UI补齐时基口径 / 页面补齐规划 SNTP 页行 / 任务规划 README 叶数与
暂缓项行(SNTP 叶已绑、UI_PAGE_MAP_COUNT=31 口径)等约 30 处现势
口径同步;arch / net_stack 两图生成器与 SVG 同笔重跑。

台账:ram_baseline --update + check_mem_numbers --write + 体积凭证
(Code 254,648→253,428,−1,220 B)。静态链复测发现 timeSyncTask
1,904 B / iec104Task 1,600 B 低于 ISR 硬线:master 2b848c4a 同判据
timeSyncTask 即 2,056 B(本 PR 只减不增,−152 B 旧任务自身帧),
双 FAIL 为 #74/#77 后既有债;抬栈属 Ask-first 未擅自执行,登记簿
新增「静态链硬线双 FAIL」待台架复采,复测快照入 docs/内存管理/data。

验证:keil-build 0 错 0 警;time_sync/sntp 主机单测绿;
ci_local 全绿;doc-links --all 0。
2026-11-04 18:07:03 +08:00
wandering1 2b848c4a0b Merge pull request 'feat(sntp): 板端 SNTP 校时接入——coreSNTP 序列化器 + [sntp] 段 + 设置页(#73)' (#77) from impl-sntp-sync-ca4c69f49d3e into master
CI / 静态门禁 (pre-commit) (push) Failing after 5m45s
CI / 主机侧单测 (MSVC) (push) Failing after 44s
Reviewed-on: #77
2026-11-04 16:46:30 +08:00
108 changed files with 5430 additions and 2273 deletions
-6
View File
@@ -1,6 +0,0 @@
---
name: template-skill
description: Replace with description of the skill and when Claude should use it.
---
# Insert instructions below
+9 -9
View File
@@ -360,19 +360,19 @@ repos:
files: ^(App/fs/vol_idle_sync\.(c|h)|App/task/default_task\.c|test/host/vol_idle_sync/.*|test/host/common/unit_test_harness\.py)$
pass_filenames: false
# 7g) 时间同步(time_sync)主机侧单元测试(2026-10-10 加)
# 背景:time_sync.c 是 TCP 时间同步协议状态机,也是探针窗口心跳缺口那项看门狗风险的**全部
# 逻辑贡献者**——"listen 重建 -> 800ms~1s 心跳间隔"由本模块的分片延时/退避/
# 结算等待组成,板端只能看到"是否复位"这一结果,看不到各段延时是否如设计。本钩子
# 用 MSVC 离线编译真实源文件(#include 纳入)+ 可脚本化的网络/事件桩(含 longjmp
# 跳出 for(;;) 任务循环),把分片喂狗节奏、监听退避、报文重组(半包/粘连/EOF/真错/
# 预算耗尽/tick 回绕)、重听门控逐条钉死。
# files 含被测源与其头、被测的真实看门狗头,以及 harness 本身。
# 7g) 时间同步(time_sync)主机侧单元测试(2026-10-10 加,2026-11-04 随 :8888 退役收缩)
# 背景::8888 退役后 time_sync.c 只剩 timeSyncTask 载体编排——就绪屏障 + 200ms 校时节拍
# + SNTP 客户端调用。探针窗口心跳缺口那项看门狗风险的逻辑贡献者(分片延时节奏、屏障
# 等待态喂心跳)仍在本模块,板端只能看到"是否复位"这一结果,看不到各段延时是否如设计;
# 本钩子用 MSVC 离线编译真实源文件(#include 纳入)+ 可脚本化的事件/代次/SNTP 桩
# (含 longjmp 跳出 for(;;) 任务循环),把分片喂狗节奏、屏障分片、代次下传逐条钉死。
# 历史(监听退避、TIME 报文重组、30s 预算、tick 回绕用例)随 :8888 退役删除,见 git 历史。
# files 含被测源与其头、节拍契约头 time_sntp.h、被测的真实看门狗头,以及 harness 本身。
- id: time-sync-unit-test
name: 时间同步单测(主机侧)
entry: python test/host/time_sync/run_unit_test.py
language: system
files: ^(App/sync/time_sync\.(c|h)|App/util/task_watchdog\.h|test/host/time_sync/.*|test/host/common/unit_test_harness\.py)$
files: ^(App/sync/time_sync\.(c|h)|App/sync/time_sntp\.h|App/util/task_watchdog\.h|test/host/time_sync/.*|test/host/common/unit_test_harness\.py)$
pass_filenames: false
# 7h) ADC 采样有效性校验主机侧单元测试(2026-10-11 加)
+1 -1
View File
@@ -16,7 +16,7 @@
- **采集**:TPAFE5160(计量级 8 路,并行总线)+ 片内 ADC1(9 路,DMA)→ TIM3 1 kHz 节拍 + 原子快照 → adcTask → 语义取数与有效性校验 → 全周傅氏相量 → **测频与遥测快照(`meas` 200 ms 双区,104 与 UI 共用同一份上游)**+ 保护判据(protectTask 20 ms 判据节拍)→ 104 遥信/遥测上送
- **存储**:GD5F SPI NAND → dhara FTL → FatFs → `/log` 运行/自检等七本记录 + SOE、`/config.ini` 配置、FTP 根目录
- **网络**:CH395F → netTask 串行 socket 栈 → FTP(21) / 对时(8888) / RemoDispBus 远程显示(7003) / IEC 60870-5-104 上行(工厂默认 2404)
- **网络**:CH395F → netTask 串行 socket 栈 → FTP(21) / RemoDispBus 远程显示(7003) / IEC 60870-5-104 上行(工厂默认 2404);对时 = timeSyncTask 的 SNTP 客户端(UDP 123 主动出网,:8888 推送监听已退役)
- **人机**:LVGL 160×160 单色菜单(uiTask),**与 PC 模拟器同一份 UI 源码**,远端可看图 + 注键
**目录地图**(只列顶层——稳定边界;细结构自己 `ls`,别背路径;**仓库根不放一次性产物**——提交信息草稿 / 临时改写脚本 / 门禁输出与日志一律进 `ci-artifacts/`(已忽略,口径见 `.gitignore` 尾注),根目录只留工程配置与两份生成器输入 `ui_menu_tree.txt`、`ui_cn_chars.txt`):
+109
View File
@@ -29,6 +29,17 @@
* len 1/2/4 小端补码)——s_decode_int() 用 strtol + ERANGE +
* 宽度上下界校验,s_encode() 带负号输出;负零点偏移从此可
* 干净落盘(动因见 docs/任务规划/数据可信.md §4.4 与 §7 决策 3)
* v1.6 2026-11-05 DTU 项目组 热重载/保存视图一致性守卫(issue #73 SNTP 补验揪出)——
* poll stat→read→复 stat 三点校验 + 内容合法性 s_view_bad
* (空读或任意偏移含 NUL = 坏视图;台架 15:21 实证同尺寸
* 全 0 旧映射块可骗过纯三点校验);命中拒绝应用:RAM 与
* 基线不动、2s 重试自愈、首次自检留痕 + 每 30 趟
* WARN 限速;save 读视图与 stat 基准不符或内容坏
* 拒写(断"短/坏视图→整档
* 外科重写→非默认段被删"吞段链,台架实测 1066B→986B)。
* 台架根因为卷层 dhara 旧视图回滚(复现多形态:空读、
* 短读、同尺寸全 0 块),引擎侧无法分辨"一致但陈旧"的
* 整卷回滚——该形态重启必收敛,见设计说明
* 函数说明:引擎状态非重入——调用方须收敛同一任务(defaultTask:poll/save;
* 启动期 load 先于任务竞争);FS 卷并发由 FatFS REENTRANT 卷锁保证
* (见《配置文件设计说明》D15 A+ 方案)
@@ -102,6 +113,8 @@ static cfg_file_stat_t s_last; /* 上次 poll 的 stat */
static uint8_t s_stable; /* 连续相同轮询计数(沉降去抖) */
static uint8_t s_base_valid; /* 基线是否已建立 */
static uint8_t s_snap[CFG_SNAP_MAX];
static uint16_t s_reject_streak; /* 连续被拒重载计数(视图不一致;0 = 无进行中
拒绝;饱和不回绕,仅用于告警限速节奏) */
static int s_sec_hdr[CFG_FILE_MAX_SECTIONS]; /* 段头行号(0xFFFF = 未见) */
static uint16_t s_key_line[CFG_FILE_MAX_SECTIONS][CFG_FILE_MAX_KEYS]; /* 受管键行号(0xFFFF = 未见) */
@@ -613,6 +626,34 @@ static int s_load_file(uint8_t **p_pbuf, size_t *p_len) {
return 0;
}
/*
* 函数功能:读视图内容合法性判定(stat/mtime 三点校验抓不住的内容层破视图)
* 入口参数:p_buf - s_load_file 成功缓冲 const uint8_t *
* len - 实际长度 size_t
* 返回值:1 - 视图非法(空读,或 [0,len) 内出现 NUL 字节);0 - 基本通过
* (配置文件按 INI UTF-8 文本约定生成与编辑,任何偏移都不得含 0x00:
* 引擎保存只写可打印文本,手写/FTP 文档亦然;即便出现合法前缀 +
* 尾部零填充的"部分旧块",解析器按行切分遇 NUL 即断行,零块后内容
* 本就不可达 = 静默截断同源故障,一并拒绝不误伤任何可解析文档)
* 限定条件:仅可用于"重载/保存"的既有文档上下文(boot load 首读不经此路:
* 空文件 = 合法待建形态)。真机台架 2026-11-05 实证:同尺寸整块全 0
* 旧视图可通过长度+再 stat 双检(dhara 旧映射块恰与目标同尺寸),
* 解析零错误、RAM 打回默认——首字节即 NUL,本判定 100% 拦截
*/
static int s_view_bad(const uint8_t *p_buf, size_t len) {
size_t i;
if (len == 0u) {
return 1; /* 空读:解析空文档 = 全体打回默认 */
}
for (i = 0u; i < len; i++) {
if (p_buf[i] == 0u) {
return 1; /* 全 0 旧映射块 / 含 NUL 坏块 */
}
}
return 0;
}
/*
* 函数功能:经后端原子写配置文档(写盘唯一闸口:模板/外科手术同闸)
* 入口参数:p_buf - 文档数据 const uint8_t *
@@ -1240,6 +1281,27 @@ int cfg_file_save(void) {
return -1;
}
/* 2026-11-05 视图一致性守卫(真机台架实证,issue #73 SNTP 补验揪出):
* stat 与 read 之间卷层可给出旧视图(dhara 缓存回滚/FTL 视图滞后)。旧实现
* 直接按"读到的视图"外科重写整档,视图偏短时非默认段随重写一并被静默删掉
* (实测 1066B → 986B,[sntp] 段整段蒸发)。读长与 stat 报长不符、或读期间
* 文件被改写 → 拒存:原文件不动、返回 -1;属主任务脏位保留 = 下一趟自然
* 重试(defaultTask 50ms 循环 / iec104 下轮 poll 投递,均自带重试语义) */
{
cfg_file_stat_t st2;
if (in_len != (size_t)st.size ||
cfg_store_stat(cfg_store_config_path(), &st2) != 0 ||
st2.size != st.size || st2.mtime != st.mtime ||
s_view_bad(p_in, in_len) != 0) {
cfg_store_free(p_in);
DBG_ERROR("save: view %luB != stat %luB, aborted (file untouched)",
(unsigned long)in_len, (unsigned long)st.size);
syslog_post(SYSLOG_SELFTEST, "cfg save view stale");
return -1;
}
}
/* Pass 1 在独立副本上切分(避免破坏原文的行结束符);
* 副本在 p_out 分配前释放,堆峰值维持 p_in + p_out(≤ CFG_HEAP_BUDGET,
* 编译期已校验,见文件常量区) */
@@ -1371,6 +1433,51 @@ void cfg_file_poll(void) {
if (s_load_file(&p_buf, &len) != 0) {
return; /* 读失败:保留,下次 poll 重试 */
}
/* 2026-11-05 视图一致性守卫(与 save 侧同族,真机台架实证 issue #73):
* 三点校验 stat → read → 再 stat + 内容合法性 s_view_bad。台架后续
* 实证(15:21):同尺寸"整块全 0 旧映射块"可骗过纯长度/再 stat 双检
* (dhara 旧映射块恰与目标同尺寸 1064B),解析零错误、RAM 照打回
* ——故必须验内容:INI UTF-8 文本任何偏移不得含 NUL(见 s_view_bad)。
* 命中形态:空读/截断/全 0 块/含 NUL 坏块/读期间改写;不一致 →
* 拒绝应用:RAM 副本原样保留、基线不刷新,下一趟(2s)重试,视图
* 恢复一致即正常应用(自愈);若持续到重启,boot 路径全新挂载必然
* 收敛。首次拒绝自检留痕 + ERROR 一行,此后每 30 趟(约 60s)一条
* WARN 计数行(限速,防日志风暴) */
{
cfg_file_stat_t st2;
int stale;
if (len != (size_t)st.size) {
stale = 1; /* 空读/截断/旧视图 */
}
else if (cfg_store_stat(cfg_store_config_path(), &st2) != 0 ||
st2.size != st.size || st2.mtime != st.mtime) {
stale = 1; /* 读期间文件消失或被改写 */
}
else if (s_view_bad(p_buf, len) != 0) {
stale = 1; /* 内容层坏视图:全 0 旧映射块/含 NUL */
}
else {
stale = 0;
}
if (stale != 0) {
cfg_store_free(p_buf);
if (s_reject_streak < 0xFFFFu) {
s_reject_streak++;
}
if (s_reject_streak == 1u) {
DBG_ERROR("poll: view %luB != stat %luB, HELD (RAM kept)",
(unsigned long)len, (unsigned long)st.size);
syslog_post(SYSLOG_SELFTEST, "cfg poll view stale");
}
else if ((s_reject_streak % 30u) == 0u) {
DBG_INFO("WARN: cfg reload held %u rounds, reboot to converge",
(unsigned)s_reject_streak);
}
return; /* 基线不刷新 = 同一变更下趟仍触发重试;RAM 不动 */
}
}
for (i = 0; i < (int)CFG_FILE_MAX_SECTIONS; i++) {
const cfg_sec_t *p_sec = &s_sections[i];
@@ -1395,6 +1502,8 @@ void cfg_file_poll(void) {
DBG_INFO("poll: config file reloaded");
}
s_reject_streak = 0u; /* 应用成功(含超长重建)= 拒绝期结束 */
/* 重载后刷新基线(回调触发的写盘不引发二次重载) */
{
cfg_file_stat_t st2;
+16 -4
View File
@@ -18,6 +18,10 @@
* v1.4 2026-10-25 DTU 项目组 「数据可信」有符号零点类型:新增 CFG_VAL_INT 有符号十进制值类型
* (len = 1/2/4,小端补码)——标定零点偏移等负值需有符号
* 落盘,动因与取舍见 docs/任务规划/数据可信.md §4.4
* v1.5 2026-11-05 DTU 项目组 契约同步视图一致性守卫(issue #73 SNTP 补验揪出):
* poll 读视图与 stat 令牌不符或内容坏 = 拒绝应用(RAM/基线不动、2s
* 重试自愈);save 读视图不符 = 拒存返回 -1(原文件不动)。
* 细节见 cfg_file.c v1.6 与《配置文件设计说明》变更节
*/
#ifndef CFG_FILE_H
@@ -116,7 +120,11 @@ int cfg_file_load(void);
* 值原位改写,缺失段/键补写;文件缺失/损坏 → 按 RAM 副本重建
* 完整文档(含文件头注释);写盘 = 临时文件 + 原子改名;输出超
* CFG_FILE_MAX_LEN → 拒绝保存返回 -1(原文件不动 + 自检上报,
* 引擎写盘闸口同拒)
* 引擎写盘闸口同拒);读视图与 stat 基准不符(空读/截断/读中
* 被改写)或内容坏(INI 文本任意偏移含 NUL——dhara 同尺寸全 0
* 旧映射块 2026-11-05 台架实证)同样拒存返回 -1——防按短/坏视图
* 外科重写把文件写小、非默认段被静默删除(视图一致性守卫,
* 调用方脏位保留 = 下一趟自然重试)
*/
int cfg_file_save(void);
@@ -129,9 +137,13 @@ int cfg_file_save(void);
* 函数说明:(size, mtime 变更令牌) 相对基线变化且连续 CFG_FILE_SETTLE_CNT
* 次轮询稳定 → 先查 st.size 超 CFG_FILE_MAX_LEN = 损坏 → 工厂默认
* + 重建模板 + 自检留痕(不触发段回调:保留在线修复通道,重启
* 收敛);否则重载全部段(各段复位工厂默认后解析);挂回调
* 段有差异 → 调用其回调(如触发网络重建);重载后刷新基线
* (回调触发的写盘不引发二次重载)
* 收敛);否则过视图一致性守卫(读长 = st.size、内容无 NUL(dhara
* 同尺寸全 0 旧映射块 2026-11-05 台架实证)且读前后 (size,
* mtime) 不变;不符 = 卷层旧视图/坏块/读中被改写 → 拒绝应用:RAM 与
* 基线不动,2s 重试自愈,持续到重启则由 load 全新挂载收敛;首次
* 拒绝自检留痕,其后每 30 趟一条 WARN)后重载全部段(各段复位
* 工厂默认后解析);挂回调段有差异 → 调用其回调(如触发网络重建);
* 重载后刷新基线(回调触发的写盘不引发二次重载)
*/
void cfg_file_poll(void);
+1 -1
View File
@@ -48,7 +48,7 @@ extern "C" {
* 同款先例):
* ca 1..65535:0 为非法公共地址(104 半字地址域,点表无 0 号站)
* port 1024..65535:拒绝把监听端口配到 1..1023 系统保留段,避免误配顶掉
* 系统服务;与 8888/7003 带内相撞属配置者责任(启动锚点
* 系统服务;与 7003 带内相撞属配置者责任(启动锚点
* "i104: listening on %u" 打印实际端口,可核) */
#define IEC104_COMM_CA_MIN 1u
#define IEC104_COMM_CA_MAX 65535u
+6 -7
View File
@@ -7,18 +7,18 @@
| 文件 | 作用 |
|---|---|
| `time_sync.c/h` | **时间同步任务**:等待网络就绪 → 与时间源交互 → 校准墙钟 |
| `time_sntp.c/h` | **SNTP 校时客户端**(2026-11-04 落地):挂在 time_sync 主循环里的 UDP/123 轮询,编解码用 `Lib/coreSNTP/` 序列化器,配置读 `[sntp]` 段(属主 `../../Drivers/BSP/NETCFG/sntp_cfg.c`);单测 `test/host/sntp/` |
| `time_sync.c/h` | **时间同步任务载体**:等待网络就绪 → 200 ms 节拍驱动 SNTP 客户端(:8888 私有推送已于 2026-11-04 退役,理由见墙钟维护说明 §15) |
| `time_sntp.c/h` | **SNTP 校时客户端**(2026-11-04 落地):由 time_sync 任务循环驱动的 UDP/123 轮询,编解码用 `Lib/coreSNTP/` 序列化器,配置读 `[sntp]` 段(属主 `../../Drivers/BSP/NETCFG/sntp_cfg.c`);单测 `test/host/sntp/` |
## 工作流
```
timeSyncTask 启动
↓ osEventFlagsWait(SYS_EVT_NET_READY, ...|osFlagsNoClear) // 状态位不可消费!
time_sync 主循环 → TCP :8888 被动接收("TIME"+u32 → sys_clock 校准)
↘ 每轮顺带 time_sntp_run(gen):到点主动向 [sntp] 服务器发 48 B 查询
time_sync 主循环(200 ms 节拍,长等待分片 ≤50ms 逐片喂心跳)
↘ 每轮 time_sntp_run(gen):到点主动向 [sntp] 服务器发 48 B 查询
(单轮等待切片 ≤50 ms),校验通过按策略步进/只记日志,
首个通过的同步置 SYS_EVT_TIMESYNC_READY
首个通过的同步置 SYS_EVT_TIMESYNC_READY;网络代次变化自弃旧 socket
```
> ⚠️ 等待**就绪位**(`SYS_EVT_NET_READY`)必须 `osFlagsNoClear`——它是状态位,
@@ -26,6 +26,5 @@ time_sync 主循环 → TCP :8888 被动接收("TIME"+u32 → sys_clock 校准
## 相关文档
- `docs/子系统设计/系统墙钟时间维护说明.md` — 墙钟基准 / tick 回绕防护
- `test/host/time_sync_server.py` — PC 端对时推送服务(测试用)
- `docs/子系统设计/系统墙钟时间维护说明.md` — 墙钟基准 / tick 回绕防护 / §15 :8888 退役注记 / §16 SNTP
- `docs/架构设计/项目启动顺序管理.md` — 就绪屏障
+2 -2
View File
@@ -46,7 +46,7 @@
#define SNTP_STEP_DEADBAND_MS 2000
/* 内部钟面 = 本地时间(#56 裁定 §1.1:sys_clock 存"钟面秒",104 写 UTC 的
* 8 小时差已有文档口径)——SNTP 给的是 UTC,落钟面前加固定东八区偏移;
* 全仓无时区存储,本常量与 UI 手工对时 / 8888 推送同源 */
* 全仓无时区存储,本常量与 UI 手工对时同口径(:8888 推送已退役) */
#define SNTP_TZ_LOCAL_OFFSET_SECS 28800U
/* 合理性下限:2020-01-01 UTC;上限 = sys_clock 钟面域 0x7FFFFFFF 扣除时区 */
#define SNTP_UNIX_MIN_VALID 1577836800U
@@ -313,7 +313,7 @@ static int32_t s_off_clamp(int64_t off) {
* (含死区内未步进),复位退避并按 poll_min 重排下一轮;
* 首个成功投 SYS_EVT_TIMESYNC_READY(状态位,不消费);
* 每次实际步进落一条 quiet 操作记录("clock set by SNTP",
* 与 8888/104 同口径,失败不落痕)
* 与 104 同口径,失败不落痕)
*/
static void s_handle_success(const SntpResponseData_t *p_resp, uint32_t now) {
int64_t utc;
+39 -226
View File
@@ -1,7 +1,7 @@
/*
* 模块名称:Time Sync — PC 本地时间推送接收(TCP)
* 模块功能:在独立任务 timeSyncTask 中以 TCP Server 方式监听端口,接收 PC 推送的本地时间包,
* 调用 sys_clock_set_unix() 更新系统墙钟并写回 SD2506 RTC
* 模块名称:Time Sync — timeSyncTask 载体(网络校时节拍宿主)
* 模块功能:独立任务 timeSyncTask:等网络就绪后按固定节拍驱动 SNTP 校时客户端
* (App/sync/time_sntp.c),长等待一律分片并逐片喂任务心跳
* 适用平台:STM32F407ZGTx + CH395F
* 作者:王建锋
* 创建日期:2026-08-27
@@ -10,58 +10,45 @@
* v1.1 2026-08-28 王建锋 改为 TCP Server,迁入独立任务 timeSyncTask,
* 所有 socket 操作经 net_socket 线程安全 API 走消息队列,
* netTask 仅负责 net_poll/net_process_messages,多任务并发安全
* v1.3 2026-10-27 DTU 项目组 道G task-50:对时**成功应用**后投一条 quiet
* 操作记录("clock set by 8888")——task-49 盘点盘出
* "104 对时留痕、本端口不留"的同类不对称,Lead 批准补齐;
* 被拒不落痕;epoch 时标语义未裁定,本改动不碰、不补
* 任何时区补偿。
* v1.2 2026-10-02 王建锋 第 8b 轮消抖:等待片长 200ms→50ms,并把各处长
* 等待(500/2000/200ms)统一走 time_sync_delay_fed()
* 按 ≤50ms 分片、每片喂心跳——消除"心跳滑出两个连续
* 100ms 抽样窗"的节拍抖动(第 7 轮台架 snap=0x17)
* v1.3 2026-10-27 DTU 项目组 道G task-50:对时**成功应用**后投一条 quiet
* 操作记录("clock set by 8888")——task-49 盘点盘出
* "104 对时留痕、本端口不留"的同类不对称,Lead 批准补齐
* v1.4 2026-11-04 DTU 项目组 SNTP 客户端接入(#57 调研落地):accept 轮询
* 片内驱动 time_sntp_run()(48B UDP 请求/应答状态机
* 在 App/sync/time_sntp.c,节奏/退避/步进策略见该文件);
* 本任务循环结构与 8888 语义不变
* 在 App/sync/time_sntp.c,节奏/退避/步进策略见该文件)
* v2.0 2026-11-04 DTU 项目组 私有 TCP :8888 对时退役(SNTP 上线后退出历史
* 舞台):监听重建、"TIME" 包重组、OPER 留痕、头阻塞
* 收口整条链随退——历史协议与退役理由见
* docs/子系统设计/系统墙钟时间维护说明.md §15 退役注记;
* PC 推送工具 time_sync_server.py 与探针 e02_probe.py
* 同日删除。本任务收缩为纯节拍宿主:NET_READY 屏障 →
* 200ms 循环驱动 time_sntp_run()。心跳分片纪律
* (v1.2,第 8b 轮消抖)与屏障喂心跳(2026-10-02
* 台架修复)原样保留。
*/
#include <string.h>
#include "time_sync.h"
#include "time_sntp.h"
#include "net_socket.h"
#include "sys_clock.h"
#include "sys_events.h"
#include "sys_log.h"
#include "task_watchdog.h"
/* 深调用链模块(timeSyncTask 栈仅 2048 B,本任务链 = 建监听 → net_bind → CH395F):
* 日志行缓冲收到 128 B(默认 192),本模块最长行渲染后 < 128 → 不截断 */
#define DBG_LINE_BUF_MAX 128U
#define DBG_TAG "[TIME_SYNC]"
#include "dbg_log.h"
/* 监听端口:PC 推送端(TCP 客户端)需连到本端口 */
#define TIME_SYNC_PORT 8888
/*
* 头阻塞修复 + 挂起请求(pending)化(timeSync 侧;lftpd 侧见 lftpd_inet.c):
* 旧实现用单次 30s 阻塞 net_recv(默认 NET_RECV_TIMEOUT_MS)等时间包——等待期间
* netTask(全部 socket 操作的唯一执行者)被独占,其余任务的网络操作(远端显示 /
* FTP)整体停摆(历史审计遗留问题)。
* 2026-09-22 先落地分片有界读(5ms 片),同日 pending 化后改为"挂起请求":
* 每次等待 = 一次挂起登记(netTask 零占用,完成按主循环节拍检查),调用方
* 单次超时 = 剩余总预算(总等待 ≤ TIME_SYNC_TOTAL_BUDGET_MS,语义与旧 30s
* 一致);等待期间调用方在自己上下文睡任务通知,旧分片协议(片长/片间让出)退役。
*/
#define TIME_SYNC_TOTAL_BUDGET_MS 30000U
/* 看门狗分片等待:单次 net_recv_to 的等待片长上限。须显著小于看门狗抽样窗
/* 看门狗分片等待:单次延时的分片上限。须显著小于看门狗抽样窗
* (task_watchdog.c WD_POLL_PERIOD_MS=100ms)——片长 ≤50ms 时每片前喂的心跳
* 必然落在同一个 100ms 抽样窗内,消除"心跳恰好滑过两个连续窗口"的边界抖动
* (第 7 轮台架稳态 snap=0x17 即抽样窗 vs 心跳节拍的良性错位,第 8b 轮消抖)。
* 语义上仅把一次长等待拆成多次短等待,总预算不变。 */
* 语义上仅把一次长等待拆成多次短等待,总时长不变。 */
#define TIME_SYNC_WAIT_SLICE_MS 50U
/* 主循环节拍:每轮驱动一次 SNTP 状态机后的等待时长,与 :8888 时代的
* accept 轮询片同值(time_sntp_run 对单次驻留另有 ≤50ms 收片上限,
* 与本延时片叠加不破 100ms 抽样窗,心跳纪律不变)。 */
#define TIME_SYNC_TICK_MS 200U
/*
* 函数功能:可喂心跳的延时(把长等待切成 ≤50ms 短片,每片喂一次心跳)
* 入口参数:ms - 总延时(ms) uint32_t
@@ -82,147 +69,16 @@ static void time_sync_delay_fed(uint32_t ms) {
}
}
/*
* 函数功能:创建并监听 TCP 时间同步服务端口
* 入口参数:无
* 返回值:监听 Socket 描述符(>=0),失败返回 -1
* 限定条件:net_init() 已成功;可在非 netTask 上下文调用
* 函数说明:net_socket/net_bind/net_listen 均为线程安全 API,内部经消息队列由 netTask 串行处理。
* 单连接模式下监听 Socket 在收到连接后会转为数据通道,连接关闭后即被释放,
* 因此每次调用都会新建监听 Socket(与 lftpd 同模式),失败自动重试。
*/
static int time_sync_open_listener(void) {
int retry;
for (retry = 0; retry < 5; retry++) {
task_wd_beat(TASK_WD_TIMESYNC); /* 每次重试前喂心跳(见下方 500ms/2000ms 延时) */
int s = net_socket(NET_AF_INET, NET_SOCK_STREAM);
if (s < 0) {
DBG_ERROR("time_sync: net_socket FAIL");
time_sync_delay_fed(500U);
continue;
}
struct net_sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = NET_AF_INET;
addr.sin_port = net_htons(TIME_SYNC_PORT);
addr.sin_addr.s_addr = NET_INADDR_ANY;
if (net_bind(s, (struct net_sockaddr *)&addr, sizeof(addr)) != 0) {
DBG_ERROR("time_sync: bind port %d FAIL", TIME_SYNC_PORT);
net_close(s);
time_sync_delay_fed(2000U);
continue;
}
if (net_listen(s) != 0) {
DBG_ERROR("time_sync: listen FAIL");
net_close(s);
time_sync_delay_fed(2000U);
continue;
}
DBG_INFO("time_sync: TCP listen on :%d (sock=%d)", TIME_SYNC_PORT, s);
return s;
}
return -1;
}
/*
* 函数功能:处理一个已建立的时间同步连接
* 入口参数:conn_sock - 已建立的连接 Socket 描述符(单连接模式下即监听 Socket 自身)
* 返回值:无
* 函数说明:pending 读取 PC 发来的时间包("TIME"+uint32 大端 本地时间),解析后
* 写回 RTC。**不在此 close**(单连接模式下 conn_sock 即
* 监听 fd,close 连监听一起毁、重建窗 ~0.3-1s;net 层 auto_relisten
* 已把同 fd 收回监听,外层直接续 accept——lftpd 样板)。每次等待 =
* 一次挂起请求(netTask 零占用),单次超时 = 剩余总预算
* (≤30s,语义与旧 30s 阻塞一致);跨调用累积,容忍时间包被 TCP 分段送达
*/
static void time_sync_handle_conn(int conn_sock) {
uint8_t buf[16];
int got = 0;
TickType_t t0 = xTaskGetTickCount();
while (got < (int)sizeof(buf)) {
/* 单次预算 = 剩余总预算(pending:等待期 netTask 零占用,调用方
* 在自己上下文睡任务通知,旧片间 vTaskDelay(1) 让出退役)
* ⚠ 看门狗约束:本任务在 required_mask 内,而单次 net_recv_to 可睡满
* 30s 预算 —— 等待期必须周期性喂心跳,否则"对端连上但不发时间包"这种
* 完全正常的场景会被判为任务卡死(见设计说明 §4.4 长耗时白名单)。
* 做法:把长等待切成 WD 窗口内的短片(片长 ≤200ms),每片先喂心跳。 */
TickType_t elapsed = xTaskGetTickCount() - t0;
uint32_t rem = (elapsed >= (TickType_t)pdMS_TO_TICKS(TIME_SYNC_TOTAL_BUDGET_MS)) ? 0U
: (uint32_t)((TickType_t)TIME_SYNC_TOTAL_BUDGET_MS - elapsed);
if (rem == 0U) {
DBG_INFO("time_sync: no TIME packet in 30s, drop conn");
break; /* 总预算耗尽(语义同旧 30s 超时) */
}
task_wd_beat(TASK_WD_TIMESYNC);
if (rem > TIME_SYNC_WAIT_SLICE_MS) {
rem = TIME_SYNC_WAIT_SLICE_MS; /* 分片:等待期保持心跳节奏 */
}
int n = net_recv_to(conn_sock, buf + got, (int)(sizeof(buf) - got), rem);
if (n > 0) {
got += n;
if (got >= 8) {
break; /* 时间包收齐,解析 */
}
continue; /* 包未收齐(分段送达),继续等余下字节 */
}
if (n == 0) {
break; /* 对端关闭(EOF) */
}
if (n == -2) {
continue; /* 本片预算等满无数据 → 下一片重算剩余预算 */
}
break; /* 真错误 */
}
if (got >= 8) {
if (buf[0] == 'T' && buf[1] == 'I' && buf[2] == 'M' && buf[3] == 'E') {
uint32_t epoch = ((uint32_t)buf[4] << 24) |
((uint32_t)buf[5] << 16) |
((uint32_t)buf[6] << 8) |
((uint32_t)buf[7]);
if (sys_clock_set_unix(epoch) == 0) {
/* 操作留痕(道G task-50):对时改的是装置时钟——与 104 的
* "clock set by 104"(App/task/iec104_serv.c 对时处)同类同口径,
* 补齐 task-49 盘出的不对称。**被拒不投**:失败不得记成"时钟被改过";
* 连续两次成功各投一条——每次对时是独立事件,无合并语义。
* quiet 口:本任务栈 2048 B(见本文件 DBG_LINE_BUF_MAX 段),
* syslog_post 的两个满态留痕分支各内联约 216 B 行缓冲,不选它。
* ⚠ 记录里的时标语义(本端口写钟面、104 写 UTC 的 8 小时差)
* 未裁定——留痕按现有通道原样落,不做任何时区补偿。 */
syslog_post_quiet(SYSLOG_OPER, "clock set by 8888");
}
DBG_INFO("time_sync: wall clock updated (epoch=%lu)", (unsigned long)epoch);
}
} else {
/* 头阻塞收口(docs/网络/网络自愈架构设计.md §5.2 E13):本层放弃会话 → 主动拆除。
* 挂起但 TCP 仍活的客户端(PC 内核自动 ACK keepalive,芯片僵尸判不死)
* 会永久占住单连接监听;EOF 路径 drop 幂等返 0(net 层已 relisten)。
* 模拟器多连接后端 conn≠ls,由 sim 实现按数据 fd 关闭。 */
(void)net_drop_conn(conn_sock);
}
/* 原 net_close(conn_sock) 已删——单连接模式 conn==监听 fd,
* close 毁监听(AGENTS 模块约定:EOF 时应用层不得 close);net 层
* auto_relisten 已把同 fd 收回 LISTENING,外层循环直接续 accept。
* 模拟器多连接后端 conn≠ls,由调用方(外层)负责关数据 fd。 */
}
/*
* 函数功能:时间同步任务主体(独立 FreeRTOS 任务)
* 入口参数:argument - 未使用
* 返回值:无
* 限定条件:net_init() 已由 netTask 完成;netTask 正在处理消息队列
* 函数说明:等待网络栈就绪后,循环:建监听 -> 等连接 -> 处理 -> **同 fd 续
* accept**(会话收尾不 close,监听跨会话常驻,仅网络
* 代次变化时重建)。全部 socket 操作经消息队列由 netTask 串行执行,
* 与本任务/其它网络任务并发安全。
* 函数说明:等待网络栈就绪后,按 TIME_SYNC_TICK_MS 节拍驱动 SNTP 校时客户端
* (time_sntp_run 内部:UDP socket 懒建/代际变化自弃旧归还,
* 等待应答期单次驻留 ≤50ms)。心跳 = 每轮循环头一次 + 延时片每片
* 一次;本任务在 IWDG required_mask 内,节拍上没有任何超过抽样窗
* 的不喂窗口。全部 socket 操作经消息队列由 netTask 串行执行。
*/
void time_sync_task(void *argument) {
(void)argument;
@@ -230,13 +86,12 @@ void time_sync_task(void *argument) {
task_wd_bind(TASK_WD_TIMESYNC); /* FTL 心跳路由:登记本任务句柄(入口一次) */
/* 等网络栈真正就绪(取代拍脑袋的 8s 魔法延时),确保 netTask 已开始处理消息;
* osFlagsNoClear:就绪位是状态,不能被本任务消费掉(否则其它等待者永不唤醒) */
* osFlagsNoClear:就绪位是状态,不能被本任务消费掉(否则其它等待者永不唤醒)。
* 2026-10-02 台架修复:等待改 100ms 分片 + 每片喂心跳——IWDG 必需掩码含
* TS 位,原 osWaitForever 无心跳 → 启动初期(存储已就绪、网络未就绪)
* 掩码 800ms 不可达 → 停喂 → 复位循环(2026-10-02 台架根因之一)。
* 100ms 分片 = 抽样窗,纯任务睡眠零队列开销。 */
if (sys_evtHandle != NULL) {
/* osFlagsNoClear:就绪位是状态,不能被本任务消费掉(否则其它等待者永不唤醒)。
* 2026-10-02 台架修复:等待改 100ms 分片 + 每片喂心跳——IWDG 必需掩码含
* TS 位,原 osWaitForever 无心跳 → 启动初期(存储已就绪、网络未就绪)
* 掩码 800ms 不可达 → 停喂 → 复位循环(2026-10-02 台架根因之一)。
* 100ms 分片 = 抽样窗,纯任务睡眠零队列开销。 */
for (;;) {
uint32_t r = osEventFlagsWait(sys_evtHandle, SYS_EVT_NET_READY,
osFlagsWaitAny | osFlagsNoClear, 100u);
@@ -247,57 +102,15 @@ void time_sync_task(void *argument) {
}
}
/* 监听 fd 跨会话常驻:仅首次/网络代次变化/被毁时重建 */
int ls = -1;
for (;;) {
/* 心跳:本任务在 required_mask 内。以下每一处可能长于 100ms 抽样窗的
* 阻塞点(监听重试 2s、accept 轮询 200ms/次、收尾 50ms)都就近补心跳。 */
/* 心跳:本任务在 required_mask 内。time_sntp_run 的收片驻留 ≤50ms
* 落在两次心跳之间(循环头 + 下面延时片每片前置),抽样窗不破。 */
task_wd_beat(TASK_WD_TIMESYNC);
/* 记录本次监听对应的网络代次;代次变化(网络重建)则放弃旧监听重建 */
uint32_t gen = net_get_generation();
/* 网络代次随参数下传:断网/重建由 time_sntp_run 内部自理(关闭旧
* socket 归还),代次变化后下一轮自然在新网上重新发起。 */
time_sntp_run(net_get_generation());
if (ls < 0) {
ls = time_sync_open_listener();
if (ls < 0) {
DBG_ERROR("time_sync: open listener FAIL, retry later");
time_sync_delay_fed(2000U);
continue;
}
}
/* 等待 PC 连接:net_accept 在无连接时立即返回 -1,循环重试同一监听 Socket */
int conn = -1;
do {
conn = net_accept(ls, NULL, NULL);
if (conn < 0) {
if (net_get_generation() != gen) {
net_close(ls); /* 网络重建:旧监听失效,回外层重建 */
ls = -1;
break;
}
/* SNTP 客户端节拍:accept 轮询片内驱动(等待应答期单次
* 驻留 ≤50ms 收片,心跳仍由下面的分片延时喂,100ms 抽样窗
* 不破)。代次变化由 time_sntp_run 内部自理(弃旧 socket)。 */
time_sntp_run(gen);
time_sync_delay_fed(200U);
}
} while (conn < 0);
if (conn < 0) {
DBG_INFO("time_sync: network re-init, relisten");
continue;
}
time_sync_handle_conn(conn);
/* 会话收尾不 close(单连接模式 conn==ls,close 连监听
* 一起毁);net 层 auto_relisten 已把同 fd 收回 LISTENING,下轮循环
* 直接续 accept。模拟器多连接后端(conn≠ls)才关数据 fd。 */
if (conn != ls) {
net_close(conn);
}
time_sync_delay_fed(50U);
time_sync_delay_fed(TIME_SYNC_TICK_MS);
}
}
+6 -8
View File
@@ -1,13 +1,14 @@
/*
* 模块名称:Time Sync — PC 本地时间推送接收(TCP)
* 模块功能:以 TCP Server 方式监听 TIME_SYNC_PORT,接收 PC 推送的本地时间包,
* 更新系统墙钟并写回 SD2506 RTC
* 模块名称:Time Sync — timeSyncTask 载体(网络校时节拍宿主)
* 模块功能:timeSyncTask 任务入口:等网络就绪后按固定节拍驱动 SNTP 校时客户端
* 适用平台:STM32F407ZGTx + CH395F
* 作者:王建锋
* 创建日期:2026-08-27
* 修改记录:
* v1.0 2026-08-27 王建锋 创建初始版本(UDP 推送)
* v1.1 2026-08-28 王建锋 改为 TCP Server,迁入独立任务 timeSyncTask
* v2.0 2026-11-04 DTU 项目组 TCP :8888 对时退役,TIME_SYNC_PORT 宏随退,
* 任务收缩为 SNTP 节拍宿主(细节见 time_sync.c 文件头)
*/
#ifndef TIME_SYNC_H
@@ -19,16 +20,13 @@
extern "C" {
#endif
/* 监听端口:PC 推送端(TCP 客户端)需连到本端口 */
#define TIME_SYNC_PORT 8888
/*
* 函数功能:时间同步任务主体(独立 FreeRTOS 任务)
* 入口参数:argument - FreeRTOS 传入参数(未使用)
* 返回值:无
* 限定条件:net_init() 已由 netTask 完成;网络消息队列由 netTask 处理
* 函数说明:以 TCP Server 方式监听 TIME_SYNC_PORT,接收 PC 推送的本地时间包,
* 经消息队列(由 netTask 串行执行)完成 socket 操作,更新系统墙钟。
* 函数说明:等网络就绪后按 200ms 节拍驱动 SNTP 校时客户端(App/sync/time_sntp.c),
* socket 操作经消息队列(由 netTask 串行执行)完成。
* 该任务与 FTP 等其它网络任务并发安全。
*/
void time_sync_task(void *argument);
+45 -18
View File
@@ -48,6 +48,7 @@
#include "main.h"
#include "ff.h"
#include "nand_ftl.h"
#include "bsp_err.h" /* BSP_ERR_NO_SPACE / BSP_ERR_CRC:卷健康探针按失败类分流(C4) */
#include "net_cfg.h"
#include "cfg_file.h"
#include "run_par.h" /* 运行参数段落盘(「数据可信」这一项,配置引擎属主 = 本任务) */
@@ -523,30 +524,56 @@ static FRESULT storage_bring_up(FATFS *fs) {
FS_VOL_PROBE(hfr); /* 两击确认 */
}
if (hfr != FR_OK) {
/* C4 消费点(2026-11-04,问题 #79):探针只拿到 FRESULT,失败类在
* disk_read/disk_write 返回时就被 FatFs 契约抹掉了。这里把 FTL 留下的
* 跨调用快照读出来,**先判"重格式化有没有意义"再决定动作**——
* 这正是 存储架构说明 §10.4 那条一直只写在文档里、没有消费者的判据。
*
* 为什么必须先判:BSP_ERR_NO_SPACE 是 journal/映射层块池见底(介质健康),
* 重格式化只会把问题推回去(文档原文);而 BSP_ERR_CRC 才是"页级太坏,
* 换页/reformat 可能救"。两类都走 reformat 的话,块池见底会被反复擦盘。 */
nand_ftl_fault_t fault;
nand_ftl_fault_get(&fault);
if (fault.active != 0u) {
DBG_ERROR("[FS] probe failed (fr=%d), FTL last fault: op=%u class=%ld lpn=%lu count=%lu",
(int)hfr, (unsigned)fault.op, (long)fault.cls,
(unsigned long)fault.lpn, (unsigned long)fault.count);
}
/* ⚠ FR_INVALID_NAME 绝不可入本集合:它是路径名语法错误(纯 RAM 判定、
* 不碰盘),与卷健康无关(曾误入 → "无限重格式化"事故) */
if (hfr == FR_DENIED || hfr == FR_INVALID_OBJECT ||
hfr == FR_INT_ERR || hfr == FR_DISK_ERR ||
hfr == FR_NO_FILE || hfr == FR_NO_PATH ||
hfr == FR_NO_FILESYSTEM) {
DBG_INFO("[FS] volume FAT invalid (fr=%d), reformatting...",
(int)hfr);
f_mount(NULL, "", 0);
/* 格式化前清空 FTL map 树(同首启路径:新卷从空树写起) */
(void)nand_ftl_format();
{
static uint8_t fs_work2[FF_MAX_SS];
MKFS_PARM opts2 = { FM_FAT32, 0, 0, 0, 0 };
fr = f_mkfs("", &opts2, fs_work2, sizeof(fs_work2));
if (fr == FR_OK) {
fr = f_mount(fs, "", 1);
}
}
if (fr == FR_OK) {
DBG_INFO("[FS] volume reformatted OK");
/* 按失败类分流:块池见底 ≠ 介质坏。前者擦卷救不回来,只上报
* (后续应走容量恢复,见 存储维护与容量恢复.md),后者才 reformat。 */
if ((fault.active != 0u) && (fault.cls == (int32_t)BSP_ERR_NO_SPACE)) {
DBG_ERROR("[FS] volume probe failed: FTL out of space, "
"reformat skipped (needs capacity recovery, not mkfs)");
syslog_post(SYSLOG_SELFTEST, "storage full");
fr = FR_INT_ERR;
} else {
DBG_ERROR("[FS] volume repair failed (fr=%d)", (int)fr);
syslog_post(SYSLOG_SELFTEST, "storage fault");
DBG_INFO("[FS] volume FAT invalid (fr=%d), reformatting...",
(int)hfr);
f_mount(NULL, "", 0);
/* 格式化前清空 FTL map 树(同首启路径:新卷从空树写起) */
(void)nand_ftl_format();
{
static uint8_t fs_work2[FF_MAX_SS];
MKFS_PARM opts2 = { FM_FAT32, 0, 0, 0, 0 };
fr = f_mkfs("", &opts2, fs_work2, sizeof(fs_work2));
if (fr == FR_OK) {
fr = f_mount(fs, "", 1);
}
}
if (fr == FR_OK) {
DBG_INFO("[FS] volume reformatted OK");
} else {
DBG_ERROR("[FS] volume repair failed (fr=%d)", (int)fr);
syslog_post(SYSLOG_SELFTEST, "storage fault");
}
}
} else {
/* 其余错误(写保护/卷锁/参数类)不重格式化——只上报,
@@ -685,7 +712,7 @@ static void wave_store_drain(void) {
}
}
if ((why == NULL) && (s_wscan_done == 0u)) {
FRESULT rr;
FRESULT rr = FR_OK;
fr = f_opendir(&s_wdir, WAVE_ST_DIR);
if (fr == FR_OK) {
+52
View File
@@ -8,6 +8,11 @@
* 2026-07-16 王建锋 创建初始版本
* 2026-07-17 王建锋 切换硬件 SPI,修正擦除地址,参考 NuttX 驱动
* 2026-08-27 补充函数注释(代码规范 V1.0);修正工厂坏块扫描为首页;增加 BBT 持久化
* 2026-11-04 问题 #79 取证配套:① init 解锁块保护(A0h)后补回读校验——
* 与 2026-10-23 修过的 ECC(B0h)同族的"只写不回读"缺口
* (实测本板 A0h 已为 0,写保护非本次根因,校验留作哨兵);
* ② `gd5f_bbt_load()` 合并后若坏块数 > 出厂扫描数则打一条
* "BBT after merge",让现场一眼区分真坏与误标固化。
*/
/* 头文件包含区 */
@@ -839,6 +844,39 @@ int32_t gd5f2gq5ue_init(void) {
DBG_ERROR("Unlock block protection failed: %d", ret);
return ret;
}
/* 回读 A0h 校验保护位**真正清零**(2026-11-04,问题 #79 取证发现)。
*
* 为什么必须校验:本项与 2026-10-23 修过的 ECC(B0h) 是同一条缺陷的另一半——
* `gd5f_set_feature()` 只写不回读,"写了但没生效"对上层完全不可见。
* A0h 没清干净的后果比 ECC 没开更直接:**整片只读**。
*
* 台架现场(11-04 17:40 本次启动,`repair-nand-volume` 取证):
* BBT scan: 0 bad blocks found ← 介质出厂坏块为 0
* 读操作全部正常(Map resumed / FAT 探针能读到内容)
* 写操作**全部**失败:LPN=211(块 3)与 LPN=15(块 0)两个不同块
* 连 nand_ftl_format() 后的 map sync 都失败 → storage disabled
* "读正常 + 写全废 + 跨多个无关块 + 出厂坏块为 0" 这组特征排除了
* "某一页/某一块真坏"(那不会跨块、也不会让全新 map sync 失败),
* 指向芯片处于**写保护态**。
*
* 判据:A0h bit0-3 (BP0..BP3) 与非易失的 BP 位组合决定保护范围;
* 读到非 0 即保护未解除,必须**明确失败**而不是继续跑(继续跑会让
* 上层把"写保护"误判成"介质损坏",进而反复格式化——正是本单现场)。
*/
{
uint8_t prot = 0;
ret = gd5f_private_get_feature(GD5F_REG_PROTECT, &prot);
if (ret != GD5F_OK) {
DBG_ERROR("Read A0h failed: %d", ret);
return ret;
}
if (prot != 0u) {
DBG_ERROR("Block protection NOT cleared (A0h=0x%02X), NAND is read-only",
prot);
return GD5F_ERROR;
}
}
DBG_INFO("Locating BBT pool...");
ret = gd5f_private_bbt_locate_pool();
@@ -854,6 +892,20 @@ int32_t gd5f2gq5ue_init(void) {
DBG_ERROR("Load persisted BBT failed: %d (use scanned BBT)", ret);
}
/* 【#79】持久化 BBT 若把连续段判坏(出厂扫描 0 坏块、底层写全部成功),
* 那是运行期误标被固化后的结果,不是介质坏。此处只打一条汇总,
* 让下次现场一眼能区分"真坏"与"误标"。 */
{
uint32_t bad = 0;
for (uint32_t b = 0; b < GD5F_TOTAL_BLOCKS; b++) {
if ((s_bbt[b >> 3] >> (b & 7)) & 1) bad++;
}
if (bad > 0) {
DBG_ERROR("BBT after merge: %lu bad blocks (factory scan was 0)",
(unsigned long)bad);
}
}
DBG_INFO("NAND init OK");
return GD5F_OK;
}
+162 -12
View File
@@ -25,10 +25,31 @@
* 单一真源 + 两条负数组编译期守卫:越界上界依赖
* log2_ppb,换料时只改 GD5F_* 而忘改字面量会**静默**
* 把守卫算大 = 越界守卫失效,现改为直接编译错
* 2026-11-04 王建锋 问题 #79(台架 LPN=211 恒 TOO_BAD 致 f_mount 失败、
* 整卷禁用)两处修复:
* ① `nand_ftl_format()` 不再被脏缓存 flush 失败挡住——
* 旧实现先 flush、失败即 return,导致**恢复动作自己在
* 同一页上死锁**(map 从未清过,f_mkfs 在旧映射上必失败)。
* 格式化语义本就是销毁映射,故尽力刷一次后无条件丢缓存;
* ② 补 C4 跨调用失败类快照(`nand_ftl_fault_get/clear`),
* 让 disk_initialize/读/刷/同步的失败归类能穿过 FatFs 的
* RES_ERROR 边界,供 defaultTask 探针按类分流(见 存储架构
* 说明 §10.4);③ .c 自包含 include 本模块头(主机侧单测
* 直接 #include 本文件,缺头则类型不可见)。
* ④(真机取证后定案)`dhara_nand_erase/prog()` 不再把
* **传输层/等忙失败**当坏块证据:只有芯片明确回 E_FAIL /
* P_FAIL 才标坏。真凶即在此——非坏类失败被标坏后由
* mark_block_bad 立即持久化(不可撤销),台架 BBT 遂固化
* 129 个误标块(1016–1142 连续段),journal prepare_head()
* 连续 8 次 is_bad → TOO_BAD → 整卷禁用;已固化的误标由
* 恢复动作 A 重建 BBT 清除(见 存储维护与容量恢复 §2.1)。
*/
/* 头文件包含区 */
#include <string.h>
#include "nand_ftl.h" /* 本模块公开契约:失败快照类型(C4)与 nand_ftl_* 原型。
* 必须自包含——旧版靠调用方先 include 本头,主机侧单测
* 直接 #include "nand_ftl.c" 时类型不可见(实测编译错)。 */
#include "gd5f2gq5ue.h"
#include "ff.h"
#include "diskio.h"
@@ -125,10 +146,19 @@ static uint8_t s_copy_buf[FTL_PAGE_SIZE];
/* 初始化状态 */
static uint8_t s_initialized;
/* 失败快照(C4):把"最近一次存储失败"的归类带出函数边界。
* 为什么需要:disk_read/disk_write 对 FatFs 只能回 RES_ERROR(FatFs 契约),
* 失败类在 return 那一刻就被抹掉,上层因此无法区分「页级 TOO_BAD,重格式化可解」
* 与「块池见底 / 映射损坏,重格式化只会把问题推回去」。
* 多写者纪律:defaultTask 与 testTask 都会碰存储,故语义是"最近一次"而非账本;
* 并发下可能被另一路覆盖——诊断用途可接受,记在此处以免日后误当权威计数。 */
static nand_ftl_fault_t s_fault;
/* ======================== 私有函数声明 ======================== */
static bsp_err_t ftl_flush_cache(void);
static bsp_err_t ftl_read_page(dhara_sector_t lpn);
static void ftl_fault_note(uint32_t op, bsp_err_t cls, dhara_sector_t lpn);
/* SPI 原语从 gd5f2gq5ue.h 获取 */
@@ -184,6 +214,52 @@ static bsp_err_t ftl_class_from_dhara(dhara_error_t err) {
}
}
/* ======================== 失败快照(C4) ======================== */
/*
* 函数功能:记录一次存储失败到跨调用快照
* 入口参数:op - 失败的操作(NAND_FTL_OP_*)
* cls - 失败类(ftl_class_from_dhara 的结果)
* lpn - 涉及逻辑页号(未知传 NAND_FTL_LPN_NONE)
* 返回值:无 void
* 限定条件:可在任何上下文调用;本函数只写几个字,不加锁(见下方顺序说明)
* 函数说明:**不覆盖已有的非 NONE 归类除非新失败更具体**——不,刻意选择
* "后写覆盖":快照回答的是"最近一次失败是什么",最靠近处置点的现场才有用。
* count 单独累计,用来回答另一个问题:"是不是一直在撞同一页"(本单现场正是
* LPN=211 反复失败 15 次)。两者分开存,避免为了统计把最近现场挤掉。
*
* 写入顺序是有意的:先写内容字段,最后置 active=1(写侧无锁,读侧可能
* 在任意指令边界被抢占)。这样读到 active=1 时内容字段必然已经写好;
* 最坏情况是读到旧内容 —— 诊断用途可接受,且不会比"没有快照"更差。
*/
static void ftl_fault_note(uint32_t op, bsp_err_t cls, dhara_sector_t lpn) {
s_fault.op = op;
s_fault.cls = (int32_t)cls;
s_fault.lpn = (uint32_t)lpn;
if (s_fault.count < 0xFFFFFFFFu) {
s_fault.count++;
}
s_fault.active = 1u;
}
void nand_ftl_fault_get(nand_ftl_fault_t *p_out) {
if (p_out == NULL) {
return;
}
/* 整结构拷贝:调用方拿到的是一致快照,不会一半新一半旧 */
*p_out = s_fault;
}
void nand_ftl_fault_clear(void) {
/* 先清 active 再清内容:反序会让读侧看到 active=0 但 count 仍是旧值,
* 虽然无害,但"active=0 时其余字段无意义"这条契约更该由写法保证 */
s_fault.active = 0u;
s_fault.op = NAND_FTL_OP_NONE;
s_fault.cls = (int32_t)BSP_OK;
s_fault.lpn = NAND_FTL_LPN_NONE;
s_fault.count = 0u;
}
/* ======================== 页面缓存管理 ======================== */
static bsp_err_t ftl_flush_cache(void) {
@@ -196,6 +272,7 @@ static bsp_err_t ftl_flush_cache(void) {
bsp_err_t cls = ftl_class_from_dhara(err); /* 只在失败分支需要(cppcheck variableScope) */
DBG_ERROR("Cache flush FAIL: LPN=%lu dhara=%s class=%d",
s_cached_lpn, ftl_err_name(err), cls);
ftl_fault_note(NAND_FTL_OP_FLUSH, cls, s_cached_lpn);
return cls;
}
@@ -210,6 +287,7 @@ static bsp_err_t ftl_read_page(dhara_sector_t lpn) {
bsp_err_t cls = ftl_class_from_dhara(err); /* 只在失败分支需要(cppcheck variableScope) */
DBG_ERROR("Page read FAIL: LPN=%lu dhara=%s class=%d",
lpn, ftl_err_name(err), cls);
ftl_fault_note(NAND_FTL_OP_READ, cls, lpn);
return cls;
}
@@ -243,9 +321,24 @@ int dhara_nand_erase(const struct dhara_nand *n, dhara_block_t b, dhara_error_t
}
ret = gd5f_block_erase(ftl_phy_block(b));
if (ret == GD5F_ERASE_FAIL || ret != GD5F_OK) {
dhara_nand_mark_bad(n, b);
dhara_set_error(err, DHARA_E_BAD_BLOCK);
if (ret != GD5F_OK) {
if (ret == GD5F_ERASE_FAIL) {
/* 芯片明确回 E_FAIL:该块确实擦不净,标坏是正确处置 */
DBG_ERROR("Erase failed with E_FAIL: block=%lu", (unsigned long)b);
dhara_nand_mark_bad(n, b);
dhara_set_error(err, DHARA_E_BAD_BLOCK);
} else {
/* 【#79 核心修复】传输层/等忙失败(GD5F_ERROR / GD5F_WAIT_EXPIRED)
* 不是坏块证据:芯片根本没回 E_FAIL,把块标坏等于把"线抖了一下"
* 固化成"这块永久报废",并立即写进持久化 BBT(不可撤销)。
* 这类失败只报 BAD_BLOCK 让 dhara 重试,**不标坏**。
* 真机取证(2026-11-04 17:53):出厂扫描 0 坏块、底层 prog/erase
* 全部成功,而持久化 BBT 把 1016–1142 连续段判坏,prepare_head()
* 连续 8 次撞 is_bad → DHARA_E_TOO_BAD → 整卷禁用。 */
DBG_ERROR("Erase transport/timeout failure (not a bad block): "
"block=%lu ret=%d", (unsigned long)b, ret);
dhara_set_error(err, DHARA_E_BAD_BLOCK);
}
return -1;
}
return 0;
@@ -264,15 +357,27 @@ int dhara_nand_prog(const struct dhara_nand *n, dhara_page_t p, const uint8_t *d
gd5f_write_enable();
ret = gd5f_program_load(0, data, FTL_PAGE_SIZE);
if (ret != GD5F_OK) {
dhara_nand_mark_bad(n, p >> n->log2_ppb);
/* 【#79】装载失败是传输层问题(SPI/DMA/等忙),芯片未回 P_FAIL,
* 不得标坏块;只报 BAD_BLOCK 让 dhara 重试。 */
DBG_ERROR("Program load transport failure (not a bad block): "
"page=%lu ret=%d", (unsigned long)phy_pg, ret);
dhara_set_error(err, DHARA_E_BAD_BLOCK);
return -1;
}
ret = gd5f_program_exec(phy_pg);
if (ret == GD5F_PROGRAM_FAIL || ret != GD5F_OK) {
dhara_nand_mark_bad(n, p >> n->log2_ppb);
dhara_set_error(err, DHARA_E_BAD_BLOCK);
if (ret != GD5F_OK) {
if (ret == GD5F_PROGRAM_FAIL) {
/* 芯片明确回 P_FAIL:页确实写不进去,标坏是正确处置 */
DBG_ERROR("Program failed with P_FAIL: page=%lu", (unsigned long)phy_pg);
dhara_nand_mark_bad(n, p >> n->log2_ppb);
dhara_set_error(err, DHARA_E_BAD_BLOCK);
} else {
/* 【#79】传输层/等忙失败不是坏块证据,不标坏,只重试 */
DBG_ERROR("Program transport/timeout failure (not a bad block): "
"page=%lu ret=%d", (unsigned long)phy_pg, ret);
dhara_set_error(err, DHARA_E_BAD_BLOCK);
}
return -1;
}
@@ -431,6 +536,14 @@ DSTATUS disk_initialize(BYTE pdrv) {
s_cached_lpn = (dhara_sector_t)-1; /* -1 表示缓存未加载;LPN 0 合法,不能用 0 作哨兵 */
s_cache_dirty = 0;
/* 失败快照初值:一次上电从"无失败"起算。刻意放在 map_init 之后、
* resume 之前——resume 失败本身就是要被记进快照的第一件事。 */
s_fault.active = 0u;
s_fault.op = NAND_FTL_OP_NONE;
s_fault.cls = (int32_t)BSP_OK;
s_fault.lpn = NAND_FTL_LPN_NONE;
s_fault.count = 0u;
{
dhara_error_t err = DHARA_E_NONE;
if (dhara_map_resume(&s_map, &err) < 0) {
@@ -453,6 +566,9 @@ DSTATUS disk_initialize(BYTE pdrv) {
DBG_ERROR("Map resume failed (dhara=%s class=%d), volume kept, "
"storage unavailable", ftl_err_name(err),
ftl_class_from_dhara(err));
ftl_fault_note(NAND_FTL_OP_MAP_RESUME,
ftl_class_from_dhara(err),
(dhara_sector_t)NAND_FTL_LPN_NONE);
return STA_NOINIT;
}
} else {
@@ -598,6 +714,8 @@ DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) {
dhara_error_t err;
if (dhara_map_sync(&s_map, &err) < 0) {
DBG_ERROR("Map sync failed: %d", err);
ftl_fault_note(NAND_FTL_OP_SYNC, ftl_class_from_dhara(err),
(dhara_sector_t)NAND_FTL_LPN_NONE);
return RES_ERROR;
}
}
@@ -634,20 +752,52 @@ int nand_ftl_format(void) {
}
}
/* 处置开始:清掉历史失败快照,此后新失败重新记账
* (否则一次旧失败会永久污染"本次格式化到底成没成"的判定) */
nand_ftl_fault_clear();
/* 【本单核心修复 2026-11-04,问题 #79】
* 旧实现先 `if (ftl_flush_cache() != BSP_OK) return GD5F_ERROR;`——而
* ftl_flush_cache() 在失败分支**不清 s_cache_dirty**(那是刻意的:写不进去
* 就不能假装写成功了),于是只要脏页落在"写不动的那个 LPN"上,
* 本函数就在第一道闸门返回,**dhara_map_clear() 永远执行不到**。
*
* 台架现场(11-04 08:16 与 08:42 两次独立捕获,head/tail/epoch 一字不变):
* 探针写 /fschk.tmp → disk_write → flush LPN=211 失败(TOO_BAD)
* → 重试同页再次失败 → 判卷损坏 → 走本函数 → 又被同一页挡住
* → f_mkfs 在旧映射上跑 → 失败 → 3 轮重试耗尽 → storage disabled。
* 每次启动必现、断电重启不恢复,因为 s_cache_dirty 与 LPN=211 的脏数据
* 在**同一次启动内**恒存,而每轮启动都会重新踩上同一条路。
*
* 为什么"跳过 flush 直接丢缓存"在这里是正确的:
* 本函数的语义是**销毁整卷逻辑映射**(头文件:「破坏性:整卷逻辑地址→
* 物理映射作废」,只允许显式命令/恢复流程调用;现存两个调用点
* ——首启无卷与 FAT 探针判卷损坏——都紧接着 f_mkfs 重建卷)。既然这份
* 脏页映射注定被扔掉,为它挡住格式化既救不回数据,又让**恢复动作本身
* 永久失效**。故:尽力刷一次(成功则顺带落盘、日志更干净),失败就
* 丢缓存并继续——这正是"格式化"该有的优先级。
*
* ⚠ 不得把本改动挪到普通写路径:disk_write/disk_read 里的 flush 失败
* 必须继续向上报错(那是"这次写没落地"的真相),只有本函数有权丢弃缓存。
*/
if (ftl_flush_cache() != BSP_OK) {
return GD5F_ERROR;
DBG_ERROR("format: dirty cache at LPN=%lu undiscardable, "
"dropping it (map is being destroyed anyway)", s_cached_lpn);
}
/* 无条件失效页面缓存:格式化后旧映射作废,绝不能让它再被当成有效缓存 */
s_cache_dirty = 0;
s_cached_lpn = (dhara_sector_t)-1;
dhara_map_clear(&s_map);
if (dhara_map_sync(&s_map, &err) < 0) {
DBG_ERROR("Map sync after clear failed: %d", err);
DBG_ERROR("Map sync after clear failed: %s class=%d",
ftl_err_name(err), ftl_class_from_dhara(err));
ftl_fault_note(NAND_FTL_OP_SYNC, ftl_class_from_dhara(err),
(dhara_sector_t)NAND_FTL_LPN_NONE);
return GD5F_ERROR;
}
s_cache_dirty = 0;
s_cached_lpn = (dhara_sector_t)-1;
DBG_INFO("NAND FTL formatted, capacity: %lu pages", dhara_map_capacity(&s_map));
return GD5F_OK;
}
+61
View File
@@ -19,6 +19,40 @@ extern "C" {
#include <stdint.h>
/*
* 失败快照(C4):把"最近一次存储失败的归类"从失败点带出来。
*
* 为什么要单独成一个结构而不是复用 bsp_err_t:调用方需要的不只是失败类,
* 还要能回答"这次失败值不值得再试一次"(重试同一 LPN 会不会又撞同一页)。
* 故带上 LPN 与 op,便于 run.log/wdev.log 里一条日志说清现场。
*
* 字段:
* active - 1 = 快照可用(自上次 nand_ftl_fault_clear() 以来发生过失败)
* op - 失败发生的操作(NAND_FTL_OP_*),0 = 无
* cls - 失败类(bsp_err_t:BSP_ERR_CRC / BSP_ERR_NO_SPACE / BSP_ERR_IO …)
* lpn - 失败涉及的逻辑页号(未知时填 NAND_FTL_LPN_NONE)
* count - 自上次 clear 以来累计的失败次数(饱和不减,用于判"反复撞同一页")
*
* 尺寸:5 × uint32 = **20 B**,无隐式填充(字段全为 4 字节宽,任何编译器布局一致)。
* 不引入任何动态分配。
*/
#define NAND_FTL_LPN_NONE ((uint32_t)0xFFFFFFFFu)
#define NAND_FTL_OP_NONE ((uint32_t)0u)
#define NAND_FTL_OP_MAP_RESUME ((uint32_t)1u) /* disk_initialize 的 dhara_map_resume */
#define NAND_FTL_OP_READ ((uint32_t)2u) /* ftl_read_page(FatFs 读路径) */
#define NAND_FTL_OP_FLUSH ((uint32_t)3u) /* ftl_flush_cache(写回路径) */
#define NAND_FTL_OP_SYNC ((uint32_t)4u) /* disk_ioctl(CTRL_SYNC) 的 map sync */
typedef struct {
uint32_t active; /* 1 = 快照可用(自上次 nand_ftl_fault_clear() 以来发生过失败) */
uint32_t op; /* 失败发生的操作(NAND_FTL_OP_*),0 = 无 */
int32_t cls; /* 失败类(bsp_err_t:BSP_ERR_CRC / BSP_ERR_NO_SPACE / BSP_ERR_IO …)。
* 写死 int32_t 宽度:bsp_err_t 是 int,跨编译器布局才稳定 */
uint32_t lpn; /* 失败涉及的逻辑页号(未知时 = NAND_FTL_LPN_NONE) */
uint32_t count; /* 自上次 clear 以来累计失败次数(饱和不减,用于判"反复撞同一页") */
} nand_ftl_fault_t;
/*
* 函数功能:初始化 FTL(等价于 disk_initialize(0):SPI 起链 + dhara_map_resume)
* 入口参数:无
@@ -53,6 +87,33 @@ int nand_ftl_format(void);
*/
void nand_ftl_deinit(void);
/*
* 函数功能:取"最近一次存储失败"的跨调用快照(C4,2026-11-04 补还)
* 入口参数:p_out - 快照输出 nand_ftl_fault_t* 可为 NULL(=只查询是否有失败)
* 返回值:无 void(新 API 不把"有没有失败"塞进返回值:本函数是纯查询,
* 判定一律读 p_out->active)
* 限定条件:任何任务上下文可读;**仅诊断用途**,不得据此自动清卷/重格式化
* 函数说明:为什么需要它——disk_read/disk_write 对 FatFs 只能回 RES_ERROR
* (FatFs 契约),失败类在函数返回时就被抹掉,上层因此无法区分
* 「页级 TOO_BAD,重格式化可解」与「块池见底 / 映射损坏,重格式化只会把问题
* 推回去」。本快照把 nand_ftl.c 就地分类的结果留在 RAM 里,供
* defaultTask 的卷健康探针按类分支(消费点见 storage_bring_up())。
* ⚠ 多写者:defaultTask 与 testTask 都可能触发写入失败,故快照是"最近一次"
* 语义、非累计账本;并发下可能被另一路覆盖(诊断场景可接受)。
* 成功路径**不清**它(失败证据要留存到显式 clears),语义同 dbg latch。
*/
void nand_ftl_fault_get(nand_ftl_fault_t *p_out);
/*
* 函数功能:清除失败快照(把 active 置 0)
* 入口参数:无
* 返回值:无
* 限定条件:仅"已按快照处置完毕"的调用方清除(当前 = defaultTask 卷修复路径)
* 函数说明:不清就会让一次历史失败永久污染后续判定;清早了又会丢掉现场。
* 调用点因此只有一处,见 storage_bring_up() 的重格式化分支。
*/
void nand_ftl_fault_clear(void);
#ifdef __cplusplus
}
#endif
+5 -3
View File
@@ -9,9 +9,11 @@
* 写入点 = App/task/protect_task.c 的 s_log_active_edge();
* "记录类型 = 日志 ID 本身"(一类记录一个文件,记录体内没有类型字段位,
* Lead 裁定 2026-10-26)——本页只读 accid.log 一个文件,不做跨文件混排。
* 台架待补(不在本批,已登记 docs/任务规划/登记簿.md):真 NAND 上真实记录的翻页读取、
* 掉电后记录保持、清除记录后本页归零这三件事都要上板复核;模拟器侧该文件
* 没有写入方,像素黄金只能验空态"无记录"。
* 台架复核已完成(2026-11-06,Issue #53 台架轮、实机 boot 188–193,证据贴 Issue #53 评论):
* 本页真机实读为空态"无记录"且属实况(事故写入方在保护未标定闭锁内,台架期间
* 零触发,NAND 无 accid.log);空类清除幂等经同页其余行实机复核,翻页与保持
* 逻辑经同构记录页(操作 / 遥控 / 启动)真记录复核。模拟器侧该文件仍无写入方,
* 像素黄金维持空态"无记录"口径。
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用)
* 作者:DTU 项目组
* 创建日期:2026-10-28
+5 -3
View File
@@ -9,9 +9,11 @@
* 写入点 = App/task/protect_task.c 的 s_log_active_edge();
* "记录类型 = 日志 ID 本身"(一类记录一个文件,记录体内没有类型字段位,
* Lead 裁定 2026-10-26)——本页只读 alarm.log 一个文件,不做跨文件混排。
* 台架待补(不在本批,已登记 docs/任务规划/登记簿.md):真 NAND 上真实记录的翻页读取、
* 掉电后记录保持、清除记录后本页归零这三件事都要上板复核;模拟器侧该文件
* 没有写入方,像素黄金只能验空态"无记录"。
* 台架复核已完成(2026-11-06,Issue #53 台架轮、实机 boot 188–193,证据贴 Issue #53 评论):
* 本页真机实读为空态"无记录"且属实况(告警写入方在保护未标定闭锁内,台架期间
* 零触发,NAND 无 alarm.log);清除页本行两段式空类清除已实机复核幂等;翻页与
* 保持逻辑经同构记录页(操作 / 遥控 / 启动)真记录复核。模拟器侧该文件仍无
* 写入方,像素黄金维持空态"无记录"口径。
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用)
* 作者:DTU 项目组
* 创建日期:2026-10-28
+7 -5
View File
@@ -5,13 +5,15 @@
* 注入 reader 取自 sys_log(/log/oper.log,容量上限 512 条,满时删除重建);
* 空日志显示单条伪行"无记录";向框架 ui_content_page 提供页面描述符(零 LVGL 对象)
* 记录口径(本文件只读显示、不实现写入方;权威表 App/log/README.md §五类记录):
* 触发判据 = 人工/远端操作留痕:定值保存、强制复归、对时(8888 与 104)、清除记录;
* 写入点 = App/task/default_task.c(定值保存)、App/protocol/iec104/iec104_pts.c(复归与整定写入)、App/task/iec104_serv.c 与 App/sync/time_sync.c(对时)、App/log/sys_log_mcu.c(清除记录留痕,OPER 自身除外);
* 触发判据 = 人工/远端操作留痕:定值保存、强制复归、对时(SNTP 与 104)、清除记录;
* 写入点 = App/task/default_task.c(定值保存)、App/protocol/iec104/iec104_pts.c(复归与整定写入)、App/task/iec104_serv.c 与 App/sync/time_sntp.c(对时)、App/log/sys_log_mcu.c(清除记录留痕,OPER 自身除外);
* "记录类型 = 日志 ID 本身"(一类记录一个文件,记录体内没有类型字段位,
* Lead 裁定 2026-10-26)——本页只读 oper.log 一个文件,不做跨文件混排。
* 台架待补(不在本批,已登记 docs/任务规划/登记簿.md):真 NAND 上真实记录的翻页读取、
* 掉电后记录保持、清除记录后本页归零这三件事都要上板复核;模拟器侧该文件
* 没有写入方,像素黄金只能验空态"无记录"。
* 台架复核已完成(2026-11-06,Issue #53 台架轮、实机 boot 188–193,证据贴 Issue #53 评论):
* 真 NAND 真实记录的翻页读取、复位(RAM 全清)后从 NAND 原样重读、清除记录后
* 本页归零(73 条 → 无记录、OPER.LOG 从盘上消失)三件事均已上板复核;真·拔
* 市电本机不可控,保持性以 RAM 全清 + 全链重启代理(POR 计数差额人工一眼可补)。
* 模拟器侧该文件仍无写入方,像素黄金维持空态"无记录"口径。
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用)
* 作者:DTU 项目组
* 创建日期:2026-10-28
+7 -4
View File
@@ -17,10 +17,13 @@
* **不做跨开机累计**(用户裁定 2026-10-27)
* 几何余量(2026-10-28 黄金目检):「自电池周期」5 字 x12px 从 x=101 起、右缘 161,**余量 0**——
* 值列再加字或换字号必切边;要扩文案必须先减字或改标签列宽度,别直接加字。
* 台架待补(不在本批,已登记 docs/任务规划/登记簿.md):真机上电一次看 boot_count +1、
* 拔电换电池后 seq_state 落 RESTARTED、IWDG 复位后 rst_cause 落 IWDG、
* 主站连一次看 conn_up +1 —— 模拟器无 boot_stats(依赖 SD2506 I2C 与 RCC_CSR)
* 与 104 协议栈,黄金参考拍的是固定假数据
* 台架复核已完成(2026-11-06,Issue #53 台架轮、实机 boot 187–193,证据贴 Issue #53 评论):
* 上电一次 boot_count +1 真机复核——链条 187→193 六连击无跳号,SRAM 保持 +
* 写回正常(本机无市电开关,用 ST-LINK 系统复位代理完整上电,电池域存储语义
* 全覆盖);IWDG 复位后 rst_cause 落「独立看门狗」经 SWD 缩窗真溢出复核;
* 主站接入一次 conn_up +1 经静默窗 +1 精确归因复核;拔 RTC 电池落 RESTARTED
* 一项台架不可验(用户裁定 2026-11-05,销项不挂账)。模拟器无 boot_stats
* (依赖 SD2506 I2C 与 RCC_CSR)与 104 协议栈,黄金参考拍的是固定假数据
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用)
* 作者:DTU 项目组
* 创建日期:2026-10-28
+5 -3
View File
@@ -9,9 +9,11 @@
* 写入点 = App/task/protect_task.c 的 s_log_active_edge();
* "记录类型 = 日志 ID 本身"(一类记录一个文件,记录体内没有类型字段位,
* Lead 裁定 2026-10-26)——本页只读 start.log 一个文件,不做跨文件混排。
* 台架待补(不在本批,已登记 docs/任务规划/登记簿.md):真 NAND 上真实记录的翻页读取、
* 掉电后记录保持、清除记录后本页归零这三件事都要上板复核;模拟器侧该文件
* 没有写入方,像素黄金只能验空态"无记录"。
* 台架复核已完成(2026-11-06,Issue #53 台架轮、实机 boot 188–193,证据贴 Issue #53 评论):
* 真 NAND 真实记录的翻页读取、复位(RAM 全清)后从 NAND 原样重读、清除记录后
* 本页归零(2 条 → 无记录、START.LOG 从盘上消失)三件事均已上板复核;真·拔
* 市电本机不可控,保持性以 RAM 全清 + 全链重启代理(POR 计数差额人工一眼可补)。
* 模拟器侧该文件仍无写入方,像素黄金维持空态"无记录"口径。
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用)
* 作者:DTU 项目组
* 创建日期:2026-10-28
+5 -3
View File
@@ -9,9 +9,11 @@
* 写入点 = App/protocol/iec104/iec104_pts.c 的遥控段;
* "记录类型 = 日志 ID 本身"(一类记录一个文件,记录体内没有类型字段位,
* Lead 裁定 2026-10-26)——本页只读 yk.log 一个文件,不做跨文件混排。
* 台架待补(不在本批,已登记 docs/任务规划/登记簿.md):真 NAND 上真实记录的翻页读取、
* 掉电后记录保持、清除记录后本页归零这三件事都要上板复核;模拟器侧该文件
* 没有写入方,像素黄金只能验空态"无记录"。
* 台架复核已完成(2026-11-06,Issue #53 台架轮、实机 boot 188–193,证据贴 Issue #53 评论):
* 真 NAND 真实记录的翻页读取、复位(RAM 全清)后从 NAND 原样重读、清除记录后
* 本页归零(34 条 → 无记录、YK.LOG 从盘上消失)三件事均已上板复核;真·拔
* 市电本机不可控,保持性以 RAM 全清 + 全链重启代理(POR 计数差额人工一眼可补)。
* 模拟器侧该文件仍无写入方,像素黄金维持空态"无记录"口径。
* 适用平台:STM32F407ZGTx / PC 模拟器(两端共用)
* 作者:DTU 项目组
* 创建日期:2026-10-28
File diff suppressed because it is too large Load Diff
+2 -5
View File
@@ -122,7 +122,7 @@ STM32F4-Base/
│ ├── algo/ # 采集与算法层(语义取数与有效性 adc_input / 全周傅氏相量 phasor+freq / 保护判据 prot_set+prot_elm)
│ ├── cfg/ # 配置引擎(cfg_file 解析/持久化/迁移 + 存储后端)
│ ├── fs/ # 卷锁(vol_lock,syslog/cfg/lftpd 三条路径 try 语义)
│ ├── sync/ # 时间同步(time_sync 任务)
│ ├── sync/ # 时间同步(time_sync 任务载体 + time_sntp SNTP 客户端)
│ ├── log/ # 日志(sys_log 运行/自检记录、console_log 控制台单写者)
│ ├── task/ # FreeRTOS 任务实现
│ │ ├── default_task.c/h # 存储挂载 + 配置引擎属主 + syslog 写者
@@ -175,9 +175,7 @@ STM32F4-Base/
│ └── host/ # 主机端脚本(PC 侧;串口回归入口在 .dsh/skills/serial-boot-test/)
│ ├── ch395f_socket_test.py # Socket 通信测试
│ ├── ftp_test.py / ftp_up_dl_test.py / ftp_regression.py / ftp_integrity_test.py / ftp_capture.py
│ ├── e02_probe.py # 队头阻塞专项探针
│ ├── latency_peer.py # 链路时延 PC 对端
│ └── time_sync_server.py # 时间同步推送服务
│ └── latency_peer.py # 链路时延 PC 对端
├── docs/ # 项目文档(全量索引见 docs/README.md)
│ ├── README.md # 文档索引:目录结构 + 推荐阅读顺序 + 全量清单
│ ├── 任务规划/ # 统一待办登记簿(README 排序权威 + 拆分文件)
@@ -325,7 +323,6 @@ UI 改动回归门禁(菜单像素回归 + 内容页黄金参考 + 池水位
| `ftp_regression.py` | FTP 功能回归(会话流程全序列) |
| `ftp_integrity_test.py` | FTP 传输完整性压测(多轮 SHA-256 校验) |
| `ftp_capture.py` | FTP 流量抓取 |
| `time_sync_server.py` | 时间同步推送服务(PC → 板子) |
### 串口调试
+1 -1
View File
@@ -139,7 +139,7 @@ docs/
| [`ADC输入层单元测试说明.md`](测试说明/单元测试/ADC输入层单元测试说明.md) | adc_input 语义通道映射 / ADC1 顺序扫描(**Rank↔通道判据**)/ poll 契约 / HAL 故障路径,70 用例 |
| [`相量层单元测试说明.md`](测试说明/单元测试/相量层单元测试说明.md) | phasor 全周傅氏系数表 / 幅值·相位 / 谐波抑制与提取 / 频偏 / 采样环 / 双区交换,57 用例 |
| [`卷锁单元测试说明.md`](测试说明/单元测试/卷锁单元测试说明.md) | vol_lock 创建 / 获取 / 释放契约(**fail-open 不变量**:创建失败仍返回 1 且零阻塞)/ 幂等 / 超时透传,33 断言点 |
| [`时间同步单元测试说明.md`](测试说明/单元测试/时间同步单元测试说明.md) | time_sync 分片喂狗延时 / 监听退避 / 时间包重组 / 任务主循环(探针窗口心跳缺口的全部逻辑贡献者),80 断言点 |
| [`时间同步单元测试说明.md`](测试说明/单元测试/时间同步单元测试说明.md) | time_sync v2.0:分片喂狗延时 / 就绪屏障(100 ms 分片·NoClear)/ SNTP 节拍与网络代次交接 / 未出网守门(:8888 退役后的任务载体),33 断言点 |
| [`主机单测覆盖率口径.md`](测试说明/单元测试/主机单测覆盖率口径.md) | **跨全部 16 套 主机侧纯逻辑单测的覆盖率**:`scripts/check_test_coverage.py` 用法 / 统计面与生成物例外 / 基线增量门禁(只拦回退)/ **为什么本机拿不到分支覆盖** / 九条限制与盲区 / 未挂 pre-commit 的三条理由与待粘 YAML |
**板级测试/**(上板测试:模块测试指南 + 实机实施流程;动手写测试前先读)
+1 -1
View File
@@ -206,7 +206,7 @@ ui_page_ac / ui_page_yx / ui_page_setlist ...
9. **`ui_w_editor`**(§3.2)→ **定值整定 4 页**(8/9/10/11)。
10. **通讯设置**(29):需先建 `comm_cfg`(`[comm]` 段:104 公共地址/端口/主站地址),照 `net_cfg` 的"RAM 副本 + 保存请求交接"范式。
11. **SNTP设置**(31):**建议只做页面不接线**,或直接推迟到 SNTP 立项——当前对时走 8888 端口私有协议,SNTP 是另一条链。
11. **SNTP设置**(31)——已落地(2026-11-04):页面读写 `[sntp]` 段 RAM 副本(`ui_page_sntp.c`,PR 链 #73/#77);原「当前对时走 8888 端口私有协议」口径作废——8888 已退役(#78),SNTP 即对时唯一网络来源。
**退出判据**:就地改一条定值 → 保存 → 掉电重启 → 值保持且校验和自检通过;主站 C_RD 读到同一值。
+2 -2
View File
@@ -9,8 +9,8 @@
<text x="251" y="139" font-size="13" fill="#1e293b" text-anchor="middle">net_send() / net_recv() / net_close()(线程安全封装)</text>
<rect x="468" y="116" width="431" height="38" rx="8" fill="#ffffff" stroke="#2563eb" stroke-opacity="0.55"/>
<text x="684" y="139" font-size="13" fill="#1e293b" text-anchor="middle">net_select() / net_poll_events() / net_set_event_cb()</text>
<rect x="44" y="164" width="601" height="38" rx="8" fill="#ffffff" stroke="#2563eb" stroke-opacity="0.55"/>
<text x="344" y="187" font-size="13" fill="#1e293b" text-anchor="middle">消费方:lftpd(FTP :21)· time_sync(对时 :8888)· ui_net_sink(远程显示 :7003)</text>
<rect x="44" y="164" width="620" height="38" rx="8" fill="#ffffff" stroke="#2563eb" stroke-opacity="0.55"/>
<text x="354" y="187" font-size="13" fill="#1e293b" text-anchor="middle">消费方:lftpd(FTP :21)· time_sntp(SNTP 出向对时)· ui_net_sink(远程显示 :7003)</text>
<rect x="26" y="262" width="1148" height="140" rx="12" fill="#f5f3ff" stroke="#7c3aed" stroke-opacity="0.45"/>
<text x="44" y="288" font-size="17" font-weight="700" fill="#7c3aed">消息队列</text>
<text x="124" y="288" font-size="12" fill="#64748b">osMessageQueue · CubeMX 生成,在 MX_FREERTOS_Init() 中创建</text>

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

+38 -37
View File
@@ -1,24 +1,23 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1060" height="680" viewBox="0 0 1060 680" font-family="Microsoft YaHei, Segoe UI, PingFang SC, sans-serif">
<rect x="46.0" y="106.0" width="314.0" height="246.0" rx="10" fill="#eff6ff" stroke="#2563eb" stroke-width="2"/>
<text x="58.0" y="132.0" font-size="15" font-weight="700" fill="#0f172a">幅值轮</text>
<text x="348.0" y="132.0" font-size="10.5" text-anchor="end" font-weight="700" fill="#2563eb">先做 · 主用例</text>
<text x="348.0" y="132.0" font-size="10.5" text-anchor="end" font-weight="700" fill="#2563eb">先做 · 三档幅度</text>
<rect x="58.0" y="142.0" width="290.0" height="86.0" rx="6" fill="#ffffff" stroke="#cbd5e1" stroke-width="1"/>
<line x1="62.0" y1="185.0" x2="344.0" y2="185.0" stroke="#94a3b8" stroke-width="0.8" stroke-dasharray="3 3"/>
<line x1="68.0" y1="161.2" x2="338.0" y2="161.2" stroke="#2563eb" stroke-width="1" stroke-dasharray="5 4"/>
<line x1="68.0" y1="208.8" x2="338.0" y2="208.8" stroke="#2563eb" stroke-width="1" stroke-dasharray="5 4"/>
<polyline points="68.0,185.0 69.9,182.9 71.9,180.7 73.8,178.6 75.8,176.6 77.7,174.6 79.7,172.7 81.6,170.9 83.5,169.3 85.5,167.7 87.4,166.3 89.4,165.1 91.3,164.0 93.3,163.1 95.2,162.3 97.1,161.8 99.1,161.4 101.0,161.3 103.0,161.3 104.9,161.5 106.8,161.9 108.8,162.5 110.7,163.3 112.7,164.2 114.6,165.4 116.6,166.7 118.5,168.1 120.4,169.7 122.4,171.4 124.3,173.2 126.3,175.1 128.2,177.1 130.2,179.2 132.1,181.3 134.0,183.4 136.0,185.5 137.9,187.7 139.9,189.8 141.8,191.9 143.8,193.9 145.7,195.9 147.6,197.7 149.6,199.5 151.5,201.1 153.5,202.6 155.4,204.0 157.4,205.2 159.3,206.3 161.2,207.1 163.2,207.8 165.1,208.3 167.1,208.6 169.0,208.8 170.9,208.7 172.9,208.4 174.8,208.0 176.8,207.3 178.7,206.5 180.7,205.5 182.6,204.3 184.5,203.0 186.5,201.5 188.4,199.9 190.4,198.2 192.3,196.3 194.3,194.4 196.2,192.4 198.1,190.3 200.1,188.2 202.0,186.1 204.0,183.9 205.9,181.8 207.9,179.7 209.8,177.6 211.7,175.6 213.7,173.7 215.6,171.8 217.6,170.1 219.5,168.5 221.5,167.0 223.4,165.7 225.3,164.5 227.3,163.5 229.2,162.7 231.2,162.0 233.1,161.6 235.1,161.3 237.0,161.2 238.9,161.4 240.9,161.7 242.8,162.2 244.8,162.9 246.7,163.7 248.6,164.8 250.6,166.0 252.5,167.4 254.5,168.9 256.4,170.5 258.4,172.3 260.3,174.1 262.2,176.1 264.2,178.1 266.1,180.2 268.1,182.3 270.0,184.5 272.0,186.6 273.9,188.7 275.8,190.8 277.8,192.9 279.7,194.9 281.7,196.8 283.6,198.6 285.6,200.3 287.5,201.9 289.4,203.3 291.4,204.6 293.3,205.8 295.3,206.7 297.2,207.5 299.2,208.1 301.1,208.5 303.0,208.7 305.0,208.7 306.9,208.6 308.9,208.2 310.8,207.7 312.7,206.9 314.7,206.0 316.6,204.9 318.6,203.7 320.5,202.3 322.5,200.7 324.4,199.1 326.3,197.3 328.3,195.4 330.2,193.4 332.2,191.4 334.1,189.3 336.1,187.1 338.0,185.0" fill="none" stroke="#2563eb" stroke-width="2" stroke-linejoin="round"/>
<text x="68.0" y="151.0" font-size="10.5" fill="#64748b">峰 ±1.414 V · 基波 RMS 1.000 V</text>
<text x="68.0" y="151.0" font-size="10.5" fill="#64748b">峰 ±1.414 V · 基波有效值 1.000 V</text>
<text x="58.0" y="244.0" font-size="11" font-weight="700" fill="#2563eb">注入</text>
<text x="94.0" y="244.0" font-size="11.5" fill="#64748b">UA(R31)端子侧,正弦 50.000 Hz、1.000 V</text>
<text x="94.0" y="260.0" font-size="11.5" fill="#64748b">rms</text>
<text x="94.0" y="244.0" font-size="11.5" fill="#64748b">UA(R31)端子侧,正弦 50.000 Hz,三档 Vpp</text>
<text x="94.0" y="260.0" font-size="11.5" fill="#64748b"> 2.828 / 1.414 / 0.566</text>
<text x="58.0" y="280.0" font-size="11" font-weight="700" fill="#2563eb">判据</text>
<text x="94.0" y="280.0" font-size="11.5" fill="#0f172a">ua_mv 中位数 ≈ 万用表 × 1000,偏差 ≤2 %</text>
<text x="58.0" y="300.0" font-size="11" font-weight="700" fill="#2563eb">出口</text>
<text x="94.0" y="300.0" font-size="11.5" fill="#64748b">meas: ua_mv 为主;104 0x4011 只作交叉读</text>
<text x="94.0" y="316.0" font-size="11.5" fill="#64748b">数</text>
<text x="94.0" y="280.0" font-size="11.5" fill="#0f172a">每档 ua_mv ≈ 万用表 × 1000,偏差 ≤2 %</text>
<text x="58.0" y="300.0" font-size="11" font-weight="700" fill="#2563eb">读数</text>
<text x="94.0" y="300.0" font-size="11.5" fill="#64748b">meas: ua_mv 为主(1 mV 分辨率)</text>
<rect x="372.0" y="106.0" width="314.0" height="246.0" rx="10" fill="#f0fdfa" stroke="#0d9488" stroke-width="2"/>
<text x="384.0" y="132.0" font-size="15" font-weight="700" fill="#0f172a">波形轮</text>
<text x="674.0" y="132.0" font-size="10.5" text-anchor="end" font-weight="700" fill="#0d9488">真 RMS ≠ 基波</text>
<text x="674.0" y="132.0" font-size="10.5" text-anchor="end" font-weight="700" fill="#0d9488">真有效值 ≠ 基波</text>
<rect x="384.0" y="142.0" width="290.0" height="86.0" rx="6" fill="#ffffff" stroke="#cbd5e1" stroke-width="1"/>
<line x1="394.0" y1="161.2" x2="664.0" y2="161.2" stroke="#94a3b8" stroke-width="0.9" stroke-dasharray="5 4"/>
<polyline points="400.0,185.0 400.7,182.5 401.3,180.0 402.0,177.6 402.6,175.3 403.3,173.0 403.9,170.9 404.6,169.0 405.2,167.2 405.9,165.7 406.6,164.3 407.2,163.2 407.9,162.3 408.5,161.7 409.2,161.3 409.8,161.2 410.5,161.4 411.1,161.8 411.8,162.5 412.5,163.5 413.1,164.6 413.8,166.0 414.4,167.7 415.1,169.5 415.7,171.4 416.4,173.6 417.0,175.8 417.7,178.2 418.4,180.6 419.0,183.1 419.7,185.6 420.3,188.1 421.0,190.6 421.6,193.0 422.3,195.3 422.9,197.5 423.6,199.6 424.3,201.5 424.9,203.2 425.6,204.7 426.2,206.0 426.9,207.0 427.5,207.9 428.2,208.4 428.8,208.7 429.5,208.7 430.2,208.5 430.8,208.0 431.5,207.3 432.1,206.3 432.8,205.0 433.4,203.6 434.1,201.9 434.7,200.1 435.4,198.0 436.1,195.9 436.7,193.6 437.4,191.2 438.0,188.7 438.7,186.3 439.3,183.7 440.0,181.3 440.6,178.8 441.3,176.4 441.9,174.1 442.6,172.0 443.3,169.9 443.9,168.1 444.6,166.4 445.2,165.0 445.9,163.7 446.5,162.7 447.2,162.0 447.8,161.5 448.5,161.3 449.2,161.3 449.8,161.6 450.5,162.1 451.1,163.0 451.8,164.0 452.4,165.3 453.1,166.8 453.7,168.5 454.4,170.4 455.1,172.5 455.7,174.7 456.4,177.0 457.0,179.4 457.7,181.9 458.3,184.4 459.0,186.9 459.6,189.4 460.3,191.8 461.0,194.2 461.6,196.4 462.3,198.6 462.9,200.5 463.6,202.3 464.2,204.0 464.9,205.4 465.5,206.5 466.2,207.5 466.9,208.2 467.5,208.6 468.2,208.8 468.8,208.7 469.5,208.3 470.1,207.7 470.8,206.8 471.4,205.7 472.1,204.3 472.8,202.8 473.4,201.0 474.1,199.1 474.7,197.0 475.4,194.7 476.0,192.4 476.7,190.0 477.3,187.5 478.0,185.0" fill="none" stroke="#0d9488" stroke-width="1.8" stroke-linejoin="round"/>
@@ -27,17 +26,17 @@
<text x="529.0" y="226.0" font-size="10.5" text-anchor="middle" fill="#64748b">方波</text>
<polyline points="580.0,185.0 580.7,183.4 581.3,181.8 582.0,180.2 582.6,178.6 583.3,177.0 583.9,175.4 584.6,173.8 585.2,172.2 585.9,170.6 586.6,169.0 587.2,167.4 587.9,165.8 588.5,164.2 589.2,162.6 589.8,161.4 590.5,163.0 591.1,164.6 591.8,166.2 592.5,167.8 593.1,169.4 593.8,171.0 594.4,172.6 595.1,174.2 595.7,175.8 596.4,177.4 597.0,179.0 597.7,180.6 598.4,182.2 599.0,183.8 599.7,185.4 600.3,187.0 601.0,188.6 601.6,190.2 602.3,191.8 602.9,193.4 603.6,195.0 604.3,196.6 604.9,198.2 605.6,199.8 606.2,201.4 606.9,203.0 607.5,204.6 608.2,206.2 608.8,207.8 609.5,208.2 610.2,206.6 610.8,205.0 611.5,203.4 612.1,201.8 612.8,200.2 613.4,198.6 614.1,197.0 614.7,195.4 615.4,193.8 616.1,192.2 616.7,190.6 617.4,189.0 618.0,187.4 618.7,185.8 619.3,184.2 620.0,182.6 620.6,181.0 621.3,179.4 621.9,177.8 622.6,176.2 623.3,174.6 623.9,173.0 624.6,171.4 625.2,169.8 625.9,168.2 626.5,166.6 627.2,165.0 627.8,163.4 628.5,161.8 629.2,162.2 629.8,163.8 630.5,165.4 631.1,167.0 631.8,168.6 632.4,170.2 633.1,171.8 633.7,173.4 634.4,175.0 635.1,176.6 635.7,178.2 636.4,179.8 637.0,181.4 637.7,183.0 638.3,184.6 639.0,186.2 639.6,187.8 640.3,189.4 641.0,191.0 641.6,192.6 642.3,194.2 642.9,195.8 643.6,197.4 644.2,199.0 644.9,200.6 645.5,202.2 646.2,203.8 646.9,205.4 647.5,207.0 648.2,208.6 648.8,207.4 649.5,205.8 650.1,204.2 650.8,202.6 651.4,201.0 652.1,199.4 652.8,197.8 653.4,196.2 654.1,194.6 654.7,193.0 655.4,191.4 656.0,189.8 656.7,188.2 657.3,186.6 658.0,185.0" fill="none" stroke="#0d9488" stroke-width="1.8" stroke-linejoin="round"/>
<text x="619.0" y="226.0" font-size="10.5" text-anchor="middle" fill="#64748b">三角</text>
<text x="394.0" y="151.0" font-size="10.5" fill="#64748b">同峰值对齐(不是同 Vrms)</text>
<text x="394.0" y="151.0" font-size="10.5" fill="#64748b">同设 Vpp 2.828 V(不是同有效值)</text>
<text x="384.0" y="244.0" font-size="11" font-weight="700" fill="#0d9488">注入</text>
<text x="420.0" y="244.0" font-size="11.5" fill="#64748b">同峰值 1.414 V 改方波 / 三角(面板有效值各</text>
<text x="420.0" y="260.0" font-size="11.5" fill="#64748b">异)</text>
<text x="420.0" y="244.0" font-size="11.5" fill="#64748b">同设 Vpp 2.828 V 改方波 / 三角(面板有效</text>
<text x="420.0" y="260.0" font-size="11.5" fill="#64748b">值各异)</text>
<text x="384.0" y="280.0" font-size="11" font-weight="700" fill="#0d9488">判据</text>
<text x="420.0" y="280.0" font-size="11.5" fill="#0f172a">读数只跟基波:方波 ≈1278、三角 ≈817,±2 %</text>
<text x="384.0" y="300.0" font-size="11" font-weight="700" fill="#0d9488">出口</text>
<text x="384.0" y="300.0" font-size="11" font-weight="700" fill="#0d9488">读数</text>
<text x="420.0" y="300.0" font-size="11.5" fill="#64748b">meas: ua_mv;抬头记万用表响应类型</text>
<rect x="698.0" y="106.0" width="314.0" height="246.0" rx="10" fill="#f0fdf4" stroke="#16a34a" stroke-width="2"/>
<text x="710.0" y="132.0" font-size="15" font-weight="700" fill="#0f172a">相位轮</text>
<text x="1000.0" y="132.0" font-size="10.5" text-anchor="end" font-weight="700" fill="#16a34a">定量 · 取段</text>
<text x="1000.0" y="132.0" font-size="10.5" text-anchor="end" font-weight="700" fill="#16a34a">定量 · 录波</text>
<rect x="710.0" y="142.0" width="290.0" height="86.0" rx="6" fill="#ffffff" stroke="#cbd5e1" stroke-width="1"/>
<line x1="714.0" y1="185.0" x2="996.0" y2="185.0" stroke="#94a3b8" stroke-width="0.8" stroke-dasharray="3 3"/>
<polyline points="720.0,185.0 721.9,183.4 723.9,181.8 725.8,180.2 727.8,178.6 729.7,177.1 731.7,175.6 733.6,174.1 735.5,172.7 737.5,171.4 739.4,170.1 741.4,168.9 743.3,167.7 745.3,166.7 747.2,165.7 749.1,164.8 751.1,164.0 753.0,163.3 755.0,162.7 756.9,162.2 758.8,161.8 760.8,161.5 762.7,161.3 764.7,161.2 766.6,161.3 768.6,161.4 770.5,161.7 772.4,162.0 774.4,162.5 776.3,163.1 778.3,163.7 780.2,164.5 782.2,165.4 784.1,166.3 786.0,167.4 788.0,168.5 789.9,169.7 791.9,170.9 793.8,172.3 795.8,173.7 797.7,175.1 799.6,176.6 801.6,178.1 803.5,179.7 805.5,181.3 807.4,182.9 809.4,184.5 811.3,186.1 813.2,187.7 815.2,189.3 817.1,190.8 819.1,192.4 821.0,193.9 822.9,195.4 824.9,196.8 826.8,198.2 828.8,199.5 830.7,200.7 832.7,201.9 834.6,203.0 836.5,204.0 838.5,204.9 840.4,205.8 842.4,206.5 844.3,207.1 846.3,207.7 848.2,208.1 850.1,208.4 852.1,208.6 854.0,208.7 856.0,208.7 857.9,208.6 859.9,208.4 861.8,208.1 863.7,207.7 865.7,207.1 867.6,206.5 869.6,205.8 871.5,204.9 873.5,204.0 875.4,203.0 877.3,201.9 879.3,200.7 881.2,199.5 883.2,198.2 885.1,196.8 887.1,195.4 889.0,193.9 890.9,192.4 892.9,190.8 894.8,189.3 896.8,187.7 898.7,186.1 900.6,184.5 902.6,182.9 904.5,181.3 906.5,179.7 908.4,178.1 910.4,176.6 912.3,175.1 914.2,173.7 916.2,172.3 918.1,170.9 920.1,169.7 922.0,168.5 924.0,167.4 925.9,166.3 927.8,165.4 929.8,164.5 931.7,163.7 933.7,163.1 935.6,162.5 937.6,162.0 939.5,161.7 941.4,161.4 943.4,161.3 945.3,161.2 947.3,161.3 949.2,161.5 951.2,161.8 953.1,162.2 955.0,162.7 957.0,163.3 958.9,164.0 960.9,164.8 962.8,165.7 964.7,166.7 966.7,167.7 968.6,168.9 970.6,170.1 972.5,171.4 974.5,172.7 976.4,174.1 978.3,175.6 980.3,177.1 982.2,178.6 984.2,180.2 986.1,181.8 988.1,183.4 990.0,185.0" fill="none" stroke="#16a34a" stroke-width="2" stroke-linejoin="round"/>
@@ -45,16 +44,17 @@
<text x="720.0" y="226.0" font-size="10.5" font-weight="700" fill="#16a34a">UA 0° 实线</text>
<text x="798.0" y="226.0" font-size="10.5" font-weight="700" fill="#e11d48">UN +90° 红虚线</text>
<text x="710.0" y="244.0" font-size="11" font-weight="700" fill="#16a34a">注入</text>
<text x="746.0" y="244.0" font-size="11.5" fill="#64748b">UA(R31)与 UN(R28)同源同幅 1.000 Vrms</text>
<text x="710.0" y="264.0" font-size="11" font-weight="700" fill="#16a34a">判据</text>
<text x="746.0" y="264.0" font-size="11.5" fill="#0f172a">同段内相位差 ≈0°,B 通道改 90° 应跟到 ≈90</text>
<text x="746.0" y="280.0" font-size="11.5" fill="#0f172a">°,±2°</text>
<text x="710.0" y="300.0" font-size="11" font-weight="700" fill="#16a34a">出口</text>
<text x="746.0" y="300.0" font-size="11.5" fill="#64748b">wave_read.py fft 定量;phasor(hb) 只核</text>
<text x="746.0" y="316.0" font-size="11.5" fill="#64748b">象限</text>
<text x="746.0" y="244.0" font-size="11.5" fill="#64748b">UA(R31)与 UN(R28)同源同幅 Vpp 2.828 </text>
<text x="746.0" y="260.0" font-size="11.5" fill="#64748b">V</text>
<text x="710.0" y="280.0" font-size="11" font-weight="700" fill="#16a34a">判据</text>
<text x="746.0" y="280.0" font-size="11.5" fill="#0f172a">同段内相位差 ≈0°,B 通道改 90° 应跟到 ≈90</text>
<text x="746.0" y="296.0" font-size="11.5" fill="#0f172a">°,±2°</text>
<text x="710.0" y="316.0" font-size="11" font-weight="700" fill="#16a34a">读数</text>
<text x="746.0" y="316.0" font-size="11.5" fill="#64748b">wave_read.py fft 定量;phasor(hb) 只核</text>
<text x="746.0" y="332.0" font-size="11.5" fill="#64748b">象限</text>
<rect x="46.0" y="366.0" width="314.0" height="246.0" rx="10" fill="#fffbeb" stroke="#d97706" stroke-width="2"/>
<text x="58.0" y="392.0" font-size="15" font-weight="700" fill="#0f172a">测频轮</text>
<text x="348.0" y="392.0" font-size="10.5" text-anchor="end" font-weight="700" fill="#d97706">A 档无数 = 过</text>
<text x="348.0" y="392.0" font-size="10.5" text-anchor="end" font-weight="700" fill="#d97706">测不出数 = 过</text>
<rect x="58.0" y="402.0" width="290.0" height="86.0" rx="6" fill="#ffffff" stroke="#cbd5e1" stroke-width="1"/>
<line x1="62.0" y1="445.0" x2="344.0" y2="445.0" stroke="#94a3b8" stroke-width="0.8" stroke-dasharray="3 3"/>
<polyline points="73.0,445.0 73.8,443.6 74.6,442.3 75.4,440.9 76.2,439.6 77.0,438.3 77.8,437.0 78.7,435.8 79.5,434.5 80.3,433.3 81.1,432.2 81.9,431.0 82.7,430.0 83.5,428.9 84.3,428.0 85.1,427.0 85.9,426.2 86.7,425.4 87.5,424.7 88.4,424.0 89.2,423.4 90.0,422.9 90.8,422.4 91.6,422.0 92.4,421.7 93.2,421.5 94.0,421.3 94.8,421.2 95.6,421.2 96.4,421.3 97.2,421.5 98.1,421.7 98.9,422.0 99.7,422.4 100.5,422.9 101.3,423.4 102.1,424.0 102.9,424.7 103.7,425.4 104.5,426.2 105.3,427.0 106.1,428.0 106.9,428.9 107.7,430.0 108.6,431.0 109.4,432.2 110.2,433.3 111.0,434.5 111.8,435.8 112.6,437.0 113.4,438.3 114.2,439.6 115.0,440.9 115.8,442.3 116.6,443.6 117.4,445.0 118.3,446.4 119.1,447.7 119.9,449.1 120.7,450.4 121.5,451.7 122.3,453.0 123.1,454.2 123.9,455.5 124.7,456.7 125.5,457.8 126.3,459.0 127.1,460.0 127.9,461.1 128.8,462.0 129.6,463.0 130.4,463.8 131.2,464.6 132.0,465.3 132.8,466.0 133.6,466.6 134.4,467.1 135.2,467.6 136.0,468.0 136.8,468.3 137.6,468.5 138.5,468.7 139.3,468.8 140.1,468.8 140.9,468.7 141.7,468.5 142.5,468.3 143.3,468.0 144.1,467.6 144.9,467.1 145.7,466.6 146.5,466.0 147.3,465.3 148.2,464.6 149.0,463.8 149.8,463.0 150.6,462.0 151.4,461.1 152.2,460.0 153.0,459.0" fill="none" stroke="#d97706" stroke-width="1.8" stroke-linejoin="round"/>
@@ -66,10 +66,10 @@
<text x="58.0" y="504.0" font-size="11" font-weight="700" fill="#d97706">注入</text>
<text x="94.0" y="504.0" font-size="11.5" fill="#64748b">UA 同幅值轮接法,扫 45 / 50 / 55 Hz</text>
<text x="58.0" y="524.0" font-size="11" font-weight="700" fill="#d97706">判据</text>
<text x="94.0" y="524.0" font-size="11.5" fill="#0f172a">A 档如实报不可测:valid=0、UI 显 --;报 5</text>
<text x="94.0" y="540.0" font-size="11.5" fill="#0f172a">0.00 反而是 bug</text>
<text x="58.0" y="560.0" font-size="11" font-weight="700" fill="#d97706">出口</text>
<text x="94.0" y="560.0" font-size="11.5" fill="#64748b">freq(hb) 0.01 Hz;UI Hz、104 0x401D</text>
<text x="94.0" y="524.0" font-size="11.5" fill="#0f172a">如实报不可测(现状固件):valid=0、UI 显 -</text>
<text x="94.0" y="540.0" font-size="11.5" fill="#0f172a">-;报 50.00 反而是 bug</text>
<text x="58.0" y="560.0" font-size="11" font-weight="700" fill="#d97706">读数</text>
<text x="94.0" y="560.0" font-size="11.5" fill="#64748b">freq(hb) 0.01 Hz;UI Hz</text>
<rect x="372.0" y="366.0" width="314.0" height="246.0" rx="10" fill="#fff1f2" stroke="#e11d48" stroke-width="2"/>
<text x="384.0" y="392.0" font-size="15" font-weight="700" fill="#0f172a">削顶轮</text>
<text x="674.0" y="392.0" font-size="10.5" text-anchor="end" font-weight="700" fill="#e11d48">负向 · 单独日志</text>
@@ -81,26 +81,27 @@
<text x="420.0" y="504.0" font-size="11.5" fill="#64748b">UB(R52):DC −1.00 V 保持 ≥5 s,或 2.0 </text>
<text x="420.0" y="520.0" font-size="11.5" fill="#64748b">Hz 正弦</text>
<text x="384.0" y="540.0" font-size="11" font-weight="700" fill="#e11d48">判据</text>
<text x="420.0" y="540.0" font-size="11.5" fill="#0f172a">连续 20 拍贴底 → rail / edge 锁存 + 104 </text>
<text x="420.0" y="556.0" font-size="11.5" fill="#0f172a">该路 IV 清零;50 Hz 正弦不锁存 = 预期</text>
<text x="384.0" y="576.0" font-size="11" font-weight="700" fill="#e11d48">出口</text>
<text x="420.0" y="576.0" font-size="11.5" fill="#64748b">cal: rail / edge;取段再跑 shape 对表</text>
<text x="420.0" y="540.0" font-size="11.5" fill="#0f172a">连续 20 拍贴底 → rail / edge 锁存;50 Hz</text>
<text x="420.0" y="556.0" font-size="11.5" fill="#0f172a"> 正弦不锁存 = 预期</text>
<text x="384.0" y="576.0" font-size="11" font-weight="700" fill="#e11d48">读数</text>
<text x="420.0" y="576.0" font-size="11.5" fill="#64748b">cal: rail / edge;录波再跑 shape 对表</text>
<rect x="698.0" y="366.0" width="314.0" height="246.0" rx="10" fill="#f5f3ff" stroke="#7c3aed" stroke-width="2"/>
<text x="710.0" y="392.0" font-size="15" font-weight="700" fill="#0f172a">谐波轮</text>
<text x="1000.0" y="392.0" font-size="10.5" text-anchor="end" font-weight="700" fill="#7c3aed">定量 · 取段</text>
<text x="1000.0" y="392.0" font-size="10.5" text-anchor="end" font-weight="700" fill="#7c3aed">定量 · 录波</text>
<rect x="710.0" y="402.0" width="290.0" height="86.0" rx="6" fill="#ffffff" stroke="#cbd5e1" stroke-width="1"/>
<line x1="714.0" y1="445.0" x2="996.0" y2="445.0" stroke="#94a3b8" stroke-width="0.8" stroke-dasharray="3 3"/>
<polyline points="720.0,445.0 721.9,442.2 723.9,439.5 725.8,437.1 727.8,435.0 729.7,433.4 731.7,432.3 733.6,431.6 735.5,431.3 737.5,431.3 739.4,431.4 741.4,431.5 743.3,431.5 745.3,431.3 747.2,430.9 749.1,430.2 751.1,429.2 753.0,428.1 755.0,426.8 756.9,425.7 758.8,424.7 760.8,424.0 762.7,423.7 764.7,423.8 766.6,424.4 768.6,425.5 770.5,427.0 772.4,428.8 774.4,430.7 776.3,432.7 778.3,434.5 780.2,436.0 782.2,437.2 784.1,438.0 786.0,438.5 788.0,438.6 789.9,438.4 791.9,438.0 793.8,437.7 795.8,437.4 797.7,437.4 799.6,437.7 801.6,438.4 803.5,439.4 805.5,440.8 807.4,442.5 809.4,444.4 811.3,446.3 813.2,448.1 815.2,449.7 817.1,451.0 819.1,451.9 821.0,452.5 822.9,452.6 824.9,452.5 826.8,452.2 828.8,451.8 830.7,451.5 832.7,451.4 834.6,451.6 836.5,452.2 838.5,453.1 840.4,454.5 842.4,456.1 844.3,458.0 846.3,459.9 848.2,461.8 850.1,463.5 852.1,464.9 854.0,465.8 856.0,466.3 857.9,466.3 859.9,465.8 861.8,465.0 863.7,464.0 865.7,462.8 867.6,461.6 869.6,460.5 871.5,459.6 873.5,458.9 875.4,458.6 877.3,458.5 879.3,458.5 881.2,458.7 883.2,458.7 885.1,458.6 887.1,458.2 889.0,457.3 890.9,456.1 892.9,454.3 894.8,452.2 896.8,449.7 898.7,446.9 900.6,444.0 902.6,441.2 904.5,438.6 906.5,436.3 908.4,434.4 910.4,433.0 912.3,432.1 914.2,431.5 916.2,431.3 918.1,431.3 920.1,431.4 922.0,431.5 924.0,431.5 925.9,431.2 927.8,430.7 929.8,429.9 931.7,428.8 933.7,427.6 935.6,426.4 937.6,425.3 939.5,424.4 941.4,423.8 943.4,423.7 945.3,424.0 947.3,424.8 949.2,426.0 951.2,427.6 953.1,429.4 955.0,431.4 957.0,433.3 958.9,435.0 960.9,436.5 962.8,437.5 964.7,438.2 966.7,438.5 968.6,438.5 970.6,438.3 972.5,437.9 974.5,437.6 976.4,437.4 978.3,437.4 980.3,437.9 982.2,438.7 984.2,439.8 986.1,441.4 988.1,443.1 990.0,445.0" fill="none" stroke="#7c3aed" stroke-width="2" stroke-linejoin="round"/>
<text x="720.0" y="411.0" font-size="10.5" fill="#64748b">基波 + 2 次 + 5 次</text>
<text x="710.0" y="504.0" font-size="11" font-weight="700" fill="#7c3aed">注入</text>
<text x="746.0" y="504.0" font-size="11.5" fill="#64748b">IA(R19):基波 0.800 + 二次 0.160 + 五</text>
<text x="746.0" y="520.0" font-size="11.5" fill="#64748b">次 0.160 Vrms</text>
<text x="746.0" y="504.0" font-size="11.5" fill="#64748b">IA(R19):分三注,基波 Vpp 2.263、二五次</text>
<text x="746.0" y="520.0" font-size="11.5" fill="#64748b">各 Vpp 0.453</text>
<text x="710.0" y="540.0" font-size="11" font-weight="700" fill="#7c3aed">判据</text>
<text x="746.0" y="540.0" font-size="11.5" fill="#0f172a">Ia2 / Ia5 各 ≈0.160 Vrms,±2 %(最坏峰值</text>
<text x="746.0" y="556.0" font-size="11.5" fill="#0f172a"> 1.58 V 留余量)</text>
<text x="710.0" y="576.0" font-size="11" font-weight="700" fill="#7c3aed">出口</text>
<text x="746.0" y="540.0" font-size="11.5" fill="#0f172a">Ia2 / Ia5 各读数 ≈0.160 V,±2 %(最坏峰</text>
<text x="746.0" y="556.0" font-size="11.5" fill="#0f172a">值 1.58 V 留余量)</text>
<text x="710.0" y="576.0" font-size="11" font-weight="700" fill="#7c3aed">读数</text>
<text x="746.0" y="576.0" font-size="11.5" fill="#64748b">wave_read.py fft --ch 4;UI Ia2 / Ia5 </text>
<text x="746.0" y="592.0" font-size="11.5" fill="#64748b">目检旁证</text>
<line x1="46.0" y1="634.0" x2="1014.0" y2="634.0" stroke="#cbd5e1" stroke-width="1"/>
<text x="46.0" y="656.0" font-size="13" fill="#64748b">顺序与耗时见 §8.6(约 135 min 一趟 session);[ERR] 判读见 §8.7,失败先查 §8.8 分诊表。波形缩略图只表形状,不代表真实幅度刻度。</text>
<text x="46.0" y="656.0" font-size="13" fill="#64748b">六轮已跑完(2026-11-02 / 11-04):实测结论见 docs/硬件平台/ADC通道映射说明.md §8.2,谐波 B 行已归因板端前端 RC(fc≈796 Hz)。波形缩略图只表</text>
<text x="46.0" y="675.0" font-size="13" fill="#64748b">形状,不代表真实幅度刻度。</text>
</svg>

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 27 KiB

+75 -75
View File
@@ -1,5 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1560" height="1192" viewBox="0 0 1560 1192" font-family="Microsoft YaHei, Segoe UI, PingFang SC, sans-serif">
<rect x="0" y="0" width="1560" height="1192" fill="#ffffff"/>
<svg xmlns="http://www.w3.org/2000/svg" width="1560" height="1240" viewBox="0 0 1560 1240" font-family="Microsoft YaHei, Segoe UI, PingFang SC, sans-serif">
<rect x="0" y="0" width="1560" height="1240" fill="#ffffff"/>
<text x="26" y="40" font-size="20" font-weight="700" fill="#0f172a">STM32F4-Base 项目分层架构</text>
<text x="26" y="62" font-size="13" fill="#64748b">STM32F407ZGTx @168MHz · FreeRTOS V10.3.1 (CMSIS-RTOS2) · 上层只依赖相邻下层</text>
<rect x="26" y="78" width="1508" height="92" rx="12" fill="#eff6ff" stroke="#2563eb" stroke-opacity="0.45"/>
@@ -7,7 +7,7 @@
<text x="134" y="104" font-size="12" fill="#64748b">顶层共享配置 · 被 UI 与基础服务共用</text>
<rect x="44" y="116" width="489" height="38" rx="8" fill="#ffffff" stroke="#2563eb" stroke-opacity="0.55"/>
<text x="288" y="139" font-size="13" fill="#1e293b" text-anchor="middle">net_cfg(网口配置:IP/掩码/网关/MAC · /config.ini [network] 段)</text>
<rect x="26" y="214" width="741" height="284" rx="12" fill="#f5f3ff" stroke="#7c3aed" stroke-opacity="0.45"/>
<rect x="26" y="214" width="741" height="332" rx="12" fill="#f5f3ff" stroke="#7c3aed" stroke-opacity="0.45"/>
<text x="44" y="240" font-size="17" font-weight="700" fill="#7c3aed">② UI 层</text>
<text x="129" y="240" font-size="12" fill="#64748b">Drivers/BSP/UI · 一份显存三出(模拟器/屏板/远程)</text>
<rect x="44" y="252" width="162" height="38" rx="8" fill="#ffffff" stroke="#7c3aed" stroke-opacity="0.55"/>
@@ -32,7 +32,7 @@
<text x="330" y="419" font-size="13" fill="#1e293b" text-anchor="middle">ui_font_cn_12(中文字体)</text>
<rect x="444" y="396" width="172" height="38" rx="8" fill="#ffffff" stroke="#7c3aed" stroke-opacity="0.55"/>
<text x="530" y="419" font-size="13" fill="#1e293b" text-anchor="middle">ui_deco(浅 V 装饰)</text>
<rect x="793" y="214" width="741" height="284" rx="12" fill="#f0fdfa" stroke="#0d9488" stroke-opacity="0.45"/>
<rect x="793" y="214" width="741" height="332" rx="12" fill="#f0fdfa" stroke="#0d9488" stroke-opacity="0.45"/>
<text x="811" y="240" font-size="17" font-weight="700" fill="#0d9488">③ 基础服务层</text>
<text x="935" y="240" font-size="12" fill="#64748b">应用侧服务 / 编排</text>
<rect x="811" y="252" width="170" height="38" rx="8" fill="#ffffff" stroke="#0d9488" stroke-opacity="0.55"/>
@@ -55,77 +55,77 @@
<text x="960" y="467" font-size="13" fill="#1e293b" text-anchor="middle">cfg_file · prot_set_store(配置引擎)</text>
<rect x="1119" y="444" width="148" height="38" rx="8" fill="#ffffff" stroke="#0d9488" stroke-opacity="0.55"/>
<text x="1193" y="467" font-size="13" fill="#1e293b" text-anchor="middle">lftpd(FTP :21)</text>
<rect x="1277" y="444" width="227" height="38" rx="8" fill="#ffffff" stroke="#0d9488" stroke-opacity="0.55"/>
<text x="1391" y="467" font-size="13" fill="#1e293b" text-anchor="middle">time_sync(TCP 对时 :8888)</text>
<rect x="26" y="542" width="1508" height="140" rx="12" fill="#f0fdf4" stroke="#16a34a" stroke-opacity="0.45"/>
<text x="44" y="568" font-size="17" font-weight="700" fill="#16a34a">④ 中间件层</text>
<text x="151" y="568" font-size="12" fill="#64748b">通用库 / 协议栈</text>
<rect x="44" y="580" width="675" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="381" y="603" font-size="13" fill="#1e293b" text-anchor="middle">net_socket / net_select / net_events / net_listener / net_pending(BSD API + 阻塞模型)</text>
<rect x="729" y="580" width="147" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="803" y="603" font-size="13" fill="#1e293b" text-anchor="middle">FatFs(文件系统)</text>
<rect x="887" y="580" width="186" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="980" y="603" font-size="13" fill="#1e293b" text-anchor="middle">nand_ftl(dhara FTL)</text>
<rect x="1083" y="580" width="164" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="1165" y="603" font-size="13" fill="#1e293b" text-anchor="middle">LVGL v9.3(图形库)</text>
<rect x="1258" y="580" width="177" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="1347" y="603" font-size="13" fill="#1e293b" text-anchor="middle">sys_clock(墙钟基准)</text>
<rect x="44" y="628" width="219" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="153" y="651" font-size="13" fill="#1e293b" text-anchor="middle">task_watchdog(IWDG 判定)</text>
<rect x="26" y="726" width="1508" height="92" rx="12" fill="#fffbeb" stroke="#d97706" stroke-opacity="0.45"/>
<text x="44" y="752" font-size="17" font-weight="700" fill="#d97706">⑤ 驱动层</text>
<text x="134" y="752" font-size="12" fill="#64748b">Drivers/BSP · 芯片时序/中断</text>
<rect x="44" y="764" width="178" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="133" y="787" font-size="13" fill="#1e293b" text-anchor="middle">ch395f(SPI2 + DMA)</text>
<rect x="232" y="764" width="163" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="314" y="787" font-size="13" fill="#1e293b" text-anchor="middle">gd5f2gq5ue(SPI1)</text>
<rect x="406" y="764" width="195" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="503" y="787" font-size="13" fill="#1e293b" text-anchor="middle">tpafe5160(并行 16 位)</text>
<rect x="611" y="764" width="133" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="677" y="787" font-size="13" fill="#1e293b" text-anchor="middle">sd2506(I2C1)</text>
<rect x="754" y="764" width="171" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="840" y="787" font-size="13" fill="#1e293b" text-anchor="middle">rs485(UART4 + DE)</text>
<rect x="935" y="764" width="388" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="1130" y="787" font-size="13" fill="#1e293b" text-anchor="middle">sb_link · sb_proto(屏板链路 · USART1 700 kbaud)</text>
<rect x="26" y="862" width="1508" height="92" rx="12" fill="#f1f5f9" stroke="#475569" stroke-opacity="0.45"/>
<text x="44" y="888" font-size="17" font-weight="700" fill="#475569">⑥ 内核 / HAL</text>
<text x="176" y="888" font-size="12" fill="#64748b">调度 · 外设抽象</text>
<rect x="44" y="900" width="329" height="38" rx="8" fill="#ffffff" stroke="#475569" stroke-opacity="0.55"/>
<text x="208" y="923" font-size="13" fill="#1e293b" text-anchor="middle">FreeRTOS V10.3.1(CMSIS-RTOS2 · heap_4)</text>
<rect x="383" y="900" width="189" height="38" rx="8" fill="#ffffff" stroke="#475569" stroke-opacity="0.55"/>
<text x="478" y="923" font-size="13" fill="#1e293b" text-anchor="middle">STM32 HAL(时基 TIM7)</text>
<rect x="582" y="900" width="144" height="38" rx="8" fill="#ffffff" stroke="#475569" stroke-opacity="0.55"/>
<text x="655" y="923" font-size="13" fill="#1e293b" text-anchor="middle">CMSIS / 启动文件</text>
<rect x="26" y="998" width="1508" height="140" rx="12" fill="#fff1f2" stroke="#e11d48" stroke-opacity="0.45"/>
<text x="44" y="1024" font-size="17" font-weight="700" fill="#e11d48">⑦ 硬件</text>
<text x="117" y="1024" font-size="12" fill="#64748b">STM32F407ZGTx @168MHz</text>
<rect x="44" y="1036" width="179" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="133" y="1059" font-size="13" fill="#1e293b" text-anchor="middle">CH395F 以太网(SPI2)</text>
<rect x="233" y="1036" width="201" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="334" y="1059" font-size="13" fill="#1e293b" text-anchor="middle">GD5F2GQ5UE NAND(SPI1)</text>
<rect x="445" y="1036" width="182" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="536" y="1059" font-size="13" fill="#1e293b" text-anchor="middle">TPAFE5160 ADC(并行)</text>
<rect x="637" y="1036" width="163" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="718" y="1059" font-size="13" fill="#1e293b" text-anchor="middle">SD2506 RTC(I2C1)</text>
<rect x="810" y="1036" width="202" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="912" y="1059" font-size="13" fill="#1e293b" text-anchor="middle">RS-485(UART4 · 未接线)</text>
<rect x="1023" y="1036" width="219" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="1133" y="1059" font-size="13" fill="#1e293b" text-anchor="middle">屏板(USART1 · 700 kbaud)</text>
<rect x="1253" y="1036" width="249" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="1377" y="1059" font-size="13" fill="#1e293b" text-anchor="middle">RS232#1 日志(UART5 · 115200)</text>
<rect x="44" y="1084" width="77" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="82" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">6x LED</text>
<rect x="811" y="492" width="355" height="38" rx="8" fill="#ffffff" stroke="#0d9488" stroke-opacity="0.55"/>
<text x="988" y="515" font-size="13" fill="#1e293b" text-anchor="middle">time_sntp(SNTP 对时,UDP 出向;:8888 已退役)</text>
<rect x="26" y="590" width="1508" height="140" rx="12" fill="#f0fdf4" stroke="#16a34a" stroke-opacity="0.45"/>
<text x="44" y="616" font-size="17" font-weight="700" fill="#16a34a">④ 中间件层</text>
<text x="151" y="616" font-size="12" fill="#64748b">通用库 / 协议栈</text>
<rect x="44" y="628" width="675" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="381" y="651" font-size="13" fill="#1e293b" text-anchor="middle">net_socket / net_select / net_events / net_listener / net_pending(BSD API + 阻塞模型)</text>
<rect x="729" y="628" width="147" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="803" y="651" font-size="13" fill="#1e293b" text-anchor="middle">FatFs(文件系统)</text>
<rect x="887" y="628" width="186" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="980" y="651" font-size="13" fill="#1e293b" text-anchor="middle">nand_ftl(dhara FTL)</text>
<rect x="1083" y="628" width="164" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="1165" y="651" font-size="13" fill="#1e293b" text-anchor="middle">LVGL v9.3(图形库)</text>
<rect x="1258" y="628" width="177" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="1347" y="651" font-size="13" fill="#1e293b" text-anchor="middle">sys_clock(墙钟基准)</text>
<rect x="44" y="676" width="219" height="38" rx="8" fill="#ffffff" stroke="#16a34a" stroke-opacity="0.55"/>
<text x="153" y="699" font-size="13" fill="#1e293b" text-anchor="middle">task_watchdog(IWDG 判定)</text>
<rect x="26" y="774" width="1508" height="92" rx="12" fill="#fffbeb" stroke="#d97706" stroke-opacity="0.45"/>
<text x="44" y="800" font-size="17" font-weight="700" fill="#d97706">⑤ 驱动层</text>
<text x="134" y="800" font-size="12" fill="#64748b">Drivers/BSP · 芯片时序/中断</text>
<rect x="44" y="812" width="178" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="133" y="835" font-size="13" fill="#1e293b" text-anchor="middle">ch395f(SPI2 + DMA)</text>
<rect x="232" y="812" width="163" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="314" y="835" font-size="13" fill="#1e293b" text-anchor="middle">gd5f2gq5ue(SPI1)</text>
<rect x="406" y="812" width="195" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="503" y="835" font-size="13" fill="#1e293b" text-anchor="middle">tpafe5160(并行 16 位)</text>
<rect x="611" y="812" width="133" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="677" y="835" font-size="13" fill="#1e293b" text-anchor="middle">sd2506(I2C1)</text>
<rect x="754" y="812" width="171" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="840" y="835" font-size="13" fill="#1e293b" text-anchor="middle">rs485(UART4 + DE)</text>
<rect x="935" y="812" width="388" height="38" rx="8" fill="#ffffff" stroke="#d97706" stroke-opacity="0.55"/>
<text x="1130" y="835" font-size="13" fill="#1e293b" text-anchor="middle">sb_link · sb_proto(屏板链路 · USART1 700 kbaud)</text>
<rect x="26" y="910" width="1508" height="92" rx="12" fill="#f1f5f9" stroke="#475569" stroke-opacity="0.45"/>
<text x="44" y="936" font-size="17" font-weight="700" fill="#475569">⑥ 内核 / HAL</text>
<text x="176" y="936" font-size="12" fill="#64748b">调度 · 外设抽象</text>
<rect x="44" y="948" width="329" height="38" rx="8" fill="#ffffff" stroke="#475569" stroke-opacity="0.55"/>
<text x="208" y="971" font-size="13" fill="#1e293b" text-anchor="middle">FreeRTOS V10.3.1(CMSIS-RTOS2 · heap_4)</text>
<rect x="383" y="948" width="189" height="38" rx="8" fill="#ffffff" stroke="#475569" stroke-opacity="0.55"/>
<text x="478" y="971" font-size="13" fill="#1e293b" text-anchor="middle">STM32 HAL(时基 TIM7)</text>
<rect x="582" y="948" width="144" height="38" rx="8" fill="#ffffff" stroke="#475569" stroke-opacity="0.55"/>
<text x="655" y="971" font-size="13" fill="#1e293b" text-anchor="middle">CMSIS / 启动文件</text>
<rect x="26" y="1046" width="1508" height="140" rx="12" fill="#fff1f2" stroke="#e11d48" stroke-opacity="0.45"/>
<text x="44" y="1072" font-size="17" font-weight="700" fill="#e11d48">⑦ 硬件</text>
<text x="117" y="1072" font-size="12" fill="#64748b">STM32F407ZGTx @168MHz</text>
<rect x="44" y="1084" width="179" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="133" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">CH395F 以太网(SPI2)</text>
<rect x="233" y="1084" width="201" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="334" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">GD5F2GQ5UE NAND(SPI1)</text>
<rect x="445" y="1084" width="182" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="536" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">TPAFE5160 ADC(并行)</text>
<rect x="637" y="1084" width="163" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="718" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">SD2506 RTC(I2C1)</text>
<rect x="810" y="1084" width="202" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="912" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">RS-485(UART4 · 未接线)</text>
<rect x="1023" y="1084" width="219" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="1133" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">屏板(USART1 · 700 kbaud)</text>
<rect x="1253" y="1084" width="249" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="1377" y="1107" font-size="13" fill="#1e293b" text-anchor="middle">RS232#1 日志(UART5 · 115200)</text>
<rect x="44" y="1132" width="77" height="38" rx="8" fill="#ffffff" stroke="#e11d48" stroke-opacity="0.55"/>
<text x="82" y="1155" font-size="13" fill="#1e293b" text-anchor="middle">6x LED</text>
<line x1="780.0" y1="176.0" x2="780.0" y2="199.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 780.0 206.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="396.5" y1="504.0" x2="396.5" y2="527.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 396.5 534.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="1163.5" y1="504.0" x2="1163.5" y2="527.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 1163.5 534.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="780.0" y1="688.0" x2="780.0" y2="711.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 780.0 718.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="780.0" y1="824.0" x2="780.0" y2="847.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 780.0 854.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="780.0" y1="960.0" x2="780.0" y2="983.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 780.0 990.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<text x="26" y="1174" font-size="12" fill="#94a3b8">上层只依赖相邻下层(单向);UI 层与基础服务层同级并列,均使用顶层 net_cfg。跨层调用细节见 docs/架构设计/项目架构总览.md §1.2</text>
<line x1="396.5" y1="552.0" x2="396.5" y2="575.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 396.5 582.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="1163.5" y1="552.0" x2="1163.5" y2="575.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 1163.5 582.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="780.0" y1="736.0" x2="780.0" y2="759.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 780.0 766.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="780.0" y1="872.0" x2="780.0" y2="895.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 780.0 902.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<line x1="780.0" y1="1008.0" x2="780.0" y2="1031.0" stroke="#94a3b8" stroke-width="2.5"/>
<path d="M 780.0 1038.0 l -6 -9 h 12 z" fill="#94a3b8"/>
<text x="26" y="1222" font-size="12" fill="#94a3b8">上层只依赖相邻下层(单向);UI 层与基础服务层同级并列,均使用顶层 net_cfg。跨层调用细节见 docs/架构设计/项目架构总览.md §1.2</text>
</svg>

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

+25 -19
View File
@@ -126,7 +126,8 @@ flowchart LR
end
DEV -- "USB:ST-Link 下载器" --> TGT
DEV -- "USB→RS-232 适配器:RS232#1 @115200 调试日志" --> TGT
TGT -- "以太网 CH395F<br/>FTP:21 / 对时:8888 / 远程显示:7003" --> RMT
TGT -- "以太网 CH395F<br/>FTP:21 / 远程显示:7003" --> RMT
TGT -. "对时:SNTP 客户端 UDP 123 出向(:8888 已退役)" .-> NTP["现场/公网 NTP 源"]
```
| 环境 | 角色 | 必需性 |
@@ -153,7 +154,7 @@ flowchart LR
1. **开关柜现场部署**:设备上电 → 按 `/config.ini` 出厂 IP 组网 → 主站连工厂默认 :2404 总召 →
现场用屏板看测量、按按键翻菜单;死机由看门狗自恢复(无需到场)。
2. **远程运维**:PC 经 :7003 看同一份 UI、注键操作;FTP 取 `/log`(运行/自检/SOE 记录)
与 `/config.ini`;改 IP 后 2~5 s 生效不重启;PC 推 :8888 对时。
与 `/config.ini`;改 IP 后 2~5 s 生效不重启;SNTP 出向对时(原 PC 推 :8888 已退役)。
3. **脱离 PC 独立带屏运行**:串口屏板直连 USART1(700 kbaud),主机 275 ms 召唤、
≤200 ms 回 4208 B 帧(3200 B 显存 + 状态灯掩码 + info)——无 PC 也能看与按(§5.16)。
4. **保护运行(等标定解锁)**:1 kHz 采样 → 全周傅氏相量 → 20 ms 判据节拍 → 动作只落
@@ -250,7 +251,7 @@ flowchart LR
|---|---|---|---|
| P0 | FR-NET 网络通信(§5.1) | ✅ | CH395F + BSD 抽象 + 单连接自愈 |
| P0 | FR-STO 存储(§5.2) | ✅ | SPI NAND→dhara→FatFs,卷自愈 |
| P0 | FR-TIME 时间(§5.3) | ✅ | SD2506 墙钟 + :8888 对时(2038 已知限) |
| P0 | FR-TIME 时间(§5.3) | ✅ | SD2506 墙钟 + SNTP 对时(原 :8888 已退役;2038 已知限) |
| P0 | FR-CFG 配置引擎(§5.4) | ✅ | INI 段键表 + 外科保存 + 免重启生效 |
| P0 | FR-LOG 记录与日志(§5.5) | ✅ | 定长记录 + 控制台单写者 |
| P0 | FR-WD 看门狗(§5.7) | ✅ | 心跳位图 + 复位原因 + Fault 现场 |
@@ -319,14 +320,15 @@ flowchart LR
- 实现:`sys_clock_init()` 读一次 RTC 建基准(无效时按默认值自动校时);base+delta 法;30 天惰性再基准化(防 49.7 天 tick 回绕);`sys_clock_get_str()` → `"YYYY-MM-DD HH:MM:SS"`。
- 判据:日志时间戳真实正确;主机侧单测 100 断言点通过。
**FR-TIME-2 网络对时**
**FR-TIME-2 网络对时**(已退役 2026-11-04,由 FR-TIME-3 接替)
- 需求:PC 主动通过 TCP :8888 推送时间到设备,设备写回 RTC。
- 实现:`timeSyncTask` 等 `NET_READY` → TCP listen :8888 → 收 PC 推送 → 写 RTC;30 s 无包则掉线重建监听。
- 判据:对时后设备墙钟更新、日志时间戳正确。
- 退役:**已由 FR-TIME-3 SNTP 取代并退役**——`:8888` 监听、8 字节 "TIME" 协议、PC 推送器随
工单 #78 删除;网络校时唯一入口 = SNTP(FR-TIME-3)。历史实现见 git 历史与
`docs/子系统设计/系统墙钟时间维护说明.md` §15。
**FR-TIME-3 SNTP 校时** ✅(2026-11-04)
- 需求:设备作 SNTP(RFC 4330)客户端从配置的 IPv4 服务器经 UDP/123 取时写回 RTC;使能、主/备服务器、轮询周期可配(UI「SNTP 设置」页或 `/config.ini` `[sntp]` 段,保存后随下一轮生效)。
- 实现:`timeSyncTask` 复用 8888 事件循环(≤50 ms 等待切片,不饿任务狗与 IWDG);48 字节报文由 vendored coreSNTP 序列化器(`Lib/coreSNTP/`)编解码,节奏与判据在本方;防伪 = OriginTimestamp 须逐位等于发出的 T1(含随机小数位),mode / stratum / 闰秒指示 / Kiss-o'-Death 按 RFC 拒绝;主备轮换 + 失败指数退避(5 s 起、60 s 封顶)+ 首轮 1~5 分钟随机;成功时 |offset| < 2 s 只记日志不阶跃,更大偏差阶跃写回 SD2506——钟面 = 本地时间(UTC+8,与 8888 同一时基口径,取舍见 docs/任务规划/UI补齐.md §4 时基口径注);首个校验通过的同步置 `SYS_EVT_TIMESYNC_READY`。
- 实现:`timeSyncTask` 200 ms 校时节拍驱动(`time_sync.c` v2.0,:8888 退役后任务即纯宿主;≤50 ms 收片切片,不饿任务狗与 IWDG);48 字节报文由 vendored coreSNTP 序列化器(`Lib/coreSNTP/`)编解码,节奏与判据在本方;防伪 = OriginTimestamp 须逐位等于发出的 T1(含随机小数位),mode / stratum / 闰秒指示 / Kiss-o'-Death 按 RFC 拒绝;主备轮换 + 失败指数退避(5 s 起、60 s 封顶)+ 首轮 1~5 分钟随机;成功时 |offset| < 2 s 只记日志不阶跃,更大偏差阶跃写回 SD2506——钟面 = 本地时间(UTC+8,沿用本地钟面时基口径,取舍见 docs/任务规划/UI补齐.md §4 时基口径注);首个校验通过的同步置 `SYS_EVT_TIMESYNC_READY`。
- 判据:主机单测 `test/host/sntp`(报文格式 / 伪造拒收 / KoD 轮换 / 退避与周期 / 阶跃域守卫);真机 = 使能并配置服务器后时钟与时间源一致、`[SNTP] step offset=` 日志在场(台架窗口统一做)。
> **已知限制**:uint32 epoch → **2038 年**上限。
@@ -347,7 +349,7 @@ flowchart LR
**FR-CFG-3 变更检测与立即应用**
- 需求:FTP 上传配置后无需重启即生效;网络段变化触发网络重建。
- 实现:`defaultTask` 每 2 s `f_stat` 比对 (size, mtime),连续 2 次稳定才重载(沉降去抖);`[network]` 段变化 → `SYS_EVT_NET_RECONFIG` → 网络重建(代次 +1,服务自愈)。
- 实现:`defaultTask` 每 2 s `f_stat` 比对 (size, mtime),连续 2 次稳定才重载(沉降去抖);重载/保存前过视图一致性守卫(2026-11-05)——读到的视图与 stat 不符(卷层旧/短视图)时拒绝应用(RAM 保持当前配置、2s 重试)并拒绝按坏视图落盘,杜绝坏视图打回出厂默认与吞段(issue #73);`[network]` 段变化 → `SYS_EVT_NET_RECONFIG` → 网络重建(代次 +1,服务自愈)。
- 判据:FTP 改 IP 后 2~5 s 生效(网络重建含等链路 ≤3 s)。
**FR-CFG-4 旧档迁移**(已取消 · 2026-10-10)
@@ -611,7 +613,7 @@ flowchart LR
- 判据:动作路径零 NAND I/O(protectTask 静态链 872 B 改前后不变);104 时标 = 事件上送时刻,
与落盘记录(事件发生时刻)差 ≤ 一拍 + 排空延迟(≤50 ms)。
**FR-SOE-3 记录体系(✅ 软件面已落地;真机判据待台架)**
**FR-SOE-3 记录体系(✅ 软件面已落地;真机判据已台架复核 2026-11-06)**
- 现状:七类文本记录(运行 / 自检 / 事故 / 告警 / 启动 / 操作 / 遥控)+ 二进制 SOE 已落地,
「记录类型 = 日志 ID 本身」(一类记录一个文件,记录体内无类型字段位);UI 六页已绑
(记录 5 页 + 运行报告,2026-10-28)。运行报告的四个数取自 boot_stats(SD2506 用户 SRAM
@@ -619,8 +621,10 @@ flowchart LR
(口径 docs/UI设计/UI_数据供给设计说明.md §4.4)。
- 判据:五类记录各有写入点、可翻最近 20 条、空记录明确显示"无记录"、共用 reader——**软件面已满足**
(空态与四个范围标签由 74 张像素黄金钉住;模拟器侧这些文件没有写入方,只拍到空态)。
真记录翻页、掉电后保持、清除记录后归零、boot_count 自增与四态判定**待台架复核**
(docs/任务规划/登记簿.md §7)。
真记录翻页、掉电后保持(复位代理口径)、清除记录后归零、boot_count 自增、rst_cause=IWDG、
conn_up +1 **已于 2026-11-06 Issue #53 台架轮实机复核通过**;四态判定中「拔 RTC 电池落
RESTARTED」经用户裁定(2026-11-05)台架不可验销项(证据与口径见 Issue #53 与
docs/测试说明/专项验证/模拟器差距清单.md §2.3)。
### 5.15 IEC 60870-5-104 上行(FR-IEC104)✅
@@ -1198,7 +1202,7 @@ for (i = 1; i < LED_COUNT; i++) /* LE
| 服务 | 协议 / 端口 | 用途 | 核对方法 |
|---|---|---|---|
| FTP | TCP **21** | 文件上传/下载(根目录 `/`,NAND 存储) | 登录后任意 FTP 客户端列目录/读写(鉴权见 §7.6) |
| 墙钟对时 | TCP **8888** | PC 主动推送时间到设备 | 对时后核对设备时间 / 日志时间戳 |
| 墙钟对时(SNTP 客户端) | UDP 出向 **123**(主/备服务器 `[sntp]` 段,enable=0 出厂默认) | 设备主动取 NTP 源时间写 RTC(:8888 推送监听**已删除**,2026-11-04,§6.3) | 使能后核对设备时间 / 日志时间戳与 `[SNTP] step offset=` 留痕 |
| 远程显示(RemoDispBus) | TCP **7003** | 远端看图(160×160 1bpp)+ 远端导航按键 | DTU-RemoteLCD 或任意 TCP 客户端连 7003 收帧 |
| IEC 60870-5-104 上行 | TCP **工厂默认 2404** | 被控站接入:遥测/遥信上送、总召、遥控/定值下发(点表见 §6.8) | 任意 104 主站连 2404,STARTDT+总召往返(→ `docs/子系统设计/IEC104上行设计说明.md`) |
@@ -1254,11 +1258,13 @@ for (i = 1; i < LED_COUNT; i++) /* LE
> 详见 `docs/UI设计/RemoDispBus协议与接收设计说明.md`。MCU 与模拟器**共用同一份** `ui_net_sink.c`。
### 6.3 对时协议
### 6.3 对时协议(SNTP 客户端)
- **载体**:TCP :8888,PC 主动推送,设备接收并写 RTC。
- **行为**:`timeSyncTask` 监听 → 收包 → 写回 RTC;30 s 无包则掉线重建监听(约 4 s)。
- **待补充**:推送报文的具体帧格式(当前实现细节见 `App/sync/time_sync.c` 与 `test/host/time_sync_server.py`)。
- **载体**:设备作 **SNTP(RFC 4330)客户端**,向 `[sntp]` 段配置的主/备服务器 UDP/123 出向取时,写回 RTC。
- **行为**:`timeSyncTask` 200 ms 节拍到点发 48 字节请求,应答经 OriginTimestamp 逐位防伪校验后按阈值步进;主备轮换 + 失败指数退避(5 s 起、60 s 封顶)。
- **退役**:原 **TCP :8888 PC 推送**(8 字节 `"TIME"` 帧)已于 2026-11-04 退役删除(工单 #78),
帧格式与实现细节见 git 历史;协议口径与教训沉淀于 `docs/子系统设计/系统墙钟时间维护说明.md` §15/§16。
- **详规**:报文编解码用 vendored coreSNTP 序列化器(`Lib/coreSNTP/`),判据见 §5.3 FR-TIME-3。
### 6.4 FTP 服务
@@ -1409,7 +1415,7 @@ mac=00:00:00:00:00:00
| 指标 | 基线值 | 来源 |
|---|---|---|
| M3 压力档帧周期 | med 60.1 / p95 66.4 / max 69.3 ms(零尖峰) | `docs/测试说明/专项验证/链路延迟测试说明.md` |
| 队列响应性(挂起客户端) | 92.5 ms(pending 一期) | `test/host/e02_probe.py` |
| 队列响应性(挂起客户端) | 92.5 ms(pending 一期) | 台架实测(探针 `e02_probe.py` 已删除——2026-11-04 随 :8888 退役,正文见 git 历史) |
| FTP 传输速率 | 约 49 / 60 KB/s(上传/下载) | 128 KB 实测 |
| 网络重建生效 | 2~5 s(含等链路 ≤3 s) | 配置设计 |
| UI 刷新 | 10 ms 循环 | `ui_task_func` |
@@ -1670,7 +1676,7 @@ docs/任务规划/UI补齐.md §5);原「当前执行 6 项」(记录 5
| **多规约栈** | 17 | 12 种 | 1 种(104) | +11 种(101 / 102 / 103 / CDT / ModBus / Whm_GB / 61850 / CAN + 子站侧 3 类) |
| **国密算法** | 18 | `Comm/Ecc/` 全套 | 0 | SM2 / SM3 / ECDSA |
| **软压板铺开** | 11 | 9 面(表容量 32) | 1 面 | +8 面 |
| **SNTP 对时** | 17 | 参考对时走 SNTP | **SNTP 客户端已落地**(2026-11-04:coreSNTP 序列化器 + `[sntp]` 配置 + UI 设置页 + timeSyncTask 接入,判据 §5.3 FR-TIME-3);另有私有 TCP 8888 + 104 `C_CS` | 台架真机对时判据(现场时间源,docs/任务规划/登记簿.md) |
| **SNTP 对时** | 17 | 参考对时走 SNTP | **SNTP 客户端已落地**(2026-11-04:coreSNTP 序列化器 + `[sntp]` 配置 + UI 设置页 + timeSyncTask 接入,判据 §5.3 FR-TIME-3);另有 104 `C_CS`(私有 TCP 8888 已随 #78 退役删除) | 台架真机对时判据(现场时间源,docs/任务规划/登记簿.md) |
| **固有参数** | 1 | `8001H~800AH` 字符串类参数 | 未实现(无法短浮点上送) | 随送检点表设计 |
| **遥测增强** | 4、5 | k=1~9 谐波方和根 + 4 点平均 | 仅基波轨 | 谐波 / 等周波调频 / 零序自产外接切换 三条算法轨 |
| **屏板链路对齐** | 20 | **串口屏板通道**(**700000 8N1 / USART1 TTL 直连、无 DE**,帧 A 6 B 召唤、帧 B **4208 B** 应答:显存 3200 B + **状态灯 4 B 位掩码** + 4 B info)+ **7003 四命令**(INIT **16 B**,单色口径)+ 续传 / 拒绝握手 / 链路监视 / F1·F2 | **串口通道已交付**(4208 B 应答 / 状态灯掩码 / 键上行 / 双出口并发,屏板链路设计说明 §9.1);7003 四命令(INIT **8 B**);无续传、无 `bNeedFlash` 拒绝、无 1 分钟监视、键值 6 个 | 7003 报文口径 6 项(`参考产品复刻明细.md` §11 第 2~9 条);串口侧验收尾巴见屏板链路设计说明 §9.2 |
@@ -1754,7 +1760,7 @@ docs/任务规划/UI补齐.md §5);原「当前执行 6 项」(记录 5
| 3 | 远程显示 | DTU-RemoteLCD 连 7003 | 出图(160×160 1bpp)+ 远端菜单导航可用 |
| 4 | FTP | FTP 客户端连 :21 | 列目录 / 读写 `/` 下文件 |
| 5 | UI 功能 | 远端操作 | 菜单 7 项导航、内容页、密码(查看 `000` / 修改 `123`)、网口设置保存后立即生效 |
| 6 | 对时 | PC 推送 8888 | 设备墙钟更新、日志时间戳正确 |
| 6 | 对时 | SNTP 配置服务器对时(原 PC 推送 8888 已退役) | 设备墙钟更新、日志时间戳正确 |
| 7 | 掉电保持 | 写文件 / 改网口配置 / 改定值 → 重启 | 数据仍在(`/config.ini`、`/prot_set.bin` 按新值生效) |
| 8 | LED 状态 | 目检 | 6 路 LED 随系统状态变化(低电平点亮) |
| 9 | 104 总召与变位 | PC 主站连工厂默认 :2404 → STARTDT → 总召 | 四组数据回全、`actterm` 正常;制造变位后 COT=3 上送 |
+14 -13
View File
@@ -31,18 +31,19 @@
## 1. UI 补齐(执行清单已于 2026-10-28 清空)
菜单树共 34 叶(节点行合计 43):按行内 #page= 实测**已绑 30 叶、未绑 4 叶**(2026-10-29 复扫,
判定规则与重跑命令见 docs/任务规划/UI补齐.md §1「叶数判定与复核」)。未绑的 4 叶因缺少开入硬件
或 SNTP 产品定义而不做(原因与重开条件见 docs/任务规划/UI补齐.md §5)——**手动录波与录波回放两叶
菜单树共 34 叶(节点行合计 43):按行内 #page= 实测**已绑 31 叶、未绑 3 叶**(2026-11-04 SNTP 设置
叶随 #73 立项转绑 +1,判定规则与重跑命令见 docs/任务规划/UI补齐.md §1「叶数判定与复核」)。未绑的 3 叶
因缺少开入硬件不做(原因与重开条件见 docs/任务规划/UI补齐.md §5)——**手动录波与录波回放两叶
已随录波道绑页**,「不做」清单里的录波那一项已销。
**口径闭合**:未绑 4 = 待做 0(§1 清单已清空)+ 不做 4(遥信 3 / SNTP 1);**43 是节点行数、不是叶数**(= 9 个菜单节点 + 34 叶)。
已绑叶数以生成物 UI_PAGE_MAP_COUNT 为准:不剔 ui_menu_tree.txt 文件头的注释示例行时,按 #page= 文本计数会得 31(= 30 + 1 行示例)。
**口径闭合**:未绑 3 = 待做 0(§1 清单已清空)+ 不做 3(遥信 3);**43 是节点行数、不是叶数**(= 9 个菜单节点 + 34 叶)。
已绑叶数以生成物 UI_PAGE_MAP_COUNT 为准:不剔 ui_menu_tree.txt 文件头的注释示例行时,按 #page= 文本计数会得 32(= 31 + 1 行示例)。
**UI 补齐执行清单已于 2026-10-28 清空**:记录 5 页(事故 / 操作 / 保护告警 / 保护启动 / 遥控)与
运行报告页同日落地并绑页,内容页黄金参考 53 → 60 张(runreport 分 2 页,第 2 页单独拍一张;判据 = simulator/tests/ref/ 入库 shot_*.bin 实数,张数 = 页面个数 + 分页多拍的那一张;**该集合 2026-10-29 已扩至 66 张**,多出的是录波回放页 6 态)。
上板判据(真记录翻页、掉电保持、清除后归零、boot_count 自增、RESTARTED、rst_cause=IWDG、conn_up +1)
已登记登记簿 §7「UI 六页真机判据」,六页文件头各留「台架待补」段;模拟器差距见
docs/测试说明/专项验证/模拟器差距清单.md §2.3「开机账本 boot_stats」一行。
**已于 2026-11-06 Issue #53 台架轮复核完成并销项**(除「拔 RTC 电池落 RESTARTED」经用户裁定 2026-11-05
台架不可验,销项不挂账);六页文件头「台架待补」段已改「台架复核已完成」,登记簿 §7 对应行已删;
模拟器差距见 docs/测试说明/专项验证/模拟器差距清单.md §2.3「开机账本 boot_stats」一行。
**执行纪律:单道串行。** 菜单树与页面注册表是生成物,字库也是整文件生成物;
不要同时开多条 UI 页面分支。上板验证可累积成一批,但保存、重启、主站读回等判据不能删除。
@@ -58,21 +59,21 @@ docs/测试说明/专项验证/模拟器差距清单.md §2.3「开机账本 boo
| 顺序 | 工作 | 当前状态 | 开始或切换条件 |
|---|---|---|---|
| **1** | **UI 补齐** | **清单已清空(2026-10-28)** | 记录 5 页与运行报告页已落地并绑页;余下 5 叶属 §5「当前不做」,重开条件见 docs/任务规划/UI补齐.md §5;上板判据见 docs/任务规划/登记簿.md §7 |
| **2** | **net 层跨上下文收口** | **下一顺位(未开工)** | UI 清单已清空,切换条件已满足;**开工需用户点头**——换主线是产品决策,不由本批顺带做掉 |
| **2** | **net 层跨上下文收口** | **✅ 2026-11-06 闭环** | 子项 A(裸指针收口为状态查询 API):审计确认收口已完成(`net_listener` 单一登记入口 `net_listener_request` + 单一执行者 `net_listener_tick`、`s_relisten_req` 0 处模块外直接读写;UI 读侧快照 API `ui_data_info`/唯一填充者 `ui_data_feed`);子项 B(突发分片让路):台架重验确认新负载剖面(SNTP 请求/退避 + FTP + 104 + 7003)下 **uiTask ≥800 ms 饿死签名不复现**(`task stall` 0 条、复位 0、NAND `wdev.log` 当日零新增 STALL、7003 最差 759 ms <800 ms 线)——证据见 `网络自愈架构设计.md` 与 `看门狗设计说明.md` 变更记录 2026-11-06 条目 |
| **3** | 其余结构与可靠性评估 | 排队 | net 收口后;逐项见 `登记簿.md`,观察项不为了“清清单”而强做 |
| **4** | 数据可信(采集数据可信度) | 动态波形验证**手边可做**;变比确认与两点标定等外部资源 | 信号发生器动态波形验证(不依赖外部资源)→ 端子/子板变比确认 → 标准源两点标定;**排序调整(2026-10-29):动态验证让位给故障录波数据面**,段文件落地后判据升级为 PC 独立重算对表(docs/子系统设计/故障录波设计说明.md §11)(已知电压注入已于 2026-10-27 台架闭环并销项);外部资源到位可插入优先处理 |
| **4** | 数据可信(采集数据可信度) | 动态波形验证 **✅ 2026-11-04 闭环(六轮)**;变比确认与两点标定等外部资源 | 信号发生器动态波形验证(不依赖外部资源,✅ 2026-11-04)→ 端子/子板变比确认 → 标准源两点标定;**排序调整(2026-10-29):动态验证让位给故障录波数据面**,段文件落地后判据升级为 PC 独立重算对表(docs/子系统设计/故障录波设计说明.md §11)(已知电压注入已于 2026-10-27 台架闭环并销项);外部资源到位可插入优先处理 |
| **5** | 标准源送检与第三方 104 主站验收 | 等待标定完成 | 两点标定完成且保护 VALID 已置位;送检窗口前 2 日冻结特性 |
| **6** | 保护元件与采集增强 | 等待标准源或硬件改版 | 保护先解除未标定闭锁;三相同时刻类功能等 V0.2 硬件 |
| **7** | 验证窗口事项 | 逢条件顺带 | CI runner、PC peer、CH340、负向故障注入条件到位时执行 |
| **8** | 独立模块与暂缓项 | 当前不排 | 开入开出、SNTP、104 文件传输单独立项;RS-485 与内存优化按各自重启条件 |
| **独立** | **故障录波(1 kHz · 8 路原始码值 · 单通道回放)** | **代码面已交付;2026-10-31 远程半轮过六项、2026-11-02 回放页枚举缺陷已修复闭环,余注量对表与人到场项** | 用户裁定 2026-10-29 **录波先行**:数据面最小闭环 → 手动与保护启动触发 → 回放页。三块的**代码侧判据已收口**(主机单测 113 / 170 / 110 全 rc=0、双端编译 0 错误 0 警告、板端编码器与 PC 侧解码器字节级互验、手动录波与录波回放两叶已绑页、内容页黄金参考扩至 66 张);**2026-10-31 远程半轮已过六项**(真 FAT 落盘、触发→落盘全部落在 2 s 封存超时窗内、冷却恢复、轮转、PC 侧坏段拒收、冻结窗内 104 并发);同轮发现的缺陷「回放页段表枚举恒空」**已于 2026-11-02 远程修复并板级闭环**(根因 = 读侧 `wave_store_seg_path()` 返回值判错,顺带修键处理缺失效;回放页真段/切段/切道已实测,登记簿条目已销项,证据见设计说明 §10「回放页枚举恒空缺陷修复记录」);**没跑的是注量对表那半轮**(注 1 V / 50 Hz、与 `meas:` 行和 104 浮点遥测对表、回放页放坏段与空态画面)加 P 触发 / bench T 源,全部结果与清单见 `docs/子系统设计/故障录波设计说明.md` §10「板级远程半轮记录」。**板级判据、留痕名清单与执行顺序图的属主 = docs/子系统设计/故障录波设计说明.md §9 与 §10**(原卡片登记簿 2026-10-30 随销项并入后删除);**与 UI 道互斥**(菜单树与中文字库是整文件生成物,同刻只允许一条道写)——本波按此串行执行:UI 道在数据面与接线冻结之后才动生成物 |
| **8** | 独立模块与暂缓项 | 当前不排 | 开入开出、104 文件传输单独立项(SNTP 已单独立项并于 2026-11-04 落地 #73,:8888 随 #78 退役);RS-485 与内存优化按各自重启条件 |
| **独立** | **故障录波(1 kHz · 8 路原始码值 · 单通道回放)** | **代码面已交付;2026-10-31 远程半轮过六项、2026-11-02 回放页枚举缺陷已修复闭环、2026-11-04 注量对表闭环(#40 §8 交流轮)、2026-11-06 第二幕尾步坏段/空态画面台架远程轮拍毕——回放页三态板级判据全部实证;余 P 触发(需标定解锁决定)、bench T 源与卷占用、`task_prof` 耗时峰值等到场/裁定项** | 用户裁定 2026-10-29 **录波先行**:数据面最小闭环 → 手动与保护启动触发 → 回放页。三块的**代码侧判据已收口**(主机单测 113 / 170 / 110 全 rc=0、双端编译 0 错误 0 警告、板端编码器与 PC 侧解码器字节级互验、手动录波与录波回放两叶已绑页、内容页黄金参考扩至 66 张);**2026-10-31 远程半轮已过六项**(真 FAT 落盘、触发→落盘全部落在 2 s 封存超时窗内、冷却恢复、轮转、PC 侧坏段拒收、冻结窗内 104 并发);同轮发现的缺陷「回放页段表枚举恒空」**已于 2026-11-02 远程修复并板级闭环**(根因 = 读侧 `wave_store_seg_path()` 返回值判错,顺带修键处理缺失效;回放页真段/切段/切道已实测,登记簿条目已销项,证据见设计说明 §10「回放页枚举恒空缺陷修复记录」);**注量对表半轮已于 2026-11-04 由 #40 §8 交流轮闭环**(幅值 / 相位 / 削顶三项实测,`meas:` 行与板上读数逐项核对,104 浮点遥测按用户裁定不作对照证据;`docs/测试说明/测试数据/boot_log_data/20261104_ac_*`);**回放页放坏段与空态画面已于 2026-11-06 台架远程轮拍毕闭环**(同号翻位覆盖→「该段不可读」零波形元素绝不平线;全删→「无录波段」+ 串口 `open fail fr=4` 互证;证据 `docs/测试说明/测试数据/wave_shot_20261106/`,记录见设计说明 §10「回放页坏段/空态画面闭环记录」);**没跑的只剩** P 触发对时刻(先要标定解锁决定)/ bench T 源与卷占用(需 bench 构建)/ `task_prof` 读路径耗时峰值,全部结果与清单见 `docs/子系统设计/故障录波设计说明.md` §10「板级远程半轮记录」。**板级判据、留痕名清单与执行顺序图的属主 = docs/子系统设计/故障录波设计说明.md §9 与 §10**(原卡片登记簿 2026-10-30 随销项并入后删除);**与 UI 道互斥**(菜单树与中文字库是整文件生成物,同刻只允许一条道写)——本波按此串行执行:UI 道在数据面与接线冻结之后才动生成物 |
### 2.1 关键依赖
- **UI**:写路径、整定 4 页、装置维护 3 页与遥测死区/系数 2 页已收口(含上板判据与真机回读);
菜单树、页面注册表与字库都是生成物,同刻只允许一条道写。
- **送检**:已知电压注入(✅ 2026-10-27 闭环)→〔信号发生器动态波形验证 —— 手边可做,与后两关并行、不阻塞送检〕
→ 端子/子板变比确认 → 标准源两点标定 → 保护解除闭锁 → 送检。
- **送检**:已知电压注入(✅ 2026-10-27 闭环)→ 信号发生器动态波形验证(✅ 2026-11-04 闭环,未闭合
四项标注在 数据可信.md §5 任务卡内)→ 端子/子板变比确认 → 标准源两点标定 → 保护解除闭锁 → 送检。
- **保护扩展**:标准源未到位前不新增无法验证的判据;跨转换器相位、功率、对称分量类
功能必须等 V0.2 硬件。
- **结构债**:UI 完成后先做 net 收口;RS-485 白名单、内存优化、仓库体积等观察项不抢占
+6 -3
View File
@@ -99,8 +99,11 @@
**单写者约束**:`ui_menu_tree.txt`、页面注册表、字库生成物不得由多个分支同时修改。
`MDK-ARM/*.uvprojx` 的新源文件注册按双端注册规则处理。
**时基口径未定,勿顺手统一**:面板时钟页与 8888 对时把「本地钟面当 epoch」写入,而 104 `C_CS` 按 CP56Time2a 的
UTC 写入,后写者赢 ⇒ 装置墙钟与主机本地时刻恒差 8 小时。用户裁定前**不要改动 RTC/epoch 语义**,也不要把
**时基口径已裁定,勿顺手改语义**:口径 = 「先本地为准,内部真源是本地钟面」(用户裁定 2026-10-27,
`../子系统设计/系统墙钟时间维护说明.md` §1.1);当时冲突双方「面板时钟页 vs 8888 对时 vs 104 `C_CS` 写 UTC」中的
8888 已于 2026-11-04 退役(写入口现为 SNTP / UI 手工 / 104 `C_CS`,一律先换算成本地钟面再落库)。唯一待决的是
104 **上行** `CP56Time2a` 是否转 UTC(送检前单独定,前引
`../子系统设计/系统墙钟时间维护说明.md` §1.1 末)。裁定前**不要改动 RTC/epoch 语义**,也不要把
时钟设置页的「回读 RTC」判据改成按某一时区补偿——那等于替产品做掉一个未定的决定。
**保护闭锁必须可见**:整定页可以修改定值,但当前产品在 UA/UN/IA 未标定时保护判据闭锁。
@@ -115,5 +118,5 @@ UTC 写入,后写者赢 ⇒ 装置墙钟与主机本地时刻恒差 8 小时
|---|---|---|
| 遥信类型 / 防抖 / 双点 3 页 | V0.1 无开入硬件,配置没有消费者 | 开入固件立项后,与开入开出一起做 |
| net 层与其他结构债 | 当前只做 UI,避免两条主线互相拖慢 | UI 当前清单完成后,按 README §2 切换 |
| RTC 时基统一 | 两套写入口径并存(面板与 8888 写本地钟面、104 写 UTC),恒差 8 小时;统一任一侧都要动 104 上行语义或 UI 判据 | 用户裁定时基方向后,作为跨模块变更单独立项 |
| 104 上行 UTC 换算(原「RTC 时基统一」) | 内部口径已由用户裁定(2026-10-27:本地钟面为真源,各写入口先换算再落库,见 §4 注),「恒差 8 小时」的后写者赢阶段已结束;剩下的只是 104 上行是否按标准转 UTC,动了要改 104 上行语义 | 送检/第三方主站验收方向定下来后,作为跨模块变更单独立项(墙钟说明 §1.1 末) |
| 主站地址白名单 | CH395F 单连接 socket 上「拒绝即 close+重 listen」等于给扫描风暴开门,且该值现在没有任何既有消费点 | 有真实消费场景或多连接后端立项时再评 |
+41 -39
View File
@@ -26,7 +26,7 @@
|---|---|---|
| 1 通路活 | 9 路都在转换、没串道、极性没反? | ✅ 2026-10-27 已证 |
| 2 静态引脚电压 | 注 1 V 直流,读数是不是 1 V? | ✅ 2026-10-27 已证(六项判据全 PASS,§2.6) |
| **3 动态引脚波形** | **注 1 V 正弦,算出来还是不是 1 V?** | **⬜ 一次也没做过(§2.7 → 方案见 §4.6)** |
| **3 动态引脚波形** | **注 Vpp 2.828 V 正弦(板上读数 ≈1 V),算出来还是不是 1 V?** | **✅ 2026-11-02 / 11-04 已跑两轮、六轮全部闭合**(削顶 2 Hz 档与复位复核经用户裁定 2026-11-04 关闭;谐波 B 行超差已归因板端前端 RC fc≈796 Hz → §4.6 任务卡;实测结论 `docs/硬件平台/ADC通道映射说明.md` §8.2) |
| 4 端子二次值 | 引脚上这 1 V 对应端子侧几 V? | 🟡 等子板原理图或实物 |
| 5 精度等级验收 | 额定工况下整条链误差够几级? | 🟡 等标准源 |
@@ -44,9 +44,9 @@
| 你想做什么 | 直接看 |
|---|---|
| 判断现在这些数能信到什么程度 | §1 这张图 + §2.6(静态证到哪)+ §2.7(动态没证什么) |
| 判断现在这些数能信到什么程度 | §1 这张图 + §2.6(静态证到哪)+ §2.7(动态证到哪) |
| 改采集 / 算法 / 品质位相关代码 | §2.1 §2.2 §2.3(口径)+ §4.1~§4.5(设计依据) |
| 上台架做正弦验证 | §4.6(接法、六轮判据、读数出口、坑)+ §5 的「信号发生器动态波形验证」卡 |
| 上台架做正弦验证 | ✅ 已闭环(2026-11-04);复跑看 §4.6(接法、六轮判据、数字从哪儿读、坑)+ §5 的「信号发生器动态波形验证」卡 |
| 看还差谁、按什么顺序做 | §5 任务卡 + §6 顺序图 |
| 确认某件事是**故意不做**而不是漏了 | §9;有没有踩坑风险看 §8 |
@@ -137,12 +137,12 @@ V0.1 恒命中 UB/UC/IB/IC/IN,位图 `0xE6`),它表示"这路不能测交
> `eng` 升 1 的条件是电气 8 路 VALID **全置位**(`App/app/ui_data_feed.c` 的 `feed_eng()`)。
> **本节编号与承诺边界口径勿删**——`adc_cal.*` / `meas.*` / `ui_data*` / `simulator/main.c` 的头注释都指到这里。
### 2.7 动态验证:正弦波一次也没采过
### 2.7 动态验证:已跑两轮(2026-11-02 / 11-04),六轮实测结论在 `docs/硬件平台/ADC通道映射说明.md` §8.2
**一句话**:整条计算链现在只在**PC 合成数据**上验过,从没在**真实交流波形**上验过。
不是"精度差一点",是"这一档完全空白"。
**一句话**:这一档**不再是空白**——真实交流波形已经台架两轮验证(幅值/波形/相位/测频/谐波/削顶直流档都过了);
本节先留"当时为什么判空白"的证据链,下面按下游的表已按两轮实测更新。
证据(逐条可查,全部是各套件自己的自陈,不是推测):
当时的证据(逐条可查,全部是各套件自己的自陈,不是推测——正是它们说明 PC 套件自己闭不了这一档):
| 出处 | 原话要点 |
|---|---|
@@ -153,19 +153,18 @@ V0.1 恒命中 UB/UC/IB/IC/IN,位图 `0xE6`),它表示"这路不能测交
| `docs/测试说明/专项验证/ADC前端注入验证流程.md` | 「**只验直流**:零点 / 线性 / 通道映射 / 极性。不验交流有效值——台架无信号源」 |
| `App/task/adc_task.c` 心跳块 | `adc:` 是当拍瞬时码值、`meas:` 是 200 ms 快照——**没有一行能给出波形形状** |
按下游列一遍"现在能不能信":
按下游列一遍"现在能不能信"(2026-11-04 按台架两轮更新;数只详述在 `docs/硬件平台/ADC通道映射说明.md` §8.2,此处不抄第二份):
| 下游 | 现在 | 为什么 |
|---|---|---|
| 基波有效值(RMS) | 🟡 算法在 PC 上证过(幅值 ≤1 %、49/51 Hz 下 ≤1.5 %),**经真 ADC 后一次没测** | 1 V 正弦进 ADC 后 `fAmSQ` 是否 = 1 V,无实测 |
| 相位 | ❌ 从未在真信号上比过;且代码里**没有跨通道相位符号约定** | 只许比同片内通道(§9 的硬件限制) |
| 频率 | ❌ **恒不启动** | 幅值门 50 V 是二次值口径,引脚域 ≤5 V 恒不过(§2.3 #1)→ UI `Hz` 行恒 `--`、104 `0x401D` 恒 IV |
| 削顶 / 品质 | 🟡 位图逻辑对,真削顶路径没跑过 | `rail:` 那条 `[ERR]` 至今只在直流饱和里起过 |
| 谐波 C04 / C05 | ❌ 实例建了,**无消费者、无出口** | `prot_elm.c` 无引用,`meas` 只算 `harm=1` |
| 基波有效值 | ✅ 过(±2 % 内,三档幅值两点复现) | 台架幅值轮 + 波形轮(基波分量口径)实证;端子二次值仍不归这档(§4.6.5) |
| 相位 | ✅ 同片内过(录波档 ≤2° 判据) | 同段 UA/UN 两路实测(0° 与 90° 两工况);**跨转换器仍禁比**——无同刻性是 V0.1 硬件边界(§9),不是待修缺陷 |
| 频率 | ✅ 「如实报不可测」成立(这就是现状判据) | 含满幅注入段全不可测、UI 恒 `--`;**45~55 Hz 精度仍未验**——要验须降 `FREQ_AMP_MIN` 单跑一轮 → §7 #8 |
| 削顶 / 品质 | ✅ DC −1.00 V 档锁存 + sticky 实证;2.0 Hz 低频档与复位复核经用户裁定 2026-11-04 关闭 | `[ERR] rail: edge=0x2 sticky=0x2` 唯一一条、撤注恒持;执行见 §4.6 任务卡 |
| 谐波 C04 / C05 | 🟡 选择性轨已证(单注 100/250 Hz 分别只进对应桶、纯基波两桶为 0);**仍无消费者、无处上送** | 250 Hz→`Ia5` 行 −4.4 % **已按板端前端真实衰减关闭(2026-11-04)**:IA 前端差分滤波 C35 = 100 nF + R19/R21 各 1 k 构成一阶低通 fc ≈ 796 Hz,板端读数忠实、工频不受影响;谐波产品化需板改(模型与数据 `docs/硬件平台/ADC通道映射说明.md` §8.2,执行手册谐波记录 B 行);接到哪、给谁用归 §9 的谐波轨立项 |
| 保护判据 | 🔒 闭锁中 | §4.3 |
→ **下一跳就是 §4.6**:把一根真正的 50 Hz 正弦从**已经验证过的那个注入点**灌进去,
一次把上表里"手边设备能改"的几行改掉。
→ 两轮已按 **§4.6** 跑完(从**已验证过的那个注入点**灌正弦);六轮全部闭合(谐波 B 行超差已归因板端前端 RC,见 §2.7 谐波行;削顶 2 Hz 低频档与复位复核经用户裁定 2026-11-04 关闭,见 §2.7 削顶行与执行手册削顶卡步 3 行)。
---
@@ -242,7 +241,7 @@ M4 的六条退出判据(逐条对齐现状,别整格打勾):
- 与"自检失败 / 采样故障闭锁"同构(`PROT_HF_LOCK_MASK` 那一套),**不新增机制**。
- 现有台架 `/serial-boot-test` 的期望会因此变化——**这是有意的**,任务卡里同步更新判据。
- 台架调试要旁路只能走编译期开关 `DTU_BENCH`,不进 cfg、不进 104。
⚠ **`DTU_BENCH` 只旁路这一处**:它**不**旁路 §2.3 #1 的测频幅值门,也不产生任何读数出口。
⚠ **`DTU_BENCH` 只旁路这一处**:它**不**旁路 §2.3 #1 的测频幅值门,也不产生任何新的读数通道。
### 4.4 落盘:拆两段,不碰引擎
@@ -300,7 +299,7 @@ typedef struct {
| 注入点已经验证过,且就在那儿 | `docs/测试说明/专项验证/ADC前端注入验证流程.md` §3 的注入点清单(串联电阻端子侧 = `U5` 排针);③ 段 1:1 已拿到台架证据(§2.6) |
| **不知道 ④ 变比也能验算法** | 注入点在 ④ **之前**,发生器给的电压就是引脚电压,算法链要证的正是"引脚域里算得对不对" |
| 幅度小两个数量级 | 只需 ±2 V 以内的正弦(TPAFE 侧判据上限);端子二次值验证要上 100 V / 220 V,风险与设备都在那一级 |
| 现有静态验证的读数出口可直接复用 | 串口心跳 + 104 YC,零固件改动(§4.6.3) |
| 现有静态验证的读数的地方可直接复用 | 串口心跳,零固件改动(§4.6.3) |
**这一跳证的是功能性**(算得对不对、品质报得实不实、节拍稳不稳),**不是计量**(误差几级)——
发生器不当"标准"的界线见 §4.6.5 与 §7 #9。
@@ -313,34 +312,37 @@ typedef struct {
> **轮次名一律用语义短语(用户裁定 2026-10-30:清退"字母+数字"判据号)**:D1 → 幅值轮、D2 → 波形轮、
> D3 → 相位轮、D4 → 测频轮、D5 → 削顶轮、D6 → 谐波轮;本族旧号作废不得再取走
> (与二极管位号、网络自愈决策记录、链路延迟缺陷编号只是同形,各不相干)。
>
> **注入幅度一律按峰峰值 Vpp 设定(用户裁定 2026-11-04)**:发生器面板的有效值显示不当设定基准
> (同一个 Vpp 换波形后有效值显示跟着变,切波形瞬间还残留上一波形的值);万用表 AC 档与板上读数
> 天然是有效值刻度,正弦下 有效值 = Vpp ÷ 2.828,换算着比。
| 轮次 | 验什么 | 接法 | 读哪 | 过判据 |
|---|---|---|---|---|
| **幅值轮** | 基波幅值计量 | UA(R31 / `AIN1`)注 1.000 Vrms、50.000 Hz 正弦 | `meas:` 的 `ua_mv`;或 104 `0x4011` | 读数 = 万用表 AC 档读数,偏差 ≤2 %(与静态同档)。⚠ 别用 `phasor(hb)` 行比幅值——那是 ×0.1 定点,注 1 V 只剩 10 格(§4.6.3) |
| **幅值轮** | 基波幅值计量 | UA(R31 / `AIN1`)注 Vpp 2.828 V(= 峰值 ±1.414 V)、50.000 Hz 正弦 | `meas:` 的 `ua_mv` | 读数 = 万用表 AC 档读数,偏差 ≤2 %(与静态同档)。⚠ 别用 `phasor(hb)` 行比幅值——那是 ×0.1 定点,注 1 V 只剩 10 格(§4.6.3) |
| **波形轮** | 读数是否只跟基波走 | 同幅值改方波、三角 | 同上 | 期望值 = **基波分量有效值**(同峰值下的基波 / 峰值比:方波 ≈ **0.90**,闭式 4/π ÷ √2 = 0.900、20 点整周期 DFT 实算 0.904;三角 ≈ **0.573**,闭式 8/π² ÷ √2 = 0.573、实算 0.578),**不是**真有效值(方波 = 1.000、三角 = 0.583 峰值);偏差 ≤2 %。算术与逐波形对照表见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8.5 的波形卡。顺带把"这台仪表读的是基波"这条口径钉进文档——用户拿真有效值表去对会以为差了 10 % |
| **相位轮** | 相位 | UA 与 UN 两路**同片**(都走 TPAFE)注同幅、同相 | **定量档**:录波段文件 `test/host/wave_read.py fft`(浮点重算基波相位;段内表序 `UA` = 0、`UN` = 3);**定性档**:`phasor(hb)` 各行 `Re=` / `Im=` | **定量档**:同段内两路相位差 ≤2°,把发生器相位改 90° 后差值跟到 ≈90°。**定性档只判"跟随"**(差值落进 80°~100°)——`phasor` 出口是 ×0.1 定点,1.000 Vrms 时每格 0.1 V,角度量化最坏 ≈ atan(0.1 / 0.707) ≈ 8°,判不动 2°(§4.6.3)。⚠ 段与发生器**无绝对相位锁定**(触发瞬间钉在段内点 159),只能比**同段内两路**的相对差,跨段比相位或拿发生器相位当绝对基准都不成立。**只许比同片内**——跨转换器无同刻性(§9),STM32 那五路还有 1 拍乒乓滞后 |
| **测频轮** | 测频 | 同幅值轮的 1 V/50 Hz | `freq(hb):` 与 104 `0x401D` | **预期就是"不出数"**(幅值门 50 V 在引脚域恒不过,§2.3 #1)→ 这条的判据是"如实报不可测"(`freq_valid=0`、UI `Hz` 显示 `--`、104 上送 IV),**不是**报出一个错误的 50.00。想真验 45~55 Hz 精度(PC 侧判据 0.02 Hz)须临时把 `FREQ_AMP_MIN` 降到引脚域量级(如 0.5 V)单跑一轮 → §7 #8 + §8 风险行 |
| **削顶轮** | 削顶与品质路由(**负向用例**) | 给 UB(R52 / `AIN2`)注 **DC −1.00 V 并保持 ≥5 s**;或 1.000 Vrms 而频率 **2.0 Hz** 的正弦——两档都能造出"连续贴同一侧轨带"。⚠ **注 50 Hz 同幅正弦造不出锁存,且这是预期而非故障**:1 kHz 下一个周波只 20 点、正半周必落中带,而 `adc_health_rail_watch()` 任何一拍回中带就把计数清零(`App/algo/adc_health.c`),连续贴底最长 ≈ 209/360 × 20 ≈ 11 拍 < 20。TPAFE 侧在 ±2 V 判据上限内造不出这条(轨带 ±32112 码 ≈ ±4.9 V),只有 STM32 那五路能做 | `cal:` 行的 `rail=` / `edge=`;`rail: edge=…` 的 `[ERR]` 行;104 `0x4012`;段文件档另加 `wave_read.py shape` 的三把尺子(`--strict` / 再加 `--clip-superset` / 不带),逐条配法见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8.5 的削顶卡 | 负半周钉下轨 → **连续 20 拍同侧后该路贴轨位锁存**(`ADC_RAIL_N_RUN = 20`,`App/algo/adc_health.h:174`)、`edge` 起沿、104 上该路 IV 且值清零。锁存另有**释放沿前提**:该通道此前须出现过中带样本 → **先上电见基线摆动、再开发生器输出**,开机就注会测出假不通过。撤掉注入后 `rail` 仍非 0 是 sticky 语义(只有 `adc_health_rail_init()` / 复位清)——**复位后仍不清才是 bug**。⚠ 这条会**故意造出 `[ERR]`**,而 `/serial-boot-test` 的 forbidden 标记含 `[ERR]` → 人工判读、排在最后单独一轮(§8 第一行) |
| **谐波轮** | 谐波轨 | 基波 + 20 % 二次 + 20 % 五次(IA 上注)。⚠ 峰值预算:1.000 Vrms 基波 + 两个 20 % 分量的最坏对齐 ≈ 1.98 V 已顶 ±2 V 红线 → 基波用 **0.800 Vrms**、二次与五次各 0.160 Vrms | **定量档**:段文件 `test/host/wave_read.py fft --ch 4 --all`(`IA` = 段内表序 4,直接给基波与 2 / 5 次谐波 RMS,单位 mV);**旁证**:UI 交流量页 `Ia2` / `Ia5`(1 mV)与 `phasor(hb) C04-IA-F2` / `C05-IA-F5`(×0.1 定点,只证这根轨不是恒 0) | 谐波轨读数 = 注入分量(**±2 %,走定量档**;周期行档判不动:0.160 Vrms 在 ×0.1 出口只有 1~2 格)。⚠ 这两根轨**目前没有任何下游消费者**(`prot_elm.c` 无引用、`meas` 只算 `harm=1`),所以谐波轮只证"算得对",**不证"有人用"**——出口归 §9 的谐波轨立项 |
| **相位轮** | 相位 | UA 与 UN 两路**同片**(都走 TPAFE)注同幅、同相 | **录波档**:录波段文件 `test/host/wave_read.py fft`(浮点重算基波相位;段内表序 `UA` = 0、`UN` = 3);**心跳档**:`phasor(hb)` 各行 `Re=` / `Im=` | **录波档**:同段内两路相位差 ≤2°,把发生器相位改 90° 后差值跟到 ≈90°。**心跳档只判"跟随"**(差值落进 80°~100°)——`phasor` 串口行是 ×0.1 定点,Vpp 2.828 V(板上读数 ≈1000 mV)时每格 0.1 V,角度量化最坏 ≈ atan(0.1 / 0.707) ≈ 8°,判不动 2°(§4.6.3)。⚠ 段与发生器**无绝对相位锁定**(触发瞬间钉在段内点 159),只能比**同段内两路**的相对差,跨段比相位或拿发生器相位当绝对基准都不成立。**只许比同片内**——跨转换器无同刻性(§9),STM32 那五路还有 1 拍乒乓滞后 |
| **测频轮** | 测频 | 同幅值轮的 Vpp 2.828 V / 50 Hz | `freq(hb):` | **预期就是"不出数"**(幅值门 50 V 在引脚域恒不过,§2.3 #1)→ 这条的判据是"如实报不可测"(`freq_valid=0`、UI `Hz` 显示 `--`),**不是**报出一个错误的 50.00。想真验 45~55 Hz 精度(PC 侧判据 0.02 Hz)须临时把 `FREQ_AMP_MIN` 降到引脚域量级(如 0.5 V)单跑一轮 → §7 #8 + §8 风险行 |
| **削顶轮** | 削顶与品质路由(**负向用例**) | 给 UB(R52 / `AIN2`)注 **DC −1.00 V 并保持 ≥5 s**;或 Vpp 2.828 V 而频率 **2.0 Hz** 的正弦——两档都能造出"连续贴同一侧轨带"。⚠ **注 50 Hz 同幅正弦造不出锁存,且这是预期而非故障**:1 kHz 下一个周波只 20 点、正半周必落中带,而 `adc_health_rail_watch()` 任何一拍回中带就把计数清零(`App/algo/adc_health.c`),连续贴底最长 ≈ 209/360 × 20 ≈ 11 拍 < 20。TPAFE 侧在 ±2 V 判据上限内造不出这条(轨带 ±32112 码 ≈ ±4.9 V),只有 STM32 那五路能做 | `cal:` 行的 `rail=` / `edge=`;`rail: edge=…` 的 `[ERR]` 行;录波档另加 `wave_read.py shape` 的三把尺子(`--strict` / 再加 `--clip-superset` / 不带),逐条配法见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8.5 的削顶卡 | 负半周钉下轨 → **连续 20 拍同侧后该路贴轨位锁存**(`ADC_RAIL_N_RUN = 20`,`App/algo/adc_health.h:174`)、`edge` 起沿。锁存另有**释放沿前提**:该通道此前须出现过中带样本 → **先上电见基线摆动、再开发生器输出**,开机就注会测出假不通过。撤掉注入后 `rail` 仍非 0 是 sticky 语义(只有 `adc_health_rail_init()` / 复位清)——**复位后仍不清才是 bug**。⚠ 这条会**故意造出 `[ERR]`**,而 `/serial-boot-test` 的 forbidden 标记含 `[ERR]` → 人工判读、排在最后单独一轮(§8 第一行) |
| **谐波轮** | 谐波轨 | 基波 + 20 % 二次 + 20 % 五次(IA 上注)。⚠ 峰值预算:Vpp 2.828 V 基波 + 两个 20 % 分量的最坏对齐峰值 ≈ 1.98 V 已顶 ±2 V 红线 → 基波用 **Vpp 2.263 V**、二次与五次各 Vpp 0.453 V | **录波档**:段文件 `test/host/wave_read.py fft --ch 4 --all`(`IA` = 段内表序 4,直接给基波与 2 / 5 次谐波有效值,单位 mV);**旁证**:UI 交流量页 `Ia2` / `Ia5`(1 mV)与 `phasor(hb) C04-IA-F2` / `C05-IA-F5`(×0.1 定点,只证这根轨不是恒 0) | 谐波轨读数 = 注入分量(**±2 %,走录波档**;心跳档判不动:读数 0.160 V 在 ×0.1 串口行上只有 1~2 格)。⚠ 这两根轨**目前没有任何下游消费者**(`prot_elm.c` 无引用、`meas` 只算 `harm=1`),所以谐波轮只证"算得对",**不证"有人用"**——接到哪、给谁用,归 §9 的谐波轨立项 |
**先做幅值 / 波形 / 削顶三轮**(纯读数、无跨通道约定),相位 / 谐波次之,测频轮视 §7 #8 的裁定。每条的两档跑法(周期行标量档 /
录波段文件定量档)、触发动作、耗时排布与失败分诊在 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8.6。
**先做幅值 / 波形 / 削顶三轮**(纯读数、无跨通道约定),相位 / 谐波次之,测频轮视 §7 #8 的裁定。每条的两档跑法(心跳档 /
录波档)与触发动作在 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8.4–§8.5 的注入卡里(耗时排布与失败分诊两节已随 2026-11-04 轮次收尾删除,将来复跑照卡自行排程)。
#### 4.6.3 读数出口(零固件改动)
#### 4.6.3 数字能从哪儿读(零固件改动)
| 出口 | 有什么 | 坑 |
| 读数的地方 | 有什么 | 坑 |
|---|---|---|
| 串口每 10 s 心跳(`App/task/adc_task.c` 心跳块) | `adc:`(9 路码值)、`cal:`(三路 mV + `vl`/`cl`/`rail`/`edge` 位图)、`phasor(hb)`(逐实例 `Re` / `Im` / `rms`)、`freq(hb)`、`meas:`(快照轨) | MicroLIB 无 `%f`,全是定点:`phasor` ×0.1(**1 V 注入只剩 10 格**)、`freq` ×0.01 Hz、`cal:` / `meas:` ×1000(1 mV)。10 s 一行的单点瞬时值对 50 Hz 等价于随机相位抽样 |
| 104 YC(现成 PC 主站 `test/host/iec104_master.py`) | `0x4011`~`0x4018` 八个电气量 + `0x401D` 频率,**浮点无量化**,还带品质 | UB/UC/IB/IC/IN 恒 IV、值清零 → 那五路只能回读串口码值域 |
| UI 交流量页 | `Ua` / `U0` / `Ia` / `Ia2` / `Ia5` / `Hz` / 标定徽标 共 7 行 | 160×160 单色;`--` **同时**表示"没数"和"有数但不可信" → 不能当判据,只能当旁证 |
| **段文件样本出口(代码侧已落地,2026-10-29)** | 每次触发一段:`/wave/WAVE00.BIN` 起共 100 个号轮转(FTP 根下可见),8 路 × 320 点原始码值加封存瞬间的标定与品质快照;PC 侧 `test/host/wave_read.py` 提供 dump / fft / shape / plot 四个子命令(bench 工具,纯标准库,自带 `--selftest`) | 「比对派生标量」已可升级成「PC 独立重算 vs 板上读数」对表(判据与执行步骤见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §4,格式属主见 `docs/子系统设计/故障录波设计说明.md` §6.2 与 §6.3)。**但板级那一轮还没跑**(注 1 V / 50 Hz、与 `meas:` 与 104 YC 对表、CRC 不符必须拒收的实测,见 `docs/子系统设计/故障录波设计说明.md` §10);示波器仍旧只作旁证、不当判据。段内点序:触发瞬间落在段内点 159(预触发 160 点的最后一点),段的绝对相位与发生器无锁定关系,可核对的是相对相位与极性 |
| **仍然没有的(2026-10-29 更新)** | 没有命令控制台、也没有「把窗里 20 / 40 个点导出来」的定点 dump 子命令——**但样本出口本身已成立**(上一行的段文件:一次 320 点 / 8 路,比原来规划的 20 / 40 点窗更宽) | 现场取回一律走现成 FTP(21 端口),形状就地看回放页单通道、或在 PC 侧用同一脚本出图;示波器只对照发生器、不当判据。**判据已升级为「PC 独立重算 vs 板上读数」对表**,对表的执行轮次待台架(见 `docs/子系统设计/故障录波设计说明.md` §11) |
| **段文件(原始样本,代码侧已落地,2026-10-29)** | 每次触发一段:`/wave/WAVE00.BIN` 起共 100 个号轮转(FTP 根下可见),8 路 × 320 点原始码值加封存瞬间的标定与品质快照;PC 侧 `test/host/wave_read.py` 提供 dump / fft / shape / plot 四个子命令(bench 工具,纯标准库,自带 `--selftest`) | 「比对派生标量」已可升级成「PC 独立重算 vs 板上读数」对表(判据与执行步骤见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §4,格式属主见 `docs/子系统设计/故障录波设计说明.md` §6.2 与 §6.3)。**板级注入对表已随交流六轮跑过两轮**(2026-11-02 / 11-04,注 Vpp 2.828 V / 50 Hz、fft 与 `meas:` 互合,结论 `docs/硬件平台/ADC通道映射说明.md` §8.2;CRC 不符必须拒收的实测更早、2026-10-31 远程半轮已绿),余下板级判据(周波数 / 极性等逐项)见 `docs/子系统设计/故障录波设计说明.md` §10;示波器仍旧只作旁证、不当判据。段内点序:触发瞬间落在段内点 159(预触发 160 点的最后一点),段的绝对相位与发生器无锁定关系,可核对的是相对相位与极性 |
| **仍然没有的(2026-10-29 更新)** | 没有命令控制台、也没有「把窗里 20 / 40 个点导出来」的定点 dump 子命令——**但原始样本这条通道本身已成立**(上一行的段文件:一次 320 点 / 8 路,比原来规划的 20 / 40 点窗更宽) | 现场取回一律走现成 FTP(21 端口),形状就地看回放页单通道、或在 PC 侧用同一脚本出图;示波器只对照发生器、不当判据。**判据已升级为「PC 独立重算 vs 板上读数」对表**,对表的执行轮次待台架(见 `docs/子系统设计/故障录波设计说明.md` §11) |
#### 4.6.4 接法与红线(照抄既有红线,不新发明)
- 注入点:串联电阻的**端子侧**焊盘(`U5` 排针),逐路清单见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §3;
引脚侧没有串阻保护,必须外串 **10 k** 限流。
- 幅度按**峰值**算,别看 Vrms 数字:1.000 Vrms 正弦峰值已 1.414 V;TPAFE 侧按判据只到 **±2 V**(满量程 ±5 V),
- 幅度按**峰峰值 / 峰值**核,别看有效值数字:Vpp 2.828 V 正弦峰值已 ±1.414 V;TPAFE 侧按判据只到 **±2 V 峰值(= Vpp 4 V)**(满量程 ±5 V),
STM32 那五路是 **0~3.3 V 单极性**——给它们注交流只能是削顶轮那种"故意削顶"的用例,峰值同样不得超 3.3 V。
- 发生器与板**必须共地**(否则量到的是两地之间的差),且不形成地环:优先单点共地、必要时发生器浮地。
- **不许**因为"反正发生器便宜"就往端子侧上额定电压——那是 §5 第二张卡(要变比)与 §9(要标准源)的范围。
@@ -352,7 +354,7 @@ typedef struct {
| 端子二次值 | 注入点在 ④ 之前,算出来还是引脚域 | §5「端子/子板变比确认」 |
| 精度等级(0.5 级 / 1 级) | 发生器自己的幅值误差本身就是要被校的量,不能冒充标准源 | §5「两点标定与精度验收」+ §7 #1 |
| 跨转换器相位 / 功率 / 对称分量 | 两片转换器无共同采样触发(V0.1 硬件缺陷)+ STM32 侧 1 拍乒乓滞后;量纲链路口径见通道映射说明的链路分段一节 | §9(本波不做矢量类运算) |
| THD / 谐波方和根 | 固件里只有两根谐波轨,没有合成出口 | §9(挂谐波轨立项) |
| THD / 谐波方和根 | 固件里只有两根谐波轨,没有合成后的数送出去 | §9(挂谐波轨立项) |
| 温升、EMC、长时间漂移 | 单轮台架不覆盖 | 送检与型式试验 |
---
@@ -366,14 +368,14 @@ typedef struct {
| 标识(任务名)| DoD(可验证验收判据) | 硬依赖 | 资源 | 写范围 | 状态 |
|---|---|---|---|---|---|
| **信号发生器动态波形验证** | 按 §4.6.2 跑完六轮(测频轮允许以"如实报不可测"通过),逐条记实测 / 判据 / 结论;执行步骤与判据表**新增到** `docs/测试说明/专项验证/ADC前端注入验证流程.md`(直流节之后开一节"交流"),实测结论在 `docs/硬件平台/ADC通道映射说明.md` §8.1 之后新开一节;证据(串口日志 + 104 落库)归档 `docs/测试说明/测试数据/boot_log_data/` | 静态注入闭环(✅ 2026-10-27)+ 一台能出 50 Hz 正弦、幅度可调到 1 Vrms 的交流信号发生器(**不需要标准源、不需要端子加压**) | 🔴 台架 + 手边发生器 | `docs/测试说明/`、`docs/硬件平台/` | ⬜ |
| **信号发生器动态波形验证** | 按 §4.6.2 跑完六轮(测频轮允许以"如实报不可测"通过),逐条记实测 / 判据 / 结论;执行步骤与判据表**新增到** `docs/测试说明/专项验证/ADC前端注入验证流程.md`(直流节之后开一节"交流"),实测结论在 `docs/硬件平台/ADC通道映射说明.md` §8.1 之后新开一节;证据(串口日志 + 录波段文件)归档 `docs/测试说明/测试数据/boot_log_data/` | 静态注入闭环(✅ 2026-10-27)+ 一台能出 50 Hz 正弦、幅度可调到 Vpp 2.828 V 的交流信号发生器(**不需要标准源、不需要端子加压**) | 🔴 台架 + 手边发生器 | `docs/测试说明/`、`docs/硬件平台/` | ✅ **已验证(2026-11-02 / 11-04 两轮、六轮全部闭合;用户裁定 2026-11-04 打勾保留本行)**:实测已回填执行手册各轮记录表、结论新开 `docs/硬件平台/ADC通道映射说明.md` §8.2、证据已归档 `boot_log_data`。**未闭合项(均已裁定不做或另登记)**:① 谐波叠加工况(基波+二次+五次同段)未跑——发生器无谐波叠加/ARB 功能,属设备缺口;算法侧由 `test/host/phasor/phasor_test.c` TC-PHASOR-006 覆盖,待有谐波功能标准源复跑;② 削顶 2 Hz 低频档与 sticky 复位复核——用户裁定 2026-11-04 关闭;③ 测频"降幅值门证 0.02 Hz 测准"的改码档未做(现状档以如实报不可测通过);④ 谐波 B 行归因一阶低通模型(fc≈796 Hz)未做绝对仪器证伪(预测 250 Hz 额外滞后 ≈17°,示波器到手复核);谐波功能产品化需板改(C35 换小 + 清点各路容值),已登记 `docs/任务规划/登记簿.md` §3 |
| **端子/子板变比确认** | 给出"端子电压 → ADC 引脚电压"的比值(万用表同时量端子与引脚,或查子板原理图后实测核对),写入 `docs/硬件平台/ADC通道映射说明.md`;据此判定 `eng` 能否置 1;数据缺失则本波只交付引脚电压并登记缺口 | 已知电压注入验证(✅);**与动态验证无依赖关系**,可并行 | 🟡 子板实物或原理图 | `docs/硬件平台/` | ⬜ |
| **两点标定与精度验收** | 电压 4 路(UA/UB/UC/UN)+ 电流 4 路(IA/IB/IC/IN)各做两点标定(零点 + 满度,温度不纳入),写入 `[adc_cal]` 并置 `VALID`;误差 ≤ 目标精度(待定:0.5 级 / 1 级 → §7 #1);证据归档 | 端子/子板变比确认;削顶五路的处置结论(削顶轮) | 🟡 标准源 / 继保测试仪 | `docs/算法/`、`docs/测试说明/测试数据/boot_log_data/` | ⬜ |
**为什么把动态验证排在第一**(不是因为它最重要,而是因为它把后面两张卡踩实):
1. 它**不依赖任何外部资源**,而另两张卡都在等东西;等待期正好做它。
2. 它复用刚闭环的注入点与读数出口,**边际成本几乎为零**。
2. 它复用刚闭环的注入点与读数的地方,**边际成本几乎为零**。
3. 它会先把削顶轮那类"预期内的 `[ERR]`"暴露在台架规程里并写清判读,避免第二、三张卡跑到一半
才发现"自动化测试把这轮读成 FAIL"。
4. 它顺手把"发生器能证 / 不能证"的界线钉住,两点标定开跑时判据不会串档。
@@ -434,9 +436,9 @@ flowchart TD
| 风险 | 触发条件 | 缓解 |
|---|---|---|
| **削顶负向用例被当成固件 bug** | 做削顶轮时 STM32 那五路必然钉下轨 → `rail: edge=…` 是 `[ERR]` 行,而 `/serial-boot-test` 的 forbidden 标记含 `[ERR]` → 整轮被判 FAIL | 判读规则写进流程文档:"做削顶轮的这一轮 `[ERR] rail:` 属预期,只人工判读、不计入 `/serial-boot-test` 结论",或把这五路排在最后单独一轮并事先声明。同时别忘 `cl=0xE6` 是**来源派生**(§2.6),不是本轮新削出来的 |
| **拿发生器的精度当标准用** | 用发生器自报 Vrms 当基准值去比 | 基准 = 万用表 AC 档实测(§7 #9);发生器只当"波形干净、频率可锁"的信号源,它自己的幅值误差正是要被校的量 |
| **拿发生器的精度当标准用** | 用发生器自报的有效值数字当基准值去比 | 基准 = 万用表 AC 档实测(§7 #9);发生器只当"波形干净、频率可锁"的信号源,它自己的幅值误差正是要被校的量 |
| **临时改了 `FREQ_AMP_MIN` 忘了还原** | 走 §7 #8 的 B 方案 | 改动落在产品头文件里、会编进固件。单列一条收尾判据:还原后 `/keil-build` 0 错误 0 警告 + `git diff` 里 `App/algo/freq.h` 必须为空;并在 §7 #8 那行留一句"本轮台架已还原" |
| **峰值当成有效值,顶到量程外** | 只看 Vrms 数字:1.000 Vrms 峰值已 1.414 V | 接线前按**峰值**核一遍:TPAFE 侧 ≤±2 V、STM32 侧峰值必须 <3.3 V(且负半周本就钉轨,只作削顶轮用) |
| **峰值当成有效值,顶到量程外** | 只看面板有效值数字:正弦有效值 1.000 V = Vpp 2.828 V,峰值已 ±1.414 V | 接线前按**峰值**核一遍:TPAFE 侧 ≤±2 V、STM32 侧峰值必须 <3.3 V(且负半周本就钉轨,只作削顶轮用) |
| **发生器与板不共地 / 地环** | 两台设备各自接电网地 | 单点共地,必要时发生器浮地;读数漂或出现与幅度无关的偏置先查这里 |
| **非整 50 Hz 注入被当成 `meas` 抖动 bug** | 注 49.5 / 50.5 Hz | `meas` 是**瞬时基波有效值透传、200 ms 是上送节拍不是平均窗**(§4.5)→ 快照轨会有拍频式周期间跳动,属预期。测频腿要扫频时读 `freq(hb)`,别读 `meas:` |
| **`cfg` 键数顶格** | 后续给 `[adc_cal]` 加键 | 已按 8+1 / 8 拆段;加键前先看 `CFG_FILE_MAX_KEYS`,必要时再拆 |
@@ -452,9 +454,9 @@ flowchart TD
| 不做 | 理由 / 归属 |
|---|---|
| THD / 谐波方和根真有效值、快照 4 点平均 | 挂 `docs/算法/继电保护功能复现规划.md` 的「遥测谐波轨(可选)」一起做;快照保持"基波有效值 + 直取相量"口径(§4.5) |
| **谐波轨的消费出口**(C04 / C05 目前无人消费) | 谐波轮只证"算得对";接线到判据或上送属谐波轨立项范围,本波不动 |
| **谐波轨被谁消费**(C04 / C05 目前无人消费) | 谐波轮只证"算得对";接线到判据或上送属谐波轨立项范围,本波不动 |
| 端子级额定电压、绝缘耐压、温升 | 要标准源 / 型式试验条件;本波所有注入都在 `U5` 排针侧 ±2 V 以内 |
| 录波(原始码值段文件) | **已交付代码面**(2026-10-29 立项并当日落地;判据属主 `docs/子系统设计/故障录波设计说明.md` §10,原卡片登记簿 2026-10-30 销项并入)本卡「动态波形验证」的样本出口**已**由录波段文件承担(§4.6.3 出口表已改),排序也随之调整(`docs/子系统设计/故障录波设计说明.md` §11);**没跑的是板级那一轮**(§10) |
| 录波(原始码值段文件) | **已交付代码面**(2026-10-29 立项并当日落地;判据属主 `docs/子系统设计/故障录波设计说明.md` §10,原卡片登记簿 2026-10-30 销项并入)本卡「动态波形验证」的原始样本**已**由录波段文件承担(§4.6.3 读数地点表已改),排序也随之调整(`docs/子系统设计/故障录波设计说明.md` §11);**没跑的是板级那一轮**(§10) |
| 104 文件传输(规约侧读文件) | 仍独立待排;现场与台架取回一律走现成 FTP(21 端口),规约侧文件服务等送检或第三方交接需求再议 |
| 等周波调频 | 与标定正交、无标准源时判据不可达,见 `docs/算法/继电保护功能复现规划.md` §3.1 |
| 功率 / 相位跨相比较 / 功率因数 / 对称分量 | **V0.1 硬件禁止**:跨转换器无同一时刻性,`docs/硬件平台/ADC通道映射说明.md` §7 通道归属行 |
@@ -472,9 +474,9 @@ flowchart TD
|---|---|
| **`docs/测试说明/专项验证/ADC前端注入验证流程.md`** | **执行步骤的属主**。本文只写"证到哪、判据是什么、为什么这么排";怎么接表笔、读哪一行、填哪张表一律在那篇里。动态验证的**步骤**同样落那篇(新开"交流"节),本文 §4.6 只留判据 |
| **通道映射说明** | `docs/硬件平台/ADC通道映射说明.md` §7.1(①②③④ 链路分段)与 §8.1(静态六项实测)是**量纲与实测记录的属主**;本文 §2.1 / §2.6 是它的**消费者**,不另立口径,动态实测结论也回写该文件 |
| **`docs/子系统设计/故障录波设计说明.md`** | 录波段文件是本卡「动态波形验证」的**样本出口**,数据面代码侧已落地(2026-10-29:环与段格式在 `App/algo/wave_ring.c` / `App/algo/wave_store.c`,PC 侧 `test/host/wave_read.py`);判据从「比对派生标量」升级为「PC 独立重算 vs 板上读数」对表的**执行轮次待台架**,动态验证的排序已因此让位给录波数据面(用户裁定 2026-10-29,理由与三处口径变更见 docs/子系统设计/故障录波设计说明.md §11) |
| **`docs/子系统设计/故障录波设计说明.md`** | 录波段文件是本卡「动态波形验证」的**原始样本来源**,数据面代码侧已落地(2026-10-29:环与段格式在 `App/algo/wave_ring.c` / `App/algo/wave_store.c`,PC 侧 `test/host/wave_read.py`);判据从「比对派生标量」升级为「PC 独立重算 vs 板上读数」对表的**执行轮次待台架**,动态验证的排序已因此让位给录波数据面(用户裁定 2026-10-29,理由与三处口径变更见 docs/子系统设计/故障录波设计说明.md §11) |
| **`docs/算法/采集与算法层设计说明.md`** | 算法与判据正文(全周傅氏、测频、保护元件);本文只规定"这些算法的信度到什么程度" |
| **`docs/子系统设计/IEC104上行设计说明.md`** | 动态验证的**读数出口**(`0x4011`~`0x4018` + `0x401D`);送检验收索引在 `docs/任务规划/登记簿.md` §7 |
| **`docs/子系统设计/IEC104上行设计说明.md`** | 104 上行协议本体(点表 `0x4011`~`0x4018` + `0x401D`、品质位绑定)——送检与验收的参照;**不是本验证轮的读数通道**;送检验收索引在 `docs/任务规划/登记簿.md` §7 |
| **送检验收** | 标准源送检依赖本文「两点标定与精度验收」;顺序不可倒(先变比 → 再标定 → 才解卡 → 才送检,§6) |
| **UI 补齐** | 已交付的 `meas_snap_t` + `adc_cal_flags()` 供 `ui_data_rt_t` 填 `eng`:现为 0 = 引脚电压,变比确认拿到变比后才升 1 = 二次值。**UI 不必等本文任何一张卡** |
| **双转换器无共同采样触发(V0.2 硬件改版)** | 本波的 `CLIPPED` 位就是这条硬件缺陷在软件里的可见形态;V0.2 改版后该位恒 0,页面与 104 绑定零改动 |
+7 -7
View File
@@ -20,14 +20,14 @@
| # | 事项 | 发现 | 证据与现状 | 出处 |
|---|---|---|---|---|
| dhara 重试自旋残留 | **dhara 重试自旋残留**——`try_recover()` 的 `DHARA_MAX_RETRIES`(8) 自旋在坏块密集时仍可能长时间占用 defaultTask(喂狗点) | 2026-10-02 | 低优先:现有 `vol_lock` + 喂狗节奏缓解;若台架再出"存储侧喂狗饥饿"再排期 | `Lib/dhara/map.c` |
| 可选全序列卷锁 | **可选全序列卷锁**——现卷锁仅覆盖 `syslog` / `cfg` / `lftpd` 三条路径(`vol_lock_wait(0)` try 语义),其它潜在访问点(如 UI 读日志)未纳入 | 2026-10-02 | 待评估:先确认是否真有第二写者;无则关闭本项 | `App/fs/vol_lock.{c,h}` |
| dhara 重试自旋残留 | **dhara 重试自旋残留**——`try_recover()` 的 `DHARA_MAX_RETRIES`(8) 自旋在坏块密集时仍可能长时间占用 defaultTask(喂狗点) | 2026-10-02;2026-11-05 复核未复发 | 低优先:现有 `vol_lock` + 喂狗节奏缓解,自旋另有 FTL 入口直接喂狗兜底(`../架构设计/STM32F4-Base存储架构说明.md` §10.5);若台架再出"存储侧喂狗饥饿"再排期 | `Lib/dhara/map.c` |
## 3. 硬件(V0.1 缺陷 → V0.2 改版项)
| # | 事项 | 发现 | 证据与现状 | 出处 |
|---|---|---|---|---|
| 双转换器无共同采样触发 | **8 路电气量分属两片转换器(V0.1 硬件缺陷,需下一版硬件修改)**——UA/UN/IA 走 TPAFE5160(16 位、8 通道同步、±5 V 双极性),UB/UC/IB/IC/IN 走 STM32 ADC(12 位、顺序扫描、0~3.3 V 单极性):① 两片转换器无共同采样触发 + STM32 侧顺序扫描(9 通道一轮 ≈ 67 µs)→ 跨转换器通道**无同一时刻性、相位关系不确定**,主板侧功率/功率因数/相角/对称分量类运算不成立;② 同族电气量精度与量程不一致(LSB ≈ 152.6 µV vs ≈ 806 µV,且 STM32 侧前端无中点偏置、负半周削顶);③ 语义与硬件归属交叉,固件映射/UI 通道序/自检注入须逐通道查表绕开 | 2026-10-10 定性更正(**撤销** 2026-10-09 建档时"有意分配、不要修正"的说法) | **V0.2 改版要求**:8 路电气量 UA/UB/UC/UN/IA/IB/IC/IN **全部接 TPAFE5160**,与 TPAFE 上 5 路备用路(AIN5/13/7/15/12)对调串联电阻在转换器一侧的目的地——元件数量与料号不变,属走线级改动。**V0.1 现板软件口径**:主板侧只做逐通道独立监视,禁止跨转换器做相位/功率/功率因数/矢量类运算(此类量取子板计量模块结果)。固件侧消费者已落地(ADC 采集链路,2026-10-10,按语义映射表取数)→ V0.2 改版只改映射表内容,上层语义与代码不动 | `../硬件平台/ADC通道映射说明.md` §1/§7;`../硬件平台/V0.1_网表详细分析报告.md` §1.4 V10、§6-3 |
| IA 前端差分滤波限制谐波带宽 | **IA 通道差分滤波电容 C35 = 100 nF 构成一阶低通 fc ≈ 796 Hz,谐波产品路线的硬件前置未清**——250 Hz 注入读数 −4.4 % 即前端真实衰减(板端读数忠实;R19/R21 各 1 k `docs/硬件平台/V0.1.tel`:49 + C35 跨接差分对,拓扑 FR-ADC-5 `docs/产品需求/产品需求设计文档.md`);工频测量不受影响,外推 5 次 −4.6 %、9 次 −13 %、15 次 −27 %、21 次(1050 Hz)−39.6 % | 2026-11-04(模型与实测数据 `docs/测试说明/测试数据/boot_log_data/20261104_ac_ia_rc_model.txt`) | **改版/改板方向**:C35 换 10 nF(fc≈8 kHz、21 次仅 −0.9 %;改板优先于软件逐阶修正——容差与温漂使修正表不可信,理由详 `docs/硬件平台/ADC通道映射说明.md` §8.2)+ **清点其余各路差分滤波电容容值**(网表无容值标注,C35 = 100 nF 系用户口头确认,其余各路未定);将来有示波器可按预测复核(250 Hz 差分分量额外滞后 ≈17°)。详述 `docs/硬件平台/ADC通道映射说明.md` §8.2 | `docs/测试说明/专项验证/ADC前端注入验证流程.md` 谐波记录 B 行;`docs/硬件平台/ADC通道映射说明.md` §8.2 |
## 4. 测试与验证基础设施
@@ -42,6 +42,7 @@
| rs485_task 白名单缺口 | **KNOWN_GAPS 白名单清理**——现存唯一缺口 = `App/task/rs485_task.c`(RS-485 接线门禁未满足、刻意不接线,随 RS-485 采集链路 暂缓,见 `暂缓-RS485.md`) | 白名单不清 = "写了不编译"盲区仍在 | 随 RS-485 采集链路 一并出白名单(`--strict` 供审计复跑) | 结构债 | 报告 N 族残余(报告已删) |
| 缩堆迁 CCM 后半(暂缓) | **内存优化簇剩余**:原报告缩堆建议的后半(缩堆 56→32 KB → 迁 CCM)· 同类三项 | ⏸ **整簇暂缓**(2026-10-15 用户裁定):没有功能在等这块预算,而搬迁要动 scatter、要逐条过 DMA 可达性清单、缩堆还要上板复测。⚠ 代价落在"以后加任务 / 抬栈 / 加堆"那一刻——CCM 只剩 7,904 B、FreeRTOS 堆 `min_ever` 8,464 B,届时 `mem-budget` 会先报警 | 重开条件见 `../内存管理/RAM使用分析与优化方案.md` §4。⚠ **原报告另有一条已判定不可行**(CMSIS-RTOS2 `freertos_os2.h` 有 `#if (configMAX_PRIORITIES != 56) #error`,改小直接编译失败),不再列入 | **暂缓** | 报告 R 族剩余/§5.5(报告已删) |
| 仓库体积膨胀观察 | **仓库膨胀**:`.git` **233 MB**(2026-10-25 实测)+ 手册图片 36.3 MB(受控文件合计仅 79.3 MB,`.git` 已是它的 3 倍) | clone/备份慢,且持续恶化 | 降采样 / 拆 submodule / LFS 三选一 **+ 一次 `git filter-repo` 历史重写**(三项都不解决历史膨胀)。**已决策(2026-10-11):暂不处理、登记观察**——推送/协作前重评 | **仓库决策** | 报告 D 族 |
| 静态链硬线双 FAIL | **timeSyncTask / iec104Task 静态最坏链跌破 ISR 硬线**(判据 = margin ≥ max(1024 B, cfg×30%),静态 margin 是唯一拦提交项但尚未挂 pre-commit 钩子,口径见 `../内存管理/RAM使用分析与优化方案.md` §4.0.7 第③条)——2026-11-04 复测:master 2b848c4a timeSyncTask **2056 B(余 504)**、iec104Task **1600 B(余 960)**,双 FAIL;#78 合入后 timeSyncTask **1904 B(余 656)**,只减不增(−152 B = 旧 8888 任务自身帧)。两链同尾 = `ch395f SPI 故障收尾 → dbg_console_drain 幻影环`(`../内存管理/RAM使用分析与优化方案.md` §4.0.7「休眠环」在 #74 UDP / #77 SNTP 出向链接入后被重新展开) | 抬栈属 Ask-first:先台架复采 `[STACK]` 水位(scripts/stack_gate.py 三档判据),拿真实余量再定抬栈或接受现状;幻影环是 armlink 记账非设备故障,**不得写成优化收益也不得当作已越线事故** | ⏳ 待台架复采 | #78 复测留痕 `docs/内存管理/data/stack_report_20261104.md`;`../内存管理/RAM使用分析与优化方案.md` §2.3 |
---
@@ -49,10 +50,10 @@
| 顺序 | 条目 | 要做什么 | 完成或关闭判据 |
|---|---|---|---|
| 1 | **net 层跨上下文收口** | 同批处理两件事:裸指针收口为状态查询 API;对时 reconcile/relisten 突发导致 uiTask 800 ms 以上连续缺席,评估优先级矩阵与突发分片让路 | 同类台架负载下不再出现目标饿死签名;网络与 UI 回归通过;证据写入网络与看门狗模块文档 |
| 2 | **网络性能资源建议簇** | 分别评估 PASV 重复建监听、PHY 强制 100M 无回退、`NET_MAX_SOCKETS` 与单连接语义不一致;DE 项随 RS-485,不在本项做。机理见 `../网络/Net层阻塞模型架构设计.md` 与 `Drivers/BSP/NET/README.md` | 每项形成“修改并验证”或“有理由不做”的结论;不为了清清单做无收益重构 |
| 3 | **dhara 重试自旋与卷锁评估** | 先确认是否仍出现存储侧喂狗饥饿、是否确有第二写者,再决定是否修改 | 有新证据才排修改;无第二写者则关闭全序列卷锁项 |
| 4 | **uvprojx 空 TU 观察** | 201 个 LVGL `.c` 中 127 个在 `.map` 零产出,但当前增量构建仅 4~5 秒;有全量构建耗时痛点时先补计时基线,再用 Keil 原生 `<IncludeInBuild>0</IncludeInBuild>` 可逆排除 | 有实测收益才保留改动;否则继续观察 |
| 1 | **网络性能资源建议簇** | 分别评估 PASV 重复建监听、PHY 强制 100M 无回退、`NET_MAX_SOCKETS` 与单连接语义不一致;DE 项随 RS-485,不在本项做。机理见 `../网络/Net层阻塞模型架构设计.md` 与 `Drivers/BSP/NET/README.md` | 每项形成“修改并验证”或“有理由不做”的结论;不为了清清单做无收益重构 |
| 2 | **uvprojx 空 TU 观察** | 201 个 LVGL `.c` 中 127 个在 `.map` 零产出,但当前增量构建仅 4~5 秒;有全量构建耗时痛点时先补计时基线,再用 Keil 原生 `<IncludeInBuild>0</IncludeInBuild>` 可逆排除 | 有实测收益才保留改动;否则继续观察 |
> 原第 1 项「net 层跨上下文收口」已于 2026-11-06 闭环并销项(子项 A 审计确认收口完成、子项 B 台架重验确认新负载下 uiTask ≥800 ms 饿死签名不复现;证据见 `../网络/网络自愈架构设计.md` 与 `../子系统设计/看门狗设计说明.md` 变更记录 2026-11-06 条目)。原「dhara 重试自旋与卷锁评估」项随 #45 复核(卷锁无第二写者)关闭销项。
> RS-485 白名单随 `暂缓-RS485.md` 整簇处理,不列为 UI 后的独立编码任务。
> 并行写域、工作树与合并纪律统一见 `docs/环境与部署/并行任务工作树方案.md`。
@@ -66,7 +67,6 @@
| **队列往返基线待重验** | 台架 + PC peer | 下次 Phase 13 窗口重锁基线 | 本文件 §1 |
| **网络负向场景台架验证** | 拔线、SPI 故障注入、远显压力条件 | PHY 拔线、芯片级 `net_init` 失败、短写压测 | 本文件 §1 |
| **CI 远端闭环未验证** | runner 与第二台机器 | 验证远端两 job 闭环和不同工具路径 | 本文件 §4 |
| **UI 六页真机判据(记录 5 页 + 运行报告)** | 台架:NAND 里有真实事件记录、SD2506 电池域可控、104 主站可连 | 上板复核六件事:真记录翻页与掉电后保持、清除记录后对应页归零、上电一次看 `boot_count` +1、拔 RTC 电池后 `seq_state` 落 RESTARTED、IWDG 复位后 `rst_cause` 落 IWDG、主站连一次看 `conn_up` +1(模拟器侧这些记录文件无写入方、无 `boot_stats`、无 104 协议栈,黄金只拍得到空态「无记录」与固定假数据的显示口径) | 六个页面模块文件头「台架待补」段 + `../测试说明/专项验证/模拟器差距清单.md` §2.3 开机账本一行 |
| **SNTP 校时真机判据** | 台架:板与 PC SNTP 服务器(192.168.31.161 / .13)同网段可达 | `[sntp]` 使能 + 配服务器后上板复核:`[SNTP] step offset=` 步进日志、钟面与时间源一致(本地 UTC+8 口径)、`poll_min` 周期到点重对、拔线后指数退避与主备轮换、恢复后回到周期 | `../子系统设计/系统墙钟时间维护说明.md` §16 |
**送检顺序不可倒过来**:产品构建当前要求 UA/UN/IA 的标定 VALID 全部置位才走保护判据。
@@ -47,10 +47,10 @@ dhara 失败类 +84;RO 另 +208,全是该失败类名表)→ `ER_IROM1`
<!-- MEM_SNAPSHOT:BEGIN generated by scripts/check_mem_numbers.py -->
| 区域 | 用量 | 容量 | 占比 |
|---|---|---|---|
| ER_IROM1 | 284,800 B (278.12 KB) | 1,048,576 B (1024 KB) | 27.2% |
| RW_IRAM1 | 94,736 B (92.52 KB) | 131,072 B (128 KB) | 72.3% |
| ER_IROM1 | 285,716 B (279.02 KB) | 1,048,576 B (1024 KB) | 27.2% |
| RW_IRAM1 | 94,752 B (92.53 KB) | 131,072 B (128 KB) | 72.3% |
| RW_CCM | 57,376 B (56.03 KB) | 65,280 B (64 KB) | 87.9% |
| **Flash (ROM 合计)** | **286,872 B (280.1 KB)** | 1,048,576 B (1024 KB) | **27.4%** |
| **Flash (ROM 合计)** | **287,788 B (281.0 KB)** | 1,048,576 B (1024 KB) | **27.4%** |
<!-- MEM_SNAPSHOT:END -->
各区的容量与常量来源:
@@ -125,7 +125,7 @@ dhara 失败类 +84;RO 另 +208,全是该失败类名表)→ `ER_IROM1`
| ftpTask | `1024*4` | 4KB | lftpd FTP 服务 | 740 B(余 81%)/ 静态 1216 B |
| testTask | `2048*4` | 8KB | 测试套件(产品构建不创建;存储套件深链需要) | 未创建 / 静态 496 B |
| defaultTask | `1280*4` | 5KB | FatFS 挂载/探针 + 配置引擎 + syslog + 栈水位探针 | 2152 B(余 41%)/ 静态 **3016 B**(栈余量收口时抬栈 1024→1280,2026-10-12) |
| timeSyncTask | `640*4` | 2.5KB | TCP 时间同步 | 616 B(余 50%)/ 静态 **1264 B**(栈余量收口时抬栈 512→640,2026-10-12) |
| timeSyncTask | `640*4` | 2.5KB | 网络校时节拍宿主(SNTP 客户端;:8888 监听 2026-11-04 退役 #78,任务入口不变) | 616 B(余 50%,2026-10-12 实测)/ 静态 **1904 B**(2026-11-04 #78 交付态复测,`docs/内存管理/data/stack_report_20261104.md`;链尾 `time_sntp_run→net_sendto→ch395f_spi_fault_set→控制台 drain 幻影环`,§4.0.7 同族记账。**master 2b848c4a 同判据实测 2056 B = FAIL**,本 PR 只减不增(−152 B = 旧任务自身帧)——FAIL 属 #77/#74 后既有债,与 iec104Task 1600 B 同源,见登记簿「静态链硬线双 FAIL」;台架 `[STACK]` 水位待复采后再定抬栈与否,未据静态值擅自抬栈) |
| adcTask | `640*4` | 2.5KB | TPAFE5160 采样消费 + 全周傅氏相量 + 有效性校验(TIM3 1 kHz 节拍,ADC 采集链路→全周傅氏相量→「采样有效性校验」 2026-10-11) | **952 / 2560**(余 1608 B / 62%,台架 `/serial-boot-test` 实测 2026-10-11);静态 **1320 B**(2026-10-12 复测,保护判据接线后) |
| iec104Task | `640*4` | 2.5KB | IEC104 上行服务(默认 2404 监听 + link 状态机,IEC 104 上行 2026-10-12) | 未上板 / 静态 **1456 B**(拆链→重建监听→net_bind→SPI 故障→日志尾,日志主导;512 words 时余 592 B < ISR 底线 → 抬至 640,余 1104 B / 43%) |
| protectTask | `512*4` | 2KB | 保护判据节拍(prot_elm_run 消费者 + 「自检失败闭锁」采样闭锁,保护任务 2026-10-12) | 未上板 / 静态 **872 B**(float 判据 + phasor 快照 + 日志尾,余 1176 B / 57%) |
+3 -3
View File
@@ -15,15 +15,15 @@
<!-- MEM_BUDGET:BEGIN generated by scripts/ram_baseline.py -->
| 区域 | 用量 | 容量 | 占比 | 门禁(≤92%) |
|---|---|---|---|---|
| ER_IROM1 (Flash) | 284,800 B | 1,048,576 B | 27.2% | 参考 |
| ER_IROM1 (Flash) | 285,716 B | 1,048,576 B | 27.2% | 参考 |
| RW_CCM | 57,376 B | 65,280 B | 87.9% | PASS |
| UNINIT_CCM | 48 B | 256 B | 18.8% | 参考 |
| RW_IRAM1 | 94,736 B | 131,072 B | 72.3% | PASS |
| RW_IRAM1 | 94,752 B | 131,072 B | 72.3% | PASS |
| 子系统(静态 RW+ZI;除 RTOS 堆在 CCM 外均在 SRAM1) | 现值 | 配额 | 状态 |
|---|---|---|---|
| 网络 | 13,958 B | 12 KB | ⚠ 超 1.6 KB |
| 存储 | 7,072 B | 12 KB | OK |
| 存储 | 7,092 B | 12 KB | OK |
| UI | 36,475 B | 16 KB | ⚠ 超 19.6 KB |
| RTOS 堆 | 57,376 B | 56 KB | 堆=配额 |
| 应用 | 26,433 B | 8 KB | ⚠ 超 17.8 KB |
@@ -0,0 +1,97 @@
# Stack budget report
- Source: `MDK-ARM\STM32F407-Demo\STM32F407-Demo.htm` (Keil static call graph)
- Linker run: Wed Nov 04 17:43:34 2026
- Global maximum stack usage: **3040 B** (any call tree)
Rule: `margin = cfg - max(static_max_depth, runtime_peak)` must be >= max(1024 B ISR, 30% of cfg).
| Task | Entry | Cfg (B) | Static max (B) | Runtime peak (B) | Worst (B) | Margin (B) | Margin % | Verdict |
|---|---|---|---|---|---|---|---|---|
| defaultTask | `StartDefaultTask` | 5120 | 3040 | - | 3040 | 2080 | 40% | PASS |
| netTask | `StartNetTask` | 3840 | 1936 | - | 1936 | 1904 | 49% | PASS |
| ftpTask | `StartFtpTask` | 4096 | 1600 | - | 1600 | 2496 | 60% | PASS |
| uiTask | `StartUiTask` | 16384 | 1632 | - | 1632 | 14752 | 90% | PASS |
| testTask | `start_test_task` | 8192 | 744 | - | 744 | 7448 | 90% | PASS |
| timeSyncTask | `time_sync_task` | 2560 | 1904 | - | 1904 | 656 | 25% | FAIL |
| adcTask | `adc_task_func` | 2560 | 1424 | - | 1424 | 1136 | 44% | PASS |
| iec104Task | `iec104_serv_task` | 2560 | 1600 | - | 1600 | 960 | 37% | FAIL |
| protectTask | `protect_task` | 2048 | 880 | - | 880 | 1168 | 57% | PASS |
`Static max` = armlink worst-case call-tree depth; `Runtime peak` = measured high-water mark (boot + whatever workload ran before the sample); `Worst` = max of the two, which is what the verdict is computed from.
## Worst call chain per task
### defaultTask: 3040 B (own frame 0 B)
```
StartDefaultTask -> default_task_func -> storage_bring_up -> net_cfg_load -> cfg_file_load -> s_write_template -> s_write_doc -> cfg_store_write_atomic -> f_rename -> sync_fs -> disk_ioctl -> ftl_flush_cache -> dhara_map_write -> prepare_write -> auto_gc -> dhara_map_gc -> try_recover -> raw_gc -> trace_path -> dhara_journal_read_meta -> dhara_nand_read -> gd5f_read_from_cache -> dbg_console_write_line -> con_append -> dbg_console_drain -> MX_UART5_Init -> HAL_UART_Init -> HAL_UART_MspInit -> Error_Handler -> dbg_console_write_line (Cycle)
```
### netTask: 1936 B (own frame 0 B)
```
StartNetTask -> net_task_func -> net_process_messages -> net_close_locked -> net_udp_settle_close -> net_udp_datagram_read -> ch395f_read_recv_buf -> ch395f_spi_dma_transfer -> ch395f_spi_fault_set -> dbg_console_write_line -> con_append -> dbg_console_drain -> MX_UART5_Init -> HAL_UART_Init -> HAL_UART_MspInit -> Error_Handler -> dbg_console_write_line (Cycle)
```
### ftpTask: 1600 B (own frame 24 B)
```
StartFtpTask -> lftpd_start -> lftpd_inet_listen -> net_bind -> net_udp_bind_exec -> ch395f_open_socket -> ch395f_poll_cmd_status -> ch395f_get_cmd_status -> ch395f_write_cmd -> ch395f_spi_fault_set -> dbg_console_write_line -> con_append -> dbg_console_drain -> MX_UART5_Init -> HAL_UART_Init -> HAL_UART_MspInit -> Error_Handler -> dbg_console_write_line (Cycle)
```
### uiTask: 1632 B (own frame 0 B)
```
StartUiTask -> ui_task_func -> ui_port_service_keys -> lv_refr_now -> lv_display_refr_timer -> refr_invalid_areas -> refr_area -> refr_configured_layer -> refr_obj_and_children -> refr_obj -> lv_obj_redraw -> refr_obj (Cycle)
```
### testTask: 744 B (own frame 224 B)
```
start_test_task -> dbg_console_write_line -> con_append -> dbg_console_drain -> MX_UART5_Init -> HAL_UART_Init -> HAL_UART_MspInit -> Error_Handler -> dbg_console_write_line (Cycle)
```
### timeSyncTask: 1904 B (own frame 0 B)
```
time_sync_task -> time_sntp_run -> s_send_round -> net_sendto -> net_udp_sendto_exec -> net_send_locked -> ch395f_write_send_buf -> ch395f_spi_dma_transfer -> ch395f_spi_fault_set -> dbg_console_write_line -> con_append -> dbg_console_drain -> MX_UART5_Init -> HAL_UART_Init -> HAL_UART_MspInit -> Error_Handler -> dbg_console_write_line (Cycle)
```
### adcTask: 1424 B (own frame 384 B)
```
adc_task_func -> adc_health_report -> syslog_post -> dbg_console_write_line -> con_append -> dbg_console_drain -> MX_UART5_Init -> HAL_UART_Init -> HAL_UART_MspInit -> Error_Handler -> dbg_console_write_line (Cycle)
```
### iec104Task: 1600 B (own frame 160 B)
```
iec104_serv_task -> s_serv_poll -> s_service_link -> s_drop_conn -> s_bind_listen -> net_bind -> net_udp_bind_exec -> ch395f_open_socket -> ch395f_poll_cmd_status -> ch395f_get_cmd_status -> ch395f_write_cmd -> ch395f_spi_fault_set -> dbg_console_write_line -> con_append -> dbg_console_drain -> MX_UART5_Init -> HAL_UART_Init -> HAL_UART_MspInit -> Error_Handler -> dbg_console_write_line (Cycle)
```
### protectTask: 880 B (own frame 160 B)
```
protect_task -> s_log_active_edge -> dbg_console_write_line -> con_append -> dbg_console_drain -> MX_UART5_Init -> HAL_UART_Init -> HAL_UART_MspInit -> Error_Handler -> dbg_console_write_line (Cycle)
```
## Frame-size ranking (own frame, top 15)
| Bytes | Function |
|---|---|
| 624 | `lv_draw_sw_arc` |
| 400 | `ui_task_wave_seg_win` |
| 400 | `draw_line_skew` |
| 384 | `adc_task_func` |
| 384 | `sb_link_poll` |
| 352 | `lv_draw_sw_triangle` |
| 352 | `net_stack_bring_up` |
| 352 | `net_udp_datagram_read` |
| 344 | `ui_w_editor_draw` |
| 328 | `lv_obj_redraw` |
| 328 | `view_frame_draw_cb` |
| 324 | `s_transform` |
| 320 | `wd_stall_evidence` |
| 312 | `nc_draw_cb` |
| 312 | `sn_draw_cb` |
@@ -19,7 +19,7 @@
关键事实:
1. **CCM 对 CPU 是全速内存**。Cortex-M4 无 语义取数与有效性 cache,"CCM 是慢内存"的直觉只适用于带 cache 的核(M7/出口与记录/H7 的非 cacheable 旁路),**在本芯片上不成立**——任何"按速度分配区域"的论证对本文档无效。
1. **CCM 对 CPU 是全速内存**。Cortex-M4 无 L1 cache,"CCM 是慢内存"的直觉只适用于带 cache 的核(M7/L4/H7 的非 cacheable 旁路),**在本芯片上不成立**——任何"按速度分配区域"的论证对本文档无效。
2. **DMA 对 CCM 地址的传输静默不落地**。2026-09-21 首轮 CCM 实验实证:以 CCM 上栈缓冲(dhara meta 132B / is_free 64B)为 DMA 源/目的时传输不生效,引发 FTL 重格式化循环与幻影坏块。此后 DMA 阈值提至 1024B 消除。**工程规则按"DMA 不可达 CCM"执行,不论数据手册如何表述。**
3. CCM 存在性已用 `ST-LINK_CLI -r32 0x10000000` 本机实测可读写;**克隆片可能缺 SRAM3,换料必须重测并回退布局**。
4. 工程不进入 Stop/Standby 低功耗模式,两区域掉电保留行为无差异,不构成分配判据。
@@ -2,11 +2,11 @@
> **模块名称**:故障录波——采样源沿用 TIM3 1 kHz 节拍,专用录波环(`App/algo/wave_ring.c`,已落地)、触发、落盘(defaultTask 是文件系统唯一写者)、取回(FTP 21 端口)、现场回放(UI 单通道页)。
> **文档定位**:本波的**设计属主**——口径、通道集、数据形态、触发模型、文件格式、预算与所有权边界、显示契约、二期不返工的结构约束在此定稿。**板级判据与本波执行顺序的属主即本文 §9 与 §10**——原任务规划下的《故障录波》卡片登记簿已于 2026-10-30 随销项并入本文后删除(沿革见 §14);排期顺位在 `docs/任务规划/README.md` §2.0「独立」行。
> **状态**:设计已定稿,**数据面 + 触发与落盘接线 + UI 两个页面(手动录波、录波回放)的代码面已交付(2026-10-29)**——主机单测 113 / 170 / 110 全 rc=0、双端编译 0 错误 0 警告、板端编码器与 PC 侧解码器两份独立实现字节级互验通过。**没做完的只有板级判据那一轮**(注量对表、FTP 拉回、与 `meas:` 和 104 浮点 YC 对表、CRC 不符必须拒收的实测、回放页放一段真波、两个待台架核数值),逐条列在本文 §10 板级各行。三条已裁定口径见 §1.2。**2026-10-31 远程半轮**已把其中不需要到场与注入的六样跑过(落盘道、触发时序、冷却恢复、轮转、PC 侧坏段拒收、104 并发)——结果与回放页新缺陷「段表枚举恒空」全在 §10「板级远程半轮记录」小节;**该缺陷已于 2026-11-02 远程修复并板级闭环**(根因 = 读侧 `wave_store_seg_path()` 返回值判错 + 键处理缺失效,证据与前后对拍见 §10「回放页枚举恒空缺陷修复记录」)。
> **状态**:设计已定稿,**数据面 + 触发与落盘接线 + UI 两个页面(手动录波、录波回放)的代码面已交付(2026-10-29)**——主机单测 113 / 170 / 110 全 rc=0、双端编译 0 错误 0 警告、板端编码器与 PC 侧解码器两份独立实现字节级互验通过。**没做完的只有板级判据那一轮**(注量对表、FTP 拉回、与 `meas:` 对表、CRC 不符必须拒收的实测、回放页放一段真波、两个待台架核数值),逐条列在本文 §10 板级各行。三条已裁定口径见 §1.2。**2026-10-31 远程半轮**已把其中不需要到场与注入的六样跑过(落盘道、触发时序、冷却恢复、轮转、PC 侧坏段拒收、104 并发)——结果与回放页新缺陷「段表枚举恒空」全在 §10「板级远程半轮记录」小节;**该缺陷已于 2026-11-02 远程修复并板级闭环**(根因 = 读侧 `wave_store_seg_path()` 返回值判错 + 键处理缺失效,证据与前后对拍见 §10「回放页枚举恒空缺陷修复记录」)。
> **相关文档**:
> `docs/子系统设计/ADC采样节拍设计说明.md`(节拍与时序账的属主;本文 §3 的数据源就是它)
> `docs/硬件平台/ADC通道映射说明.md`(网名 `AINn` 不等于板级 `ADCn`,也不等于转换器通道号;链路分段与削顶归属)
> `docs/任务规划/数据可信.md` §4.6(动态波形验证判据;录波落地后它的读数出口升级,见 §11)
> `docs/任务规划/数据可信.md` §4.6(动态波形验证判据;录波落地后它的读数通路升级,见 §11)
> `docs/架构设计/STM32F4-Base存储架构说明.md` §10.1(FatFs 两条实证陷阱与 8.3 短名限制)
> `docs/内存管理/内存内容分配策略.md` §6 与 R6 规则(新增静态缓冲大于 4 KB 的前置动作)
> `docs/UI设计/内容页架构.md`、`docs/UI设计/RemoDispBus协议与接收设计说明.md`(回放页与远端看图的能力边界)
@@ -311,7 +311,7 @@ flowchart TD
- **实际落地形态(逐字)**:打印点在 `App/task/adc_task.c`:782 行,格式串 `"wave: seg=%lu armed=%u src=%s pts=%u err=%lu ovf=%lu drop=%lu"`——**字段名与顺序就是上面的模板**(台架与 PC 脚本按行名 grep,动它就断脚本);`src` 取 M(手动)/ P(保护)/ T(定时自抓)/ `-`(本次上电还没触发过);`armed` 只在 FREEZE 与 SEALED 为 1(COOL 期只挡新触发不录新段,画进 armed 会被台架误读);`seg` 是累计**成功回执**的段数、不是轮转号;`err` = 落盘失败 + SEALED 滞留超时自弃(含 §5.2 第四条的 ring abandoned 判废),由环内计数收口,落盘道不数第二份账。`err` 与 `ovf` 的**已知容差**(lead 裁定 2026-10-29,不修只入档):这两个计数是跨上下文的读-改-自增(`ovf` 由任意上下文的拒绝路径加、`err` 由 adcTask 的滞留自弃与 defaultTask 的落盘失败分别加),本层双端编译、不许引 FreeRTOS / CMSIS 的临界区内在函数,所以并发拒绝或并发失败时**理论上可能少计一次**。定性为**观测计数的已知容差**:只用于趋势与判读,**不作为任何判据的唯一依据**——要坐实「冷却期内确实来了第二次触发」,同时看 `armed` 与那一刻 `/log/start.log` 的时刻。契约原文见 `App/algo/wave_ring.h` 文件头「观测计数的已知容差」段;
- **落盘道失败留痕名清单(2026-10-30 并入原卡片登记簿;台架判读按名索引,不新增第二种形态)**:单板上一律一行 `[WAVE] seg drop: <原因> (idx=… written=…)`,统一打印点 `App/task/default_task.c`:816——`crc selftest FAIL` / `mkdir /wave` / `opendir /wave` / `readdir /wave` / `seg_path` / `pack_start` / `f_open` / `pack_next` / `f_write short` / `pack stall` / `f_close` / `len mismatch` / **`ring abandoned`**(最后一条即 §5.2 第四条陷阱的处置留痕,代码与主机单测面已有、板级未测,观察项见 §10);另有一条非失败的慢段留痕 `[WAVE][WARN] seg held <毫秒> ms (idx=…)`(`App/task/default_task.c`:831)——搬得慢不是错,真失败才走 `seg drop`。
- 只在原先静默的黑洞处补锚点,别重复已有步骤——每条 DBG 日志约 90 B Flash 加 216 B 栈(`AGENTS.md` 的日志与工具链节);
- 该行已同步进 `docs/测试说明/专项验证/ADC前端注入验证流程.md` 的读数出口表(2026-10-29;同一张表还登记了段文件出口与 PC 侧读段工具)。
- 该行已同步进 `docs/测试说明/专项验证/ADC前端注入验证流程.md` 的读数地点表(2026-10-29;同一张表还登记了录波段文件与 PC 侧读段工具)。
---
@@ -322,9 +322,9 @@ flowchart TD
| 主机侧纯逻辑单测(新增,进 `test/host/`) | ① 环:预触发与后触发点数、冻结与解冻、冷却丢弃计数;② 段格式编解码往返,含 CRC 不符、零长度、字节数不符三条失败路径;③ 触发状态机三条来路(手动 / 保护 / bench)。**环与格式必须是纯逻辑**(不碰寄存器、不碰 RTOS)才能这样测——这是 `App/algo/` 既有分层纪律 |
| PC 侧工具的定性 | `test/host/wave_read.py` 是 **bench 工具**(`test/host/` 下的 loose .py,先例 `test/host/ftp_capture.py`),**不是**主机单测套件 → 不建 `run_unit_test.py`、不加 pre-commit 专属钩子(专属钩子默认不补,按 Lead 裁定 2026-10-27);它自带 `--selftest` 就是它的自带回归,跑法与四个子命令见 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §4 |
| 跨工具链分叉(实证,写进来是为了下一个模块别重踩) | 两份录波 .c 只 include 自身头(链上只有 stdint.h)时,ARMCC 报 22 条 identifier "NULL" is undefined;而主机 MSVC / gcc 会传递性把 stddef.h 拉进来,**主机单测完全照不出这个分叉** → 新增模块需要用 NULL 就自己 include stddef.h(与 `App/algo/sample_ring.c` 同口径,别塞公共头) |
| 板级 | 信号发生器注 1 V / 50 Hz → 手动一段 → FTP 拉回 → PC 脚本量出周波数、幅值、极性与注入一致;再把 PC 重算的基波有效值与板上 `meas:` 与 104 浮点 YC 对表。**判据只量四样:周波数、幅值、极性、钉轨路数——不比绝对相位**(理由见 §4.2「段内点序」:触发瞬间在工频周期内任意落点,段字节里没有绝对时间参考;真要比相位必须让发生器给同步触发,本波不做)。**钉轨对表的合格判据 = 头位图 ⊇ 实测钉轨路数,且差异必须能由注入条件解释**——因为 `clip_mask` 是按来源派生的链路可信性标记(§6.2 偏移 24 行),不是本段实测值:只加直流或小幅注入时那五路本就不该钉轨,硬取等式会假红。**同段另起一条强观察项**:V0.1 下这五路若在做**交流注入**时反而没钉轨,先怀疑接线或该路根本没被驱动——这是告警面,不是失败面(等式仍作为默认尺子留在 PC 侧 `shape --strict` 里,因为它有这个信号价值;要放行差异用那条判据的解释权,不靠改尺子)。**§5.2 第四条的板级观察项(代码与单测面已有、板级未测)**:bench 连续自抓期间人为把卷占住 2 s 以上(例如同一段跑 FTP 大文件读),看串口 `wave:` 行的 `err` 是否加一、是否只出现**一条** `[ERR] … seg drop: ring abandoned` 留痕(不是每拍刷屏)、且段号不推进(下一段仍写同号文件) |
| 板级 | 信号发生器注 1 V / 50 Hz → 手动一段 → FTP 拉回 → PC 脚本量出周波数、幅值、极性与注入一致;再把 PC 重算的基波有效值与板上 `meas:` 对表。**判据只量四样:周波数、幅值、极性、钉轨路数——不比绝对相位**(理由见 §4.2「段内点序」:触发瞬间在工频周期内任意落点,段字节里没有绝对时间参考;真要比相位必须让发生器给同步触发,本波不做)。**钉轨对表的合格判据 = 头位图 ⊇ 实测钉轨路数,且差异必须能由注入条件解释**——因为 `clip_mask` 是按来源派生的链路可信性标记(§6.2 偏移 24 行),不是本段实测值:只加直流或小幅注入时那五路本就不该钉轨,硬取等式会假红。**同段另起一条强观察项**:V0.1 下这五路若在做**交流注入**时反而没钉轨,先怀疑接线或该路根本没被驱动——这是告警面,不是失败面(等式仍作为默认尺子留在 PC 侧 `shape --strict` 里,因为它有这个信号价值;要放行差异用那条判据的解释权,不靠改尺子)。**§5.2 第四条的板级观察项(代码与单测面已有、板级未测)**:bench 连续自抓期间人为把卷占住 2 s 以上(例如同一段跑 FTP 大文件读),看串口 `wave:` 行的 `err` 是否加一、是否只出现**一条** `[ERR] … seg drop: ring abandoned` 留痕(不是每拍刷屏)、且段号不推进(下一段仍写同号文件) |
| 板级·触发来路(2026-10-30 并入原卡「手动触发与保护启动接线」板级段) | 真机面板按一次「手动录波」出一段;造一次过流,段号与该时刻 `/log/start.log` 事件对齐;冷却期内二次触发只加 `ovf` 不重录(**同时看 `armed` 与那一刻 start.log 的时刻,不要只盯 `ovf` 数字**——容差见 §9);冻结窗口内 104 上送与保护判据不受影响(这条是「丢录波样本不丢采集」的验收) |
| 板级·回放页(2026-10-30 并入原卡「现场单通道回放页」板级段) | 真机上放一段真波(不是模拟器合成节拍);远端看图能拍到该页做留证(只作留证,不是波形通路,§8.4);**空态与 CRC 失败态绝不允许画成一条直线**——用坏段在真机复现一次。**2026-10-31 远程半轮进展见下「板级远程半轮记录」小节**:PC 侧坏段拒收已过;回放页坏段/空态画面的测试面**已于 2026-11-02 枚举缺陷修复后打开**(真机已验证真段显示 + 切段切道,见下「回放页枚举恒空缺陷修复记录」小节),坏段/空态两画面本身仍是到场轮要拍的项 |
| 板级·回放页(2026-10-30 并入原卡「现场单通道回放页」板级段) | 真机上放一段真波(不是模拟器合成节拍);远端看图能拍到该页做留证(只作留证,不是波形通路,§8.4);**空态与 CRC 失败态绝不允许画成一条直线**——用坏段在真机复现一次。**2026-10-31 远程半轮进展见下「板级远程半轮记录」小节**:PC 侧坏段拒收已过;回放页坏段/空态画面的测试面**已于 2026-11-02 枚举缺陷修复后打开**(真机已验证真段显示 + 切段切道,见下「回放页枚举恒空缺陷修复记录」小节),坏段/空态两画面本身**已于 2026-11-06 台架远程轮拍毕闭环——见下「回放页坏段/空态画面闭环记录」小节,本行判据全部板级实证完毕** |
| UI | `ui-verify` 五步;回放页入 `ui-golden` 黄金参考(**参考图一旦入库只能改代码对齐,禁止刷参考掩盖**);新叶走 `gen_menu.py` 重生成 + 字库链 |
| 构建 | `/keil-build` 要求 0 错误 0 警告;新 .c 双端注册走 `new-source-file`(`MDK-ARM/STM32F407-Demo.uvprojx` 与 `simulator/CMakeLists.txt` 两处显式列表) |
| 台账 | R6 三处同步 + `scripts/ram_baseline.py --update` + `mem-numbers` 与 `mem-budget` 钩子 |
@@ -380,10 +380,11 @@ try 锁纪律)照常读出并显示 ⇒ try 锁读径正常;`manual_req` 作
「0 段缓存」,回放页从此假显「无录波段」、直到下一次 `manual_req` 才重试;失败应不钉表、
下键重试,与 soe_store 读者同纪律。
**本半轮没跑的(人到场轮清单)**:注量对表(周波数 / 幅值 / 极性 / 钉轨路数)、`meas:` 与 104
浮点 YC 数值对表、两个待台架核数值(封存超时窗 §4.2 兜底行与冷却时长 `App/algo/wave_ring.h`)、P 触发与 start.log 对齐(还得先解标定闭锁)、
**本半轮没跑的(人到场轮清单)**:注量对表(周波数 / 幅值 / 极性 / 钉轨路数)、`meas:`
浮点数值对表、两个待台架核数值(封存超时窗 §4.2 兜底行与冷却时长 `App/algo/wave_ring.h`)、P 触发与 start.log 对齐(还得先解标定闭锁)、
bench T 源与卷占用 2 s 的 `ring abandoned` 观察(需 bench 构建)、~~回放页坏段画面与空态画面
(等枚举缺陷修复后才有测试面)~~ **(2026-11-02 枚举缺陷修复后测试面已开,见下小节)**、
(等枚举缺陷修复后才有测试面)~~ **(2026-11-02 枚举缺陷修复后测试面已开,见下小节;2026-11-06
台架远程轮两画面已拍毕闭环,见「回放页坏段/空态画面闭环记录」小节)**、
`task_prof` 读路径耗时峰值。**执行动作侧**(到场的人做什么、
说哪句话、会看到什么)→ `docs/测试说明/专项验证/故障录波板级到场轮执行手册.md`。
@@ -440,6 +441,42 @@ bench 锁全程持有;三次烧录(埋点 / 诊断加强 / 根因修复)
(Before/After、切段、切道共四帧 + 串口实录,见该目录 README)。
**至此回放页「真段 / 坏段 / 空态」三态全部有了测试面**,第二幕尾步的坏段画面判据可跑。
### 回放页坏段/空态画面闭环记录(2026-11-06,台架远程轮,#68 第二幕尾步)
bench 锁全程持有(任务 `remote-shoot-68-274d2d56da74`,17:03:38 起、收工 `--bench-pass` 释放),
无人到场;固件 `Nov 6 2026 00:17:43 suite=NONE`(#53 台架轮复核构建,回放页读侧代码自 11-02
修复后零改动,本轮**不涉代码**)。执行手册 §4 步 7 原文流,三态画面 + 恢复态共四帧入档
`docs/测试说明/测试数据/wave_shot_20261106/`(README 含判据对照、串口锚点、复现口令与
sha256 全清单;7003 `LCDMEM` 原帧 4× 渲染,与上小节同法):
| 画面 | 实拍结果 | 判据 |
|---|---|---|
| 覆盖前 `UA SEG6 M` | 阶梯正弦 + 0 线 + 触发光标,Pk≈1423 mV | 对照基准(真段正常放波) |
| **坏段同号覆盖后** | **仅标题 + 「该段不可读」,零波形元素、零顶行底行字段** | **绝不许画直线 = 过**(画面逐比特 = `WP_ST_BAD` 显式文案路径) |
| **空态(`/WAVE` 全删后开页)** | **仅标题 + 「无录波段」**,同刻串口 `[ERR][UI_TASK] ui wave head idx=8 open fail fr=4` | 显式说「没有」= 过;再按 `r` 再探盘画面逐字节不变 |
| 九件原件恢复后 | 网格 + 波形区回归,帧与到场首帧逐字节相同 | 收工板况 = 到场板况 |
坏段制造 = `RETR WAVE06.BIN → byte[130]^=0x01 → STOR 同号覆盖`(页开着覆盖、`r` 走满一圈
再入该段触发读侧判废——`ui_task_wave_load_head()` 头 CRC+长度等式+数据区流式 CRC 全量验,
`App/task/ui_task.c`);PC 侧同件 `wave_read dump` 同判 `REJECT: data CRC16 mismatch:
stored 0xF991 calc 0xB111 …nothing drawn`(rc=1),画面与解码器两份独立实现互证。
收工处置走手册 §7 二选一的**「不留常设负样本」**分支:板上坏段与本环投放的 `WAVE09.BIN`
均已删除,`/WAVE` 恰为到场九件原件、逐件 RETR+sha256 复验一致;坏样本点名留档在证据目录
`samples/WAVE06_bitflip_reject.BIN`(原件 `samples/WAVE06_original.BIN` 一并留档,两件只差
第 131 字节一比特)。
两条现场发现(都记账不修码):**F1** 开机后 `STOR` 的新文件(坏版、有效版都试过)**不进
回放页段表**——表只在 `manual_req` 或「当前段消失」时重扫(11-02 v1.6 钉表纪律),页开关不
触发重扫;首攻 `WAVE09` 因此静默出局,改列内既有段同号覆盖一次即中(FTP 手工投放段要让回放
页看见需顶掉当前段或触发一次手动录波——纪律性事实,供后续轮引用)。**F2** 数据 CRC 判废在
串口**静默**、靠画面自证(留痕只给 `open fail fr=` 一类),与 11-02 修复记录的留痕设计一致。
另记台架环境事实:到场时板网链路已断(会议室网口),人插回网线后远程轮才得以执行——
`[ERR][I104] i104: bind port 2404 FAIL` 在该构建每次上电复现,属 #53 跟踪面,本轮不新开。
**至此第二幕(注量对表 + 坏段/空态画面)全幕闭环**:注量三项 2026-11-04 由 #40 §8 交流轮
跑完(幅值 / 相位 / 削顶,104 浮点遥测按用户裁定不作对照证据),尾步两画面 2026-11-06 拍毕;
手册第二幕状态与 `docs/任务规划/README.md` §2.0「独立」行已同步销项。
---
## 11. 与 `docs/任务规划/数据可信.md` 的口径变更(三处)
@@ -447,7 +484,7 @@ bench 锁全程持有;三次烧录(埋点 / 诊断加强 / 根因修复)
| 旧口径 | 新口径 | 原因 |
|---|---|---|
| 「录波通道必须先有工程量,排在本波之后」 | 录波录**原始码值**,不等工程量;解释靠头里的系数快照 | §3.2:现在根本没有工程量,等下去等于永远不动 |
| 动态波形验证的读数出口 = 派生标量(`meas:` / 104 / `phasor(hb)`) | 派生标量仍是**判据**,但样本改从录波段导出 → 判据升级为「PC 独立重算 vs 板上读数」对表 | 录波段就是现成的样本出口,不必再造一条串口通路 |
| 动态波形验证读数的地方 = 派生标量(`meas:` / 104 / `phasor(hb)`) | 派生标量仍是**判据**,但样本改从录波段导出 → 判据升级为「PC 独立重算 vs 板上读数」对表 | 录波段就是现成的样本来源,不必再造一条串口通路 |
| 动态波形验证「手边可做、排在最前」 | 排在录波 P1 之后(用户裁定 2026-10-29:录波先行) | 先有样本通路,验证才不留遗憾 |
(2026-10-30 更新:原卡片登记簿已销项并入本文,§10 尾有本波执行顺序图;排期顺位在 `docs/任务规划/README.md` §2.0「独立」行。)
@@ -223,7 +223,7 @@ static HAL_StatusTypeDef iwdg_deferred_start(const IWDG_HandleTypeDef *a_h) { (v
|---|---|---|---|
| NAND 初始化 / `f_mkfs` / `dhara_map_resume` / `f_mount` | 启动段 | 数百 ms ~ 数秒 | **① 启动段不启动狗**(§4.1) |
| PHY 链路等待(60×50 ms) | `net_stack_bring_up` | 最长 3 s | **② 分片心跳**:循环内每轮 `task_wd_beat` |
| `time_sync_handle_conn` 的 30 s 总预算 | `App/sync/time_sync.c` | 单次可睡满 30 s | **② 切片**:`TIME_SYNC_WAIT_SLICE_MS=200` 夹住每次 `net_recv_to` 的 `rem`,每片先喂位(总预算语义不变) |
| `time_sntp_run` 的单次响应等待(UDP `net_recvfrom_to`) | `App/sync/time_sntp.c` | 单次调用 ≤1 片 `SNTP_RECV_SLICE_MS=50` | **② 切片**:响应总预算(5 s 起指数放大)拆成 50 ms 片,任务 200 ms 节拍每轮喂位(旧 `time_sync_handle_conn` 30 s 预算行随 :8888 退役于 2026-11-04 删除,见 `../子系统设计/系统墙钟时间维护说明.md` §15) |
| 就绪屏障等待(NET/STORAGE READY) | net / ui / ftp / timesync 入口 | 不定 | **② 分片**:等待按 100 ms 分片并喂位 |
| 卷锁等待(FatFs 多任务) | `lftpd_io.c`、`App/fs/vol_lock.h` | 不定 | **② 分片**:100 ms 分片阻塞 + 每片 `lftpd_task_wd_beat()` |
| 卷锁 try 失败(defaultTask / uiTask **从不等锁**,取不到就跳过本轮) | `App/fs/vol_lock.c` 观测计数 | 不定 | **④ 只计数、不在失败分支留日志**:锁层记 5 态(`acquired` / `try_timeout` / `blk_timeout` / `failopen`,16 B 静态),读口 `vol_lock_get_stats()` **不取锁**、任意上下文可调。为什么不许在 try 失败处补一条日志——唯一能把事写下来的通道(`/log/wdev.log`、`run.log`)自己也要取这把锁,而卷锁**非递归**,被卷忙挡住时既写不出还会自取死锁;一次性留痕交给 syslog 唯一写者按差值 latch 补投(道G task-17,接口口径见 `App/fs/vol_lock.h`) |
@@ -376,7 +376,7 @@ snapshot == required → miss_streak=0、证据门闩复位、喂狗
| netTask | 主循环;`net_stack_bring_up` 的 PHY 等待循环内;就绪屏障等待分片;入口 `task_wd_bind()` |
| ftpTask | 主循环 = lftpd 事件循环:`lftpd.c` 事件循环每轮、RETR/STOR 每分片;`lftpd_inet.c` 连接/数据等待每轮每片;`lftpd_io.c` 卷锁等待每片;入口 `task_wd_bind()` |
| uiTask | 主循环;就绪屏障等待分片;入口 `task_wd_bind()` |
| timeSyncTask | 主循环;监听重试(500 ms/2 s)前;accept 轮询;`time_sync_handle_conn` 的 **200 ms 切片**;屏障等待分片;入口 `task_wd_bind()` |
| timeSyncTask | 主循环(200 ms 校时节拍,每轮首行喂位;`time_sntp_run` 单次 ≤50 ms 片 + `time_sync_delay_fed` 50 ms 分片);屏障等待 100 ms 分片;入口 `task_wd_bind()`(旧「监听重试 / accept 轮询 / handle_conn 200 ms 切片」三处埋点随 :8888 退役于 2026-11-04 删除,墙钟说明 §15) |
| adcTask | 主循环每 1 ms 节拍 `task_wd_beat(TASK_WD_ADC)`;**不做 NAND I/O → 不登记 FTL 心跳路由**(无需 `task_wd_bind()`) |
| testTask | **不埋点、不登记、不入掩码** |
| NAND FTL | `gd5f2gq5ue.c`:长操作入口 `nand_ftl_wd_beat()` + `nand_ftl_wd_feed()`;`gd5f_wait_busy` 每 100 ms 双管(路由到调用者任务) |
@@ -713,3 +713,4 @@ enter/exit 段还能读出"此刻仍在段内已多久"——**永久阻塞的
| 2026-10-12 | **iec104Task / protectTask 纳入监视(IEC 104 上行/保护任务):必需掩码 `0x77`→`0xF7`→`0x1F7`** | 两行合并记录(IEC 104 上行 落地时漏补本文,保护任务 一并纠偏):**IEC 104 上行** 新增 `TASK_WD_IEC104 = 7`(iec104Task 100 ms 服务循环喂位,NET_READY 屏障等待按 100 ms 分片喂位),产品 `0x77`→`0xF7`、HW 层 `0x75`→`0xF5`;**保护任务** 新增 `TASK_WD_PROTECT = 8`(protectTask 20 ms 判据节拍喂位,见 `docs/算法/继电保护功能复现规划.md` §7),产品 `0xF7`→`0x1F7`、HW 层 `0xF5`→`0x1F5`。两任务均**不依赖存储/网络之外的屏障**(protectTask 无任何屏障)→ 任何构建都置位;均不做 NAND I/O → 不登记 FTL 心跳路由。主机侧单测 `beat_all()` 与 `tc_003`/`tc_005`/`tc_011` 掩码断言同步至 `0x1F7`,39 断言全绿。⚠ 注意 `0x1F7` 不含 bit3(testTask 任何构建不入掩码,口径不变) |
| 2026-10-25 | **停喂判定按位分账(v1.5,大窗判读 F2)**:stall/停喂唯一判据从「复合连续缺席窗数」改为「**任一必需位的连续缺席窗数**」——同一任务连续 8 窗(800 ms)没跑过才申报停摆并停喂;多任务交替缺席(本窗缺 A、下窗缺 B)各自清零、且缺席窗在容忍线下**照常喂狗**(旧实现自第一个缺席窗起就不喂,800ms 只是申报点)。动因 = 2026-10-25 台架大窗:54 个探针重建窗里 9 条 stall 行中 16:24/16:28 两起为复合误升级(mg=877/918,无任何单位到 800ms 单串),16:39 为真 UI 单串(~1.2 s,受害者面修复另立 F3 票);`MISS start` 降级为复合边沿**诊断行**(不再代表停喂,判读口径 §6.1/§11.1 同步);真停摆到复位的总时长最坏 +约 0.7 s(§2.2 链注)。§0/§2.2/§3.2/§5.3/§6.1/§11.1/§11.6 同步;主机单测 `test/host/watchdog/watchdog_test.c` 断言按新判据改写 + 新增 **TC-WATCHDOG-017**(20 窗交替缺席:零 stall、20 窗持续喂)/ **TC-WATCHDOG-018**(同位 8/9/10 连击必报停 + 停喂;恢复窗喂、账本重启,第二段亚容忍串不误报),47 断言全绿 |
| 2026-10-26 | **卷锁 try 失败纳入 ④「只计数」口径 + 修一处会骗人的契约(道G task-17)** | §4.3 场景表新增一行:卷锁 try 失败(defaultTask / uiTask 从不等锁,取不到就跳过本轮)既不需要分片也不需要心跳,缺的是**可观测**。落地形态:`App/fs/vol_lock.c` 记 5 态计数(`acquired` / `try_timeout` / `blk_timeout` / `failopen`,共 16 B 静态、一次自增),`vol_lock_get_stats()` **不取锁**、不关中断、任意上下文可调、NULL 无害。为什么不许在 try 失败处补一条日志:能把事写下来的通道(`/log/wdev.log`、`run.log`)自己也要取这把锁,而卷锁**非递归**,被卷忙挡住时既写不出东西还会自取死锁——所以留痕只能由 syslog 唯一写者按差值 latch 补投(另立 task-40 接在 `syslog_drain()` 的 `s_quiet_drop` 差值块之后)。同时修契约:`App/fs/vol_lock.h` 原写「0 - 超时未获取」、`vol_lock.c` 原 :38 把 fail-open 归给 0,而代码(:46)与 `TC-VOLLOCK-008` 都是**返 1**;现在两处都按代码写实并显式警告「返 1 也可能是零互斥」,`failopen` 计数就是它的证据。**观测时刻刻意不在锁层**:记时刻要读 tick,等于给 defaultTask 取锁链添 callee 与本帧(本档 §11 一贯按字节省的就是这条链),改由消费方观测并自盖 `obs_first_ms` / `obs_last_ms`——那是**被观测到的时刻**,不等于发生时刻,命名与文案都不许写成"首次发生"。机器证据:`test/host/vol_lock` 新增 TC-VOLLOCK-015~019(45 断言全绿:T2/T3 互不冒领、fail-open 计数可累加、读取不消耗证据);另把「喂狗点取锁一律 timeout=0」从注释纪律升级成会 FAIL 的断言——4 套假件加 `s_last_wait_to`,断言落在 TC-SYSLOG-010/012、TC-SOESTORE-016/018、TC-CFGFST-003/016/032/033、TC-LFTPIO-034,并做过红-绿反证(把 `sys_log_mcu.c:318` 的 `0u` 改 `50u` → 135/137 双红;把 `lftpd_io.c:48` 的 `100u` 改 `0u` → 32/33 红;随后按原串改回、SHA-256 逐字节相同) |
| 2026-11-06 | **台架重验(#39 子项 B):新负载剖面下 uiTask ≥800 ms 饿死签名不复现** | 新负载剖面一整轮 30 min(00:34–01:04):SNTP 请求/退避(poll_min=1,无可达服务器)+ 持续 FTP 512KB + 周期 104 GI/COV + 7003 拉帧 10Hz。结果:看门狗 `task stall` **0 条**、复位 **0 次**、NAND `/log/wdev.log` **当日零新增 STALL**(独立佐证,最新一条为 2026-11-05 11:24:39);**880** 次瞬时节拍抖动(UI/FTP/IEC104 位)全部 <800 ms 自恢复、均与网络 relisten 瞬间同刻——阈值下抖动,非饿死;7003 最差单轮 **759.1 ms**(<800 ms 线)、18000/18000 零 CRC 零超时;FTP 188/188 全过;104 协议负载正常(16/18 检查项,COV 触发 FAIL = 台架浮空模拟输入已知限制、无 B10 源)。结论:8888 reconcile/relisten 突发源退役(#78,2026-11-04)+ 异步 `net_drop_conn` 收口后,新负载下 **uiTask ≥800 ms 饿死签名无触发源**——子项 B 完成判据(台架负载下不再出现目标饿死签名)本轮达成。网络侧记录见 `网络自愈架构设计.md` 变更记录 2026-11-06 条目 |
@@ -24,8 +24,9 @@
### 1.1 时基口径:内部一律**本地钟面**(用户裁定 2026-10-27)
**裁定原文:「时基先本地为准」。** 定的是**冲突时谁赢**:面板时钟页与 8888 对时把「本地钟面当 epoch」写入,
而 104 的 `C_CS NA`(对时命令)携的是 UTC,两条写入口**后写者赢** ⇒ 装置墙钟与主机本地时刻恒差 8 小时。
**裁定原文:「时基先本地为准」。** 定的是**冲突时谁赢**:(当时的)面板时钟页与 8888 对时把「本地钟面当
epoch」写入,而 104 的 `C_CS NA`(对时命令)携的是 UTC,两条写入口**后写者赢** ⇒ 装置墙钟与主机本地时刻
恒差 8 小时(8888 已于 2026-11-04 退役,写入口现为 SNTP / UI / 104,见 §15、§16)。
本裁定结束「后写者赢」:**内部真源 = 本地钟面**,任何来源写入前都要先换算成本地钟面再落库。
这条同时也纠正了**本文自己的矛盾**(这才是 8 小时的根):§2 曾写 epoch = 「自 1970-01-01 00:00:00 **UTC**
@@ -298,8 +299,8 @@ uint32_t now = sys_clock_get(); /* Unix 秒,可用于 FatFS 文件时间、
| 项目 | 现状 | 可扩展方向 |
|------|------|------------|
| 时间范围 | 受 `uint32_t` 限制至 2038 | 改用 `uint64_t`/`time_t` 扩展 |
| 运行期校准 | 30 天惰性再基准化已实现(§7):纯自我参照、零 I2C;**有意不**周期性重读 RTC 重锚——RTC 漂移(±20ppm ≈ ±1.7 s/天)远大于 Tick 漂移,重锚反而降低精度;时间纠偏由时间同步(§15)负责 |
| 网络校时 | 已实现两条:PC 推送 / TCP 8888(§15);**SNTP 客户端 / UDP 123(§16,2026-11-04 落地)** | NTP 公网源需现场路由,口径不变;104 `C_CS` 写入口径见 §1.1 末待决项 |
| 运行期校准 | 30 天惰性再基准化已实现(§7):纯自我参照、零 I2C;**有意不**周期性重读 RTC 重锚——RTC 漂移(±20ppm ≈ ±1.7 s/天)远大于 Tick 漂移,重锚反而降低精度;时间纠偏由时间同步(§16)负责 |
| 网络校时 | **SNTP 客户端 / UDP 123(§16,2026-11-04 落地)为唯一网络校时来源**;PC 推送 / TCP 8888 同日退役(§15) | NTP 公网源需现场路由,口径不变;104 `C_CS` 写入口径见 §1.1 末待决项 |
| 时区 | **口径已定:内部一律本地钟面,不存时区**(用户裁定 2026-10-27,见 §1.1) | 「API 层加偏移参数」这条旧建议**作废**;唯一待决的是 104 上行是否要转 UTC(§1.1 末,送检前定) |
### 13.1 用户 SRAM 的占用分配(共享资源,用之前先在这里登记)
@@ -333,98 +334,45 @@ SD2506 有 **70 字节电池保持用户 SRAM**(寄存器 `2CH~71H`,`Drivers
| `Drivers/BSP/SD2506/sd2506.c` / `.h` | SD2506 RTC I2C 驱动(`sd2506_get_time` / `sd2506_set_time`) |
| `App/app/app_main.c` | 初始化调用顺序:`sd2506_init()` → `boot_stats_init()`(用户 SRAM 上电账本,§13.1)→ `sys_clock_init()` |
| `App/util/boot_stats.c` / `.h` | 用户 SRAM 上电账本 + 本次开机复位原因快照(占用见 §13.1;单测 `test/host/boot_stats/`) |
| `App/sync/time_sync.c` / `time_sync.h` | 时间同步实现(TCP Server,`timeSyncTask`) |
| `App/sync/time_sntp.c` / `time_sntp.h` | SNTP 校时客户端(§16,同一任务内挂 8888 事件循环);单测 `test/host/sntp/` |
| `App/sync/time_sync.c` / `time_sync.h` | `timeSyncTask` 实现(网络校时节拍宿主;TCP :8888 推送监听 2026-11-04 退役,§15);单测 `test/host/time_sync/` |
| `App/sync/time_sntp.c` / `time_sntp.h` | SNTP 校时客户端(§16,同任务内由 200 ms 校时节拍驱动);单测 `test/host/sntp/` |
| `Drivers/BSP/NETCFG/sntp_cfg.c` / `.h` | `[sntp]` 配置段属主(注册在 `net_cfg_load()`) |
| `Lib/coreSNTP/` | vendored coreSNTP v2.0.0 序列化器(MIT,仅 serializer + LICENSE;48 字节报文编解码) |
| `test/host/time_sync_server.py` | PC 端时间推送客户端(TCP) |
---
## 15. 时间同步(PC 推送 / TCP)
## 15. 时间同步(PC 推送 / TCP :8888)——已退役(2026-11-04)
除 RTC 自身走时与开发期校时宏外,系统支持由 **PC 通过 TCP 主动推送本地墙钟** 来同步板子时间,使板子时间与开发电脑一致(无需公网 NTP)。
> **状态:已退役。** SNTP 客户端上线(§16,PR #77)当日,`:8888` 推送监听、8 字节 "TIME" 协议、
> PC 端推送器 `test/host/time_sync_server.py` 与探针 `test/host/e02_probe.py` 一并删除,网络校时
> **唯一入口 = §16 SNTP**。历史实现(协议帧、监听/退避状态机、约 80 断言点的主机单测、真机验收日志)
> 以 git 历史为准(`App/sync/time_sync.c` v1.x 与本节旧版);旧验证锚点
> `[TIME_SYNC] time_sync: TCP listen on :8888 (sock=1)` 仅供解读旧日志(`scripts/v5_log_gap_report.py`
> 的探针窗口分类器仍识别 `no TIME packet`,属历史取证,不改)。
### 15.1 模块与角色
| 角色 | 提供方 | 说明 |
|------|--------|------|
| 时间同步服务端(板子) | `App/sync/time_sync.c` / `time_sync.h` | TCP Server,监听 `TIME_SYNC_PORT`(默认 8888) |
| 同步任务 | `timeSyncTask`(FreeRTOS 任务) | 独立任务,由 `Src/freertos.c` 创建(优先级 `osPriorityNormal`,栈 2KB) |
| 时间推送端(PC) | `test/host/time_sync_server.py` | Python TCP 客户端,周期推送本机本地时间 |
| 落盘接口 | `sys_clock_set_unix()` | 收到时间包后调用,内部转 `sd2506_time_t` 并写回 SD2506 |
### 15.2 协议
PC 每轮发送固定 8 字节帧:
```
字节 0..3 : 魔术字 "TIME"(0x54 0x49 0x4D 0x45)
字节 4..7 : 本地 Unix 时间戳,uint32,大端(PC 本地时间,含时区,与电脑显示一致)
```
板子 `time_sync_handle_conn()` 读取后校验魔术字,取大端 uint32 调用 `sys_clock_set_unix(epoch)` 更新运行基准并写回 RTC。
### 15.3 任务流程
`timeSyncTask` 启动后先等待 `SYS_EVT_NET_READY` 事件标志(取代旧版 8s 魔法延时;网络不就绪则一直等待),进入循环:
```c
/* osFlagsNoClear:就绪位是"状态"不是"事件",任何消费者都不得把它清掉
* (否则其它等待者永不唤醒——2026-09-21 FTP 永不监听事故的根因) */
osEventFlagsWait(sys_evtHandle, SYS_EVT_NET_READY, osFlagsWaitAny | osFlagsNoClear, osWaitForever);
for (;;) {
ls = time_sync_open_listener(); /* net_socket + net_bind + net_listen,失败重试 */
conn = net_accept(ls, NULL, NULL); /* 阻塞等待 PC 连接(无连接立即返回 -1,循环重试) */
time_sync_handle_conn(conn); /* net_recv 读到 8 字节 → sys_clock_set_unix → net_close */
/* conn(单连接模式下即 ls)被 net_close 释放,下次循环重建监听 */
}
```
> 单连接模式下监听 Socket 收到连接后即转为数据通道,连接关闭后被释放;因此每轮循环都**重新创建监听 Socket**(与 `lftpd` 同模式),与 FTP 不冲突。
### 15.4 为什么用 TCP 而非 UDP
- 所有 socket 操作(`net_socket` / `net_bind` / `net_listen` / `net_accept` / `net_recv` / `net_close`)均走 `net_socket` 的**线程安全 API**,内部经消息队列由 `netTask` 串行执行;
- netTask 因此只需做 `net_poll()` + `net_process_messages()`,不掺杂任何应用层网络逻辑;
- **TCP 的全部 API 已经是基于消息队列的**(已在 `net_socket.c` 实现);UDP 的 `net_bind` / `net_sendto` / `net_recvfrom` **曾经**绕过队列,**2026-11-03 已并入队列**(改造事实见 `docs/网络/BSD_Socket_API_使用指南.md` §9.0)。也就是说:**"UDP 不安全"不再是本节选 TCP 的理由**——本节结论不变(现有 TCP:8888 时间同步通道继续有效),但若日后要换成 UDP(#57 SNTP 方向),不再需要先改 net 层。
### 15.5 Socket 分配与冲突
- `net_socket()` 从 0 开始分配第一个空闲 Socket 控制块(`alloc_socket()`),并把硬件 Socket 号设为该下标;调用时的第三个参数(0)仅为协议占位,不影响分配。
- 当前启动顺序:FTP 任务(`NET_READY` + `STORAGE_READY` 屏障满足后,无魔法延时)先监听 → 占用一个 Socket(单连接模式下监听通道复用为数据通道);时间同步任务(`NET_READY` 后)后监听 → 占用另一个空闲 Socket。二者不冲突。
- 单连接模式允许**任意** Socket 作为"监听 + 数据复用"通道,且总共 8 个 Socket,FTP 与时间同步各用 1 个,余量充足。
- SNTP 客户端(§16)另占 1 个 UDP Socket:懒创建(首次到点才 `net_socket`+`net_bind` 本地口 0 = 芯片动态分配),断网代际变化、`enable=0` 或内核错误码时关闭归还;不监听、不参与端口台账。
### 15.6 客户端实现要点(避坑)
PC 端 `test/host/time_sync_server.py` 发送 8 字节后**必须保持连接打开**,等待板子读取(或短延时)后再 `close()`:
- 若发送后立刻关闭,CH395F 在收到 FIN 时会**丢弃接收缓冲里尚未被板子读出的 8 字节**;
- 板子 `net_recv` 经消息队列异步执行(有 ~10ms+ 调度延迟),等它去读时连接已 DISCONNECT、缓冲已清空,`net_recv` 走 CLOSED 分支返回 0,时间包丢失、同步失败;
- 客户端改为 `sendall` 后 `recv` 直到板子主动关闭(EOF)或 2s 超时,即可保证板子先读到数据。
### 15.7 验证
板子日志应出现:
```
[TIME_SYNC] time_sync: TCP listen on :8888 (sock=1)
[NET] sock1 standalone accept
[NET] recv sock1 len=8
[CLK] sys_clock_set: wall clock updated to <epoch>
[CLK] sys_clock_set: SD2506 RTC written
[TIME_SYNC] time_sync: wall clock updated (epoch=<epoch>)
```
PC 端 `python test/host/time_sync_server.py` 每 `interval` 秒推送一次,epoch 随电脑本地时间递增即表示同步正常。
- **当初定位**:开发期让板子时间对齐 PC(无需公网 NTP)——PC 周期推固定 8 字节帧
`"TIME"(54 49 4D 45) + uint32 大端"本地 Unix 时间戳"(与电脑显示一致)`,板端校验魔术字后走
`sys_clock_set_unix()` 同一收口写回 SD2506(§1.1 口径的第二个历史写入口)。
- **退役理由**:① SNTP 落地后它只剩"开发期工具"定位,与 SNTP 双写并存时现场钟面**后写者赢**、
节奏不可控;② 单连接监听被 `time_sync_handle_conn()` 全程占用,一条连接不结算(30 s 预算/
半包等待)其他对时全排队——head-of-line 风险,为喂狗才做的 200 ms 分片只是缓解;③ 依赖 PC 上
Python 推送器在场,现场不可持续;真机对时判据已由 UI 对时页 + `[SNTP]` 日志/OPER 痕覆盖。
- **仍然有效的教训**:CH395F 单连接 TCP 服务在收到 **FIN 时会丢弃该 socket 内尚未读走的缓冲数据**
(旧推送器因此必须 sendall 后保持读至 EOF/2 s 超时)。`lftpd`、`ui_net_sink` 与今后任何常驻
TCP 服务同样受此约束(先结算再断开);UDP 校时(§16)无此坑。
- **Socket 预算变化**:`alloc_socket()` 从 0 分配、硬件 Socket 号=下标的机制不变;常驻监听由
21/8888/7003 三个减为 21/7003 两个,SNTP 的 1 个 UDP Socket 仍懒创建、按代次/开关归还(§16)。
- **TCP 而非 UDP 的旧论证**(选 TCP 的队列/串行化背景)已被 2026-11-03 UDP 并入消息队列
(`docs/网络/BSD_Socket_API_使用指南.md` §9.0)与本文第 16 节的落地取代,不再单独成立。
---
## 16. SNTP 校时(客户端,2026-11-04 落地)
- 模块:`App/sync/time_sntp.c/.h`(挂在 timeSyncTask 的 8888 事件循环里,等待切片 ≤50 ms,不饿任务狗);
- 模块与任务骨架:`App/sync/time_sntp.c/.h` 由 `timeSyncTask`(`App/sync/time_sync.c` v2.0,:8888
退役后该任务即纯校时节拍宿主)驱动——屏障等 `SYS_EVT_NET_READY`(100 ms 分片喂心跳)→ 主循环
每 200 ms 一轮:`task_wd_beat` → `time_sntp_run(net_get_generation())`(应答收片 ≤50 ms,不饿任务狗;
代次变化由 `time_sntp_run` 内部弃旧 Socket 自重建)→ `time_sync_delay_fed(200)` 分片续心跳;
48 字节报文编解码 = vendored coreSNTP 序列化器(`Lib/coreSNTP/`,MIT,零堆),节奏与准入判据在本方。
- 配置:`/config.ini` `[sntp]` 段(`enable` / `server1` / `server2` / `poll_min`,属主 `Drivers/BSP/NETCFG/sntp_cfg.c`,
注册在 `net_cfg_load()`);现场改法 = UI「通讯参数 → SNTP 设置」页(密码叶)保存后随下一轮生效,或 FTP 改文件(4 s 落定)。
@@ -436,5 +384,7 @@ PC 端 `python test/host/time_sync_server.py` 每 `interval` 秒推送一次,e
响应源地址必须等于请求目的地址。失败:超时指数退避(5 s 起、60 s 封顶)+ 主备轮换;成功:恢复 `poll_min` 周期。
- 步进策略:|offset| < 2 s 只记日志不步进;≥ 2 s 或冷启动直接步进并留痕 `[SNTP] step offset=`、`syslog` OPER
「clock set by SNTP」;首个校验通过的同步置 `SYS_EVT_TIMESYNC_READY`(就绪位,不覆盖后续步进语义)。
- 与 8888 的关系:同一任务、同一 `sys_clock_set_unix` 收口,**后写者赢**维持现状(两路并存是部署选择,不是冲突缺陷)。
- 与 8888 的关系(历史):2026-11-04 当日 SNTP 落地在前(PR #77)、:8888 清除在后,中间两路短暂
并存、同一 `sys_clock_set_unix` 收口**后写者赢**;退役后本模块是**唯一网络校时入口**,
`sys_clock_set_unix` 现存三个写入口 = SNTP / UI 手工对时 / 104 `C_CS`(口径见 §1.1)。
- 主机单测:`test/host/sntp/`(报文格式、防伪拒收、KoD、退避与周期、阶跃域守卫、配置注册表)。
+5 -5
View File
@@ -81,7 +81,7 @@ mac=00:00:00:00:00:00
- **加载校验(逐键容错)**:单个键值非法(越界/格式错)不影响其他键——非法键回工厂默认并留痕(`parse: [network] <键> value invalid`);文件缺失 → 自动生成本模板;文件 > 4KB = 损坏 → 工厂默认 + 重建模板(坏配置不带崩网络)。
- **保存(外科手术式)**:注释 / 未知段 / 未知键逐行保留,受管键按 RAM 副本原位改写、缺失键补写;写盘 = 临时文件 `/config.TMP` + `f_rename` 原子替换(掉电不损坏目标文件)。
- **外部变更自动重载**(P4 阶段接入):2s 轮询检测 (size, mtime) 变化、4s 沉降(连续 2 次轮询稳定)后重载 `[network]` 段并重建网络——FTP 上传编辑后的文件无需重启即生效。
- **外部变更自动重载**(P4 阶段接入):2s 轮询检测 (size, mtime) 变化、4s 沉降(连续 2 次轮询稳定)后重载 `[network]` 段并重建网络——FTP 上传编辑后的文件无需重启即生效。重载/保存均过**视图一致性守卫**(2026-11-05):卷层给回与 stat 不符的旧/短视图时拒绝应用/拒绝落盘(RAM 配置不会被坏视图打回出厂默认,文件也不会被短视图重写吞段),2s 重试自愈;若串口持续出现 `[CFG] poll ... HELD` / `WARN ... held` 告警,重启一次即收敛。机制详见 `docs/子系统设计/配置文件设计说明.md` §5.3。
完整设计(引擎 / 双端 / 并发模型 D15)见 `docs/子系统设计/配置文件设计说明.md`。
@@ -263,7 +263,7 @@ sequenceDiagram
**机制**:`请求 → netTask 重建 → 代次号 → 服务自愈`
**约束与对策**:网络重建会复位 CH395F,所有监听 Socket 随之失效;而三个 TCP 服务(FTP :21 / 对时 :8888 / 远程显示 :7003)的监听由各自任务持有。为此引入"网络代次号"——各服务检测到代次变化后主动重建监听,在新 IP 上恢复服务。
**约束与对策**:网络重建会复位 CH395F,所有监听 Socket 随之失效;而两个常驻 TCP 服务(FTP :21 / 远程显示 :7003;对时 :8888 已退役,2026-11-04)的监听由各自任务持有。为此引入"网络代次号"——各服务检测到代次变化后主动重建监听,在新 IP 上恢复服务。
```mermaid
sequenceDiagram
@@ -271,7 +271,7 @@ sequenceDiagram
participant CFG as net_cfg
participant NT as netTask
participant NS as net_socket
participant SVC as FTP/对时/远程显示
participant SVC as FTP/远程显示/对时(SNTP 出向)
UI->>CFG: 保存行 ENTER → net_cfg_save()(写盘)
CFG->>NT: net_cfg_request_apply() → 回调置 SYS_EVT_NET_RECONFIG
@@ -281,12 +281,12 @@ sequenceDiagram
SVC->>SVC: 轮询发现代次变化 → 关闭旧监听 → 重建监听(新 IP)
```
**三个服务的自愈点**:
**各服务的自愈点**:
| 服务 | 端口 | 检测位置 | 自愈方式 |
|---|---|---|---|
| FTP | 21 | `lftpd_inet_accept()` | 代次变化 → 返回 -1 → `lftpd_start` 外层循环重建监听 |
| 对时 | 8888 | `time_sync_task()` 的 accept 循环 | 代次变化 → 关旧监听 → 回外层重建 |
| 对时(SNTP 客户端) | UDP 出向(无监听) | `time_sntp_run(net_gen)` 每轮比对代次 | 代次变化 → 弃旧 Socket 归还 → 下轮到点懒重建(2026-11-04 起原 :8888 监听行随退役删除) |
| 远程显示 | 7003 | `ui_net_sink_poll()` | 代次变化 → 关旧监听/客户端 → 重建 |
**关键设计点**:
@@ -215,7 +215,7 @@ flowchart TD
- **超长守卫(v1.12)**:外科手术输出超 `CFG_FILE_MAX_LEN`(4096B)→ **拒绝保存返回 -1**(原文件不动 + 自检上报 `cfg save overflow`);`s_write_doc`(模板/外科同闸的唯一落盘出口)硬性拒写 >4096B —— "引擎永不产出超长 config.ini"是结构性质。超长文件一律按损坏处置(load/poll 同判,见 §5.3)
**(3) 变更检测** —— `cfg_file_poll()`(defaultTask / 模拟器主循环,2s 节拍):`f_stat` 取 (size, mtime-epoch) 与基线比对 → 沉降后**先按真实 `st.size` 查超长**(v1.12):>4096B = 损坏 → 各段复位工厂默认 + 重建模板 + 自检留痕(`cfg poll oversized`),**不触发段回调**(保留 FTP/在线修复通道,下次保存或重启收敛);正常路径重载 → 段变化则触发该段回调 → 刷新基线。
**(3) 变更检测** —— `cfg_file_poll()`(defaultTask / 模拟器主循环,2s 节拍):`f_stat` 取 (size, mtime-epoch) 与基线比对 → 沉降后**先按真实 `st.size` 查超长**(v1.12):>4096B = 损坏 → 各段复位工厂默认 + 重建模板 + 自检留痕(`cfg poll oversized`),**不触发段回调**(保留 FTP/在线修复通道,下次保存或重启收敛);正常路径重载先过**视图一致性守卫**(v1.17,§5.3):stat → read → 再 stat 三点必须一致且**内容过 `s_view_bad`**——读长 ≠ `st.size`、读期间 (size, mtime) 变化、或视图含 NUL 字节(同尺寸全 0 旧映射块,台架实证形态)= 卷层给了旧/短/坏视图或读中被改写 → 拒绝应用(RAM 不动、基线不刷新,2s 重试自愈);一致后重载 → 段变化则触发该段回调 → 刷新基线。
**(4) 段变更回调** —— 未来模块的接入点:
@@ -300,6 +300,7 @@ sequenceDiagram
- 检测粒度 2s(轮询周期);网络重建含等链路 ≤3s,总生效时间约 2~5s
- 下载天然支持(RETR 即文件读)
- **沉降去抖(D15-②)**:(size, mtime) 相对基线变化且**连续 2 次轮询(4s)稳定**才重载——防 FTP STOR 进行中的中间态触发多次重载(STOR 先写 `.TMP`,目标文件 (size, mtime) 在 rename 前不变,rename 单次原子更新 → 至多一次重载)
- **视图一致性守卫(D15-②延伸,v1.17,issue #73 台架实证)**:沉降触发重载后校验 stat → read → 再 stat 三点一致(读长 == `st.size` 且读期间 (size, mtime) 不变)+ **内容判据 `s_view_bad`**(INI UTF-8 文本约定下任何偏移都不得含 NUL 字节——空读、整块全 0、合法前缀+尾部零填充的"部分旧块"全部命中;解析器遇 NUL 断行,被零块吞掉的尾部内容本就不可达,拒之不误伤任何可解析文档)。台架 15:21 实证:**同尺寸整块全 0 旧映射块可骗过纯三点校验**(dhara 旧映射块恰与目标同长 1064B),解析零错误、RAM 照打回——内容判据是该形态的唯一引擎侧拦截。不一致视图若照单应用 = 全段静默打回工厂默认(真机 8/8 复现、10.5h 对时沉默元凶),若照短视图外科保存 = 重写整档吞段(实测 1066B→986B)。拒绝语义:poll **不动 RAM、不刷基线**(2s 重试,视图收敛即自愈;持续到重启则 boot 全新挂载必然收敛);save **返回 -1**(调用方保留 dirty 标志重试)原文件一字节不动。首次拒绝 ERROR + 自检留痕(`cfg poll view stale` / `cfg save view stale`),poll 此后每 30 趟(≈60s)一条 WARN 计数行(限速);HELD 行打印的是“读长B != stat B”,两数相等即内容判据命中(同尺寸旧映射块)而非空读。**边界**:内容合法但陈旧的整卷视图((size,mtime) 与内容三者皆一致滞后)引擎层无法检出——属卷层(dhara/FTL)领域,重启收敛是最后防线;运行期"改过配置后重启一次"在卷层根治前始终是最稳口径
- **单写者(D15-③)**:`/config.ini` 的直接写者收敛为 defaultTask(UI 保存 = 请求投递至 defaultTask,由其落盘(tmp+rename)+ 应用(触发网络重建),复用既有 `SYS_EVT_NET_RECONFIG` 路径);唯一例外 = FTP STOR 路径(lftpd,tmp+rename,与 defaultTask 写路径经卷锁互斥)
### 5.4 线程安全(FatFS 可重入)
@@ -554,6 +555,7 @@ void adc_cfg_init(void)
| FTP STOR 半截写(掉电 / 断链) | 中 | 逐键容错 + 工厂回退;0 字节 STOR 自动删文件(lftpd 现状)→ 下次上电重新生成模板;下次保存自愈 |
| 墙钟无效(开机 RTC 读取失败且默认校时失败) | 低 | mtime 退化为固定值(检测退化为 size);既有开机告警链 + 默认校时(RTC_DEFAULT_INIT)兜底,实际极罕见 |
| mtime 秒边界碰撞(同秒两次写) | 低 | (size, mtime) 双比对;2s 轮询通常跨秒;误报 = 多一次重载(无害) |
| 卷层给回旧/短/坏视图(dhara FTL 缓存 / 整卷回滚 / 同尺寸全 0 旧映射块,台架 issue #73 实证) | 高 | 引擎视图一致性守卫 = 三点校验 + 内容判据 s_view_bad(§4-(3) / §5.3):stat 与 read 不符或视图含 NUL → poll 拒绝应用 / save 拒绝落盘,坏视图既不碰 RAM 也不重写文件;"一致但陈旧"的整卷视图引擎不可检出,属卷层课题,重启收敛兜底 |
| save 堆峰值与 LVGL / lftpd 争用 | 低 | 事件触发(罕见);FR_TIMEOUT 兜底;实施后 map 复核堆空闲 |
| 8.3 文件名约束 | 无 | `config.ini` 合规;段名 / 键名属文件内容,不受限 |
| 卷重新格式化丢配置 | 中(现状一致) | 与现状相同(f_mkfs 清空卷);文档提示 |
@@ -591,3 +593,4 @@ void adc_cfg_init(void)
| 2026-10-10 | v1.14:**删除旧档 NCFG 迁移(D10 撤销)**——`Drivers/BSP/NETCFG/net_cfg_legacy.{c,h}` 整体移除、`cfg_store_legacy_path()` 撤销(MCU / 模拟器后端与主机单测 `test/host/cfg_file/cfg_file_test.c` 同步删除),`net_cfg_load` 不再调用 `net_cfg_legacy_migrate()`;旧档 `/cfg/netcfg.bin` 若存在则被**忽略**(不读、不删、不迁移),配置回落工厂默认。理由:该一次性路径把整条配置写链挂进启动期调用图,defaultTask 静态最坏栈链 **+600 B**(该链整体 5312 → 2776 B,另三个杠杆见 `docs/内存管理/RAM使用分析与优化方案.md`),而本仓库不存在携带旧档的设备。连带影响:`App/util` 的 CRC-16/MODBUS 失去唯一调用者(现为零调用者);模拟器 `--cfgtest` 不再覆盖迁移场景;§2 D10 / §3.5 / §4.2 / §5.1 / §6.2 / §6.4 / §7 / §9 / §11.1 同步 |
| 2026-10-26 | v1.15:**新增 `[comm]` 段(道G task-8,「UI 补齐」波次里的非 UI 前置项)**——`App/protocol/iec104/iec104_comm.h/.c` 配对模块(104 公共地址 / 监听端口 2 键,getter 合法带自愈,adc_cal 先例);内核前 `iec104_comm_init()` 注册([adc_cal] / [run_par] 同「先注册后 load」契约);生效 = **改后重启**(不挂回调、不新增事件位,区别于 [network] 免重启重建);段占位 5→6 / 8,键表与主站地址不做理由 → `docs/子系统设计/网络配置说明.md` §3.6;机器钉 = `test/host/cfg_file` TC-CONFIG-056/057(段/键上限)+ `test/host/iec104` TC-IEC104-031~033(模板/重载/带外/ca 端到端)
| 2026-11-04 | v1.16:**新增 `[sntp]` 段(板端 SNTP 客户端接入,#57 调研结论落地)**——`Drivers/BSP/NETCFG/sntp_cfg.h/.c`(enable / server1 / server2 / poll_min 4 键;出厂默认**关闭 + 服务器留空 + 60 分钟** = "未配置零网络足迹"口径;`poll_min` 带外自愈 1..1440 → 60 不写回 RAM);数据本体 = `Drivers/BSP/NETCFG/sntp_cfg.h/.c`(不依赖引擎头,分层门禁 layer-deps 口径),段描述符由 `net_cfg.c` 的 `s_sntp_register()` 组装,注册编排 = `net_cfg_load()`(与 [ftp] 同编排,先注册后 load);消费方 = `App/sync/time_sntp.c`(挂 timeSyncTask 既有循环,vendor `Lib/coreSNTP` serializer 做 48B 报文编解码/防欺骗校验);保存立即生效 = 每轮直读 RAM 副本 + 网络代次重建弃 UDP socket 重散布,**无段回调、不新增事件位**;段占位 6→7 / 8;键表与生效细则 → `docs/子系统设计/网络配置说明.md` §3.7;机器钉 = `test/host/net_cfg` TC-NETCFG-005/006b..d/007(段注册契约)+ `test/host/sntp`(RFC 4330 §10 节奏 / §5.3 防欺骗 / §5.5 步进策略 / poll 钳位)
| 2026-11-05 | v1.17:**热重载/保存路径视图一致性守卫(issue #73 台架实证根治)**——真机 8/8 复现"运行中改配置触发热重载打回出厂默认"且此后任何保存吞段(1066B→986B):卷层在 stat→read 窗口给回旧/短视图,引擎照单应用(全段 memcpy 默认、零解析错误行)或照短视图外科重写文件。① `cfg_file_poll` 沉降读取后三点校验 + 内容判据(读长 == `st.size` + 读后复 stat (size, mtime) 不变 + `s_view_bad`:INI 文本任意偏移含 NUL = 坏块——台架 15:21 再实证**同尺寸整块全 0 旧映射块**可骗过纯三点校验,解析零错误 RAM 照打回,内容判据是该形态唯一引擎侧拦截):不符 → **拒绝应用**(RAM 原样 / 基线不刷新 / 2s 重试自愈),首次拒绝 `cfg poll view stale` 自检 + ERROR 一行(该行打印"读长B != stat B",内容判据或复 stat 命中时两个数可相等,命中的是内容/读中改写项),此后每 30 趟(≈60s)一条 WARN 计数;② `cfg_file_save` 同族守卫:视图与 stat 不符或内容坏 → **拒存返回 -1**(调用方保留 dirty 重试)原文件一字节不动 + `cfg save view stale` 自检——"短/坏视图 → 外科重写 → 非默认段被删"链就此斩断;③ 边界如实披露:一致但陈旧的整卷视图引擎层无法检出(dhara/FTL 属卷层),重启必然收敛,卷层根治前"改过配置后重启一次"仍是最稳口径。机器钉 = TC-CONFIG-058(poll HELD + 自愈)/ 059(save 拒存文件不动)/ 060(读中改写检出 + 日志限速)/ 061(同尺寸全 0 块内容判据拦截 + 自愈)/ 062(save 遇全 0 块拒存不动盘);`cfg_file.c` v1.6 / `cfg_file.h` v1.5 契约同步
@@ -643,7 +643,7 @@ LPN 与原始码的位置**就地分类并打印(`ftl_err_name()` 给可读名
| dhara 错误 | 归类 | 处置上为什么不同 |
|---|---|---|
| `ECC` / `TOO_BAD` | `BSP_ERR_CRC` | 位翻转不可纠或页太坏:**是页级问题**,读重试 / 由 dhara 换页,不代表卷坏 |
| `ECC` / `TOO_BAD` | `BSP_ERR_CRC` | 位翻转不可纠或页太坏:**是页级问题**,读重试 / 由 dhara 换页,不代表卷坏(**但见下方 10.4.1:页级失败会因重试语义升级成整卷禁用**) |
| `JOURNAL_FULL` / `MAP_FULL` | `BSP_ERR_NO_SPACE` | 介质还健康,是 **journal / 映射层块池见底**:该走容量恢复(`../测试说明/专项验证/存储维护与容量恢复.md`),此时重格式化只是把问题推回去 |
| `BAD_BLOCK` / `RECOVER` / `NOT_FOUND` / `CORRUPT_MAP` / 越界 | `BSP_ERR_IO` | 映射或介质**完整性**故障:保卷 + 上报,不许自愈重格式化 |
@@ -651,7 +651,121 @@ LPN 与原始码的位置**就地分类并打印(`ftl_err_name()` 给可读名
checkpoint(`DHARA_E_TOO_BAD`)才算真空白卷",本表则保证失败**可读**——两者合起来
才是"别把瞬态毛刺当卷损坏去 `f_mkfs`"(旧行为:单次 I2C/SPI 抖动 → 清 map → 整卷
重格式化 → 静默销毁全部用户数据)。
- **仍未闭环**:分类目前**只进日志**;`disk_read`/`disk_write` 对 FatFs 仍只能回 `RES_ERROR`
(那是 FatFs 的契约)。要让 defaultTask 的卷健康探针**按类分支**,还需要一个跨调用
存活的失败类快照(`nand_ftl_last_error()`,8 B;代价是要先定多写者纪律——
defaultTask 与 testTask 都会碰存储)→ 即登记簿条目「可选全序列卷锁」的待还项。
- **已闭环(2026-11-04,问题 #79)**:分类不再只进日志。`nand_ftl.c` 新增跨调用
失败快照 `nand_ftl_fault_get()` / `nand_ftl_fault_clear()`(`nand_ftl_fault_t`,
20 B:`active`/`op`/`cls`/`lpn`/`count`),在 `disk_initialize` 的 resume 失败、
`ftl_read_page`、`ftl_flush_cache`、`disk_ioctl(CTRL_SYNC)` 四个失败点记账;
defaultTask 的卷健康探针在 `storage_bring_up()` 里读它并按类分流:
`BSP_ERR_NO_SPACE` → **跳过重格式化**(只上报 `storage full`,留待容量恢复),
其余类 → 才 reformat。多写者纪律:语义是"最近一次"而非累计账本,并发下可能被
另一路覆盖(诊断用途可接受),故不加锁、不做权威计数。
### 10.4.1 「页级 TOO_BAD」为什么会升级成「整卷禁用」(2026-11-04 台架实证,问题 #79)
本表上一版只写了「`TOO_BAD` 是页级问题,不代表卷坏」。这句话在**单次读写**的尺度上
成立,但在**连续重试**的尺度上会误导——台架现场正是这条误解造成的:
```
[NAND_FTL] Map resumed: 14094/97504 sectors used ← 映射本身健康
[ERR][NAND_FTL] Cache flush FAIL: LPN=211 dhara=TOO_BAD class=-7
[ERR] [FS] volume FAT invalid (fr=1), reformatting...
[ERR] [FS] volume repair failed (fr=1)
[ERR] [FS] f_mount failed (fr=1) ← 3 轮重试
[ERR] [FS] storage retries exhausted (fr=1), storage disabled
```
两个独立的放大机制叠在一起:
1. **`ftl_flush_cache()` 失败不清 `s_cache_dirty`**(刻意的:写不进去不能假装写成功)
⇒ 缓存里那一页仍是脏的,**下一次任何存储访问都会重试同一个 LPN**。15 条
`Cache flush FAIL` 就是这么来的,11 秒内撞 15 次。
2. **`nand_ftl_format()` 旧实现先 flush、失败即 `return GD5F_ERROR`** ⇒ 本应"销毁
映射重建卷"的恢复动作,被**同一页**在第一步挡住,`dhara_map_clear()` 从未执行;
接着 `f_mkfs` 在**旧映射**上跑,必然失败。每轮启动都重新踩同一条路,故
**重启不恢复**。
- **判据修正**:`TOO_BAD` 仍归类 `BSP_ERR_CRC`(归类没错),但"不代表卷坏"必须加上
限定——**不代表介质坏,不代表卷内容好**。单个 LPN 反复写不进去,配合"脏缓存不清 +
格式化被挡"这两条,足以让整卷在本次启动内不可用。
- **处置修正**:`nand_ftl_format()` 现在尽力刷一次缓存,失败则**丢弃缓存并继续**
`dhara_map_clear()`——格式化语义本就是销毁整卷映射(见 `nand_ftl.h` 该函数注释
「破坏性」),为一份注定作废的脏页挡住恢复动作没有任何收益。⚠ 该"丢弃"权限
**只在 format 内**;`disk_read`/`disk_write` 的 flush 失败必须继续向上报 `RES_ERROR`。
- **与 10.4 表的关系**:格式化的**该不该做**由失败类决定(§10.4 快照分流),
格式化的**做得成做不成**不再被脏缓存劫持(本节)。两者一起才是完整判据。
### 10.4.2 上游真凶定案:误标坏块被持久化(2026-11-04 真机闭环,问题 #79)
10.4.1 的两条放大机制修掉后真机**并未恢复**——`format` 这次确实清了 map,但紧随的
`Map sync after clear failed: TOO_BAD` 说明**全新的 map 也落不了盘**。逐层加临时
诊断(prog/erase 原语失败打印 → is_bad 命中打印 → BBT 合并后打印)后定案:
| 观测 | 结论 |
|---|---|
| `[NAND] BBT scan: 0 bad blocks found` | 出厂无坏块 |
| prog/erase 原语 `[DIAG]` **零输出** | 底层写**全部成功**,TOO_BAD 不来自当次 I/O 失败 |
| `BBT: 129/2048 blocks bad`(合并持久化 BBT 后) | 坏块全部来自**持久化 BBT 的 OR 叠加** |
| 误标是 1016–1142 **连续段**;`Map head=65024`>>6 = **1016** 正中段首 | 不是随机位老化形态 |
| `is_bad hit` 连续命中 1016..1142 | `prepare_head()` 连续 8 次撞坏 → `DHARA_E_TOO_BAD`(journal.c:820-832) |
**机理链**:某次台架操作(断电 / ST-LINK reset 打在写窗口内)造成**传输层/等忙失败**
→ 旧 `dhara_nand_erase/prog()` 把一切失败都 `dhara_nand_mark_bad()` →
`gd5f2gq5ue_mark_block_bad()` **每次都立即持久化 BBT**(轮转池 + 版本号 + CRC,
不可撤销)→ 误标固化 → 此后每轮启动 journal 写头爬进误标段即 TOO_BAD。这解释了
「11-03 20:54 还好的、11-04 起每轮必现、重启不恢复」的全部特征。
- **修复**:只有芯片明确回 `E_FAIL` / `P_FAIL`(状态位证据)才标坏;传输层/超时
只报 `DHARA_E_BAD_BLOCK` 让 dhara 重试,**不标坏**。回归用例
TC-NANDPORT-207/208/505(主机侧,178 条全绿;把修复回退即见红)。
- **哨兵**:`gd5f2gq5ue_init()` 解锁块保护(A0h)后补回读校验(与 B0h ECC 同族
缺口;实测本板 A0h=0,写保护非本次根因,校验留作哨兵);`gd5f_bbt_load()` 合并后
坏块数 > 0 且出厂扫描为 0 时打 `BBT after merge: %lu bad blocks (factory scan
was 0)`——现场一眼区分真坏与误标。
- **存量误标的处置**:代码修复只防未来。已固化的 129 个误标用恢复动作 A
(`TEST_SUITE_STORAGE` + `ENABLE_STORAGE_RECOVERY_TESTS`,重建 BBT + format)
清除:`BBT rebuilt and persisted` → `Storage Recovery: 3/3 PASSED` →
持久化 BBT version=71。产品镜像复烧后 `[FS] FATFS mounted`、
`[CFG] load: file missing, factory template generated`,0 条 flush FAIL。
⚠ 动作 A 语义 = 卷内容全失(旧卷随 map clear 作废),本次台架卷为可弃数据。
### 10.5 卷锁覆盖面审计与 dhara 重试自旋复核(2026-11-05,问题 #45 评估结论)
**结论先行:卷锁之外没有第二写者,登记簿「可选全序列卷锁」项就此关闭;
「存储侧喂狗饥饿」无 2026-10-02 之后的新证据,dhara 重试自旋保留为长期观察。**
判据 = 对 master `c487ce4` 的调用点枚举(判据:`App/` 与 `Drivers/BSP/` 下全部带
`FA_WRITE` 的 `f_open` 与 `f_unlink`/`f_rename`/`f_mkdir`/`f_opendir` 调用点)
+ 2026-11-05 之前的全部台架留档。评估过程与逐条证据见 Gitea 问题 #45。
**覆盖面清单(生产构建的全部卷访问序列):**
| 访问道 | 任务上下文 | 串行化纪律 |
|---|---|---|
| `/log` 七本 + `wdev.log`(追加写 / 清除 / `f_mkdir /log`) | defaultTask | `vol_lock_wait(0)` try,锁跨 open…close 完整序列(`App/log/sys_log_mcu.c`) |
| `/log/soe.log` | defaultTask | 同上(`App/log/soe_store.c`) |
| `/config.ini` 原子写 tmp+rename / unlink;`/prot_set.bin` 同后端 | defaultTask | 同上,store 后端四函数全覆盖(`App/cfg/cfg_file_store_mcu.c` v1.3;`App/cfg/prot_set_store.c` 走 `cfg_store_read`/`cfg_store_write_atomic`,无独立盘触点) |
| `/wave` 录波段(mkdir / 追加写 ≤21×`f_write` / unlink) | defaultTask | 同上,锁跨完整序列(`App/task/default_task.c` 录波段) |
| FTP RETR/STOR/LIST/DELE/MKD | ftpTask | 100 ms 分片阻塞 + 每片 `lftpd_task_wd_beat()`,锁跨 open…close / opendir…closedir 全程(`Drivers/BSP/NET/lftpd/lftpd_io.c`) |
| 回放页段表/段窗读、UI 记录页读 | uiTask | try(0) 锁跨完整序列(`App/task/ui_task.c`、`App/log/sys_log_mcu.c` 读径) |
| 空闲 flush 兜底(`CTRL_SYNC`) | defaultTask | try(0) 闸门,卷忙跳过(§5.5;`App/fs/vol_idle_sync.c`) |
| `f_mount`/`f_mkfs`/`/fschk.tmp` 探针/`nand_ftl_format` | defaultTask 启动段 | **就绪屏障门控**:`STORAGE_READY` 在 `storage_bring_up()` 末尾才置位,netTask/ftpTask/uiTask 的卷入口全部等屏障(`App/task/default_task.c` 卷锁创建处注释),启动期卷写无并发使用者 |
LVGL 的 FatFs 驱动桥(`Lib/lvgl/src/libs/fsdrv/lv_fs_fatfs.c`)`LV_USE_FS_FATFS`
默认关闭、本仓未接线,不是卷使用者;`test/board/` 的存储测试任务仅存在于互斥测试
构建(`test-suite-switch` 门禁),不在产品镜像。**登记簿原口径「卷锁仅覆盖
syslog/cfg/lftpd 三条路径」是 2026-10-02 建档快照,已被本表取代**——SOE、录波段写、
`/prot_set.bin`、UI 读径与空闲 sync 随后都进了同一把锁。
**dhara 重试自旋**:`try_recover()` 的自旋有界——`DHARA_MAX_RETRIES`(8) 次 restart
后以 `DHARA_E_TOO_BAD` 定案(`Lib/dhara/map.c:270-306`),journal 层六处重试环同为
有界;且 NAND 长操作在驱动入口与 `gd5f_wait_busy` 每 100 ms 经 `nand_ftl_wd_feed()`
**直接喂 IWDG**(`Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c`)——自旋即便落在
defaultTask(喂狗点)内也不饿狗,残留形态收敛为「有界时长的存储服务延迟」。
真 NAND 卡死 = 持续喂狗、设备存活但存储冻结,属已声明边界
(`../子系统设计/看门狗设计说明.md` §9 R4;要改成"NAND 死也复位"需给
`nand_ftl_wd_feed()` 加上限,非本单判据)。**复发复核**:「存储侧喂狗饥饿」唯一
实证 = 2026-10-02 台架轮(并发 FTL 写 → journal 竞争,另有同日 IWDG 超时被配成
复位默认值的 P0 修复,见 `../子系统设计/看门狗设计说明.md` 变更记录),此后
2026-10-25 F2/F3 探针轮、2026-11-02 录波枚举台架轮(卷锁 try 超时 0 次)、
2026-11-05 PR #82 补验 soak(STOR 密集)均无该签名。重开判据不变:**台架再出
存储侧喂狗饥饿才排期**;观察行留登记簿 §2。
@@ -42,7 +42,7 @@
| `ftpTask` | 1024 / 4096 | Normal | 等网络**且**存储(`WaitAll`)→ `lftpd_start("/", 21)` → 单客户端会话循环 |
| `testTask` | 2048 / 8192 | BelowNormal | 测试套件入口(`test/board/test_config.h` 选择)。**产品构建不创建**(未选套件时立即 `vTaskDelete` 回收其 8 KB CCM 栈) |
| `uiTask` | 4096 / 16384 | BelowNormal | 等网络 → `ui_port_init`/`ui_menu_init`/`ui_standby_init`(空闲 60 s 切待机屏)/`ui_net_sink` → 10 ms 刷新 + 数据注入 |
| `timeSyncTask` | 640 / 2560 | Normal | 等网络 → TCP :8888 收 PC 推送时间 → 写 RTC |
| `timeSyncTask` | 640 / 2560 | Normal | 等网络 → 200 ms 校时节拍 `time_sntp_run()`(SNTP 客户端 UDP 出向 → 写 RTC;:8888 推送监听已退役 2026-11-04) |
| `adcTask` | 640 / 2560 | AboveNormal | **采集主线唯一消费者**:每拍 `adc_input_poll()`(TPAFE 快照 + ADC1 DMA 帧)→ `adc_health` 有效性 → `phasor_run()` 相量 → `freq_run()` 测频 → 每 200 ms `meas_tick()` 发布遥测快照 |
| `iec104Task` | 640 / 2560 | Normal | 等网络 → TCP 工厂默认 :2404 监听 → 104 链路状态机(总召/变位/周期/遥控/定值/对时)+ 断链重听 + 网络代次自愈 |
| `protectTask` | 512 / 2048 | Normal | **20 ms 判据节拍**:采样故障闭锁判定 → 定值校验和巡检 → `prot_elm_run()` 元件判据 → 动作边沿投递 SOE(**不做 NAND I/O**) |
@@ -115,7 +115,7 @@ sequenceDiagram
N-->>F: set SYS_EVT_NET_READY
F->>F: wait NET_READY|STORAGE_READY(All|NoClear)→ lftpd_start("/", 21)
U->>U: wait NET_READY(Any|NoClear)→ ui_port_init → ui_menu_init → ui_net_sink_start(7003)
I->>I: wait NET_READY(Any|NoClear)→ TCP listen :2404(默认)/ :8888
I->>I: wait NET_READY(Any|NoClear)→ TCP listen :2404(默认)/ 200ms SNTP 校时节拍
```
> **顺序铁律**:① 配置段注册必须**先于** `cfg_file_load`(否则 FTP 上传的段不生效);
+7 -7
View File
@@ -43,9 +43,9 @@
| 录波链路(三任务交接) | adcTask `wave_ring_push()/tick()`(与相量主线同拍**并行**、互不阻塞)→ 触发冻结、后触发计满封段 → defaultTask 见 `wave_ring_sealed()` 游标分次搬进 `/wave` → uiTask 单通道回放页;落盘回执才解冻。取回 = FTP :21 |
| SOE 链路 | protectTask 动作/复归边沿 `soe_store_post()`(纯 RAM:取时标 + 组 64B 记录 + 队列,**零文件系统**)→ defaultTask(`/log` 唯一写者,`syslog_drain` 尾部挂接)落 `/log/soe.log` |
| `lftpd` / `net_cfg` / 测试 → `FatFs` → `nand_ftl` → `gd5f2gq5ue` | 文件、配置、录波段与 SOE 落 NAND |
| `ui_net_sink` / `time_sync` → `net_socket` | 远程显示 :7003 / 对时 :8888 共用同一 TCP 栈;屏板链路走 USART1 串口(不经 TCP),与 :7003 是同一份显存的两个出口(**串口为主**) |
| `ui_net_sink` / `time_sync` → `net_socket` | 远程显示 :7003 走 TCP;对时 = `time_sntp` 经同一消息队列走 **UDP 出向**(:8888 监听已退役,2026-11-04,墙钟说明 §15);屏板链路走 USART1 串口(不经 TCP),与 :7003 是同一份显存的两个出口(**串口为主**) |
| `ui_menu` → `ui_content_page` → `ui_page_*` | 框架 + 页面插件(描述符解耦;节点→页面绑定由注册表 `ui_page_registry.c` 生成,见 §6) |
| `time_sync` / `sys_clock` → `sd2506` | 墙钟基准与写回 RTC |
| `time_sntp` / `sys_clock` → `sd2506` | 墙钟基准与写回 RTC(对时写钟入口,:8888 退役后唯一网络来源) |
| `ui_port` / `ui_page_*` → `LVGL` | UI 全部绘制走 LVGL(1bpp 离屏渲染到内存帧缓冲) |
### 1.3 端到端链路鸟瞰(另一视角:一个电气量走到底)
@@ -72,7 +72,7 @@
| `ftpTask` | 4096 | Normal | 等网络**且**存储(`WaitAll`)→ `lftpd_start("/", 21)` → 单客户端会话循环(断开后经 `net_listener` 重建监听);录波段文件的取回通道 | `StartFtpTask` |
| `testTask` | 8192 | BelowNormal | 测试套件入口(`test/board/test_config.h` 选择)。**产品构建不创建**:CubeMX 生成区无条件建后,`MX_FREERTOS_Init()` 在未选套件时(`!TEST_SUITE_SELECTED`)立即 `vTaskDelete` 回收其 8KB CCM 栈(2026-10-04) | `start_test_task` |
| `uiTask` | 16384 | BelowNormal | 等网络 → `ui_port_init`/`ui_menu_init`/`ui_standby_init`(空闲 60s 切待机屏)/`ui_net_sink` → 10ms 刷新:`ui_data_feed_tick()` 三帧装配 + 屏板链路驱动(组帧 B / 出键 / 离线判定 / 状态灯位)+ 录波回放页 | `ui_task_func` |
| `timeSyncTask` | 2560 | Normal | 等网络 → TCP :8888 收 PC 推送时间 → 写 RTC | `time_sync_task` |
| `timeSyncTask` | 2560 | Normal | 等网络 → 200 ms 校时节拍 `time_sntp_run()`(SNTP 客户端,UDP 出向;写 RTC 经 `sys_clock_set_unix`。:8888 推送监听已退役 2026-11-04) | `time_sync_task` |
| `adcTask` | 2560 | AboveNormal | 纯消费者 + **唯一发布者**:`osThreadFlagsWait` 等 TIM3 1kHz 唤醒(ISR 内 `adc_tick_irq_notify` 置位)→ `adc_input_poll()`(TPAFE 原子快照 + STM32 ADC1 DMA 双缓冲)→ 标定折算 → 相量 → 测频;录波支路 `wave_ring_push()/tick()`;**每 200ms `meas_tick()` 发布遥测快照**(双区无锁,104 与 UI 共用同一份上游) | `adc_task_func` |
| `iec104Task` | 2560 | Normal | 等网络 → IEC 60870-5-104 上行(工厂默认 :2404 监听 + link 状态机;遥测读 meas 快照、遥信读 `prot_elm` 元件态,COV 死区/变位上送;`[comm]`/`[run_par]` 配置;IEC 104 上行/第二轮)。任何构建都创建,纳入 IWDG `required_mask` | `iec104_serv_task` |
| `protectTask` | 2048 | Normal | 保护判据 20ms 节拍:`prot_elm_run()` + 「自检失败闭锁」采样故障闭锁 + 定值校验和巡检 + 动作/复归边沿 SOE 投递(保护任务);⚠ **当前处于「未标定闭锁」态**——`adc_cal_flags()` 无 VALID 时判据停走,两点标定写入 `[adc_cal]` 后自动解卡(用户裁定 2026-10-25:保持闭锁,不用万用表走捷径);纳入 IWDG `required_mask`(产品 `0x1F7`) | `protect_task` |
@@ -155,7 +155,7 @@ sequenceDiagram
F->>F: wait NET_READY|STORAGE_READY(All|NoClear)→ lftpd_start("/", 21)<br/>→ 串口输出:waiting for connection...
U->>U: wait NET_READY(Any|NoClear)→ ui_port_init → ui_menu_init → ui_net_sink_start(7003)<br/>→ 10ms 循环:ui_data_feed_tick + 屏板组帧/出键/灯位
T->>T: wait NET_READY(Any|NoClear)→ TCP listen :8888
T->>T: wait NET_READY(Any|NoClear)→ 200ms 校时节拍 time_sntp_run()(SNTP 客户端 UDP 出向)
I->>I: wait NET_READY(Any|NoClear)→ IEC104 listen 默认 :2404(遥测读 meas 快照 / 遥信读 prot_elm)
P->>P: 20ms 判据节拍 prot_elm_run()(不依赖网络;未标定即闭锁停走)+ SOE 边沿投递
C->>C: wait TIM3 1kHz 唤醒(ISR adc_tick_irq_notify)→ adc_input_poll() 纯消费<br/>→ 标定→相量→测频 → wave_ring_push/tick → 每 200ms meas_tick() 发布快照
@@ -217,7 +217,7 @@ flowchart TB
NS --> Q["netMsgQueue<br/>(串行化到 netTask)"]
Q --> NT["netTask<br/>net_poll() + net_process_messages()"]
NS --> C1["lftpd<br/>FTP :21"]
NS --> C2["time_sync<br/>对时 :8888"]
NS --> C2["time_sync 任务<br/>time_sntp SNTP 客户端<br/>UDP 123 出向(:8888 已退役)"]
NS --> C3["ui_net_sink<br/>RemoDispBus :7003"]
NS --> C4["iec104_serv<br/>104 上行默认 :2404"]
C3 -.->|"回送 1bpp 帧 + 接收远端按键"| CLIENT["DTU-RemoteLCD 客户端"]
@@ -320,8 +320,8 @@ STM32F4-Base/
│ │ console_log(UART5 控制台单写者)、soe_rec(64B SOE 纯编解码)+ soe_store(投递/落盘胶水)
│ ├── cfg/ 配置引擎:cfg_file(静态态单任务收敛于 defaultTask)、store(MCU=FreeRTOS 堆)、
│ │ prot_set_store(/prot_set.bin 原子写,保护定值持久化)
│ ├── fs/ 卷锁 vol_lock(syslog / cfg / lftpd 三条路径 try 语义)、vol_idle_sync
│ ├── sync/ time_sync(TCP 对时服务)
│ ├── fs/ 卷锁 vol_lock(全卷访问点串行化:写者/读者 try、lftpd 分片阻塞)、vol_idle_sync
│ ├── sync/ time_sync(timeSyncTask 载体)、time_sntp(SNTP 校时客户端,UDP)
│ └── util/ sys_clock(墙钟)、task_watchdog(IWDG 判定状态机)、boot_stats、sha256、task_prof
├── Drivers/BSP/ 纯手工驱动/服务(不受 CubeMX 保护)
│ ├── CH395F/ 以太网 MAC+PHY(SPI2 + DMA)
@@ -1,49 +1,22 @@
# ADC 前端注入验证流程(台架)
> **这篇是什么**:已知电压注入验证的**执行侧**——判据与实测记录在 `docs/硬件平台/ADC通道映射说明.md` §8.1,
> 这边写怎么接表笔、读哪一行日志、填哪张表、结果往哪回写。
> **这篇是什么**:已知电压注入验证的**执行侧**——怎么写表笔、读哪行日志、填哪张表、结果往哪回写。判据与实测记录在属主文档:直流轮 `docs/硬件平台/ADC通道映射说明.md` §8.1、交流轮 `docs/任务规划/数据可信.md` §4.6.2;**本文只写怎么跑**,分叉时判据从属主。证不到什么见 `docs/任务规划/数据可信.md` §4.6.1 与 §4.6.5,本文不重抄。
>
> **本文分两个轮次**:§1~§7 = **直流轮次**(零点 / 线性 / 通道映射 / 极性,2026-10-27 六项 PASS,
> 证的是"一条水平线的高度";**不需要**示波器、信号源、标准源,**只需要**一块万用表 + 一个电位器 + 串口日志)。
> §8 = **交流(正弦)动态验证轮次**(六轮:幅值 / 波形 / 相位 / 测频 / 削顶 / 谐波,证的是"给定电压算得对不对、品质报得实不实、节拍稳不稳")——
> 一台信号发生器接在本文 §3 的同一批注入点上就能跑,**同样不用等标准源**;
> 等标准源的只是**精度等级**那一步(`docs/任务规划/数据可信.md` §5 的「两点标定与精度验收」)。
> V0.1 有五路单极性削顶(`UB/UC/IB/IC/IN`),它们在交流轮次里只能作"预期削顶"的负向用例。
>
> **判据的属主是 `docs/任务规划/数据可信.md` §4.6.2**(六轮各验什么、过判据是多少),本文 §8 只写**怎么跑**。
> 两边于 2026-10-29 对齐;若将来再分叉,分两类裁定:**「验什么、算不算过」从
> `docs/任务规划/数据可信.md` §4.6.2**,**「期望值怎么算、怎么接线怎么跑」从本文 §8**。
> 这一跳为什么不用等标准源、又证不到什么,见其 §4.6.1 与 §4.6.5,本文不重抄。
---
> **两个轮次**:§1~§7 = **直流轮次**(2026-10-27 六项 PASS,只需万用表 + 电位器 + 串口日志);§8 = **交流轮次**(幅值 / 波形 / 相位 / 测频 / 削顶 / 谐波),一台信号发生器接 §3 同一批注入点就能跑,等标准源的只有**精度等级**。V0.1 五路单极性削顶(`UB/UC/IB/IC/IN`)在交流轮次只作"预期削顶"负向用例。
## 1. 为什么非做不可
下游已经全部按"工程量"消费:保护判据、104 遥测、UI 交流量页读的都是 `adc_cal_apply()` 的输出。系数错
一倍,三处一起错,且**没有任何一处会报错**。"通路活"(9 通道转换成功、零超时、互异非饱和、跨次开机
读数不同)不证明读数对。所以这一步的性质是**给整条链路的量纲盖章**,不是"补充测试"。
下游全部按"工程量"消费(保护判据、104 遥测、UI 交流量页读 `adc_cal_apply()` 输出)。系数错一倍,三处一起错,**没有任何一处会报错**。这一步是**给整条链路量纲盖章**,不是"补充测试"。
## 2. 前置事实:这个前端不是分压器
2026-10-27 按 `docs/硬件平台/V0.1.tel` 逐通道追线,以 UA 为例(图由
`tools/arch_diagram/gen_adc_frontend_svg.py` 生成,改图请改脚本重跑,勿手改 SVG):
2026-10-27 按 `docs/硬件平台/V0.1.tel` 逐通道追线(图由 `tools/arch_diagram/gen_adc_frontend_svg.py` 生成,改图改脚本重跑):
![UA 通道前端:端子 → R31 → ADC7 → TPAFE AIN_7P;C44 / R32 在差分负端,不在信号通路上](../../images/ADC前端电路.svg)
`ADC7` 这个节点上**只有** R31、C44、U3.61 三样东西,**没有对地电阻**。所谓"1k 到地"是 R32,
它接在 TPAFE 的**负输入脚 AIN_7GND**(芯片手册 pin62)上,是把差分负端经 1k 拴到 AGND,
属于差分滤波,不是信号分压。STM32 侧更直接(图 B):`AIN2 —[R52 1k]— ADC17 —[C111]— AGND`,
同样没有分流电阻,连 R32 那个接地电阻都没有。
`ADC7` 节点只有 R31、C44、U3.61,**无对地电阻**;"1k 到地"是 R32 接 TPAFE 负输入脚 AIN_7GND,属差分滤波非信号分压。STM32 侧同样无分流电阻。结论:① **不存在 2:1 分压**(`docs/任务规划/数据可信.md` §2.1 已改引脚侧系数 152.59 / 805.66),只需确认转换器 LSB 与逐通道映射;② **端子侧斜率 = 引脚侧斜率**,端子侧注入安全且能直接验 LSB。
**由此得到两条可直接用的结论**:
1. **不存在 2:1 分压**。旧口径"板级系数 305.18 / 1611.3 µV/码"(按 2:1 折算到 `AINn` 侧的条件值)
在本板上不成立;`docs/任务规划/数据可信.md` §2.1 已于 2026-10-27 改为引脚侧系数(152.59 / 805.66)。
所以已知电压注入验证只需**确认转换器 LSB 与逐通道映射**,不必再判别两种读法。
2. **端子侧斜率 = 引脚侧斜率**。所以在**端子侧**注入既安全(有 1k 串阻护着芯片)又能直接验 LSB,
不必去碰 LQFP 引脚。
期望斜率(由转换器满量程事实推出,与前端无关):
期望斜率(由转换器满量程推出):
| 转换器 | 满量程 | LSB | **期望斜率** |
| ---------- | ----------------------- | ---------------- | -------------- |
@@ -52,7 +25,7 @@
## 3. 注入点清单
串联电阻的两只焊盘就是两个注入层级:**1 脚 = 端子侧(靠 U5)**,**2 脚 = 引脚侧(靠转换器)**。
串阻两只焊盘 = 两个注入层级:**1 脚 = 端子侧(靠 U5)**,**2 脚 = 引脚侧(靠转换器)**。
| 语义 | 串阻 | 端子侧节点 | 引脚侧节点 | 转换器脚 | 期望斜率 |
| -- | --- | --------------- | ------- | ----------- | ------------- |
@@ -66,60 +39,39 @@
| IN | R48 | `AIN11`(U5.C10) | `ADC11` | U17.36(PA2) | 1241.2 |
| 温度 | R47 | `V_ZL2`(U5.C11) | `ADC14` | U17.41(PA5) | 不验(非线性,不参与标定) |
> 引脚侧没有串阻保护,注入前**必须外串 10 k 限流**。除非端子侧结果对不上、需要分离
> "转换器的错"和"前端的错",否则不要用引脚侧。
> 引脚侧无串阻保护,注入前**必须外串 10 k 限流**;除非端子侧对不上需分离"转换器的错"和"前端的错",否则不用引脚侧。
## 4. 读数出口(固件只有下面这些周期行,没有命令控制台)
## 4. 数字能从哪儿读(固件只有下面这些周期行,没有命令控制台)
> **样本出口已落地(代码侧,2026-10-29)**:故障录波的数据面已进仓(格式与判据属主见 docs/子系统设计/故障录波设计说明.md §6.2 与 §6.3、板级判据见 §10、口径变更见该文 §11;原卡片登记簿 2026-10-30 销项并入后删除)——每次触发一段,段文件直接给出 8 路 × 320 点原始码值,动态验证的判据因此**可以**从「比对下表这些派生标量」升级为「PC 独立重算 vs 板上读数」对表。下表仍是固件唯一的**周期行**出口(段文件不是周期行,只在触发时产生),两种出口对表用。
> **录波段文件能力已落地(2026-10-29)**:每次触发写一段,段文件直接给 8 路 × 320 点原始码值(格式属主 `docs/子系统设计/故障录波设计说明.md` §6.2/§6.3、板级判据 §10),判据可从「比对派生标量」升级为「PC 独立重算 vs 板上读数」互相对表。下表是固件**周期性**打印的全部输出行(段文件只在触发时产生,不在其中),两类数字互为对照。
| 日志行 | 频率 | 内容 | 用途 |
| ----------------------------------------------------------- | ------ | ------------------------ | ------------------- |
| `adc: UA=.. UB=.. UC=.. UN=.. IA=.. IB=.. IC=.. IN=.. T=..` | 每 10 s | **9 路原始码值** | 本次验证的主读数 |
| `cal: ua_mv=.. un_mv=.. ia_mv=.. vl=.. cl=..` | 每 10 s | UA/UN/IA 折算后毫伏 + 标定/削顶位图 | 旁证:码值 → 电压是否自洽 |
| `first: UA=.. … T=..` | 每次开机一次 | 9 路原始码值 | 与 `adc:` 行互校(同序同格式) |
| `frames=.. idle=.. adc1_err=.. tgap=..` | 每 10 s | 采集健康计数 | 步骤 4 的节奏判据 |
| `phasor(hb) C0x-…: Re=.. Im=.. rms=..`(逐实例)、`freq(hb): f=.. valid=..` | 每 10 s | 基波相量分量与测频读数(×0.1 / ×0.01 定点) | **交流轮次的主读数**(直流轮次只作旁证) |
| `meas: seq=.. v=.. ua_mv=.. un_mv=.. ia_mv=.. f=.. fv=..` | 每 10 s | 200 ms 遥测快照轨(基波有效值 mV) | 交流轮次的幅值比对(1 mV 分辨率,比 phasor 行细) |
| **段文件** `/wave/WAVE00.BIN` 起共 100 个号轮转(FTP 根下可见,与 /log 平级) | 每次触发一段(手动 / 保护启动 / bench 定时) | 8 路 × 320 点原始码值 + 封存瞬间的标定与品质快照(布局见 docs/子系统设计/故障录波设计说明.md §6.2) | **样本出口**:交流轮次的主对表源——预触发 160 点 + 后触发 160 点,触发瞬间落在段内点 159 |
| PC 侧脚本 `test/host/wave_read.py`(不是固件日志,bench 工具,纯标准库) | 手动跑;`--selftest` 是它的自带回归 | 四个子命令:dump(逐字段与双 CRC)/ fft(全周傅氏重算基波有效值与相位)/ shape(削顶与形态判定,可 `--strict`)/ plot(出 SVG 或 PNG,PNG 用 `-o` 落文件) | 把段文件还原成周波数、幅值、相位、削顶判定与图 = 「PC 独立重算」这条判据的执行体;CRC 不符或零长度它必须**拒绝**而不是画出东西 |
| 日志行 | 频率 | 内容 | 用途 |
|---|---|---|---|
| `adc: UA=.. UB=.. UC=.. UN=.. IA=.. IB=.. IC=.. IN=.. T=..` | 每 10 s | **9 路原始码值** | **直流轮(§1~§7)主要读的数** |
| `cal: ua_mv=.. un_mv=.. ia_mv=.. vl=.. cl=..` | 每 10 s | UA/UN/IA 毫伏 + 标定/削顶位图 | 旁证:码值→电压自洽 |
| `first: UA=.. … T=..` | 每次开机一次 | 9 路原始码值 | 与 `adc:` 互校(同序同格式) |
| `frames=.. idle=.. adc1_err=.. tgap=..` | 每 10 s | 采集健康计数 | 判节奏用(判据在 §5.5,即步骤 4) |
| `phasor(hb) C0x-…: Re=.. Im=.. rms=..`、`freq(hb): f=.. valid=..` | 每 10 s | 基波相量与测频(×0.1 / ×0.01 定点) | **交流轮(§8)主要读的数**(直流轮只旁证) |
| `meas: seq=.. v=.. ua_mv=.. un_mv=.. ia_mv=.. f=.. fv=..` | 每 10 s | 200 ms 遥测快照轨(基波有效值 mV) | 交流幅值比对(1 mV 分辨率) |
| **段文件** `/wave/WAVE00.BIN` 起 100 号轮转(FTP 根下,与 /log 平级) | 每次触发一段 | 8 路 × 320 点 + 封存瞬间标定与品质快照(`docs/子系统设计/故障录波设计说明.md` §6.2) | **录波档要用的原始样本**:预触发 160 + 后触发 160 点,触发瞬间在段内点 159 |
| PC 侧 `test/host/wave_read.py`(纯标准库) | 手动跑;`--selftest` 自带回归 | 四子命令:dump(逐字段双 CRC)/ fft(全周傅氏重算基波有效值与相位)/ shape(削顶与形态,可 `--strict`)/ plot(SVG/PNG,PNG 用 `-o`) | 「PC 独立重算」执行体;CRC 不符或零长度必须**拒绝** |
> ⚠ 直流轮次用不到后两行,但**它们一直都在**。交流轮次(判据见 `docs/任务规划/数据可信.md` §4.6)
> 必须用 `meas:` 或 104 YC 比幅值,别用 `phasor(hb)` 行——那行是 ×0.1 定点,注 1 V 只剩 10 格。
> ⚠ 交流轮次(判据 `docs/任务规划/数据可信.md` §4.6)必须用 `meas:` 比幅值,别用 `phasor(hb)`——那行 ×0.1 定点,注 1 V 只剩 10 格。
`adc:` 行是 2026-10-27 新增的(`App/task/adc_task.c` 心跳块),此前只有 `cal:` 的三路,
验 8 个通道要复位二十余次。现在**全程不必复位**。
**「码」是什么**:ADC 原始整数,**不是物理量**——电压 = 码 × LSB:
**「码」是什么**:ADC 输出的**原始整数**,中文常写「码值」/「AD 码」,英文对应 raw code / counts。
它表示"多少个最小刻度(LSB)",**本身不是物理量**——电压 = 码 × LSB,而两片转换器的 LSB 不同:
| 转换器 | 位数与极性 | 码的范围 | 1 码 = | 换算示例 |
| 转换器 | 位数与极性 | 码范围 | 1 码 | 示例 |
|---|---|---|---|---|
| TPAFE5160 | 16 位双极性 | −32768 ~ +32767(共 65536 码 = 10 V 跨度) | 152.59 µV | 11430 码 × 152.59 µV ≈ **1.744 V** |
| STM32 ADC1 | 12 位单极性 | 0 ~ 4095(共 4096 码 = 3.3 V 跨度) | 805.66 µV | 1000 码 × 805.66 µV ≈ **0.806 V** |
| TPAFE5160 | 16 位双极性 | −32768~+32767(65536 码 = 10 V) | 152.59 µV | 11430 码 ≈ **1.744 V** |
| STM32 ADC1 | 12 位单极性 | 0~4095(4096 码 = 3.3 V) | 805.66 µV | 1000 码 ≈ **0.806 V** |
同一个整数落在两把刻度尺上代表不同电压(图由 `tools/arch_diagram/gen_adc_code_scale_svg.py`
生成,改图请改脚本重跑,勿手改 SVG):
![两把刻度尺:TPAFE 16 位双极性 1 码 152.59 µV;STM32 12 位单极性 1 码 805.66 µV](../../images/ADC码值刻度.svg)
![两把刻度尺:TPAFE5160 16 位双极性 −32768~+32767、1 码 152.59 µV、11430 码≈1.744 V;STM32 ADC1 12 位单极性 0~4095、1 码 805.66 µV、1000 码≈0.806 V](../../images/ADC码值刻度.svg)
**两把尺子不能混用**(同样"1000"差 5.3 倍)。§5 各表每格必须写明哪一路(UA/UB/… 属 TPAFE,T 属 STM32),抄错一行全盘作废。本文一律用"码"不用"伏":固件 `adc:` 行打印的就是码;**标定还没做,把码换成伏正是本次要验证的事**。判据:**TPAFE ≤ 30 码、STM32 ≤ 5 码**(≈4.6 mV / ≈4.0 mV)。
**两把尺子不能混用**:同样是"1000",在 TPAFE 上是 0.153 V,在 STM32 上是 0.806 V,差 5.3 倍。
所以 §5 各步的记录表里每一格都必须写明是哪一路(UA/UB/… 属 TPAFE,T 属 STM32),
抄错一行全盘结论作废。
⚠ **TPAFE 档 2026-10-27 由 ≤10 放宽到 ≤30**:首次实测残差 UA −14 / UN −15 / IA −13(≈2 mV)。原 ≤10 比实测噪声还紧,必然误判。残差若 >30 码 → 前端有真实失调,回前端查,不得再放宽。
本文一律用"码"而不是"伏",有两个理由:① 固件 `adc:` 行打印的就是码,抄数不用心算;
② **标定还没做,把码换成伏正是本次要验证的事**——先换算再用,等于默认了尚未验证的系数。
判据按转换器分两档:**TPAFE 侧 ≤ 30 码、STM32 侧 ≤ 5 码**——即短接后读数离 0 不超过
30 / 5 个刻度,折算 **≈4.6 mV / ≈4.0 mV**。两档数值差 6 倍是因为两种刻度差 5.3 倍
(TPAFE 152.59 µV/码、STM32 805.66 µV/码),统一到物理量后都在 4~5 mV 量级。
⚠ **TPAFE 档于 2026-10-27 由 ≤10 放宽到 ≤30**:首次实测三路残差 UA −14 / UN −15 / IA −13
(≈2 mV),按 16 位 /10 V 跨度算只有 0.02% FS。原来的 ≤10(≈1.5 mV)定判据时**没有实测依据**,
比实测噪声还紧,必然误判失败。**这不是"把判据改成能过"**——若残差继续增大(>30 码 / ≈4.6 mV),
说明前端确有真实失调(R32 侧接地断、TPAFE 失调),那时必须回前端查,不得再放宽。
⚠ `adc:` 行某路取数失败时该槽打 0,所以"9 路全 0"要读作"没数据",判据是同一份心跳里
`frames` 是否还在涨。
⚠ `adc:` 行某路取数失败时该槽打 0,"9 路全 0"读作"没数据",判据看同一心跳 `frames` 是否还在涨。
## 5. 步骤
@@ -129,25 +81,17 @@
| 量哪里 | 期望 | 验的是什么 |
|---|---|---|
| **串阻两端**(1 脚 ↔ 2 脚,即端子侧焊盘 ↔ 引脚侧焊盘) | **≈ 1 kΩ** | 串阻焊好、没虚焊 |
| **注入点 ↔ AGND**(TPAFE 侧,UA/UN/IA) | **≈ 1 MΩ 量级** | 无意外短路;**不是 1 kΩ** |
| **注入点 ↔ AGND**(STM32 侧,UB/UC/IB/IC/IN) | 高阻,不定量 | 无设计直流通路,只作短路排查 |
| **串阻两端**(1 脚 ↔ 2 脚) | **≈ 1 kΩ** | 串阻焊好、没虚焊 |
| **注入点 ↔ AGND**(TPAFE 侧 UA/UN/IA) | **≈ 1 MΩ 量级** | 无意外短路;**不是 1 kΩ** |
| **注入点 ↔ AGND**(STM32 侧 UB/UC/IB/IC/IN) | 高阻,不定量 | 无设计直流通路,只作短路排查 |
### 5.2 步骤 1:零点(这一步是整套测试的分水岭)
### 5.2 步骤 1:零点(这一关先过:零点都不干净,后面每一步的数都不可信)
**做什么**(8 路逐个重复,每路约 1 分钟):
**做什么**(8 路逐个,每路约 1 min):断电把该路**注入点短接 AGND**(短接线先 0 Ω 档确认直通)→ 上电等 `adc:` 行 → 抄进下表 → 断电拆线换下一路。
1. 断电,把该路**注入点短接到 AGND**(短接线之前先用 0 Ω 档确认该点与 AGND 直通);
2. 上电,等 `adc:` 行出现(每 10 s 一行,9 路码值都在里面);
3. 把该路码值抄进**下面的零点记录表**;
4. 断电拆短接线,换下一路。
**记录**(现场填;判据只看"短接后"列,"空载"列留证):
**记录**(现场填;判据只看"短接后"那一列,"空载"列是留证用):
> ⚠ **本表行序 = `adc:` 日志的列序**(UA UB UC UN IA IB IC IN),照着日志**从左往右**抄,
> 不要按"TPAFE 三路 / STM32 五路"重新分组。2026-10-27 现场实测就栽在这里:按语义分组抄,
> 结果 UN/IA 填成了 STM32 的 ~1000、UB/UC 填成了 TPAFE 的 ~11450——而 UN/IA 属 TPAFE、
> UB/UC 属 STM32,这两个量级在物理上不可能。**"转换器"列就是给这一眼准备的**。
> ⚠ **本表行序 = `adc:` 日志列序**(UA UB UC UN IA IB IC IN),照日志**从左往右**抄,别按"TPAFE 三路 / STM32 五路"分组。2026-10-27 就栽在这里:按语义分组抄,UN/IA 填成 STM32 ~1000、UB/UC 填成 TPAFE ~11450——量级物理上不可能。**"转换器"列就是给这一眼准备的**。
| 通道 | 转换器 | 端子侧节点 | 空载码值(浮空) | 短接 AGND 后码值 | 判据 |
| --- | --- | --- | --- | --- | --- |
@@ -160,26 +104,15 @@
| IC | STM32 | `AIN10`(U5.C9) | 991~1092 | 0 | ≤ 5 |
| IN | STM32 | `AIN11`(U5.C10) | 979~1065 |1~2 | ≤ 5 |
**为什么这一步最关键**:空载(输入浮空)读数比判据高两个数量级,最可能的解释是输入悬空后
漏电流在滤波电容上建立的平衡点——短接 AGND 后应塌回 0。但如果**短接后仍读 11430**,那就是
真实偏置,且超过零点补偿上限 `ADC_CAL_B_MAX`(8192 码)——`adc_cal_set()` 会直接拒掉、
回退 ROM 系数、永远置不了 `VALID`,保护也就永远解不了锁。**那种情况必须回前端查**
(R32 那侧接地是否断、TPAFE 是否失调),不能靠软件补偿。
**2026-10-27 实测:8 路全部 PASS。** 短接后 **0~5 码**(TPAFE ≤4.6 mV、STM32 ≤4.0 mV),远小于零点补偿上限 `ADC_CAL_B_MAX`(8192 码),**可正常标定、不触发回退**。
**2026-10-27 实测结论:8 路全部 PASS。** 短接后落在 **0~5 码**(TPAFE ≤4.6 mV、STM32 ≤4.0 mV),
全部远小于零点补偿上限 `ADC_CAL_B_MAX`(8192 码),**可以正常标定、不会触发回退**。
空载 → 短接的塌陷幅度:TPAFE 约 11430 → 0~4(三个数量级),STM32 约 1000 → 0~5(两个数量级),
两者都证明短接真实到位、输入前端没有意外直流通路。
⚠ **IB 最贴边**:2~5 码正好触上限(1.6~4.0 mV,物理没问题),**八路里余量最小**;日后 IB 零点变大第一个查 R49 那侧(`AIN9` / U5.A8)。
⚠ **IB 最贴边**:2~5 码,上限 5 码正好触到。折算 1.6~4.0 mV,物理上没问题,但**它是八路里
余量最小的一路**;若日后 IB 零点继续变大,第一个该查的是 R49 那侧(`AIN9` / U5.A8)。
### 5.3 步骤 2:三点线性(用 UA,免复位)
### 5.3 步骤 2:三点线性(用 UA 做,免复位)
3.3 V 轨经 10 k 电位器分压作源,逐点注入,**每点同时记两个数**:万用表读注入点电压、`adc:` 行读码值。
3.3 V 轨经 10 k 电位器分压作源,逐点注入。**每点同时记两个数**:万用表读注入点实际电压、
`adc:` 行读对应码值。
**记录**(UA 一路,三点;"目标"列是调电位器的靶子,"实测"列填万用表读数):
**记录**(UA 三点;"目标"列是靶子,"实测"列填万用表):
| 目标注入 | 实测电压(万用表) | 码值 | 反算 µV/码 | TPAFE 期望码 | STM32 期望码 |
| -------- | --------- | -- | ------- | --------- | --------- |
@@ -189,26 +122,17 @@
拟合 R² = 0.9999997 斜率 = 6544.2 码/V 偏差 = −0.14 % 截距 = −7.2 码(≈ −1.1 mV)
反算 LSB = 152.81 µV/码,与 TPAFE 期望 152.59 差 0.14 %——**与斜率偏差同源,是同一个数**。
反算 LSB = 152.81 µV/码,与 TPAFE 期望 152.59 差 0.14 %——**与斜率偏差同源**。期望码两列并列:同样三点也可复验 STM32 侧某路,两列差 5.3 倍,一眼确认表笔接的是哪片转换器。
期望码两列并列,是因为同样的三个注入点也可能拿去复验 STM32 侧某一路(UA 对不上时换路交叉验证);
两列数值差 5.3 倍,一眼能确认手上这支表笔当前接的是哪一片转换器。
判据:三点拟合 **R² ≥ 0.999**、斜率偏差 **≤ 2 %**。偏差 > 2 % **先查前端**(焊点、串阻实际值、电位器负载效应),不要用系数凑。
判据:三点线性拟合 **R² ≥ 0.999**,斜率与期望值偏差 **≤ 2 %**。
偏差 > 2 % 时**先查前端**(焊点、串阻实际值、电位器负载效应),不要用系数去凑——
把硬件的错固化成"标定值"是最坏的结果。
**2026-10-27 实测结论:PASS。** R² = 0.9999997(判据 ≥0.999)、斜率偏差 −0.14 %(判据 ≤2 %)。
三条残差 −2.0 / +3.5 / −1.4 码,落在读数噪声内,**无系统性弯曲**——即前端在这三个点上确实是
线性的,不存在未识别的分压元件。这是"③ 段变比 = 1:1"在台架上的第一次直接证据。
**2026-10-27 实测:PASS。** R² = 0.9999997、斜率偏差 −0.14 %。
### 5.4 步骤 3:极性(只 TPAFE 三路)
TPAFE 是双极性、二进制补码,可以注负压;STM32 是单极性,负半周测不了。给 UA/UN/IA 各加一个
**−1.0 V** 点。
TPAFE 双极性补码可注负压;STM32 单极性负半周测不了。UA/UN/IA 各加 **−1.0 V** 点。
**记录**(三路各两个点):
**记录**(三路各两点):
| 通道 | +1.0 V 码值 | −1.0 V 码值 | 对称性偏差 |
| -- | --------- | --------- | ----- |
@@ -216,40 +140,26 @@ TPAFE 是双极性、二进制补码,可以注负压;STM32 是单极性,
| UN | 6549 | −6568 | 0.29 % |
| IA | 6548 | −6566 | 0.27 % |
判据:−1.0 V 点码值为**负**且落在 **−6554** 附近,幅值与 +1.0 V 点对称(差值 ≤ 2 %)
→ 符号位与补码解释正确。这一步专门补"连极性都没证过"这个缺口。
判据:−1.0 V 点码值**为负**且落在 **−6554** 附近,与 +1.0 V 对称(差 ≤ 2 %)→ 符号位与补码解释正确。
**2026-10-27 实测结论:PASS。** 三路 −1.0 V 点全部为负,落在 −6566~−6568(相对 −6554 偏
−0.18 %~−0.21 %);对称性偏差 0.27 %~0.34 %,远小于 2 % 判据。**补码符号位解释正确**。
**2026-10-27 实测:PASS。** 三路 −1.0 V 全负,落在 −6566~−6568;对称性 0.27 %~0.34 %,远小于 2 %。
### 5.5 步骤 4:节奏(注入期间顺带看)
注入期间 `frames=` 应仍**严格 1000 Hz 递增**(10 s 间隔 +10000 左右),`idle=0`,
`adc1_err=0`。这一条替代了原方案里"用示波器看 U3.14 BUSY 有脉冲"的判据——不需要示波器。
注入期间 `frames=` 应仍**严格 1000 Hz 递增**(10 s +10000 左右),`idle=0`、`adc1_err=0`。
**2026-10-27 实测结论:PASS。** 注入**前**(20:58 那次开机)与注入**后**(21:29)各取两行相隔
10 s 的心跳,两边都是 **Δ9998 码 / ≈10.0 s ≈ 1000.1 Hz**,`idle=0`、`adc1_rc=0`、`adc1_err=0`:
**2026-10-27 实测:PASS。** 注入**前**(20:58)与**后**(21:29)各取两行相隔 10 s 心跳,两边都是 **Δ9998 码 / ≈10.0 s ≈ 1000.1 Hz**,`idle=0`、`adc1_rc=0`、`adc1_err=0`:
| 时点 | `frames=` 两行 | Δ | 折算 |
|---|---|---|---|
| 注入前(20:58) | 29997 → 39995 | 9998 | 1000.5 Hz |
| 注入后(21:29) | 1819639 → 1829637 | 9998 | 1000.1 Hz |
⚠ **口径说明**:这两次是"注入**前后**",不是"注入**进行中**"——已知电压注入验证判据 ⑤ 要的正是"注入前后
`tpafe5160_frame_seq()` 仍严格 1000 Hz 递增",故按此口径已达标。若日后要连"进行中"也钉住,
在任一注入过程里再抓两行即可(注入不改变 TIM3 硬件触发,理论上无影响,但没测过就不算证过)。
`adc1_gap` / `tgap` / `skip` 是**本次开机以来的累计值**(548 / 363 / 183),10 s 内只增 3 / 2 / 1,
占比约 0.03 %,属正常漏检量级,不是停摆。
### 5.6 步骤 5:回写
1. 把实测斜率、零点、映射结果写进 `docs/硬件平台/ADC通道映射说明.md` §8,把"尚未执行"改成
实测值 + 日期;
2. 若实测确认无分压,同步在 `docs/硬件平台/ADC通道映射说明.md` §7.1 的链路分段表把第 ③ 段
(`AINn` ↔ 转换器引脚)从"待台架实测"改为实测结论;
3. `docs/任务规划/数据可信.md` 的已知电压注入验证行按"完成即删"销项;判据与实测证据的属主是
`docs/硬件平台/ADC通道映射说明.md` §8.1。
1. 实测斜率、零点、映射写进 `docs/硬件平台/ADC通道映射说明.md` §8("尚未执行"改实测值 + 日期);
2. 确认无分压后,把 `docs/硬件平台/ADC通道映射说明.md` §7.1 量纲链路的第 3 段(`AINn` 焊盘 ↔ 转换器引脚)改成实测结论;
3. `docs/任务规划/数据可信.md` 已知电压注入行按"完成即删"销项;判据与证据属主 `docs/硬件平台/ADC通道映射说明.md` §8.1。
## 6. 判据汇总
@@ -262,438 +172,252 @@ TPAFE 是双极性、二进制补码,可以注负压;STM32 是单极性,
| 极性 | −1.0 V → −6554 码 | −6566 / −6568 / −6566,对称性 ≤0.34 % | PASS | 补码符号处理错 |
| 节奏 | 注入期间仍 1000 Hz | 注入前/后各 **Δ9998 / 10 s ≈ 1000 Hz**,`idle=0`、`adc1_err=0` | PASS | 注入改变了输入共模,触发转换异常 |
**总体结论(2026-10-27)**:**六项全部 PASS**。合起来证明了三件事:
① ③ 段(`AINn` ↔ 转换器引脚)**变比确为 1:1**,无隐藏分压(斜率偏差 −0.14 %);
② 8 路语义 ↔ 物理端子**一一对应**(零点步骤逐路代偿);
③ TPAFE 补码符号位解释正确(对称性 ≤0.34 %)。
已知电压注入验证的判据 ①②③④⑤⑥ 至此全部闭环(判据与实测记录 → `docs/硬件平台/ADC通道映射说明.md` §8.1)。
⚠ **两项残留口径**(不影响本轮 PASS,但别当成已验证):**串扰**未单独证(见上表"映射"行);
**节奏**只测了注入前后、没测注入进行中。两项若日后怀疑,各自的补做方法已写在对应小节。
**总体结论(2026-10-27)**:**六项全部 PASS**——结论一:从焊盘到转换器引脚那一段变比 1:1、无隐藏分压;结论二:8 路语义 ↔ 物理端子一一对应;结论三:TPAFE 补码符号位正确。全部闭环(→ `docs/硬件平台/ADC通道映射说明.md` §8.1)。⚠ **两项残留**(不影响 PASS):**串扰**未单独证;**节奏**只测注入前后。
## 7. 安全红线
1. **STM32 侧严禁超过 3.3 V**(VDDA + 0.3 V 即击穿),电位器上限就接 3.3 V 轨,不要接 5 V。
2. **TPAFE 侧按判据只到 ±2 V**,虽芯片容 ±5 V,但判据不需要更大。
3. **端子侧不许直接上额定电压**(220 V / 100 V 二次值)。本次是直流低压注入,
与"加压试保护"是两件事,后者要等端子/子板变比确认(`docs/硬件平台/ADC通道映射说明.md` §7.1 链路分段表 ④ 行)之后单独排。
4. **引脚侧注入必须外串 10 k**,且先接线后上电、先断电后拆线。
5. 注入源与板子**共地**;电位器一端接 3.3 V、一端接 AGND、中间抽头串 10 k 到注入点。
1. **STM32 侧严禁超过 3.3 V**(VDDA + 0.3 V 即击穿),电位器上限接 3.3 V 轨。
2. **TPAFE 侧按判据只到 ±2 V**(芯片容 ±5 V 但判据不需要更大)。
3. **端子侧不许直接上额定电压**(220 V / 100 V 二次值);"加压试保护"另排(`docs/硬件平台/ADC通道映射说明.md` §7.1 ④ 行)。
4. **引脚侧注入必须外串 10 k**,先接线后上电、先断电后拆线。
5. 注入源与板子**共地**;电位器一端 3.3 V、一端 AGND、抽头串 10 k 到注入点。
---
## 8. 交流(正弦)动态验证轮次(六轮:幅值 / 波形 / 相位 / 测频 / 削顶 / 谐波)
> **判据的属主是 `docs/任务规划/数据可信.md` §4.6.2**(六轮各验什么、过判据是多少),本节只写**怎么跑**:
> 接哪个点、发生器怎么设、读哪一行的哪个字段、期望值怎么算、结果往哪回写。两边于 2026-10-29 对齐;将来
> 若再分叉,按两类裁定——**「验什么、算不算过」从 `docs/任务规划/数据可信.md` §4.6.2,「期望值怎么算、
> 怎么接线怎么跑」从本节**。为什么这一跳不用等标准源、以及它证不到什么,看其 §4.6.1 与 §4.6.5,本节不重抄。
>
> **引用写法**:本节凡引用判据文档的小节,一律写成「文件名 + 小节号」的紧邻形式;只写 §8.x 的是本文自己的节。
> **引用写法**:引用判据文档小节一律「路径 + 小节号」紧邻;只写 §8.x 的是本文自己的节。本节只写**怎么跑**(接哪个点、发生器怎么设、读哪行哪个字段、期望值怎么算、结果往哪回写)。
先下图建立全局轮廓——每一轮注什么波形、验什么、读哪个出口,再进 §8.5 逐轮执行卡:
![六轮一图速查:注入信号形状 → 接法与设定 → 判据一句话 → 数字从哪儿读;过判据属主在 数据可信.md §4.6.2](../../images/交流六轮速查.svg)
![六轮一图速查:注入信号形状 → 接法与设定 → 判据一句话 → 主读数出口;过判据属主在 数据可信.md §4.6.2](../../images/交流六轮速查.svg)
### 8.1 动手前先弄清楚:数字从哪儿读、能读到多细(决定今天判得动哪几轮)
### 8.1 动手前先把出口分辨率算清楚(决定今天能判到哪一档)
这轮能读到数字的地方共 5 处——3 处是**串口周期打印的日志行**、1 处是**板子屏幕**、1 处是**触发录波段文件后在 PC 上重算**。分辨率天差地别,各自判得动的轮次也不同,下表逐处列清:
这一轮和直流轮次**不一样:样本出口已经有了**。2026-10-29 故障录波的数据面并入主干,一次触发就是一段
`/wave/WAVE<NN>.BIN`(`NN` = 00~99 轮转号;8 路 × 320 点原始码值 + 封存瞬间的标定与品质快照),PC 侧 `test/host/wave_read.py` 把它还原成
周波数、幅值、**相位**、谐波与削顶判定。所以本轮每条用例都有两个档:**周期行标量档**(只读串口 / 104 / UI,
快,不用 FTP)与**段文件对表档**(多一次触发 + 一次取段 + 跑脚本,判得到位)。各出口的实际分辨率如下——
这张表决定每条用例走哪个档:
| 出口 | 打印处 | 分辨率 | 能判 | 判不动 |
| 在哪儿读 | 看到的形态 | 数字精度 | 判得动什么 | 判不动什么(为什么) |
|---|---|---|---|---|
| `meas: seq=.. v=.. ua_mv=.. un_mv=.. ia_mv=.. f=.. fv=..` | `App/task/adc_task.c:605` | **1 mV**(整数毫伏,只发 UA/UN/IA) | 幅值轮、波形轮的幅值 ≤2 % | 相位、谐波、其余五路 |
| 104 YC `0x4011`~`0x4018` + `0x401D`(短浮点 + 品质) | `App/protocol/iec104/iec104_pts.c:70` | 3 位有效数字 ≈ 0.01 V | 单个静态工作点的幅值交叉读数、品质 IV | **小步进**(每点 0.5 V / 0.005 A 变化死区)、相位、谐波 |
| `phasor(hb) C0x-…-F1: Re=.. Im=.. rms=.. (x0.1)` | `App/task/adc_task.c:209` | **0.1 V,且向下截断** | 有数没数、量级、象限 | ⚠ **相位轮的 ≤2° 与谐波轮的 ±2 %**:注 1.000 Vrms 时 `rms` 只有 10 格,20 % 的谐波只有 2 格 |
| `freq(hb): f=.. valid=.. (x0.01)` | `App/task/adc_task.c:224` | 0.01 Hz | 测频轮的读数与新鲜度 | — |
| UI 交流量页 `Ua/U0/Ia/Ia2/Ia5`(3 位小数)、`Hz`(2 位) | `Drivers/BSP/UI/ui_page_ac.c:47` | **1 mV**(人工目检 + 拍照留证) | 谐波轮谐波幅值、幅值轮交叉旁证、测频轮的 `Hz` 显 `--` | 相位(页面上没有角度) |
| 录波段文件 `/wave/WAVE<NN>.BIN`(`NN` = 00~99,100 个号轮转;FTP 根下,与 `/log` 平级)+ `test/host/wave_read.py`(`dump` / `fft` / `shape` / `plot`,纯标准库) | **已落地**(2026-10-29 并入 `v2-on-ui`;格式属主 `docs/子系统设计/故障录波设计说明.md` §6.2 与 §6.3) | 一次触发 8 路 × 320 点原始码值;`fft` 给基波 RMS、相位、2 次与 5 次谐波 RMS(mV) | **相位轮的 ≤2° 与谐波轮的 ±2 % 现在判得动**:PC 独立重算 vs 板上读数对表 | 段与发生器**无绝对相位锁定**(触发点在段内点 159)→ 只能比同段内相对相位;320 ms 快照不等于长时间稳定性 |
| **串口心跳行** `meas:`(打印处 `App/task/adc_task.c:605`,200 ms 一行) | `meas: seq=.. v=.. ua_mv=.. un_mv=.. ia_mv=.. f=.. fv=..` | **1 mV**(整数毫伏;电气量只发 UA/UN/IA 三路) | 幅值轮、波形轮的幅值 ≤2 % | 相位、谐波(这行没这两个数);其余五路(这行不发) |
| **串口心跳行** `phasor(hb)`(打印处 `App/task/adc_task.c:209`) | `phasor(hb) C0x-…-F1: Re=.. Im=.. rms=.. (x0.1)` | **0.1 V、向下截断**(×0.1 定点) | 有数没数、量级、象限 | ⚠ 相位 ≤2°、谐波 ±2 % 想都别想:注 Vpp 2.828 V(板上 ≈1000 mV)时 `rms` 满打满算 10 格,20 % 谐波只占 2 格 |
| **串口心跳行** `freq(hb)`(打印处 `App/task/adc_task.c:224`) | `freq(hb): f=.. valid=.. (x0.01)` | 0.01 Hz | 测频轮的读数和新鲜度(`valid`) | — |
| **板子屏幕** 主界面→实时数据→交流量(代码 `Drivers/BSP/UI/ui_page_ac.c:47`) | 页 7 行 `Ua/U0/Ia/Ia2/Ia5/Hz/量纲`;量值行 3 位小数、Hz 行 2 位 | **1 mV**(靠人眼看屏 + 拍照留证) | 谐波轮 `Ia2`/`Ia5` 幅值;幅值轮交叉旁证;测频轮 `Hz` 显 `--` | 相位(页面上没有角度) |
| **录波段文件 + PC 重算**:把 `/wave/WAVE<NN>.BIN` 段取回本机用 `test/host/wave_read.py` 算(四子命令见 §4 表;格式属主 `docs/子系统设计/故障录波设计说明.md` §6.2/§6.3) | 段内 8 路 × 320 点原始码 + 封存瞬间的标定与品质快照 | `fft` 浮点重算:基波有效值、相位、2 次与 5 次谐波有效值(mV) | 相位 ≤2°、谐波 ±2 %——**只有这条路判得动**;顺带 PC 独立重算与板上数字互相对表 | 段与发生器**没有绝对相位锁**(触发点固定在段内点 159)→ 只能比同一段内的相对相位;一段 320 ms,不代表长时间稳定 |
**所以每条用例按两个档摆**(出口从"缺样本"变成"有段文件"的经过与口径变更,见 `docs/子系统设计/故障录波设计说明.md` §11;原卡片登记簿 2026-10-30 销项并入该文 §10):
> **2026-11-02 / 11-04 两轮已跑、六轮全部闭合**。实测结论只详述在 `docs/硬件平台/ADC通道映射说明.md` §8.2,此处不抄第二份。
| 档 | 条目 | 说明 |
|---|---|---|
| **周期行就判得动** | 幅值、波形、测频、削顶四轮(削顶轮的接法要按 §8.5 改,原因写在那张卡里) | 判据在 `meas:` / 104 / `freq(hb)` / `rail:` 上分辨率都够,不取段也能收工 |
| **段文件档才判到位** | 相位轮、谐波轮 | 段文件已落地 → 浮点重算,≤2° 与 ±2 % 都是**定量**判据;周期行退为旁证,只在没取到段时走定性档。触发动作与命令写在 §8.5 的相位卡 / 谐波卡 |
| **要改代码的退路** | 相位轮抬倍数、测频轮 B 档 | 段文件落地后相位轮这条基本不必走;测频轮 B 档(放宽 `FREQ_AMP_MIN`)仍是唯一路子。两者都要重编 + 烧录 + 按 §8.9 还原,**动手前先问用户** |
**六轮用例先定「什么证据才算过」——这张快查表逐轮指定证据档**(档位重划的经过见 `docs/子系统设计/故障录波设计说明.md` §11):
| 证据档 | 哪些轮用 | 过关要求 | 定这个档的原因 |
|---|---|---|---|
| **心跳档**——串口周期行看够,**不用录波** | 幅值、波形、测频、削顶 | 串口周期行(`meas:` / `freq(hb)` / `rail:` 位图)达判据即算过 | 判据阈值 ≥ 周期行分辨率(±2 % 对 1 mV、位图对 1 bit),录波无增益 |
| **录波档**——**必须录一段波**才算定量 | 相位、谐波 | 面板触发手动录波 → FTP 把段文件取回 → `wave_read.py fft` PC 浮点重算,与板上读数对表达判据 | 板上周期行是 ×0.1 截断定点(上限表「判不动」列),≤2°、±2 % 只有重算才判得动;谐波轮就算拿 UI 的 1 mV 也不行——**屏上那个数本身就是板子 DFT 算出来的答案**,系数表用错行、索引错位这类算术错会原样透传到屏上,必须靠 PC 独立重算当第二把尺子(段文件还顺带核对频位:100 Hz 确落 2 次 bin);**没录段文件只能退回「心跳档」记,定量判据不算过** |
| **改码退路**(默认不走) | 相位抬打印倍数、测频放宽 `FREQ_AMP_MIN` | 仅当录波档不可用(段取不回、PC 跑不了脚本)才考虑;做则重编 + 烧录 + 把临时补丁全量还原并核对 | 动了固件就不是「零改动验证」了——**动手前必须问用户** |
### 8.2 设备清单与开机前置门
| 项 | 要求 | 为什么 / 怎么核 |
|---|---|---|
| 信号发生器 | 正弦 / 方波 / 三角,**并有 DC 档**;频率可锁 50.000 Hz、也能设到 2 Hz;幅度 0~3 Vpp | **只要求"波形干净、幅度稳、频率锁得住"**,它的刻度不当基准(`docs/任务规划/数据可信.md` §7 #9)。DC 档是给削顶轮改法 A 用的 |
| ⚠ 发生器输出端接设置 | 接板子时设成**高阻负载**,不要按 50 Ω 端接 | 按 50 Ω 端接而实际接的是高阻板输入 → 面板值与真实电压差 2 倍;这是台架"差一倍"最常见来源 |
| 万用表 AC 档 | 能读到 mV;**记明型号与响应类型**(真 RMS / 均值响应) | 基准就是它;波形轮那一步两种表的读数都与基波期望差很多,不记响应类型就说不清是谁错 |
| 板子 | 产品构建(`test/board/test_config.h` 四个 `TEST_SUITE_*` 全注释)+ `/keil-build` 0 错误 0 警告 + 烧录 `-Rst -Run` 与回读校验 | → `stlink-flash` skill 与 AGENTS.md「构建与验证」 |
| `[adc_cal]` 状态 | **保持未标定**(`eng=0`),别为"读数好看"先写标定值 | 现在 `meas:` / `phasor` 的量纲是 **ADC 引脚电压 V**(`App/algo/meas.h` 文件头的 A-lite 口径);标定一生效就换成二次值,本节全部期望值作废 |
| 串口 | 全程抓 RX 落盘:用 `serial-assistant` skill(`open` → `clear` → 跑 → 读日志文件或 `log --tail`) | 日志文件就是证据本体,§8.10 归档归档的就是它;**长跑别用 `/serial-boot-test`**——它绑定一轮启动语义(静默 8 s、总超时 30 s、`max_boot_count` = 1,且 forbidden 含 `[ERR]`,而削顶轮故意造 `[ERR]`),约 135 min 的 session 必然超时或误判;daemon 全量写 `state/serial.log`(20 MB 上限自动截头保尾 10 MB)→ `docs/测试说明/流程与规范/自动化测试流程.md` 长时间采集一节 |
| 网口(可选) | 要读 104 那一路就插网线、PC 与板同网段(出厂 192.168.31.100),跑现成主站 `test/host/iec104_master.py`(`--ip` / `--port` / `--addr`) | 104 是浮点无量化 + 带品质,是 `meas:` 之外的第二条腿 |
| FTP 客户端 | 走现成 21 端口取段文件(出厂 `[ftp]` 账号,连续 5 次失败锁 60 s) | 段文件是相位 / 谐波轮定量档的样本出口;段文件名 `/wave/WAVE<NN>.BIN`(00~99 轮转),**取完立刻改名归档**,否则下一次触发把它盖掉 |
| 录波触发路径 | 产品构建里唯一**免改代码**的路径 = UI 菜单第 26 叶「手动录波」确认页(`Drivers/BSP/UI/ui_page_wave_manual.c` → `App/task/ui_task.c:605`) | 保护启动上升沿也算一次触发,但保护判据现处**未标定闭锁**态(AGENTS.md「现状」),别指望它自动来段;bench 定时自抓在双层编译门 `DTU_BENCH` 且 `WAVE_BENCH_AUTOCAP` 非 0 之内(默认 0,`App/task/adc_task.c:153`),开它就走 §8.9 的还原判据 |
| 共地 | 发生器 LO/GND 与板 AGND **单点**相连 | 不共地量到的是两地之差;现象见 §8.8 |
| 信号发生器 | 正弦 / 方波 / 三角,**并有 DC 档**;频率可锁 50.000 Hz、也能设 2 Hz;幅度 0~3 Vpp | 只要求"波形干净、幅度稳、频率锁得住",刻度不当基准(`docs/任务规划/数据可信.md` §7 #9)。DC 档给削顶轮的直流削顶档 |
| ⚠ 发生器端接 | 接板子时设**高阻负载**,不按 50 Ω 端接 | 50 Ω 端接而实际高阻 → 面板值与真实电压差 2 倍;台架"差一倍"最常见来源 |
| 万用表 AC 档 | 能读 mV;**记明型号与响应类型**(真有效值 / 均值)——判别法:表身或说明书没印 "True RMS" 就当均值档;拿发生器注一个 Vpp 2.828 V 方波到 AC 档,读数 ≈1.41 V = 真有效值档、≈1.57 V = 均值档(差 11 %,一眼分辨) | 基准就是它;波形轮两种表读数都与基波期望差很多,不记响应类型说不清谁错 |
| 板子 | 产品构建(`test/board/test_config.h` 四 `TEST_SUITE_*` 全注释)+ `/keil-build` 0 错 0 警 + 烧录 `-Rst -Run` + 回读校验 | → `stlink-flash` skill 与 AGENTS.md「构建与验证」 |
| `[adc_cal]` 状态 | **保持未标定**(`eng=0`),别为"读数好看"先写标定值 | 现在 `meas:` / `phasor` 量纲是 **ADC 引脚电压 V**——未标定态的设计本来就不折算(`App/algo/meas.h`);标定一生效换二次值,本节全部期望值作废 |
| 串口 | 全程抓 RX 落盘:`serial-assistant` skill(`open` → `clear` → 跑 → 读日志 / `log --tail`) | 日志文件就是证据本体;**长跑别用 `/serial-boot-test`**——它绑一轮启动语义(静默 8 s、总超时 30 s、forbidden 含 `[ERR]`,削顶轮故意造 `[ERR]`),必超时或误判;daemon 写 `state/serial.log`(20 MB 截头保尾 10 MB,长跑防截断 → `docs/测试说明/流程与规范/自动化测试流程.md` 长时间采集) |
| FTP 客户端 | 走 21 端口取段文件(出厂 `[ftp]` 账号,连续 5 次失败锁 60 s) | 相位 / 谐波的定量判据只能拿段文件来算;`/wave/WAVE<NN>.BIN`(00~99 轮转),**取回本机后立刻改名归档**,否则下次触发盖掉 |
| 录波触发路径 | 产品构建唯一**免改代码**路径 = UI 菜单第 26 叶「手动录波」确认页(`Drivers/BSP/UI/ui_page_wave_manual.c` → `App/task/ui_task.c:605`) | 保护启动上升沿也算触发,但保护判据现处**未标定闭锁**(AGENTS.md「现状」),别指望自动来段;bench 自抓在 `DTU_BENCH` 且 `WAVE_BENCH_AUTOCAP` 非 0(默认 0,`App/task/adc_task.c:153`),开它属临时措施,跑完撤销重编 |
| 共地 | 发生器 LO/GND 与板 AGND **单点**相连 | 不共地量到的是两地之差,读数带与幅值无关的偏移或漂移 |
**开机前置门**——接发生器**之前**日志就该长这样,不满足先回 §5 步骤 5.5 查节奏,别往下做:
**开机前置门**——插上网线、开了串口采集、**还没接发生器**之前,串口日志就该通过下面 8 条;任何一条不过,先回 §5.5 处理,别带着脏链往下跑:
- `adc:` 行 10 s 一行,同一心跳里 `frames` 在涨("9 路全 0"要读成"没数据",§4 尾注);`idle=0`、`adc1_err=0`;
- `meas:` 的 `v=1`、`seq` 每 10 s 约 +500(200 ms 一帧;不涨 = 发布闸门停);
- `cal:` 的 `cl=0xE6` —— **这是来源派生**(V0.1 那五路本就触底,见 `docs/任务规划/数据可信.md` §2.6),既不是本轮战果也不是本轮故障;
- 四个位图 `vl` / `cl` / `rail` / `edge` 同一个位序(语义通道枚举 `App/algo/adc_input.h:38`):bit0 `UA`、bit1 `UB`、
bit2 `UC`、bit3 `UN`、bit4 `IA`、bit5 `IB`、bit6 `IC`、bit7 `IN`、bit8 `TEMP` → `0xE6` = bit1/2/5/6/7 = `UB/UC/IB/IC/IN`;
- **先上电、在基线里看到 `adc: UB` 有正常摆动,再开发生器输出**:贴轨锁存要求该通道"此前出现过中带样本"(释放沿前提,
`App/algo/adc_health.c` 的 `adc_health_rail_watch()`),开机就注大信号会让削顶轮的锁存**装不上**,测出假不通过。
- 开机各有一条 `first:` 与 `phasor(first)` / `freq(first)` 单发行(`App/task/adc_task.c:478` 与 `App/task/adc_task.c:201`
的 `tag` 参数),与 10 s 一轮的 `hb` 行是两拨——数心跳时别把 `first` 计进去;
- `phasor` 行**只要有数就打**:打印条件只有 `phasor_get() == 0`,不带任何 valid 位(`App/task/adc_task.c:209`)→
「phasor 有数」既不说明标定可用、也不说明这一路没在削顶,判读必须配 `vl` / `cl` / `rail` 三个位图一起看;
- 注入正弦**不会**点亮 `health:` 或 `sampling fault:` 那几行:`adc_health` 的位只吃序号差、错误计数增量与 tick 差
(`App/algo/adc_health.c:91-189`),与波形幅值无关;它们若亮是节拍 / 丢帧问题,别归因给发生器(§8.8 同一条)。
- `wave:` 行(`App/task/adc_task.c:782`)基线:`armed=0`、`err=0`、`ovf=0`、`drop=0`,`seg=` 是本开机以来的成段数(**可以是 0**)。
本轮每触发一段就核 `seg` +1 且那三个计数不涨;涨了先按 §8.8 的落盘行分诊,别接着往上下注入。
| # | 看什么 | 正常该是这样 | 为什么容易看错 / 不满足怎么办 |
|---|---|---|---|
| 1 | `adc:` 行 | 10 s 一行;`frames` 在涨;`idle=0`、`adc1_err=0` | **九路数值全 0 不等于"没数据"**(没输入当然读 0,判据是 `frames` 涨不涨,§4 尾注);`frames` 不涨或 `adc1_err≠0` → §5.5 |
| 2 | `meas:` 行 | `v=1`;`seq` 每 10 s 约 +500(200 ms 一条) | `seq` 不涨 = 发布闸门停 → §5.5 |
| 3 | `cal:` 行的 `cl=0xE6` | **开机就该是这个数,不是故障** | 这是来源派生静态掩码:V0.1 硬件上 `UB/UC/IB/IC/IN` 五路本就触底(`docs/任务规划/数据可信.md` §2.6)。非战果非故障,别去"修"它。位序(`App/algo/adc_input.h:38`):bit0~8 = `UA UB UC UN IA IB IC IN TEMP`,`0xE6` = bit1/2/5/6/7 恰好这五路 |
| 4 | **开机与注入的先后** | 先上电 → 在串口看到 `adc: UB` 数值有正常摆动 → **再**开发生器输出 | 顺序反了会埋雷:贴轨锁存要求该通道"此前出现过中带样本"(`App/algo/adc_health.c` `adc_health_rail_watch()`),开机就注大信号,削顶轮的锁存**装不上**,测出假"不锁存" |
| 5 | 开机单发行 | `first:`、`phasor(first)`、`freq(first)` 各只一条(`App/task/adc_task.c:478`/`:201`) | 数心跳周期时把它们剔掉,别算进"每 10 s 一行"里 |
| 6 | `phasor(hb)` 行 | 有数就打出来 | **有数 ≠ 数有效**:这行只查 `phasor_get()==0` 不看 valid 位(`App/task/adc_task.c:209`),判读必须配着 `vl`/`cl`/`rail` 一起看 |
| 7 | `health:` / `sampling fault:` | 不该出现 | 这些位只吃序号差/错误计数/tick 差(`App/algo/adc_health.c:91-189`),注入多大正弦都不该点亮;亮了 = 节拍/丢帧问题,先修节拍链再谈读数 |
| 8 | `wave:` 行(`App/task/adc_task.c:782`) | 基线 `armed=0`、`err=0`、`ovf=0`、`drop=0`;`seg=` 成段数(**0 也正常**,从没触发过就该是 0) | 后面每触发一段核一次:`seg` +1 且那三个计数**不涨**;`err`/`ovf` 非零才是失败(`drop` 触发后涨一截属设计内:SEALED 窗口丢点、一拍加 8,`App/algo/wave_ring.c:50`,涨完即冻结) |
### 8.3 接线的四条(与直流轮次比,差别只在第 2、3 条)
1. **注入点与直流轮次完全相同**:§3 清单的**端子侧**焊盘(`U5` 排针,串阻的 1 脚侧)。③ 段 1:1 已由直流轮次实测
(斜率偏差 −0.14 %,§6),所以端子侧电压就是引脚电压,不用再算变比。引脚侧仍须外串 10 k(§7 第 4 条)。
2. **幅度按峰值核,别看面板上的 Vrms**:1.000 Vrms 正弦峰值已 1.414 V。
1. **夹子接哪儿**:跟直流轮同一个位置——§3 清单的**端子侧**焊盘(`U5` 排针,串阻 1 脚侧)。接这里的好处是**读数与设定值不用换算**:从焊盘到 ADC 引脚这一段是 1:1(直流轮已实测盖章,斜率偏差 −0.14 %,见 §6),端子侧电压就是引脚电压。⚠ 换个位置注(直接进引脚)才需要外串 10 k(§7 第 4 条),照本条接就不用。
2. **幅度一律按峰峰值 Vpp 设定**,对表时注意换算:发生器设定 = Vpp;万用表 AC 档与板上读数天然是有效值刻度,正弦下 有效值 = Vpp ÷ 2.828。
| 侧 | 判据上限(§7 红线 2) | 允许的最大正弦 Vrms | 本节用量 |
| 侧 | 判据上限(§7 红线 2) | 允许的最大正弦 Vpp | 本节用量 |
|---|---|---|---|
| TPAFE(`UA` / `UN` / `IA`) | ±2 V 峰值 | 1.414 Vrms | **1.000 Vrms**(峰值 1.414 V) |
| STM32(`UB` / `UC` / `IB` / `IC` / `IN`) | 0~3.3 V 单极性 | 无正向意义 | 只在削顶轮用:注交流 = **故意触底**,负半周本就钉 0 |
| TPAFE(`UA`/`UN`/`IA`) | 峰值 ±2 V | 4 V | **2.828 V**(= 峰值 ±1.414 V) |
| STM32(`UB`/`UC`/`IB`/`IC`/`IN`) | 0~3.3 V 单极性 | 无正向意义 | 只在削顶轮用:注交流 = **故意触底**,负半周本就钉 0 |
3. **一次只注一路**(相位轮除外,它要 `UA` 与 `UN` 两路同源),换表笔前先关输出。端子侧串阻是 **1 k**(R31 / R28 / R19 / R52 …),
STM32 那五路负半周经**片内**钳位 / ESD 路径灌向 VDDA——网表 `docs/硬件平台/V0.1.tel` :228-241 逐条实证这些节点只有
「电容 .2 + 串阻 .2 + MCU 脚」三件,**无外置钳位二极管、无隔直电容**,所以这条电流走的是芯片内部路径;
1.000 Vrms 时峰值电流约 (1.414 − 0.3) / 1 k ≈ **1.1 mA**(按片内钳位压降 0.3 V 估、仓内无实测,只用来论证量级),
但**别往上加幅度**——这种注入只允许出现在削顶轮这类"故意削顶"的用例里。
4. **电流通道也是注电压**:`IA` 的注入点同样是电压进 R19 端子侧。这一轮证的是"给定引脚电压算得对不对",
不是"一次侧 1 A 怎么办"——后者要变比,属 `docs/任务规划/数据可信.md` §5 的端子 / 子板变比确认。
四条接线画在一张图上(发生器 → 端子侧焊盘是一条主干,万用表并接、共地是两条必须存在的旁路):
```mermaid
flowchart LR
G["信号发生器<br/>输出端接 = 高阻<br/>(按 50 Ω 端接读数差 2 倍)"] -->|"注 UA / UN / IA:端子侧焊盘<br/>(1:1 已由直流轮次实测)"| R31["串阻 1 k 的 1 脚侧<br/>R31 / R28 / R19 …"]
R31 --> FE["前端分压 / 滤波"] --> U5["U5 排针 → 转换器引脚<br/>(TPAFE AIN_x 或 STM32 脚)"]
M["万用表 AC 档<br/>记响应类型"] -.->|"并接同一注入点<br/>量真实加到板上的电压"| R31
G -.->|"LO/GND 与板 AGND<br/>单点共地"| AGND["板 AGND"]
AGND -->|"不共地量到的是两地之差"| U5
G -.->|"注 UB 等 STM32 那五路(仅削顶轮)<br/>负半周经片内钳位 ≈1.1 mA"| R52["R52 端子侧"] --> STM["STM32 ADC 脚<br/>(无外置钳位 / 隔直电容)"]
```
3. **一次只注一路**(相位轮除外,它要 `UA` 与 `UN` 两路同源),换表笔前先关输出。端子侧串阻 **1 k**(R31/R28/R19/R52…)。STM32 五路负半周经**片内**钳位灌向 VDDA(网表 `docs/硬件平台/V0.1.tel` :228-241 实证:无外置钳位二极管、无隔直电容);Vpp 2.828 V 时峰值电流 ≈ **1.1 mA**(量级估算),**别往上加幅度**——这种注入只允许出现在削顶轮。
4. **电流通道也是注电压**:`IA` 注入点同样是电压进 R19 端子侧。这一轮证"给定引脚电压算得对不对",不是"一次侧 1 A 怎么办"——后者要变比,属 `docs/任务规划/数据可信.md` §5 的端子 / 子板变比确认。
### 8.4 记录表抬头(每条用例一份,与日志一起归档)
```text
日期 ____ / 操作人 ____ / 板子序列号 ____
固件 commit ________(/keil-build 0 错误 0 警告:是 / 否)
发生器:型号 ______ 输出端接 = 高阻 / 50 Ω 波形 ____ 频率设定 ____
万用表:型号 ______ AC 响应类型 = 真 RMS / 均值 共地方式 = 单点 / 发生器浮地
注入点:路名 ____(端子侧 U5 / 引脚侧外串 ____ Ω)
[adc_cal] = 未标定(eng=0)—— 必须是这个状态
基线(未注时):meas: ua_mv=____ un_mv=____ ia_mv=____ rail=0x____ cl=0x____
段文件(走定量档的用例):文件名 ________ 触发方式 = 手动 / 保护 / bench 取回时刻 ________
脚本:test/host/wave_read.py(先跑 --selftest:通过 / 否) fft / shape / dump 输出与 plot 图归档在 ________
```
这份抬头只回答一个问题:**这组数字是在什么条件下量出来的**——照下表从右边写的地方**抄**过来,不用你判断任何数;缺任何一项,这页记录三个月后就没法复核。
| 要抄的信息 | 从哪儿抄、为什么它要紧 |
|---|---|
| 日期、操作人 | 王建锋 |
| 板子序列号 + 固件版本 | `fw build: Nov 4 2026 19:05:57 suite=NONE dstr=off`(2026-11-04 补测轮整行照抄;11-02 首轮为 `fw build: Nov 2 2026 14:21:24 suite=NONE dstr=off`) |
| 发生器型号 + 端接 | VICTOR 2026H(端接必须设"高阻",设成 50 Ω 输出会被砍一半,所有期望值作废) |
| 万用表型号 + 响应类型 | FNIRST-DMT-99 + 真有效值档(判别法见 §8.2 设备表) |
| 标定状态 | cal: ua_mv=-7 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000 |
| 基线读数 | meas: seq=300 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0 |
### 8.5 逐条执行卡
**每条卡的通用动作**:接好 → 开输出 → 等 ≥30 s(相量窗 + `meas` 200 ms 轨稳定)→ 取**连续 ≥10 行**心跳 →
先确认 `frames` 还在涨、`adc1_err=0`,再核数 → 关输出 → 填表。"连续 ≥10 行"不是保守:`meas:` 是
**瞬时基波有效值透传**、200 ms 是上送节拍不是平均窗(`docs/任务规划/数据可信.md` §4.5),
单行读数带拍频式跳动,必须看一片取**中间水平(中位数)**才能定数。
**通用动作(六张卡都按这个走)**:
通用动作主干与两处分岔(采集链没清 → 回头修;偏差没进 → 先复核查再判):
1. 接好线、开发生器输出,等 ≥30 s 读数稳定;
2. 从串口取**连续 ≥10 行**心跳,先确认 `frames` 在涨、`adc1_err=0`(采不到算不得数),再核对卡片要求的读数——数字要取这 ≥10 行的**中位数**,别拿单行(`meas:` 是瞬时基波有效值透传、200 ms 是上送节拍非平均窗,`docs/任务规划/数据可信.md` §4.5,单行带拍频式跳动);
3. 这张卡的判据要录波取证的:抄完数后,从面板第 26 叶「手动录波」触发一段,把录波页屏上显示的文件名(`WAVE<nn>`)抄进该轮记录表;分析前在本机跑一次 `test/host/wave_read.py --selftest`,**不通过,分析结果不算证据**(不赶时间,六轮跑完统一取回再做);
4. 关掉发生器输出,把数填进该卡记录表。
```mermaid
flowchart TD
W["接好本路,开机前置门已过(§8.2)"] --> ON["开发生器输出"]
ON --> ST["等 ≥30 s:相量窗与 meas 轨稳定"]
ST --> HB["取连续 ≥10 行心跳"]
HB --> Q1{"frames 在涨、adc1_err = 0 ?"}
Q1 -->|"否:是节拍 / 丢帧问题"| TRI["先查 §8.8 分诊<br/>别归因给波形"]
TRI -.->|"修复后重来"| ST
Q1 -->|是| MED["10 行读数排序<br/>取第 5、6 个的平均 = 中位数"]
MED --> Q2{"与期望的偏差在判据内?"}
Q2 -->|是| OK["记通过"]
Q2 -->|"否"| CHK["先复核查:发生器端接、<br/>万用表响应类型、共地"]
CHK -->|"复查仍超"| BAD["记不通过,进 §8.8 分诊"]
CHK -->|"查出问题改完重测"| ST
OK --> OFF["关输出,填记录表"]
BAD --> OFF
OFF --> NEXT["下一条 / 下一轮"]
```
**两种情况先修再测,别往下走**:采集链没清(`frames` 不涨 / `adc1_err≠0`)→ 按 §8.2 前置门逐项查采集链;偏差没进判据 → 先复查三件事(端接 / 万用表响应类型 / 共地),改完重测,复查仍超才谈固件问题。
为什么这一步是"中位数"而不是单行或平均——机理与操作:
#### 幅值轮(先做:三档幅值的偏差都在 ±2 % 内)
![为什么连取 10 行取中位数:窗滑动让读数拍频式上下跳(左);中位数贴着密集簇,平均被毛刺拖走(右)](../../images/交流定数取中位数.svg)
#### 幅值轮:基波幅值(主用例,先做)
一句话:发生器注 50.000 Hz 正弦,**Vpp 2.828 / 1.414 / 0.566 V 三档挨个来**,每档从串口 `meas:` 行读 `ua_mv`,和并接在同一注入点上的万用表读数比——**每档偏差 ≤2 % 就算通过**。
| 项 | 内容 |
|---|---|
| 接法 | 发生器 → `UA`(R31 / `AIN1` / U5.A3)端子侧;万用表 AC 档**并同一注入点**——量真实加到板上的电压,不是面板值 |
| 设定 | 正弦、50.000 Hz、**1.000 Vrms**(峰值 1.414 V) |
| 主读数 | `meas: ua_mv=`(1 mV) |
| 期望与判据 | `ua_mv` ≈ 万用表读数 × 1000,偏差 **≤2 %**(与静态同档) |
| 交叉读数 | 104 `0x4011`(短浮点)应 ≈ 万用表读数,单位是**引脚电压域**(`eng=0`,不是二次值) |
| 坑 ① | **别用 `phasor(hb)` 比幅值**——×0.1 定点,1 V 只剩 10 格(§4 尾注同一条) |
| 坑 ② | 104 每点 0.5 V(电流 0.005 A)变化死区,生效值在 `App/algo/run_par.c` 的 `[run_par]` 副本:1.000 → 1.100 V **不会**上报变化,那是死区不是坏了;连续扫幅度只看 `meas:` |
| 坑 ③ | **`cal: ua_mv` 与 `meas: ua_mv` 同名不同物**:前者是当拍瞬时码折算(`App/task/adc_task.c:587`),后者是 200 ms 快照里那一周波的基波有效值(`App/task/adc_task.c:605`),50 Hz 下二者可以差很多——`App/task/adc_task.c:595-599` 的原注就是**勿互为判据**,幅值轮只认 `meas:` |
| 设定 | 正弦、50.000 Hz,三档挨个来:**Vpp 2.828 V → 1.414 V → 0.566 V**(档位不用拧精确,记万用表实际读数就行) |
| 读哪个数 | `meas: ua_mv=`(1 mV) |
| 通过判据 | 每档 `ua_mv` ≈ 万用表读数 × 1000,偏差 **≤2 %**(与静态轮同档) |
记录表(记录表每一行 = 连续 10 行心跳 `ua_mv` 的**中位数**:排序后取第 5、6 个的平均;
不取单行、不取峰值——单行带拍频跳动,毛刺行会拖偏算术平均。表里"序号"是一次重测):
记录表(每行 = 连续 10 行心跳 `ua_mv` 的**中位数**:排序取第 5、6 个平均;不取单行、不取峰值。"序号"是一次重测):
| 序号 | 万用表 AC (V) | `meas: ua_mv` | 期望 = 万用表 × 1000 | 偏差 % | 结论 |
|---|---|---|---|---|---|
| 1 | | | | | |
| 2 | | | | | |
| 3 | | | | | |
**加做(3 min,非判据)**:0.500 / 0.200 Vrms 两点看是否**等比**——不是验精度,是看有没有隐藏的触底或死区。
0.2 Vrms 那点 104 必然被死区吞掉,只读 `meas:`。
| 1 | 0.998 | 996 | 998 | -0.20 | PASS |
| 2 | 0.499 | 498 | 499 | -0.20 | PASS |
| 3 | 0.248 | 249 | 248 | +0.40 | PASS |
#### 波形轮:读数是否只跟基波走(同峰值改波形)
按**峰值对齐**(不是按 Vrms 对齐):三者峰值都取 1.414 V,发生器面板 Vrms 分别约 正弦 1.000 V、方波 1.414 V、
三角 0.816 V。期望的**基波有效值**(全周傅氏基波口径:`App/algo/phasor.c:3` 的系数已预乘 √2/N、`fAmSQ` 直接就是
有效值;下表的 20 点整周期 DFT 值就是按固件同一个窗算的):
三个波形都按**峰峰值对齐**:发生器统一设 **Vpp 2.828 V**(峰值 ±1.414 V)。期望的**基波有效值**(全周傅氏基波口径:`App/algo/phasor.c:3` 系数已预乘 √2/N、`fAmSQ` 直接就是有效值;下表 20 点整周期 DFT 值按固件同一个窗算):
| 波形 | 基波有效值 / 峰值 | 峰值 1.414 V 时的期望 `ua_mv` | 真有效值 / 峰值(对照) |
| 波形 | 基波有效值 / 峰值 | Vpp 2.828 V 时的期望 `ua_mv` | 真有效值 / 峰值(对照) |
|---|---|---|---|
| 正弦 | 0.707 | 1000 | 0.707 |
| 方波 | 0.904(闭式 4/π/√2 = 0.900) | ≈1278 | 1.000 |
| 三角 | 0.578(闭式 8/π²/√2 = 0.573) | ≈817 | 0.583 |
- 判据:读数 = **基波**期望 ±2 %,**不是**真有效值。方波那栏最直观——真 RMS 表会读 ≈1414 mV、
均值响应表读 ≈1570 mV,而板上读 ≈1278 mV,**这正是"这台仪表读的是基波"的证据,不是 bug**;
所以抬头里必须写清万用表响应类型(判据文档同一条:拿真有效值表去对会以为差了 10 %)。
- 系数的来路:方波基波幅值 = 4/π × 峰值、三角 = 8/π² × 峰值,再除 √2 得基波有效值 → 闭式 **0.900 / 0.573**,
20 点整周期 DFT 实算 **0.904 / 0.578**;`docs/任务规划/数据可信.md` §4.6.2 的"波形轮"行与本节同值,算术以本节为准。
- 判据:读数 = **基波**期望 ±2 %,**不是**真有效值。方波栏:真有效值表 ≈1414 mV、均值响应表 ≈1570 mV、板上 ≈1278 mV——**正是"读的是基波"的证据,不是 bug**;抬头必须写清万用表响应类型(判据文档同一条)。
- 系数算术以本节为准(4/π 与 8/π² 除 √2 得基波有效值;`docs/任务规划/数据可信.md` §4.6.2 引本表同值)。
记录表:
| 波形 | 峰值设定 (V) | 面板 Vrms | 万用表 AC 实测 | `ua_mv` | 期望 | 偏差 % | 结论 |
|---|---|---|---|---|---|---|---|
| 方波 | 1.414 | | | | ≈1278 | | |
| 三角 | 1.414 | | | | ≈817 | | |
| 波形 | 设定 Vpp (V) | 万用表 AC 实测 (V,有效值档) | `ua_mv` | 期望 | 偏差 % | 结论 |
|---|---|---|---|---|---|---|
| 方波 | 2.828 | 1.407 | 1269 | ≈1278 | -0.70 | PASS |
| 三角 | 2.828 | 0.814 | 807 | ≈817 | -1.22 | PASS |
#### 相位轮:相位(只许比同片内)
| 项 | 内容 |
|---|---|
| 接法 | `UA`(R31)与 `UN`(R28)**都走 TPAFE**,同幅 1.000 Vrms、同相——发生器单路输出分两路即天然同相;双通道机型则两通道都设 0° |
| 读数 | `phasor(hb) C02-UA-F1: Re=.. Im=..` 与 `C03-UN-F1: Re=.. Im=..`,各取 `atan2(Im, Re)` 再比差值 |
| 判据(§4.6.2) | **定量档**:同相时同段内两路相位差 ≤2°,把发生器(或 B 通道)改 90° 后差值跟到 ≈90°;**定性档只判跟随**(差值落进 80°~100°,容差写进记录表) |
| ⚠ 分辨率 | 出口只有 ×0.1 且向下截断:1.000 Vrms 时 Re/Im 各只有 ±10 格,**一格就是 0.1 V** → 角度量化误差最坏 ≈ atan(0.1 / 0.707) ≈ 8°,**≤2° 今天用串口判不出来** |
| 三个档 | ① **段文件定量档(首选,零改代码)**:同一次注入触发一段,`test/host/wave_read.py fft` 重算基波相位,比**同段内** `UA`(表序 0)与 `UN`(表序 3)的相位差——浮点重算,不受 ×0.1 量化限制,≤2° 判得动,动作见下面第 2 段;② **定性档**:没取到段时退而用,同相 ≈0°、改 90° 后差值落进 80°~100° 即算跟随,容差写进记录表;③ **抬倍数退路**:临时把 `log_phasors()` 的倍数改成 ×1000 并改掉行尾 `(x0.1)`,跑完按 §8.9 还原——段文件档已落地,这条基本不必走,要走仍**先问用户** |
| 红线 | **只许比同片内**:跨转换器无同刻性(V0.1 硬件缺陷)+ STM32 那五路另有 1 拍乒乓滞后 → `docs/硬件平台/ADC通道映射说明.md` §7 |
| 接法 | `UA`(R31)与 `UN`(R28)**都走 TPAFE**,同幅 Vpp 2.828 V(峰值 ±1.414 V)、同相(发生器单路分两路即天然同相;双通道机型两通道都设 0°) |
| 读数 | `phasor(hb) C02-UA-F1` 与 `C03-UN-F1`,各取 `atan2(Im, Re)` 再比差值 |
| 判据(`docs/任务规划/数据可信.md` §4.6.2) | **录波档**:同段内两路相位差 ≤2°,改 90° 后差值 ≈90°;**心跳档只判跟随**(差值落 80°~100°,容差写记录表) |
| ⚠ 分辨率 | 串口行的 ×0.1 向下截断:Vpp 2.828 V(板上 ≈1000 mV)时 Re/Im 各 ±10 格,**一格 0.1 V** → 角度量化误差最坏 ≈ 8°,**≤2° 串口判不出来** |
| 怎么取证 | ① **录波档(首选,零改代码)**:动作见下「录波档的具体动作」六步,比同段内 `UA`(表序 0)与 `UN`(表序 3)相位差,浮点重算不受 ×0.1 量化限制、≤2° 判得动;② **心跳档**:没录到段文件时退用,同相 ≈0°、改 90° 后差值落 80°~100° 即算跟随;③ **抬倍数退路**:临时 `log_phasors()` 倍数改 ×1000 并改行尾 `(x0.1)`,跑完撤销补丁并重编 + 重烧——录波档可用时基本不必走,要走**先问用户** |
| 红线 | **只许比同片内**:跨转换器无同刻性(V0.1 硬件缺陷)+ STM32 五路另有 1 拍乒乓滞后 → `docs/硬件平台/ADC通道映射说明.md` §7 |
记录表(定性档;定量档记脚本输出,归档口径见 §8.10 第 1 条):
记录表(按心跳档抄屏;录了波的轮次直接记脚本输出):
| 发生器相位设定 | C02-UA `Re` / `Im` | C03-UN `Re` / `Im` | 两路 `atan2` 之差 | 结论 |
|---|---|---|---|---|
| 0° / 0° | | | | |
| 0° / 90° | | | | |
| 发生器相位设定 | C02-UA `Re`/`Im` | C03-UN `Re`/`Im` | 录波文件名|两路 `atan2` 之差 | 结论 |
|---|---|---|---|---|---|
| 0° / 0° | -8 / -5 | -8 / -5 | WAVE06|心跳档两路象限全同 → Δ=0.0°(×0.1 判不动 ≤2°);**录波档 WAVE06 段实测 Δφ = 0.07°**(fft:UA 995.79 mV ∠+18.23° / UN 995.70 mV ∠+18.16°) | **PASS**(录波档 ≤2°) |
| 0° / 90° | 7 / -6 | -6 / -7 | WAVE09 | 心跳档:UA `atan2(-6,7)`=−40.6°、UN `atan2(-7,-6)`=−130.6° → 差 **+90.0°**(落 80°~100°,跟随成立);**录波档 WAVE09 段(2026-11-04 19:15:32 触发)16 个整周波全过**:UA 995.89 mV ∠−122.50°→−122.66°、UN 996.84 mV ∠+147.46°→+147.29° → Δφ(UA−UN)= **90.05°**,与 90° 设定偏差 **0.05°**,逐周波漂移 ≤0.01° | **PASS**(录波档 ≤2°;心跳档与录波档两口径互合) |
**段文件定量档的具体动作(相位轮首选,零改代码)**
**录波档的具体动作(相位轮首选,零改代码)**
1. `UA`(R31)与 `UN`(R28)两路接同一发生器输出(同相),注 **1.000 Vrms / 50.000 Hz**;
2. 稳定 ≥30 s 后,在 UI「手动录波」确认页触发一次;成段有**秒级**延迟(落盘在 defaultTask,卷空闲后一次心跳搬完整段)
→ 等串口 `wave:` 行的 `seg=` +1、`armed` 回 0 再去取文件;
3. FTP 取 `/wave/WAVE<NN>.BIN`(本轮那一段的确切号),**取完立刻改名**——100 个号轮转会被覆盖;
4. 主机侧跑:`& '.venv\Scripts\python.exe' test/host/wave_read.py fft WAVE<NN>.BIN --all`
—— 每个整周波给一行:基波 RMS、相位、2 次与 5 次谐波 RMS(单位 mV,系数镜像 `App/algo/phasor.c`);
5. 判据:`UA`(`--ch 0`)与 `UN`(`--ch 3`)在**同一周波**内的相位差——同相注入应 ≈0°,把发生器(或 B 通道)改 90° 后应 ≈90°,
容差 ±2°(`docs/任务规划/数据可信.md` §4.6.2"相位轮"行);
6. ⚠ 段的**绝对**相位与发生器没有锁定关系(触发瞬间固定落在段内点 159),所以**只能比同段内两路的相对差**;
跨段比相位、或拿发生器相位当绝对基准都不成立(段内点序见 `docs/子系统设计/故障录波设计说明.md` §6.2);
7. 交叉旁证:同一段先 `dump`(逐字段 + 双 CRC16,看封存瞬间的标定与品质快照),再 `plot --ch 0`(CRC 不符或零长度它
**必须拒收**而不是画出半张图);板上 `phasor(hb)` 的 `Re` / `Im` 象限应与脚本给的象限一致(×0.1 只够核象限)。
1. `UA`(R31)与 `UN`(R28)两路接同一发生器输出(同相),注 **Vpp 2.828 V / 50.000 Hz**;稳定 ≥30 s 后在 UI「手动录波」确认页触发一次;成段有**秒级**延迟(落盘在 defaultTask,卷空闲后搬段)→ 等 `wave:` 行 `seg=` +1、`armed` 回 0 再取文件;
2. FTP 取 `/wave/WAVE<NN>.BIN`,**取完立刻改名**(100 号轮转会被覆盖);
3. 跑 `& '.venv\Scripts\python.exe' test/host/wave_read.py fft WAVE<NN>.BIN --all`——每个整周波给一行:基波有效值、相位、2 次与 5 次谐波有效值(mV,系数镜像 `App/algo/phasor.c`);
4. 判据:`UA`(`--ch 0`)与 `UN`(`--ch 3`)在**同一周波**内相位差——同相 ≈0°,改 90° 后 ≈90°,容差 ±2°(`docs/任务规划/数据可信.md` §4.6.2);
5. ⚠ 段**绝对**相位与发生器无锁定(触发瞬间落在段内点 159)→ **只能比同段内相对差**,跨段比相位不成立(段内点序 `docs/子系统设计/故障录波设计说明.md` §6.2);
6. 交叉旁证:同一段先 `dump`(逐字段 + 双 CRC16),再 `plot --ch 0`(CRC 不符或零长度**必须拒收**);板上 `phasor(hb)` 象限应与脚本一致(×0.1 只够核象限)。
#### 测频轮(默认 A 档 = 判"如实报不可测")
#### 测频轮(现状:测不出频率才是对的)
一句话:给 `UA` 注与幅值轮同样的 Vpp 2.828 V / 50.000 Hz 正弦,看串口 `freq(hb)` 行——**固件现状就不该出数**,出数反而是算错了。
| 项 | 内容 |
|---|---|
| 接法与设定 | 同幅值轮(`UA`,1.000 Vrms / 50.000 Hz) |
| 读数 | `freq(hb): f=.. valid=..`;UI 交流量页 `Hz`;104 `0x401D` |
| 期望(A 档 = 现状) | **就是不出数**:幅值门 `FREQ_AMP_MIN 50.0f`(`App/algo/freq.h:62`,`App/algo/freq.c:231` 拿它与基波有效值比)在引脚电压域恒不过 → `valid=0`、`f=0`、UI `Hz` 显 `--`、104 `0x401D` 上送 IV |
| 接法与设定 | 同幅值轮(`UA`,Vpp 2.828 V / 50.000 Hz) |
| 读数 | `freq(hb): f=.. valid=..`;UI 交流量页 `Hz` |
| 期望(现状固件) | **就是不出数**:幅值门 `FREQ_AMP_MIN 50.0f`(`App/algo/freq.h:62`,`App/algo/freq.c:231` 拿它与基波有效值比)在引脚电压域恒不过 → `valid=0`、`f=0`、UI `Hz` 显 `--` |
| 判据 | **如实报不可测**,而不是报一个看起来对的 50.00。若门限没改却报出 50.00 → 反而是 bug,停下查 `App/algo/freq.c` |
| B 档(要用户先点头) | 临时把 `FREQ_AMP_MIN` 由 `50.0f` 降到 `0.5f` → 重编(`/keil-build`,要 build 锁)+ 重烧 → 扫 45.000 / 50.000 / 55.000 Hz 三点,PC 侧判据 0.02 Hz → 跑完**必须还原**,收尾判据见 §8.9 |
| 坑 | 非整 50 Hz 时 `meas:` 会拍频式跳动,属预期 → **扫频读 `freq(hb)`,别读 `meas:`**(`docs/任务规划/数据可信.md` §8 风险表同一条);测频的取源顺序是先 `UA`(相量实例 C02)再退 `IA`(C01)(`App/algo/freq.c:47`)——本卡注 `UA` 走的就是 UA 源;若哪天只注 `IA`,测频会跟着 IA 走,别以为它锁在 UA |
记录表(A 档):
| 频率设定 (Hz) | `freq(hb)` f | valid | UI `Hz` | 104 `0x401D` 品质 | 结论 |
|---|---|---|---|---|---|
| 50.000 | | | | | |
#### 削顶轮:触底与品质路由(负向用例)
- **判据**(`docs/任务规划/数据可信.md` §4.6.2"削顶轮"行):给 `UB`(R52 / `AIN2` / U5.B7)注 **DC −1.00 V 保持 ≥5 s**
或 **1.000 Vrms / 2.0 Hz** 的正弦 → 负半周钉下轨 → 连续 20 拍同侧后该路贴轨位锁存、`edge` 起沿、104 该路 IV 且值清零。
- ⚠ **注 50 Hz 同幅正弦造不出这个锁存,这是实现约束不是固件缺功能**:锁存条件是"连续 `ADC_RAIL_N_RUN = 20` 拍
贴同一侧轨带"(`App/algo/adc_health.h:174`),而 `adc_health_rail_watch()` 里**任何一拍回到中带就把两侧计数清零**;
1 kHz 下一个 50 Hz 周波只有 20 个点、正半周必然落在中带 → 连续贴底最长 ≈ 209°/360° × 20 ≈ **11 拍 < 20**。
- **轨带数值**(`App/algo/adc_cal.c:452` 的 `adc_cal_rail_ths()`,TEMP 不监视):STM32 侧贴底 = 码 ≤ **81**(2 % FS ≈ 65 mV)、
贴顶 = 码 ≥ 4013;TPAFE 侧 = ±32112 码(≈ ±4.9 V)→ **TPAFE 侧这一条在 ±2 V 判据上限内根本造不出来**,
只有 STM32 那五路能做。
- **改法 A(首选,零固件改动)**:发生器切 **DC 输出 −1.00 V** 注 `UB` 端子侧,保持 ≥5 s。期望:`cal:` 的 `rail=0x002`、
`edge=0x002`、一条 `[ERR] rail: edge=0x2 sticky=0x2 (code-domain, 20-run+release)`(`App/task/adc_task.c:428`)、
104 `0x4012` 该路 IV 且值清零、`adc: UB` 码值贴 0。撤掉注入后 **sticky 位不随输入恢复而清**(锁存语义,
只有 `adc_health_rail_init()` / 复位清)→ 复位一次并把"是否随复位清"记进表:这条实测行为是本轮的产出之一。
- **改法 B**:发生器 1.000 Vrms 但**频率设 2.0 Hz** → 负半周 250 ms = 250 拍贴底 ≥ 20 → 锁存;
顺带证"贴轨检测与工频无关"这条口径。
- **50 Hz 档照跑,判据就是"不锁存"**:记下 `adc: UB` 负半周钉 0 而 `rail` 仍 `0x000` —— 这一档证的是
"锁存要连续 20 拍同侧"这条实现约束本身,不是失败,也不是战果。
- **反向假阳性**:反过来注一个峰值 <65 mV(<46 mVrms)的 50 Hz 小信号,会让 `UB` 一路贴底而**锁存**——
那是"信号小到进不了中带",不是削顶。读 `rail` 时要把这条一起排除。
- **与 `cl` 区分**:`cl=0xE6` 是**来源派生**的静态触底掩码(`docs/任务规划/数据可信.md` §2.6),削顶轮要的是动态
`rail=` / `edge=`;别拿 `cl` 当本轮战果。
| 另有一档(需先取得同意) | 临时把 `FREQ_AMP_MIN` 由 `50.0f` 降到 `0.5f` → 重编(`/keil-build`,要 build 锁)+ 重烧 → 扫 45.000 / 50.000 / 55.000 Hz 三点,PC 侧判据 0.02 Hz → 跑完**必须还原**(撤销补丁 + 重编 + 重烧,`git diff` 核对干净)。这一档要改固件重烧,动它之前先问过你;不做也不影响上面那条判据成立 |
| 坑 | 非整 50 Hz 时 `meas:` 拍频式跳动属预期 → **扫频读 `freq(hb)` 别读 `meas:`**(`docs/任务规划/数据可信.md` §8 同一条);取源先 `UA`(C02)再退 `IA`(C01)(`App/algo/freq.c:47`)——注 `UA` 走 UA 源;若只注 `IA`,测频跟 IA 走 |
记录表:
| 步 | 设定 | `rail` | `edge` | `[ERR] rail:` 行数 | 104 `0x4012` | 复位后 `rail` | 结论 |
|---|---|---|---|---|---|---|---|
| 1 | 50.000 Hz / 1.000 Vrms 正弦 | | | | | 不适用 | |
| 2 | DC −1.00 V(改法 A) | | | | | | |
| 3 | 2.0 Hz / 1.000 Vrms(改法 B) | | | | | | |
| 频率设定 (Hz) | `freq(hb)` f | valid | UI `Hz` | 结论 |
|---|---|---|---|---|
| 50.000 | 0 | 0 | 未记(期望 `--`,与 fv 同源,无补测价值) | **PASS**:冻结窗口 229 行 `freq(hb)` **全部** `f=0.00 valid=0 src=0`(含 UA 满幅 Vpp 2.828 V 注入时段)——幅值门 `FREQ_AMP_MIN=50.0f`(`App/algo/freq.h:62`、`App/algo/freq.c:231`)拿**电压域有效值**比(`phasor(hb)` rms=9 = ×0.1 V 刻度),引脚域 ≈1 V 恒不过门 → **如实报不可测**,与现状判据逐字一致。**2026-11-04 复证**:19:10–20:01 采集窗 332 行 `freq(hb)` 依旧**全部** `f=0 valid=0`(含 UA+UN 双路满幅 90° 注入段与 IA 各注段)——判据在补测轮同姿势复现 |
**段文件档的两把尺子(现在能把"来源派生 vs 实测"一次核清)**
#### 削顶轮:触底与品质路由(负向用例)
`shape` 拿**实测**贴轨判定与段头 `clip_mask` 对表;而段头那一位**来自通道来源、从不实测**(`test/host/wave_read.py`
文件头的实证与本卡上面的 `cl=0xE6` 同源,两处互证)→ 三种注入分别配三把尺子:
- **判据**(`docs/任务规划/数据可信.md` §4.6.2"削顶轮"行):给 `UB`(R52 / `AIN2` / U5.B7)注 **DC −1.00 V 保持 ≥5 s** 或 **Vpp 2.828 V / 2.0 Hz** 正弦 → 负半周钉下轨 → 连续 20 拍同侧后该路贴轨位锁存、`edge` 起沿。
- ⚠ **50 Hz 同幅正弦造不出锁存,是实现约束不是固件缺功能**:锁存条件"连续 `ADC_RAIL_N_RUN = 20` 拍贴同一侧轨带"(`App/algo/adc_health.h:174`),`adc_health_rail_watch()` 里**任何一拍回中带就清零**;1 kHz 下一个 50 Hz 周波只有 20 点、正半周必落中带 → 连续贴底最长 ≈ 209°/360° × 20 ≈ **11 拍 < 20**。
- **轨带数值**(`App/algo/adc_cal.c:452` `adc_cal_rail_ths()`,TEMP 不监视):STM32 贴底 = 码 ≤ **81**(2 % FS ≈ 65 mV)、贴顶 = 码 ≥ 4013;TPAFE = ±32112 码(≈ ±4.9 V)→ **TPAFE 侧在 ±2 V 判据上限内造不出来**,只有 STM32 五路能做。
- **直流削顶档(首选,零固件改动)**:发生器切 **DC −1.00 V** 注 `UB` 端子侧,保持 ≥5 s。期望:`rail=0x002`、`edge=0x002`、一条 `[ERR] rail: edge=0x2 sticky=0x2 (code-domain, 20-run+release)`(`App/task/adc_task.c:428`)、`adc: UB` 贴 0。撤掉注入后 **sticky 位不随输入恢复而清**(只有 `adc_health_rail_init()` / 复位才清)→ 复位一次记录"是否随复位清",本轮战果之一。
- **2 Hz 低频削顶档**:发生器 Vpp 2.828 V 但**频率设 2.0 Hz** → 负半周 250 ms = 250 拍贴底 ≥ 20 → 锁存;顺带证"贴轨检测与工频无关"。
- **反向假阳性**:注 Vpp <130 mV(峰值 <65 mV)的 50 Hz 小信号会让 `UB` 贴底**锁存**——"信号太小进不了中带",不是削顶。读 `rail` 时一并排除(`cl=0xE6` 静态掩码另见 §8.2 前置门第 3 条,别当本轮战果)。
记录表:
| 步 | 设定 | `rail` | `edge` | `[ERR] rail:` 行数 | 复位后 `rail` | 结论 |
|---|---|---|---|---|---|---|
| 1 | 50.000 Hz / Vpp 2.828 V 正弦 | 0x000 | 0x000 | 0 | 未测 | ✓ 不锁存(正弦连续贴底 ≈11 拍 < 20,本步证"连续 20 拍"约束本身,非战果非失败) |
| 2 | DC −1.00 V ≥5 s(直流削顶档) | **0x002** | **0x002** | **1** | 未复核(用户裁定 2026-11-04 不做) | **2026-11-04 19:31:42 已做(注 `UB`)**:串口唯一一条 `[ERR] rail: edge=0x2 sticky=0x2 (code-domain, 20-run+release)`;`adc: UB` 由 ≈1005 码钉到 **0**;**撤注入后 rail=0x002 edge=0x002 恒持到日志尾(20:01+,≥30 min)= sticky 锁存语义实证**。"是否随复位清"未验——2026-11-04 用户裁定不复核("sticky 只有复位清"本为 `App/algo/adc_health.c` 的实现语义,不占台架时间) |
| 3 | 2.0 Hz / Vpp 2.828 V(低频削顶档) | 0x002(已被步 2 锁存掩蔽) | 0x002 | 0(无新增) | 未记 | **本窗未见 2.0 Hz 注入痕迹**:19:36:41 触发的录波段(WAVE11,锁存态下取)八路波形全 ≈0、`UB` 恒钉零码 = 撤注后取段,不是 2 Hz 工况。此步**用户裁定 2026-11-04 不补做、关闭**(直流档已证锁存与 sticky,低频档的附加信息"贴轨检测与工频无关"一并裁不要)。将来若复跑削顶轮(如标定态),**必须先复位清掉步 2 的 sticky 再做**(否则锁存态掩蔽,判不出 2 Hz 自己能否起沿) |
**段文件档的两个量具("来源派生 vs 实测"一次分清)**
`shape` 拿**实测**贴底与段头 `clip_mask` 对表;段头 bit **来源派生、从不实测**(`test/host/wave_read.py` 文件头与 `cl=0xE6` 同源互证)→ 三种注入各配一个量具:
| 注入 | 命令 | 期望 |
|---|---|---|
| 改法 A(`UB` 注 DC −1.00 V 保持 ≥5 s) | `shape WAVE<NN>.BIN --strict` | 实测贴底落进 bit1;段头静态已含 bit1 → 等式成立。**实测冒出段头没有的位**才算失败 = 有别的路被推到轨上,先查接线 |
| 极小注入 / 未驱动通道 | 同上再加 `--clip-superset` | 换成"段头覆盖实测"这把尺子:容忍"封存了但本轮没贴轨";实测有、段头没有仍然失败 |
| 原接法(50 Hz 正弦注 `UB`) | `shape WAVE<NN>.BIN`(不带 `--strict`) | 只读逐通道贴轨游程:正弦过零必回中带,`--min-run` 默认 4 也可能判不出贴轨——**别把"没判"读成 bug** |
| 直流削顶档(`UB` DC −1.00 V ≥5 s) | `shape WAVE<NN>.BIN --strict` | 实测贴底落 bit1;段头已含 bit1 → 等式成立。**实测冒出段头没有的 bit** = 失败,先查接线 |
| 极小注入 / 非驱动通道 | 同上 + `--clip-superset` | "段头覆盖实测":容"封存了但没贴底";实测有、段头没有仍判失败 |
| 原接法(50 Hz 注 `UB`) | `shape WAVE<NN>.BIN` | 只读贴底 run:正弦过零必回中带,`--min-run` 默认 4 判不出——**别把"判不出"读成 bug** |
`--min-run`(连续几点算贴轨)与固件的"连续 20 拍"是**两把不同的尺子**,别互相换算;固件侧结论仍以 `rail:` / `edge=`
位图为准(本卡上半段)。
`--min-run` 与固件"连续 20 拍"是**两个量具**,别互换;固件侧结论以 `rail:`/`edge=` 为准(本卡上半)。
#### 谐波轮:谐波轨(**段文件 `fft` 定量档 + UI 目检旁证**)
#### 谐波轮:谐波卡(录波档 fft + UI 目检旁证)
| 项 | 内容 |
|---|---|
| 接法 | 发生器 → `IA`(R19 / `AIN8` / U5.B5)端子侧 |
| 设定 | 基波 + 20 % 二次 + 20 % 五次(发生器有谐波叠加 / ARB 模式就用它) |
| ⚠ 峰值预算 | 1.000 Vrms 基波 + 两个 20 % 分量的最坏对齐峰值 ≈ 1.414 + 0.283 + 0.283 = **1.98 V,已顶到 ±2 V 判据上限**。所以基波改 **0.800 Vrms**、二次与五次各 0.160 Vrms,最坏峰值 ≈ 1.58 V 留余量;期望值随之换算 |
| 主读数 | UI 交流量页 `Ia2` / `Ia5` 两行——**3 位小数 = 1 mV**(`Drivers/BSP/UI/ui_page_ac.c:47`),目检 + 拍照;远端可走 7003 看图截屏 |
| 期望与判据 | 期望 ≈ 各分量注入值(0.160 Vrms)±2 % |
| 旁证 | `phasor(hb) C04-IA-F2` / `C05-IA-F5` 的 `rms=`:×0.1 只有 1~2 格,**只能证明这根轨不是恒 0**,判不了 ±2 %(§8.1) |
| 没有谐波叠加功能时 | 分三次单注:只注 0.160 Vrms / 100 Hz → `Ia2` 有数、`Ia5` 应 ≈0;只注 0.160 Vrms / 250 Hz → `Ia5` 有数、`Ia2` 应 ≈0;再注纯基波 → 两行都 ≈0。这一档证的是"两根轨各认各的次",**不证叠加工况**,结论里要写明 |
| 口径 | 这两根轨**目前没有任何下游消费者**(`App/algo/prot_elm.c` 无引用、`meas` 只算基波)→ 谐波轮只证"算得对",不证"有人用";出口归属 `docs/任务规划/数据可信.md` §9 的谐波轨立项 |
| ⚠ 峰值预算 | 基波 Vpp 2.828 V + 2 个 20 % 分量,最坏对齐峰值 ≈ 1.414 + 0.283 + 0.283 = **1.98 V,已顶到 ±2 V 判据上限**。所以基波改 **Vpp 2.263 V**、二次与五次各 Vpp 0.453 V,最坏峰值 ≈ 1.58 V 留余量;期望值随之换算 |
| 读哪个数 | UI 交流量页 `Ia2`/`Ia5`(3 位小数)——**1 mV**(人工目检 + 拍照留证,`Drivers/BSP/UI/ui_page_ac.c:47`);谐波幅值、交叉旁证 |
| 期望与判据 | 板上读数(有效值刻度)≈ 各分量 0.160 V(对应设定 Vpp 0.453 V)±2 % |
| 旁证 | `phasor(hb) C04-IA-F2`/`C05-IA-F5` 的 `rms=`:×0.1 只 1~2 格,**只能证"该轨非恒 0"**,判不了 ±2 %(§8.1) |
| 无谐波叠加功能时 | 三次单注:只注 Vpp 0.453 V / 100 Hz → `Ia2` 有数(读数 ≈0.160 V)、`Ia5` 应 ≈0;只注 Vpp 0.453 V / 250 Hz → `Ia5` 有数、`Ia2` 应 ≈0;再注纯基波 Vpp 2.263 V → 两轨都 ≈0。这一档证"两轨各认各的次",**不证叠加工况**,结论里写清 |
| 口径 | 这两轨**当前无下游消费者**(`App/algo/prot_elm.c` 无引用、`meas` 只算基波)→ 谐波轮只证"算得对",不证"有人用";这两轨归谁用,见 `docs/任务规划/数据可信.md` §9 谐波轨立项 |
记录表:
| 注入分量 | 发生器设定 | UI 读数 (V) | 期望 (V) | 偏差 % | `phasor` 旁证 | 结论 |
|---|---|---|---|---|---|---|
| 基波 0.800 Vrms + 二次 0.160 + 五次 0.160 | | `Ia2=` / `Ia5=` | 0.160 / 0.160 | | | |
| A 只注二次 | 100.00 Hz / Vpp 0.453 V | `Ia=0` / `Ia2=0.158` / `Ia5=0` | 0.160 / ≈0 | **−1.25 %** | —(A/B 步落在 18:22–18:28 日志盲区,心跳旁证未留) | **过**(±2 % 内;选择性成立——100 Hz 没漏进基波 / 五次桶) |
| B 只注五次 | 250.00 Hz / Vpp 0.453 V | `Ia=0` / `Ia2=0` / `Ia5=0.153`(2026-11-04 复测;11-02 初读 0.152) | ≈0 / 0.160 | **−4.4 %**(超 ±2 %) | —(两轮均未留 250 Hz 心跳旁证——带外信号 `meas:` 判不了,见上卡旁证行) | **过——已按「板端真实衰减」关闭(2026-11-04)**:−4.4 % = IA 前端差分滤波(C35 = 100 nF + R19/R21 各 1 k,一阶低通 fc ≈ 796 Hz)在 250 Hz 的真实衰减,**板端读数忠实,量与算都没错**(模型与数据 `docs/硬件平台/ADC通道映射说明.md` §8.2);工频 50 Hz 仅 −0.2 %,不受影响;选择性成立(基波 / 二次桶 = 0);谐波功能要板改(C35 换 10 nF)——登记 `docs/任务规划/登记簿.md` §3 |
| C 纯基波 | 50.00 Hz / Vpp 0.453 V(实际按 0.453 注,Vpp 2.263 那档未做) | `Ia=0.160` / `Ia2=0` / `Ia5=0`(2026-11-04 复测;11-02 初读 0.159) | ≈0 / ≈0 | 基波 **0.0 %**(对 0.160 读数;11-02 为 −0.6 %) | **有**:18:33:43 起串口可见窗 `C01 rms=1 / C04 rms=0 / C05 rms=0`,与 C 步工况吻合;2026-11-04 复测窗串口 `ia_mv=159↔160` 同刻印证屏显 | **过**(两谐波轨零值经串口旁证补认;基波读数两轮 ≤0.6 %,与幅值轮同档一致) |
| 叠加(原行,**本轮不做**) | 基波 + 二次 + 五次同段 | — | — | — | — | 发生器无谐波叠加 / ARB 功能 → 本轮不做·设备缺口·TC-PHASOR-006 单测覆盖(`test/host/phasor/phasor_test.c`,3 条谱线各 ±1 %,实跑 57/57 PASSED) |
**段文件定量档(谐波现在判得到位)**
**录波档动作(谐波现在判得到位)**
同一次注入(基波 0.800 Vrms + 二次 0.160 + 五次 0.160,峰值预算见上表)触发一段、FTP 取回后跑:
同一次注入(叠加档设想值:基波 Vpp 2.263 V + 二次与五次各 Vpp 0.453 V,峰值预算见上表;本轮发生器无叠加功能、未跑此档)触发一段,FTP 取回跑:
```text
& '.venv\Scripts\python.exe' test/host/wave_read.py fft WAVE<NN>.BIN --ch 4 --all
```
`fft` 逐整周波给**基波 RMS + 2 次与 5 次谐波 RMS**(mV,浮点重算),±2 % 在这条档是定量判据;`--ch` 是段内通道表序,
`IA` = 4(表序 `UA UB UC UN IA IB IC IN`,TEMP 不录,`App/algo/wave_ring.h:216`)。UI 目检与 7003 截图降为**旁证**——
它证的是"板上 `Ia2` / `Ia5` 与脚本算的是同一件事"(差值应在显示位数之内),不是替代判据。THD 与方和根仍不在本轮,
口径见 `docs/任务规划/数据可信.md` §4.6.5。
### 8.6 顺序与耗时(一次台架 session 跑完)
| 序 | 做什么 | 预计 | 备注 |
|---|---|---|---|
| 0 | 前置门 + 基线 30 s | 10 min | §8.2,不满足就停 |
| 1 | 幅值轮(含 0.5 / 0.2 Vrms 加做) | 15 min | 主用例 |
| 2 | 波形轮(方波 / 三角,峰值对齐) | 15 min | 抬头里记万用表响应类型 |
| 3 | 谐波轮:段文件 `fft` 定量档 + UI 目检旁证(同一次注入触发一段) | 25 min | 命令见 §8.5 的谐波卡 |
| 4 | 相位轮:段文件相对相位档(`UA` / `UN` 同源,再移 90°) | 20 min | 定性档只在没取到段时退用 |
| 5 | 测频轮 A 档 | 5 min | 判"如实报不可测" |
| 6 | 削顶轮:50 Hz 档 + 改法 A + 改法 B + 复位复观(每档各触发一段) | 30 min | **单独一份日志**,判读规则见 §8.7 |
| 7 | 同一份接线下把 104 交叉读数复跑一遍 | 15 min | `test/host/iec104_master.py` |
| 8 | 取段与脚本产物归档(FTP `get` + `dump` / `fft` / `shape` / `plot`) | 15 min | 每段取完立刻改名,100 号轮转会覆盖 |
| — | (需用户点头)测频轮 B 档 / 相位轮抬倍数档 | +40 min | 各含一次重编、烧录与还原;段文件落地后相位轮这条基本不必走 |
合计约 **135 min**(不含"需用户点头"那两档)。取段与跑脚本集中在末尾第 8 行统一做,中间各条只负责"触发 + 让
`seg=` +1",免得一次 session 里反复插拔网线。
### 8.7 `[ERR]` 的判读规则(削顶轮单独跑、单独归档)
- 削顶轮会**故意造出** `[ERR] rail: edge=… sticky=… (code-domain, 20-run+release)`,而 `/serial-boot-test` 的 forbidden 标记含
`[ERR]`(AGENTS.md「构建与验证」)→ **这一轮不要把 `/serial-boot-test` 的标记校验当结论**:改人工判读,并在归档文件名与
抬头里写明「预期 [ERR]:贴轨锁存负向用例」;§8.6 已把它排在最后单独一轮(`docs/任务规划/数据可信.md` §8 风险表「削顶负向用例被当成固件 bug」行同一条)。
- 除这一条 `[ERR] rail:` 之外,**任何 `[ERR]` 都是不通过**;四个 Fault 的崩溃日志也以 `[ERR]` 开头 →
出现 Fault 立即停线取现场(`docs/子系统设计/看门狗设计说明.md` §10),别再继续注。
- 每次开机 `rail:` 边沿只打一条、`SYSLOG` 也只留痕一次("adc code rail fault" 进 `selftest.log`)——这是设计不是漏报;
要看第二次边沿就复位一次。
### 8.8 失败分诊(先查这一列,别急着改固件)
| 现象 | 先查 | 依据 |
|---|---|---|
| 与万用表差约 2 倍 | 发生器输出端接设成了 50 Ω | §8.2 表第 2 行 |
| 差约 5.3 倍,或数字带 6553.6 / 1241.2 的痕迹 | 拿错刻度,或把 `adc:` 的码值当 mV 读 | §2 两把尺子、§4「码是什么」 |
| `phasor` 行 `rms` 只有 10 格量级 | 正常(×0.1),不是 bug | §4 尾注、§8.1 |
| 非整 50 Hz 时 `meas:` 来回跳 | 预期:瞬时透传、200 ms 不是平均窗 → 改读 `freq(hb)` | `docs/任务规划/数据可信.md` §8 风险表 |
| 104 读数不动 | 每点 0.5 V / 0.005 A 变化死区(生效值 `App/algo/run_par.c`) | §8.5 的幅值卡坑 ② |
| 50 Hz 正弦注 `UB` 但 `rail` 不锁存 | **预期**(连续贴底不足 20 拍)→ 改法 A / B | §8.5 的削顶卡 |
| 改 DC 也不锁存 | 释放沿前提没满足:开机后该通道没出现过中带样本 → 先建基线再注入 | `App/algo/adc_health.c`、§8.2 前置门末条 |
| 撤掉注入后 `rail` 仍非 0 | 锁存语义(sticky),只 `adc_health_rail_init()` / 复位清 → 复位后仍不清**才是** bug | §8.5 的削顶卡改法 A |
| 读数带与幅度无关的偏置或漂移 | 共地 / 地环 | §8.2 末行 |
| `meas: seq` 不涨 | 发布闸门停 → 先查采集链,别判交流 | §8.2 前置门 |
| `health:` 或 `sampling fault:` 亮 | 与注入的波形无关:`adc_health` 的位只吃序号差、错误计数增量与 tick 差(`App/algo/adc_health.c:91-189`)→ 查节拍 / 丢帧,别查发生器 | §8.2 前置门 |
| 9 路全 0 | 读作"没数据",不是"输入为零" | §4 尾注 |
| `wave_read.py` 报错退出 / 拒绝出图 | **这是正确行为**:CRC 不符或零长度它必须拒收而不是画出东西 → 重取一份、核对是不是搬到一半的半成品;仍拒收就 `dump` 看两处 CRC16 哪个不符 | `test/host/wave_read.py` 文件头 |
| `shape --strict` 说实测与段头不等 | 先分清尺子:段头 `CLIPPED` 位来自**通道来源、从不实测**;DC 偏置 / 极小注入 / 未驱动通道应改用 `--clip-superset` | §8.5 的削顶卡段文件档 |
| 触发后 `seg=` 不涨或 `drop` / `ovf` 涨 | 落盘道在 defaultTask 卷空闲后才搬段,先等几秒;仍不涨查 `wave:` 行三计数与 `/wave` 目录可写(`[ftp]` 写权限) | `App/task/adc_task.c:782` |
### 8.9 收尾判据(走过临时改动的一条都不许留)
| 临时改动 | 收尾判据 |
|---|---|
| 测频轮 B 档:`FREQ_AMP_MIN` 50.0f → 0.5f(`App/algo/freq.h:62`) | 还原 + `/keil-build` 0 错误 0 警告 + **`git diff` 里 `App/algo/freq.h` 必须为空** + 在 `docs/任务规划/数据可信.md` §7 #8 那行留一句"本轮台架已还原" |
| 相位轮改倍数:`log_phasors()` 的 `* 10.0f` → `* 1000.0f`(`App/task/adc_task.c:209`) | 同上,`git diff` 里 `App/task/adc_task.c` 必须为空 |
| 为 bench 定时自抓开过编译门(`DTU_BENCH` + `WAVE_BENCH_AUTOCAP` 非 0,`App/task/adc_task.c:153`) | 还原成默认 0 + `/keil-build` 0 错误 0 警告 + `git diff` 里 `App/task/adc_task.c` 必须为空(产品镜像里这段必须零存在) |
| 只动接线与发生器、没动代码 | `git status` 除归档目录外干净 |
| 全程 | `test/board/test_config.h` 四个套件宏保持全注释(产品构建);烧录仍须 `-Rst -Run` + 回读校验 |
### 8.10 归档与回写(跑完必做,缺一算没收尾)
1. **证据归档** → `docs/测试说明/测试数据/boot_log_data/`,沿用现有命名惯例(日期_主题_类型.txt):
`20261104_ac_amp_meas_log.txt`、`20261104_ac_clip_rail_log.txt`、`20261104_ac_iec104_log.txt`;UI 目检照片同目录
(该目录若不收图,就在抬头里写清照片存放位置)。**走段文件定量档的用例另加两样**:取回的段原件(原始字节,
`20261104_ac_phase_wave<nn>.BIN`)与脚本输出(`fft` / `shape` / `dump` 三份文本 + `plot` 的图)——定量档的证据本体是
**那一段原始码值**,日志只是旁证;段原件一旦覆盖就再也拿不回来,先改名再触发下一段。
2. **实测结论回写** → `docs/硬件平台/ADC通道映射说明.md`,在 §8.1(直流轮次)之后**新开一节**——
任务卡 `docs/任务规划/数据可信.md` §5 的 DoD 就是这么分的。本文只留"怎么跑",**不抄实测数**。
3. **本文回写** → 只在 §8.1 那张表下加一行指针级别的句子("YYYY-MM-DD 已按本节跑通,实测见 …");
不在本文建第二份结论表,否则两份必然漂移(`docs/文档规范.md` 同一事实只在一处详述)。
4. **判据文档的一致性维护** → 本文 §8 的期望值算术、接法与出口分档已写进
`docs/任务规划/数据可信.md` §4.6.2(2026-10-29:波形轮的逐波形系数、削顶轮的 DC / 2 Hz 接法与 50 Hz 档的
"不锁存属预期"、相位轮与谐波轮的"定量档走段文件、定性档走 `phasor(hb)`")。今后两边若再分叉,按开头引导块的
两类裁定处理(语义从那节、算术与步骤从本文),**别在本文另立第二份判据表**。
5. **销项** → `docs/任务规划/数据可信.md` §2.7 与 §6 卡片表里这一条按登记簿「完成即销项」处理,属 Ask first,
须用户明确指示后再做。
### 8.11 这一轮证不到(别让读数长得像证据)
`docs/任务规划/数据可信.md` §4.6.5 那张五行表整条适用(端子二次值 / 精度等级 / 跨转换器相位与功率与对称分量 /
THD 与谐波方和根 / 温升 EMC 长时间漂移)只适用,本节按出口已落地改三条现状(2026-10-29 录波数据面并入主干之后):
**样本出口已成立**(`/wave/WAVE<NN>.BIN` + `test/host/wave_read.py`)→ 相位轮 / 谐波轮走定量档时结论是**形状级**,不再只是标量级;
但**板级那一轮对表本身还没跑过**(判据见 `docs/子系统设计/故障录波设计说明.md` §10),本轮跑出来的就是第一批实测;
段与发生器**没有绝对相位锁定**(触发瞬间只钉在段内点 159)→ 能核的是同段内两路的**相对**相位与极性,
全局相角基准仍证不到;一次触发只有 320 点 = 320 ms,**不等于长时间稳定性**。示波器仍旧只作旁证、不进判据。
再补一条「别把台架做成功能性重复」的边界:**算法本体的精度已经在纯数字域钉住了**——`test/host/phasor/phasor_test.c`
的 TC-PHASOR-003 与 TC-PHASOR-004(基波 = 峰值 / √2 容差 1 %、注入相角容差 0.5°)和 TC-PHASOR-006(2 / 3 / 5 次
谐波 1 %),以及 `test/host/freq/freq_test.c` 的扫频判据 J1(45~55 Hz 内 ≤0.02 Hz),都是把已知正弦**直接喂进
`sample_ring`**,绕过了 `adc_cal` 的折算(那里的幅值是工程量口径,不是引脚 µV)。所以 §8 这一轮真正要证的只有
「信号走到 `sample_ring` 之前」那一段:发生器刻度与输出端接、前端串阻与滤波电容的幅频、两片转换器的同刻性、
码到 mV 的折算、出口的量化。这一轮过了**不等于**「算法精度已实测验证」,结论里别那么写。
`fft` 每整周波给基波与 2 次/5 次谐波有效值(mV,浮点重算),±2 % 是定量判据;`--ch` = 段内通道表序,`IA` = 4(`UA UB UC UN IA IB IC IN`,TEMP 不录,`App/algo/wave_ring.h:216`)。UI 目检只是**旁证**(证"板上与脚本算的是同一个东西"),不是替代判据。THD 与根均方不在本轮(`docs/任务规划/数据可信.md` §4.6.5)。
@@ -17,9 +17,25 @@
## 2. 为什么"容量"需要单独恢复(根因)
- 健康满容量 = **96064 pages(187 MB)**(`No valid map found, creating fresh` 分支下的满值)。
> ⚠ 2026-11-04 台架待核(问题 #79):三次捕获都打 `capacity: 97504 pages = 190 MB`
> (比本基线大 1440 页),且**故障前后数值一致**(不是被扣损的结果)。两种可能未定:
> ① 台架那块板的 `bb_last/bb_current` 与"全新初始化"不同口径;② 本文基线陈旧。
> 判定方法:台架跑一次动作 B(全片擦除 + 断电重启,走 `dhara_map_clear` 全新分支)
> 后读同一行的 `capacity:`——若仍是 97504,则本文基线应改。(另:本行是**故障本身
> 无关**的证据,见 架构说明 §10.4.1:容量正常 ⇒ 不是块池耗尽。)
> **2026-11-04 更新(问题 #79)**:当日跑的是动作 A(非 B),BBT 重建 0 坏块 +
> format 后容量仍报 97504=190 MB;且 129 个误标坏块存在期间读数也是 97504
> (误标只毁 journal 写头,不改本行读数)。基线改判**仍需动作 B**,未跑,本行保留。
- dhara 的坏块计数 `bb_current` / `bb_last` **持久化写在 journal checkpoint 头里**
(`Lib/dhara/journal.c` 的 `hdr_set_bb_current/hdr_set_bb_last`,随 checkpoint 一起落盘)。
容量按 `good_blocks = num_blocks − max(bb_last, bb_current) − 1` 递减。
- **⚠ 还有一处独立于 dhara 计数的坏块持久化**:板级 BBT(`gd5f2gq5ue.c` 的
`s_bbt[]` 轮转池,`mark_block_bad` 每次**立即落盘、不可撤销**)。2026-11-04 的
台架故障根因即在此:传输层失败被旧 `dhara_nand_erase/prog()` 误当坏块证据标坏,
129 个好块固化进 BBT,journal 写头爬进误标段 → `prepare_head()` 连续 8 次
`is_bad` → `TOO_BAD` → 整卷禁用(机理见 架构说明 §10.4.2)。这种"误标卷"的**处置
就是动作 A**(重扫出厂坏块会覆盖误标并持久化);A 后若 `BBT after merge` 再报
非零增量,看的是新增标坏日志 `Erase/Program ... (not a bad block)` 有没有出现。
- `dhara_journal_clear()`(即 `nand_ftl_format()` 走的路)只做 `bb_last = bb_current`,**不归零**——
所以动作 A 清不掉被扣掉的容量,断电重扫也一样(计数从 checkpoint 读回)。
- 只有让下次启动 `dhara_map_resume` **失败**、走 `dhara_map_clear` 的**全新初始化**分支
@@ -27,6 +43,23 @@
- 记账的触发:一次 `program verify` 失败(日志 `[ERR][NAND_FTL] program verify: data mismatch, blk N`)
就让 dhara 多记一个坏块;破坏性套件(写完擦、坏块注入、格式化)会累积这个数字。
### 2.1 动作 A 在 2026-11-04 之前是**静默失效**的(问题 #79,已修)
`nand_ftl_format()` 旧实现的第一步是 `if (ftl_flush_cache() != BSP_OK) return GD5F_ERROR;`,
而 `ftl_flush_cache()` 失败时刻意**不清** `s_cache_dirty`。于是只要脏页落在"写不动的那个
LPN"上,格式化就在第一道闸门返回,`dhara_map_clear()` **从未执行**——动作 A 名义上跑了,
实际上一个映射都没清,紧随其后的 `f_mkfs` 仍在旧映射上工作、必然失败。
- **现场特征**:`Cache flush FAIL: LPN=<固定值> dhara=TOO_BAD` 连打十余条 →
`reformatting...` → `volume repair failed (fr=1)` → `storage disabled`,且**每次启动必现**。
看到这条链就别再连续重试动作 A,先确认脏缓存是否正卡在坏页上。
- **修复后判据**:跑动作 A/B 时若出现新增日志
`format: dirty cache at LPN=<n> undiscardable, dropping it (map is being destroyed anyway)`
→ 说明确实撞上了"脏页卡坏页",但**格式化已经继续执行**(这是预期行为,不是新故障)。
其后应能看到 `NAND FTL formatted, capacity: ...`。
- 语义边界:丢弃脏缓存的权限**只在 format 内**。`disk_read`/`disk_write` 的 flush 失败
必须继续向上报 `RES_ERROR`——那是"这次写没落地"的真相。
## 3. 操作步骤(以容量恢复为例)
1. `test/board/test_config.h`:取消注释 `TEST_SUITE_STORAGE`;
@@ -1,7 +1,7 @@
# 故障录波板级到场轮执行手册(人要做的事,一步一行)
> **这份手册解决什么**:录波的判据里剩下的那半轮——需要**有人的手和信号发生器**的验证——把它拆成"你做什么、说哪句话、会看到什么"。
> **它不是判据属主**:判据、留痕名清单、执行顺序图全在 `docs/子系统设计/故障录波设计说明.md` §9 与 §10;本文只写**执行动作**。已完成部分(2026-10-31 远程半轮六项 PASS + 2026-11-02 缺陷「回放页段表枚举恒空」修复闭环)见 §10「板级远程半轮记录」与 §10「回放页枚举恒空缺陷修复记录」。
> **它不是判据属主**:判据、留痕名清单、执行顺序图全在 `docs/子系统设计/故障录波设计说明.md` §9 与 §10;本文只写**执行动作**。已完成部分(2026-10-31 远程半轮六项 PASS + 2026-11-02 缺陷「回放页段表枚举恒空」修复闭环 + 2026-11-04 第二幕注量对表闭环(#40 交流轮)+ 2026-11-06 坏段/空态两画面台架远程轮拍毕)见 §10「板级远程半轮记录」与 §10「回放页枚举恒空缺陷修复记录」「回放页坏段/空态画面闭环记录」。
> **一句话预算**:你到场约 1.5~2 小时;其中真正动手的只有**接三次线、按不超过六次键、拍两个决定**——其余全部由会话里的 agent 跑脚本。
---
@@ -11,7 +11,7 @@
| 幕 | 名字 | 要你在场? | 你动手的部分 | agent 跑的部分 | 对应判据 |
|---|---|---|---|---|---|
| 第一幕 | 枚举埋点与修复上板 | **已完成(2026-11-02,远程)** | 无 | 改码加埋点 → 构建 → 烧录回读 → 远程开回放页 → 读 FR 码定性 → 修复重烧 | `docs/子系统设计/故障录波设计说明.md` §10「回放页枚举恒空缺陷修复记录」 |
| 第二幕 | 注量对表 | **要到场**(只有接线需要手) | 接 UA 发生器线 1 次、拔 1 次;面板按 2 次键(或让 agent 远程注键) | 记心跳基准 → FTP 拉段 → `wave_read` 量四样 → `meas:`/104 YC 对表 → 削顶注大一遍 → 坏段上板看回放页绝不平线 | `docs/子系统设计/故障录波设计说明.md` §10「板级」行 +「板级·回放页」行后半 |
| 第二幕 | 注量对表 | **已闭环(2026-11-06)**——注量对表 2026-11-04 由 #40 交流轮跑完;坏段/空态画面 2026-11-06 台架远程轮拍毕,本幕现场无需重做 | ~~接 UA 发生器线 1 次、拔 1 次;面板按 2 次键(或让 agent 远程注键)~~ 已由远程轮与 #40 消化 | 记心跳基准 → FTP 拉段 → `wave_read` 量四样 → `meas:`/104 YC 对表 → 削顶注大一遍 → 坏段上板看回放页绝不平线 | `docs/子系统设计/故障录波设计说明.md` §10「板级」行 +「板级·回放页」行后半 +「回放页坏段/空态画面闭环记录」 |
| 第三幕 | P 触发对时刻 | **要到场**,还含**两个由你拍板的决定** | IA 两点标定各接一次线 + 过流加大到 UI 见数值过 2 A | 读码算 k/b → 写配置生效 → 验证解锁 → 触发后对 start.log 时刻/段号/src=P | `docs/子系统设计/故障录波设计说明.md` §10「板级·触发来路」行 |
| 第四幕 | bench 自抓与卷占用 | **可远程**(烧录同上;占卷用 FTP 造) | 无 | 烧 bench 构建 → 造占卷 ≥2 s → 看 `err`+1、**一条** `ring abandoned`、同号重写 → 还原产品构建 | `docs/子系统设计/故障录波设计说明.md` §10 板级行的 `ring abandoned` 观察项 |
@@ -80,7 +80,14 @@ flowchart LR
|---|---|---|---|---|---|---|---|
| UA 1.000 V 50.000 Hz | 待填 | WAVE__ | __ Hz | __ V | 正/反 | __ 路 | 过/不过 |
| 削顶注大 | 待填 | WAVE__ | __ Hz | __ V | 正/反 | __ 路 | 过/不过 |
| 坏段(回放页画面) | — | 同号覆盖 | — | — | — | — | 不平线=过 |
| 坏段(回放页画面) | — | WAVE06 同号覆盖(`RETR→byte[130]^=0x01→STOR`) | — | — | — | — | **过**(2026-11-06 台架远程轮实测:「该段不可读」零波形元素,绝非直线) |
> 2026-11-06 收工状态(台架远程轮,bench 锁全程持有,无人到场):第 3 行坏段拒收画面与配套的
> 「无录波段」空态画面真机抓屏已入档 `docs/测试说明/测试数据/wave_shot_20261106/`(README 含
> 判据对照、串口锚点与复现口令);第 1、2 行的注量实测数值归 2026-11-04 #40 §8 交流轮
> (`docs/测试说明/测试数据/boot_log_data/20261104_ac_*`,实测结论见 `docs/硬件平台/ADC通道映射说明.md` §8.2),
> 104 浮点遥测按该轮用户裁定不作对照证据。**本幕至此全幕闭环**;坏段样本收工不留板
> (手册 §7 二选一取「删除」,样本点名留档见证据目录 `samples/` 与设计说明 §10 闭环记录小节)。
---
@@ -67,7 +67,7 @@
| **CH395F 芯片** | 无(Winsock 代其 BSD API) | SPI 寄存器/命令/中断、PHY 协商、真实以太网帧 | 寄存器时序、命令回复、中断风暴、PHY 100M 全双工强制 | 板端 CH395F 套件(52 断言点)+ `/serial-boot-test` |
| **GD5F NAND** | 无 | SPI NAND:BBT 扫描、ECC、坏块管理、dhara FTL | 坏块/ECC/写入失败等路径完全不可测 | 板端 GD5F 套件(76 断言点)+ `/serial-boot-test` |
| **SD2506 RTC** | 无 | I2C RTC:时间读写、闹钟、温度、电池电压 | 时间源相关(`sys_clock_init` 降级路径)在模拟器上不可触发 | 板端 RTC 套件(18 断言点)+ `sys_clock` 主机侧纯逻辑单测(已覆盖算术面) |
| **开机账本 boot_stats(上电次数 / 复位原因快照)** | **不编译** `App/util/boot_stats.c`(依赖 SD2506 用户 SRAM 与 `RCC_CSR`);UI「运行报告」页的四个数在模拟器上是 `simulator/main.c` 的**固定假数据**(`boot_count=7`、`seq_state=延续`、`rst_cause=上电复位`、104 四枚 3 / 128 / 0 / 4096、`uptime_s=0`) |`boot_stats_init()` 读 SRAM → 自增 → 写回 → 快照驻留;四个 104 观测计数由 iec104Task 真实累加(跨重连不清零、断电归零) | 「自增有没有真落 SRAM」「电池域掉电后是否落 RESTARTED」「写失败是否只少计不重复」「104 计数是否跨重连累计」四类事在模拟器上**结构上不可见**;黄金参考只拍得到显示口径(范围标签在不在屏上、值有没有串行、`boot_ready=0` 是否显 `--` 而不是 0) | 主机单测 `test/host/boot_stats/`(SRAM 状态机与四态判定)+ 真机 `/serial-boot-test`:上电一次看 `boot_count` +1、拔电池后落 RESTARTED、IWDG 复位后 `rst_cause=IWDG`、主站连一次看 `conn_up` +1 |
| **开机账本 boot_stats(上电次数 / 复位原因快照)** | **不编译** `App/util/boot_stats.c`(依赖 SD2506 用户 SRAM 与 `RCC_CSR`);UI「运行报告」页的四个数在模拟器上是 `simulator/main.c` 的**固定假数据**(`boot_count=7`、`seq_state=延续`、`rst_cause=上电复位`、104 四枚 3 / 128 / 0 / 4096、`uptime_s=0`) |`boot_stats_init()` 读 SRAM → 自增 → 写回 → 快照驻留;四个 104 观测计数由 iec104Task 真实累加(跨重连不清零、断电归零) | 「自增有没有真落 SRAM」「电池域掉电后是否落 RESTARTED」「写失败是否只少计不重复」「104 计数是否跨重连累计」四类事在模拟器上**结构上不可见**;黄金参考只拍得到显示口径(范围标签在不在屏上、值有没有串行、`boot_ready=0` 是否显 `--` 而不是 0) | 主机单测 `test/host/boot_stats/`(SRAM 状态机与四态判定)+ 真机 `/serial-boot-test`:上电一次看 `boot_count` +1、IWDG 复位后 `rst_cause=IWDG`、主站连一次看 `conn_up` +1 —— **三件均已于 2026-11-06 Issue #53 台架轮实机复核通过**(boot 187→193 六连号无跳变、SRAM 保持+回写正常,真 IWDG 溢出经 SWD 缩窗触发,conn_up 静默窗精确 +1;「完整上电」用系统复位代理,本机无市电开关,POR 计数差额留人工一眼补验);「拔电池后落 RESTARTED」经用户裁定(2026-11-05)**台架不可验、销项不挂账**(电池域掉电需物理拔 RTC 电池,seq_state 四态判定由主机单测覆盖) |
| **TPAFE5160 ADC** | 无 | SPI ADC + BUSY EXTI 中断 | 中断驱动采集链路 | 待功能实现(上游 ADC 采集链路) |
| **RS-485 半双工** | 无 | UART4 + DE 方向控制,DWT 微秒延时 | DE 收发切换时序(特有陷阱) | 待功能实现(上游 RS-485 采集链路) |
| **启动段硬件初始化** | 只跑纯软件部分 | I2C/SPI 外设初始化、BBT 扫描耗时、FatFS 挂载 | 启动段死机(无看门狗保护窗口)**只能在真机复现** | 真机开机日志判读(`项目启动顺序管理.md` §6 已落地) |
@@ -39,7 +39,7 @@ MCU 侧真实处理只占 6.7ms,任务拾取/调度约 2.3ms(2026-09-22 重
|---|---|---|
| 远端显示 RemoDispBus | 7003 | `ui_net_sink`(真实 uiTask 生产路径) |
| FTP(lftpd) | 21 | 控制 + PASV 数据通道(数据通道复用监听 Socket,CH395F 单连接模型) |
| 对时 | 8888 | `time_sync` |
| 对时(本文实测时在场;2026-11-04 随 #78 退役,对时改 SNTP 出向) | 8888 | `time_sync`(历史) |
| 时延测试链路(M2) | 8080 | Phase 13 测试协议(服务器驱动) |
客户端 = DTU-RemtoeLCD(`remo_disp_server.py`,与本工程同级的独立项目,目录名含历史拼写 `Remtoe`)。
@@ -1,93 +1,75 @@
# 时间同步单元测试说明(主机侧)
> **模块**:Time Sync(`App/sync/time_sync.c` + `App/sync/time_sync.h`)
> **测试类型**:**主机侧纯逻辑单元测试**——在 PC 上离线验证 TCP 时间同步协议
> 状态机(分片喂狗延时 / 监听建立与退避 / 时间包重组 / 任务主循环),零硬件、零烧录、
> 毫秒级、不占 MCU 的 RAM。
> **状态**:✅ 已落地(80 断言点,`/W4` 0 告警,已挂 pre-commit 钩子)
> **日期**:2026-10-10
> **模块**:Time Sync(`App/sync/time_sync.c` + `App/sync/time_sync.h`)——timeSyncTask 载体
> **测试类型**:**主机侧纯逻辑单元测试**——在 PC 上离线验证任务编排逻辑(分片喂狗延时 /
> 就绪屏障等待 / SNTP 节拍驱动 / 网络代次交接),零硬件、零烧录、毫秒级、不占 MCU 的 RAM。
> **状态**:✅ v2.0(:8888 退役后,33 断言点,已挂 pre-commit 钩子)
> **日期**:2026-11-04(v2.0;v1.0 2026-10-10 的 TCP :8888 协议状态机套随 #78 退役重写)
> **关联文档**:
> [`../../../AGENTS.md`](../../../AGENTS.md)(平台约束与看门狗铁律)、
> [`测试开发标准流程.md`](../流程与规范/测试开发标准流程.md)(测试分层与门禁总览)、
> [`看门狗单元测试说明.md`](看门狗单元测试说明.md)(喂狗位图判定状态机)、
> [`卷锁单元测试说明.md`](卷锁单元测试说明.md)(同批落地的姊妹篇)、
> [`../../子系统设计/看门狗设计说明.md`](../../子系统设计/看门狗设计说明.md)(`required_mask` / 抽样窗 / 长耗时白名单)、
> [`../../任务规划/README.md`](../../任务规划/README.md)(登记条目「探针窗口心跳缺口」)、
> 历史审计(netTask 头阻塞;属主文档已于 2026-10-15 删除,现状见 [`../../网络/Net层阻塞模型架构设计.md`](../../网络/Net层阻塞模型架构设计.md))
> [`../../子系统设计/系统墙钟时间维护说明.md`](../../子系统设计/系统墙钟时间维护说明.md)(§15 退役历史 / §16 SNTP 现行设计)、
> [`../../子系统设计/看门狗设计说明.md`](../../子系统设计/看门狗设计说明.md)(`required_mask` / 抽样窗 / 长耗时白名单)
---
## 1. 概述
### 1.1 为什么单独做主机侧单测
### 1.1 为什么退役后仍要单独做主机侧单测
本模块是**两件已知风险的当事方**,而两件风险的成因**全部是本模块的纯逻辑**:
:8888 监听、`TIME` 包重组状态机、监听退避重试随 2026-11-04 退役删除(旧套 80 断言点的
主体),但任务本身**不能删**——它是 timeSyncTask 的载体,SNTP 校时客户端
(`App/sync/time_sntp.c`,设计见墙钟说明 §16)挂在它的 200 ms 节拍下运行。留存的纯逻辑
仍然全是「误复位」当事方,且真机上只能"跑起来看复位不复位"间接观察:
1. **探针窗口心跳缺口(看门狗余量)**:登记簿条目记录"time_sync 监听重建期间心跳缺口 800ms~1s,
距 IWDG 最坏超时 1701ms 余量仅约 0.7s"。该缺口的每一段都由本模块产生——
`time_sync_delay_fed()` 的**分片喂狗节奏**、监听重试退避(500 / 2000ms)、
`accept` 轮询退避(200ms)、收尾延时(50ms),以及"就绪屏障等待态也要喂心跳"。
真机上只能靠"跑起来看复位不复位"间接观察;主机侧可**逐片断言**心跳次数与片长。
2. **头阻塞**:旧实现用单次 30s 阻塞 `net_recv` 等时间包,独占 `netTask`,
使其余任务的网络操作整体停摆。现改为"分片有界读 + 总预算",本单测钉死其**分片语义**
(单次等待片长恒 ≤ 50ms、总预算 30s 不因分片而改变)。
1. **心跳节奏**:`time_sync_delay_fed()` 的分片喂心跳(片长 ≤ 50 ms)与主循环每轮首行喂位;
就绪屏障等待(100 ms 分片)未就绪时每轮也要补心跳——这是 2026-10-02 台架根因的回归防线。
2. **SNTP 宿主的节拍契约**:每轮恰好调一次 `time_sntp_run(当前代次)`;网络代次变化必须
**原样、当轮**传给客户端(代次交接是 `time_sntp_run` 内部弃旧 Socket 重建的唯一触发)。
3. **网络未就绪绝不出网**:屏障通过之前不得读代次、不得驱动 SNTP。
次要理由:**时间包重组状态机**(累积到 8 字节才解析、TCP 分段送达、EOF / 真错误 /
本片超时三种返回码分支、tick 回绕)是纯逻辑,板端套件无法精确构造
"分段 + 预算耗尽 + tick 回绕"这类组合。
旧套钉死的「头阻塞回归防线」(单次等待片长恒 ≤ 50 ms、总预算不因分片改变)语义由
SNTP 模块自己的主机套 `test/host/sntp/` 与本文的延时分片用例共同接力。
### 1.2 被测对象与桩
测试单元**原样 `#include` 生产源文件**,平台依赖由 7 个桩头替身 + 1 个真实头组成:
测试单元**原样 `#include` 生产源文件**,平台依赖由 5 个桩头替身 + 3 个真实头组成:
```
test/host/time_sync/time_sync_test.c
├── #include "FreeRTOS.h" / "task.h" / "cmsis_os2.h" ← 桩
├── #include "net_socket.h" / "sys_clock.h" /
│ "sys_events.h" / "dbg_log.h" ← 桩
├── #include "net_socket.h" / "sys_events.h" ← 桩
├── #include "task_watchdog.h" ← 真实头(App/util/)
├── #include "time_sntp.h" ← 真实头(App/sync/,签名对表)
└── #include "time_sync.c" ← 生产源文件(App/sync/),原样纳入
```
| 头文件 | 来源 | 桩提供的能力 |
|---|---|---|
| `FreeRTOS.h` | 桩 | `TickType_t` = `uint32_t`;`configTICK_RATE_HZ` = 1000(故 `pdMS_TO_TICKS(ms) == ms`) |
| `task.h` | 桩 | `vTaskDelay`(记录每片时长)、`xTaskGetTickCount`(返回可控 tick) |
| `cmsis_os2.h` | 桩 | `osEventFlagsWait`(按脚本返回就绪 / 超时) |
| `task.h` | 桩 | `vTaskDelay`(记录每片时长);tick 时钟桩保留(生产侧现不再读 tick,留给未来用例) |
| `cmsis_os2.h` | 桩 | `osEventFlagsWait`(按脚本返回就绪 / 超时,可第 N 次 `longjmp` 跳出) |
| `sys_events.h` | 桩 | `sys_evtHandle` + `SYS_EVT_NET_READY` 等位定义 |
| `sys_clock.h` | 桩 | `sys_clock_set_unix`(记录 epoch 与调用次数) |
| `dbg_log.h` | 桩 | `DBG_ERROR` / `DBG_INFO` 计数(`g_tstest_err_count` / `g_tstest_info_count`) |
| `net_socket.h` | 桩 | `socket` / `bind` / `listen` / `accept` / `close` / `recv_to` / `get_generation` / `htons` **全部脚本化** |
| `net_socket.h` | 桩 | **只剩 `net_get_generation`**(脚本化代次序列)——故意裁剪:生产代码若再引入监听类 API 会在本套编译/链接期即失败(绊线),旧 :8888 形态不会无声复活 |
| `task_watchdog.h` | **真实**(`App/util/`) | 提供 `task_wd_id_t` / `TASK_WD_TIMESYNC`;`task_wd_beat` / `task_wd_bind` 由测试文件实现(记录心跳节奏与位号) |
| `time_sntp.h` | **真实**(`App/sync/`) | 契约头(仅 timeSyncTask 上下文、单次 ≤50 ms 收片、调用方负责片间喂心跳);`time_sntp_run` 由测试文件实现(记录每轮收到的代次 + 可第 N 次 `longjmp`) |
| `time_sync.h` | **真实**(`App/sync/`) | 只 `#include <stdint.h>`,无平台依赖 |
`include_dirs` 顺序为 **`stub` → `App/util` → `App/sync` → 本目录**:桩目录必须排在
前面,否则会被真实头抢先命中。
> ⚠ `dbg_log.h` 桩**不得**定义 `DBG_LINE_BUF_MAX` / `DBG_TAG`——生产源(`time_sync.c:28-29`)
> 已先定义它们,桩再定义会触发 C4005 宏重定义告警。
### 1.3 关键契约(生产代码侧)
### 1.3 关键约定:分片喂心跳与报文重组契约
**(一)心跳必须落在同一个 100ms 抽样窗内。**
看门狗抽样窗为 `WD_POLL_PERIOD_MS = 100ms`(`App/util/task_watchdog.c`)。若一次长等待
(如 2000ms 退避)期间不喂心跳,或心跳节奏恰好滑过两个连续抽样窗,该任务就会被判"卡死"。
故 `time_sync_delay_fed()` 把任意长等待切成 **≤ `TIME_SYNC_WAIT_SLICE_MS` = 50ms** 的短片,
**每片前**喂一次心跳——语义等价于一次长延时,仅把心跳节奏钉在窗内(第 8b 轮台架消抖)。
**(二)`net_recv_to()` 的四态返回。**
`time_sync_handle_conn()` 的重组循环依赖该契约:
| 返回 | 含义 | 本模块动作 |
|---|---|---|
| `> 0` | 收到 `n` 字节 | 累加;`>= 8` 即收齐并解析,否则继续等余下字节 |
| `0` | 对端关闭(EOF) | 退出循环,**不解析** |
| `-1` | 真错误 | 退出循环,**不解析** |
| `-2` | 本片预算等满、无数据 | 重算剩余预算,**下一片**继续 |
**(三)总预算不因分片而改变。**
单次 `net_recv_to` 的等待片长 ≤ 50ms,但**跨片累积**仍以 `t0 = xTaskGetTickCount()`
为基准、总预算 `TIME_SYNC_TOTAL_BUDGET_MS` = 30000ms。tick 回绕由无符号减法天然处理。
- **心跳必须落在同一个 100 ms 抽样窗内**:看门狗抽样窗 `WD_POLL_PERIOD_MS = 100 ms`
(`App/util/task_watchdog.c`)。`time_sync_delay_fed()` 把任意长等待切成
≤ `TIME_SYNC_WAIT_SLICE_MS` = **50 ms** 短片,每片前喂一次心跳。
- **主循环节拍**:`task_wd_beat` → `time_sntp_run(net_get_generation())` →
`time_sync_delay_fed(TIME_SYNC_TICK_MS=200)`。SNTP 单次调用最多停留一片 50 ms
(`SNTP_RECV_SLICE_MS`,契约见 `time_sntp.h`),节拍间隙由载体任务喂位覆盖。
- **就绪屏障**:`osEventFlagsWait(sys_evtHandle, SYS_EVT_NET_READY,
osFlagsWaitAny | osFlagsNoClear, 100)`——就绪位**不得被消费**(`osFlagsNoClear`,
见 AGENTS「RTOS 与内存」);`sys_evtHandle == NULL`(模拟器)跳过屏障。
### 1.4 测试环境
@@ -114,67 +96,50 @@ test/host/time_sync/time_sync_test.c
| 项 | 说明 |
|---|---|
| **触发范围** | `App/sync/time_sync.c` / `time_sync.h`、`App/util/task_watchdog.h`,或 `test/host/time_sync/**`、`test/host/common/unit_test_harness.py` 变动 |
| **触发范围** | `App/sync/time_sync.c` / `time_sync.h` / `time_sntp.h`、`App/util/task_watchdog.h`,或 `test/host/time_sync/**`、`test/host/common/unit_test_harness.py` 变动 |
| **门禁层级** | **主机侧纯逻辑单测**(介于静态门禁与板端测试套件之间):主机侧、秒级、纯逻辑 |
| **pre-commit 钩子** | `time-sync-unit-test`(本地钩子,`.pre-commit-config.yaml` §7g) |
| **汇总行** | `=== Time Sync Tests: 80/80 PASSED (failed=0) ===` |
| **与板端测试的关系** | 互补:本单测保证**延时节奏与重组逻辑**符合设计;板端保证**真实 TCP 时序 + IWDG 不误复位**(该心跳缺口的实际余量只能由板端长跑判定) |
| **汇总行** | `=== Time Sync Tests: 33/33 PASSED (failed=0) ===` |
| **与板端测试的关系** | 互补:本单测保证**节拍编排与代次交接**符合设计;板端保证**真实 UDP/SNTP 时序 + IWDG 不误复位** |
---
## 2. 测试用例
> 命名 `TC-TS-NNN`(TS = Time Sync)。断言数(80)多于用例数(27),因为每个用例通常
> 包含 2~9 条子断言(后缀 `b` / `c` …)。桩状态在每用例前由 `fakes_reset()` 复位。
> **编号停发口径**:本文档不再使用 `TC-TIMESYNC-NNN`(新条目一律语义短语,
> [`../../编号规范.md`](../../编号规范.md) §0);旧编号族已随退役整批作废,不复用。
> 断言用**语义标签**命名。桩状态在每用例前由 `fakes_reset()` 复位。
### 2.1 `time_sync_delay_fed` — 分片喂心跳延时(TC-TIMESYNC-001..006)
### 2.1 `time_sync_delay_fed` — 分片喂心跳延时(`tc_delay_fed`)
| 用例 | 断言 |
| 场景 | 断言 |
|---|---|
| **TC-TIMESYNC-001** | `delay_fed(0)` 既不睡眠也不喂狗(零开销快路径) |
| **TC-TIMESYNC-002** | 恰好一片(50ms):1 次 `vTaskDelay(50)` + 1 次心跳 |
| **TC-TIMESYNC-003** | 非整片(120ms)切成 **50 / 50 / 20** 三片,每片喂一次心跳 |
| **TC-TIMESYNC-004** | 长延时(2000ms)= **40 片 × 50ms**,每片喂心跳(监听退避路径) |
| **TC-TIMESYNC-005** | 不足一片(49ms)单片处理,**不**被拆成 0 |
| **TC-TIMESYNC-006** | 总预算 30s = **600 片**,片长上限**恒** 50ms |
| 0 ms | 不睡眠不喂狗(零开销快路径) |
| 恰一片 50 ms | 1 次 `vTaskDelay(50)` + 1 次心跳 |
| 非整片 120 ms | 切成 **50 / 50 / 20** 三片,每片喂一次心跳 |
| 200 ms 节拍 | **4 片 × 50 ms**,每片喂心跳 |
| 不足一片 49 ms | 单片处理,**不**被拆成 0 |
| 30 s 长等待 | **600 片**,片长上限**恒** 50 ms |
### 2.2 `time_sync_open_listener` — 监听建立与退避(TC-TIMESYNC-010..015)
### 2.2 `time_sync_task` — 任务主循环(`tc_task`)
| 用例 | 断言 |
生产 `time_sync_task` 是 `for(;;)`,桩在脚本耗尽时 `longjmp` 跳出后断言副作用
(§4.1)。四个场景:
| 场景 | 断言 |
|---|---|
| **TC-TIMESYNC-010** | 首次成功:`socket` / `bind` / `listen` 各 1 次;端口经 `net_htons(8888)`;`sin_family` = `NET_AF_INET`;成功路径**无退避延时** |
| **TC-TIMESYNC-011** | `bind` 失败 → **关闭该 socket** + 退避 2000ms(40 片)+ 留痕 `DBG_ERROR`,随后重试成功 |
| **TC-TIMESYNC-012** | `listen` 失败 → 关闭该 socket + 退避 2000ms,随后重试成功 |
| **TC-TIMESYNC-013** | `socket` 连续失败 → **5 次后返回 -1**;5 条 `DBG_ERROR`;5 × 500ms 退避(50 片) |
| **TC-TIMESYNC-014** | 第 3 次重试成功并返回**新**描述符;恰好尝试 3 次;两次失败退避 500ms × 2 |
| **TC-TIMESYNC-015** | 心跳总次数 = 每轮重试(5)+ 每片延时(50);**心跳位恒为 `TASK_WD_TIMESYNC`** |
| **A · NULL 屏障 + 单轮**(`sys_evtHandle == NULL`,第 2 次读代次时跳出) | 跳过屏障直接进循环;代次读 2 次、`time_sntp_run` 1 次且收到代次 = 1;延时 4 片 × 50 ms;心跳 6 次(轮首 + 4 片 + 跳出前轮首);全部打 `TASK_WD_TIMESYNC` 位 |
| **B · 代次 1→2 当轮交接**(第 3 次读代次时跳出) | `time_sntp_run` 收到代次**逐轮 = 1、2**(代次变化当轮原样送达,客户端内部弃旧 Socket 自重建);延时 8 片;心跳 11 次 =(1+4)×2+1 |
| **C · 就绪屏障 2 次超时 + 1 次就绪**(跳出屏障后立即读代次失败跳出) | `osEventFlagsWait` 3 次、超时参 **100 ms**、选项 `osFlagsWaitAny \| osFlagsNoClear`(**就绪位不被消费**);未就绪两轮各补 1 次心跳 + 循环首行 1 次 = 3;`task_wd_bind` 已先登记心跳路由;SNTP 未跑(网络未就绪绝不出网) |
| **D · 屏障永不就绪**(第 4 次等待时跳出) | 等待 4 次全超时、循环未挂死(2026-10-02 台架根因回归防线);每次超时后各喂 1 次心跳 + 首行 = 3;**代次 0 读、SNTP 0 跑** |
### 2.3 `time_sync_handle_conn` — 时间包重组状态机(TC-TIMESYNC-020..029)
### 2.3 SNTP 驻留不拖垮心跳(`tc_sntp_dwell_then_continue`)
| 用例 | 断言 |
|---|---|
| **TC-TIMESYNC-020** | 8 字节一次收齐 → **大端**解析 epoch + 更新墙钟 1 次 + 关连接;首次请求 16 字节;单次等待片长 = 50ms;留痕 `wall clock updated` |
| **TC-TIMESYNC-021** | 分段送达(4+4)→ 累积后解析正确;读了两次;第二次**只请求剩余 12 字节**;每片 50ms |
| **TC-TIMESYNC-022** | 一次到达 16 字节 → **只取前 8 字节**;一次读够即停 |
| **TC-TIMESYNC-023** | 前缀非 `"TIME"` → **不更新墙钟**,但仍关闭连接 |
| **TC-TIMESYNC-024** | 对端关闭(`n == 0`)→ 立即退出、不解析;关闭连接 |
| **TC-TIMESYNC-025** | 真错误(`n == -1`)→ 立即退出、不解析 |
| **TC-TIMESYNC-026** | 只收到 4 字节后 EOF → **不足 8 字节不解析**;期间继续等待后续字节 |
| **TC-TIMESYNC-027** | 30s 预算耗尽 → 不再读(只读 1 次)+ 留痕 `no TIME packet in 30s, drop conn` + 关连接 |
| **TC-TIMESYNC-028** | 剩余预算不足一片 → **末片按剩余(20ms)切分** |
| **TC-TIMESYNC-029** | **32 位 tick 回绕** → 预算计算仍正确(无符号减法) |
`time_sntp_run` 第 2 次调用时跳出:第 1 轮完整走完(首行心跳 + 4 延时片)后第 2 轮
再次进入客户端——**每轮节拍都回到 SNTP**,驻留(应答收片 ≤ 50 ms)之后循环照常续转,
心跳位恒为 `TASK_WD_TIMESYNC`。
### 2.4 `time_sync_task` — 任务主循环(TC-TIMESYNC-040..044)
| 用例 | 断言 |
|---|---|
| **TC-TIMESYNC-040** | `sys_evtHandle == NULL` → **跳过就绪屏障**;`accept` 轮询 3 次(2 次无连接 + 1 次成功);收到时间包并更新墙钟;延时片数 = 4+4+1(200+200+50ms)且**全部按 50ms 分片**;心跳次数 = 主循环 1 + 退避 8 + 收连接 1 + 收尾 1 + 次轮 1 = **13**;所有心跳均打 `TASK_WD_TIMESYNC` 位 |
| **TC-TIMESYNC-041** | 就绪屏障轮询 3 次(2 次未就绪 + 1 次就绪);屏障等待按 **100ms 分片**;等待 `SYS_EVT_NET_READY` 位;`osFlagsWaitAny \| osFlagsNoClear`(**就绪位不被消费**);未就绪的两次各喂一次心跳;仍先 `task_wd_bind` 登记心跳路由 |
| **TC-TIMESYNC-042** | 屏障等待 4 次均未就绪 → **循环未挂死**(跳出并继续);每次未就绪后各喂一次心跳(2026-10-02 台架根因的**回归防线**) |
| **TC-TIMESYNC-043** | 网络代次变化 → **关闭旧监听**并重监听;留痕 `network re-init, relisten`(另含 2 条 listen 成功);每次循环只轮询一次 `accept` 即放弃 |
| **TC-TIMESYNC-044** | 监听建立失败 → 内部重试 5 次后放弃;6 条 `DBG_ERROR`(5 条 `net_socket FAIL` + 1 条 `retry later`);退避 5×500ms + 2000ms = **90 片**;心跳次数 = 2 + 5 + 50 + 40 = **97**;所有心跳均打 `TIMESYNC` 位 |
**当前结果**:80/80 PASSED(`failed=0`)。
**当前结果**:33/33 PASSED(`failed=0`)。
---
@@ -182,11 +147,11 @@ test/host/time_sync/time_sync_test.c
1. **纯延时类**:直接调 `time_sync_delay_fed(ms)`,断言 `s_delay_calls`(片数)与
`s_delays[]`(每片时长)以及 `s_beat_calls`(心跳数)。
2. **脚本化网络**:给 `s_gen_seq[]` / `s_evt_seq[]` / `recv_step_t` 数组填序列,
再驱动被测函数。
3. **跳出任务循环**:生产 `time_sync_task` 是 `for(;;)`,无法自然返回。桩在脚本耗尽时
调 **`longjmp(s_jmp, N)`** 强行跳出(见 §4.1),跳出后正常断言。
4. `CHECK(cond, "描述")` 断言;在 `main()` 里注册(并同步更新本文档 §2)。
2. **脚本化节拍**:给 `s_gen_seq[]` / `s_evt_seq[]` 数组填序列,再驱动任务循环。
3. **跳出任务循环**:桩在脚本化调用计数达到预设值时调 **`longjmp(s_jmp, N)`** 强行跳出
(见 §4.1),跳出后正常断言;SNTP 侧用 `s_sntp_run_longjmp_at`,代次侧用
`s_gen_longjmp_at`,屏障侧用 `s_evt_longjmp_at`。
4. `CHECK(cond, "语义标签")` 断言;在 `main()` 里注册(并同步更新本文档 §2)。
---
@@ -196,36 +161,30 @@ test/host/time_sync/time_sync_test.c
`time_sync_task` 是永不返回的任务循环。本单测在 `main()` 里 `setjmp` 设跳转点,
桩在"脚本化调用计数达到预设值"时 `longjmp` 回来,然后断言循环期间产生的副作用
(心跳次数 / 延时片数 / `accept` 次数 / 墙钟更新)。
(心跳次数 / 延时片数 / SNTP 轮次与代次)。
**取舍**:这比"把循环体抽成可测函数"更贴近真实——**测的就是任务主体本身**,
不需要为了可测性改动生产代码结构。代价是**必须精确设定跳出点**:跳出点设错
(多一次或少一次桩调用)会导致断言数不符,`TC-TIMESYNC-040` 的跳出点曾因此修正。
(多一次或少一次桩调用)会导致断言数不符。
### 4.2 ⚠ C 的"暂定定义"会静默合并同名静态量
本文件曾出现一个**无任何编译告警**的缺陷:文件作用域下两处 `static int s_bind_calls;`
历史教训(2026-10-10,v1.0 套):文件作用域下两处 `static int s_bind_calls;`
(一处给 `task_wd_bind` 桩、一处给 `net_bind` 桩)被 C 的**暂定定义(tentative
definition)规则静默合并为同一个对象**——于是 `task_wd_bind` 与 `net_bind` 共用一个计数器,
8 条断言失败(72/80)。
definition)规则静默合并为同一个对象**,8 条断言失败且**无任何编译告警**。
**教训**:同一编译单元内**所有** `static` 变量名必须唯一,哪怕是不同桩的"各自的"计数器。
修复手法是把看门狗侧改名为 `s_wd_bind_calls` / `s_wd_bind_id_bad`,并加注释说明。
扩展用例时**务必**先 `grep` 目标名字是否已被占用。
**教训**:同一编译单元内**所有** `static` 变量名必须唯一。扩展用例时**务必**先
`grep` 目标名字是否已被占用。
### 4.3 桩不模拟真实 TCP 时序
### 4.3 桩不模拟真实 UDP/SNTP 时序
`net_recv_to` / `net_accept` 桩按脚本返回,**不**模拟真实的分段到达时刻、重传、窗口、
CH395F 缓冲区边界。因此本单测能保证的是"**给定返回码序列,状态机反应正确**",
**不能**保证真实链路上的时序行为——后者属板端与 PC 对端(`test/host/time_sync_server.py`)职责。
`net_recvfrom_to` 等由 `test/host/sntp/` 套覆盖报文级行为;本套的 `time_sntp_run` 桩
只记录"被调了几次、收到什么代次"。因此本套能保证的是"**给定节拍与脚本,任务编排正确**",
**不能**保证真实链路的 SNTP 时序——后者属 `test/host/sntp/` 与板端职责
(真机台架对时判据已登记,见墙钟说明 §16 与 #73)。
### 4.4 探针窗口心跳缺口的实际余量仍由板端判定
### 4.4 心跳缺口的实际余量仍由板端判定
本单测把"每片喂心跳、片长 ≤ 50ms、退避值正确"这些**逻辑前提**钉死,但该缺口关注的
是**端到端心跳缺口 vs IWDG 超时**——这还取决于真实调度延迟、`netTask` 排队时长、
Flash 写耗时等主机侧无法建模的因素。故:
- 本单测 ✅ 保证"逻辑上不会出现超过 50ms 的**无喂狗**窗口";
- 板端 ✅ 保证"实测缺口 + 调度抖动仍小于 1701ms"。
两者都过,这个心跳缺口才能闭环。
本单测把"每片喂心跳、片长 ≤ 50 ms、屏障每轮补心跳"这些**逻辑前提**钉死,但端到端
心跳缺口 vs IWDG 最坏超时(1701 ms)还取决于真实调度延迟与 `netTask` 排队时长,
主机侧无法建模——板端 V5 长跑继续兜底(`../板级测试/实机测试实施指南.md` §7)。
@@ -162,8 +162,13 @@ test/host/cfg_file/cfg_file_test.c
| **TC-CONFIG-054** | poll 检出超长 → 工厂默认 + 重建模板 + 留痕;**不触发回调** | 在线修复通道保留 |
| **TC-CONFIG-056** | `[comm]` 段容量钉:段数上限 8、键数上限 16 写进断言(改上限必须同批改本行与用例) | 段/键上限是配置引擎的公开契约,不能靠"跑起来看看" |
| **TC-CONFIG-057** | 段/键写满后再新增 → 拒绝保存且原文件不动(满则拒,不是静默截断) | 溢出语义与 TC-CONFIG-043 同源,覆盖 `[comm]` 新增段 |
| **TC-CONFIG-058** | 卷层旧视图(读长 ≠ stat 长)→ poll 拒绝应用:RAM 保旧值、基线保留重试、视图追平即自愈应用 + 回调;拒绝期间零回调、全程 1 ERROR + 1 留痕 | 2026-11-05 视图一致性守卫(issue #73 热重载打回出厂默认根治) |
| **TC-CONFIG-059** | save 侧同族守卫:视图 ≠ stat → 拒存 -1、原文件一字节不动 + 自检留痕;视图追平后可再存 | 斩断"短视图 → 外科重写 → 非默认段被吞"链(实测 1066B→986B 形态) |
| **TC-CONFIG-060** | 读中改写(读后复 stat 令牌变)→ HELD 后重新沉降自愈;持续不一致:全程仅 1 ERROR + 1 留痕,WARN 每 30 趟一条 | 拒绝分支日志限速(防 2s 节拍日志风暴) |
| **TC-CONFIG-061** | 同尺寸全 0 旧映射块(长度/令牌双检全过)→ 内容判据 `s_view_bad` 拦下:HELD RAM 保旧值、零回调、1 ERROR + 1 留痕;视图刷新后自愈应用 + 回调 | 台架 15:21 实证形态:纯三点校验拦不住"恰好同长"的 dhara 旧映射块 |
| **TC-CONFIG-062** | 保存链遇同尺寸全 0 旧视图 → 拒存 -1,文件字节/写次数一字节不动 + 留痕;视图恢复后同一保存重试成功落盘 | 坏视图外科重写同样被拒(与 059 短视图互补:同长但内容坏) |
**当前结果**:139/139 PASSED(`failed=0`)。
**当前结果**:259/259 PASSED(`failed=0`)。
---
@@ -175,6 +180,9 @@ test/host/cfg_file/cfg_file_test.c
需"内容变但令牌不变"的边界用 `vfs_put_notoken(text)`;
4. 用 `vfs_get()` 取当前文件文本做检索断言(注释/未知段是否保留等);
5. 用故障注入开关 `s_fail_read / s_fail_write / s_fail_alloc / s_fail_stat` 构造故障路径;
视图不一致用 `vfs_mark_stale()`(read 冻结在旧快照、stat 报真实盘)/
`vfs_mark_stale_zeros()`(read 返回与真实盘同长的全 0 块 = 台架 dhara
旧映射块形态)/ `vfs_clear_stale()`(视图追平 = 自愈),读中改写用一次性开关 `s_touch_on_read`;
6. `CHECK(cond, "描述")` 断言;在 `main()` 里注册。
> ⚠ **`vfs_put` 与 `vfs_put_notoken` 的区别很关键**:poll 依 `(size, mtime)` 判变更,
@@ -243,7 +243,9 @@ $cli = if ($env:DTU_STLINK_CLI) { $env:DTU_STLINK_CLI } else { (Get-Command ST-L
- **30s 周期重试**,不自驻留死循环;
- 恢复后各 TCP 服务(FTP 21 等)**据代次号重建监听**,功能正常。
**验证手段**:`test/host/e02_probe.py`(网络探针)+ UI 网口设置页改 IP。
**验证手段**:FTP 客户端连 :21 + UI 网口设置页改 IP(观察代次号重建监听)。原网络探针
`e02_probe.py` **已删除**(2026-11-04 随 :8888 退役,正文见 git 历史)——它当时挂的是 :8888
time_sync 触发形态,退役后该触发场景不再存在。
**2026-10-03 台架结论**:
- **正常路径 ✅**:V5 长跑(30 min,FTP 512 KB 上/下传)**120/120 PASS、零 IWDG 复位**,
@@ -276,7 +276,7 @@ static void phaseN_run(void) {
| **`test/host/nand_port/run_unit_test.py`** | `test/host/nand_port/` | **主机侧纯逻辑单测**:离线编译真实 `Drivers/BSP/GD5F2GQ5UE/nand_ftl.c` + 真实 dhara,以 **RAM 假芯片**驱动,149 断言钉死 is_free 整页扫描与六个入口的越界守卫 |
| **`scripts/ci_local.py`** | `scripts/` | **本地跑与 CI 等价的门禁**(静态门禁 + 主机侧纯逻辑单测):自动选用装了 pre-commit 的解释器;`.map` 自适应跳过 `mem-numbers`;退出码 0/1/2 与 CI 对齐。见 §9.3 |
| `.serialtest/config.json` | 仓库 | **串口端口单一配置源**(当前 COM6 / 115200);换端口只改这个文件 |
| `test/host/ftp_*.py`(4 个)/ `ch395f_socket_test.py` / `time_sync_server.py` | `test/host/` | PC 端交互测试工具(FTP 客户端 / socket 回显 / 对时推送) |
| `test/host/ftp_*.py`(4 个)/ `ch395f_socket_test.py` | `test/host/` | PC 端交互测试工具(FTP 客户端 / socket 回显;原对时推送 `time_sync_server.py` 已随 :8888 退役删除,2026-11-04) |
| `simulator/tests/*.py`(4 个) | `simulator/tests/` | LVGL 模拟器回归脚本(见 §5) |
### 4.2 主机侧纯逻辑单测(纯逻辑,无硬件)
@@ -609,7 +609,6 @@ CI 就静默停摆(2026-10-11 实测 run 16~21 共 12 个 job 零日志)。
| `run_boot_test.py` / `verify_log.py` + `serial_tool` | 自动化闭环三件套(纯 Python 标准库 / 仓库内置) |
| `ftp_test.py` / `ftp_capture.py` / `ftp_up_dl_test.py` / `ftp_speed_test.py` | FTP PC 端测试工具 |
| `ch395f_socket_test.py` | CH395F PC 端 socket 回显 / 大文件传输工具 |
| `time_sync_server.py` | 对时推送 PC 端服务器 |
## 附录 B:模块测试文档
@@ -0,0 +1,866 @@
# 2026-11-04 交流补测轮串口日志摘录(源:serial-assistant serial.log,gen=328,daemon 打戳 +08:00)
# 板固件: fw build: Nov 4 2026 19:05:57 suite=NONE dstr=off(HEAD 87fa0276 构建,烧录回读一致)
# 完整原始日志本机备份: ci-artifacts/ac-20261104/serial_full_backup.log(本机产物,daemon 20MB 截头保险)
# 取证注意: 19:56:47 三条 [ERR][LFT_IO]/[FTP] 是 PC 侧 FTP 探测不存在文件 V5_UP.BIN 所致(操作自归因),非固件缺陷
# 通道静态位观察: 未接线的 TPAFE 输入浮空读数 ≈1743/1747 mV(撤线后 UA/IA 出现,非损伤、非零点漂移)
# # 削顶轮步2(UB 注 DC −1.00 V)锁存窗:19:31:42 唯一 [ERR] rail 行 + rail/edge 0x002 恒持 + 19:36:41 锁存态取段 WAVE11
[RX] 2026-11-04T19:30:06.563+08:00 [2026-11-04 19:30:05][ADC_TASK] frames=1259751 idle=0 skip=126 seq=1260006 frst_err=0 ring=1259625 adc1_rc=0 adc1_err=0 adc1_seq=1260005 adc1_gap=379 adc1_hw=0 tgap=276
[RX] 2026-11-04T19:30:06.584+08:00 [2026-11-04 19:30:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=1 (x0.1)
[RX] 2026-11-04T19:30:06.584+08:00 [2026-11-04 19:30:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:06.594+08:00 [2026-11-04 19:30:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:06.605+08:00 [2026-11-04 19:30:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=-1 rms=1 (x0.1)
[RX] 2026-11-04T19:30:06.605+08:00 [2026-11-04 19:30:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:06.615+08:00 [2026-11-04 19:30:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:30:06.615+08:00 [2026-11-04 19:30:05][ADC_TASK] adc: UA=11429 UB=989 UC=1006 UN=-68 IA=-1469 IB=972 IC=1066 IN=1038 T=964
[RX] 2026-11-04T19:30:06.626+08:00 [2026-11-04 19:30:05][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=-224 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:30:06.637+08:00 [2026-11-04 19:30:05][ADC_TASK] meas: seq=6300 v=1 ua_mv=0 un_mv=0 ia_mv=109 f=0 fv=0
[RX] 2026-11-04T19:30:06.647+08:00 [2026-11-04 19:30:05][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:30:16.562+08:00 [2026-11-04 19:30:15][ADC_TASK] frames=1269749 idle=0 skip=127 seq=1270006 frst_err=0 ring=1269622 adc1_rc=0 adc1_err=0 adc1_seq=1270005 adc1_gap=382 adc1_hw=0 tgap=278
[RX] 2026-11-04T19:30:16.583+08:00 [2026-11-04 19:30:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:16.583+08:00 [2026-11-04 19:30:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:16.594+08:00 [2026-11-04 19:30:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:16.604+08:00 [2026-11-04 19:30:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:16.604+08:00 [2026-11-04 19:30:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:16.615+08:00 [2026-11-04 19:30:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:30:16.615+08:00 [2026-11-04 19:30:15][ADC_TASK] adc: UA=11428 UB=1001 UC=991 UN=-41 IA=-41 IB=973 IC=1062 IN=1028 T=954
[RX] 2026-11-04T19:30:16.626+08:00 [2026-11-04 19:30:15][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:30:16.636+08:00 [2026-11-04 19:30:15][ADC_TASK] meas: seq=6350 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:30:16.647+08:00 [2026-11-04 19:30:15][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:30:26.570+08:00 [2026-11-04 19:30:25][ADC_TASK] frames=1279747 idle=0 skip=128 seq=1280006 frst_err=0 ring=1279619 adc1_rc=0 adc1_err=0 adc1_seq=1280005 adc1_gap=385 adc1_hw=0 tgap=280
[RX] 2026-11-04T19:30:26.581+08:00 [2026-11-04 19:30:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:26.581+08:00 [2026-11-04 19:30:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:26.591+08:00 [2026-11-04 19:30:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:26.602+08:00 [2026-11-04 19:30:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:26.612+08:00 [2026-11-04 19:30:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:26.612+08:00 [2026-11-04 19:30:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:30:26.622+08:00 [2026-11-04 19:30:25][ADC_TASK] adc: UA=11429 UB=1019 UC=997 UN=-43 IA=-41 IB=975 IC=1079 IN=1045 T=954
[RX] 2026-11-04T19:30:26.622+08:00 [2026-11-04 19:30:25][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:30:26.643+08:00 [2026-11-04 19:30:25][ADC_TASK] meas: seq=6400 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:30:26.643+08:00 [2026-11-04 19:30:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:30:36.564+08:00 [2026-11-04 19:30:35][ADC_TASK] frames=1289745 idle=0 skip=129 seq=1290006 frst_err=0 ring=1289616 adc1_rc=0 adc1_err=0 adc1_seq=1290005 adc1_gap=388 adc1_hw=0 tgap=282
[RX] 2026-11-04T19:30:36.574+08:00 [2026-11-04 19:30:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:36.585+08:00 [2026-11-04 19:30:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:36.595+08:00 [2026-11-04 19:30:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:36.595+08:00 [2026-11-04 19:30:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:36.606+08:00 [2026-11-04 19:30:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:36.616+08:00 [2026-11-04 19:30:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:30:36.616+08:00 [2026-11-04 19:30:35][ADC_TASK] adc: UA=11429 UB=1037 UC=1018 UN=-41 IA=-40 IB=983 IC=1082 IN=1057 T=966
[RX] 2026-11-04T19:30:36.627+08:00 [2026-11-04 19:30:35][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:30:36.637+08:00 [2026-11-04 19:30:35][ADC_TASK] meas: seq=6450 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:30:36.648+08:00 [2026-11-04 19:30:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:30:46.570+08:00 [2026-11-04 19:30:45][ADC_TASK] frames=1299743 idle=0 skip=130 seq=1300006 frst_err=0 ring=1299613 adc1_rc=0 adc1_err=0 adc1_seq=1300005 adc1_gap=391 adc1_hw=0 tgap=284
[RX] 2026-11-04T19:30:46.580+08:00 [2026-11-04 19:30:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:46.580+08:00 [2026-11-04 19:30:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:46.591+08:00 [2026-11-04 19:30:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:46.601+08:00 [2026-11-04 19:30:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:46.612+08:00 [2026-11-04 19:30:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:46.612+08:00 [2026-11-04 19:30:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:30:46.622+08:00 [2026-11-04 19:30:45][ADC_TASK] adc: UA=11428 UB=1029 UC=1003 UN=-43 IA=-41 IB=978 IC=1054 IN=1032 T=963
[RX] 2026-11-04T19:30:46.622+08:00 [2026-11-04 19:30:45][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:30:46.643+08:00 [2026-11-04 19:30:45][ADC_TASK] meas: seq=6500 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:30:46.643+08:00 [2026-11-04 19:30:45][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:30:56.566+08:00 [2026-11-04 19:30:55][ADC_TASK] frames=1309741 idle=0 skip=131 seq=1310006 frst_err=0 ring=1309610 adc1_rc=0 adc1_err=0 adc1_seq=1310005 adc1_gap=394 adc1_hw=0 tgap=286
[RX] 2026-11-04T19:30:56.576+08:00 [2026-11-04 19:30:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:56.586+08:00 [2026-11-04 19:30:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:56.596+08:00 [2026-11-04 19:30:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:56.596+08:00 [2026-11-04 19:30:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:56.607+08:00 [2026-11-04 19:30:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:56.618+08:00 [2026-11-04 19:30:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:30:56.618+08:00 [2026-11-04 19:30:55][ADC_TASK] adc: UA=11429 UB=1043 UC=1020 UN=-43 IA=-42 IB=993 IC=1053 IN=1026 T=971
[RX] 2026-11-04T19:30:56.628+08:00 [2026-11-04 19:30:55][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:30:56.639+08:00 [2026-11-04 19:30:55][ADC_TASK] meas: seq=6550 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:30:56.639+08:00 [2026-11-04 19:30:55][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:31:06.562+08:00 [2026-11-04 19:31:05][ADC_TASK] frames=1319739 idle=0 skip=132 seq=1320006 frst_err=0 ring=1319607 adc1_rc=0 adc1_err=0 adc1_seq=1320005 adc1_gap=397 adc1_hw=0 tgap=288
[RX] 2026-11-04T19:31:06.583+08:00 [2026-11-04 19:31:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:06.583+08:00 [2026-11-04 19:31:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:06.593+08:00 [2026-11-04 19:31:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:06.603+08:00 [2026-11-04 19:31:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:06.603+08:00 [2026-11-04 19:31:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:06.614+08:00 [2026-11-04 19:31:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:31:06.614+08:00 [2026-11-04 19:31:05][ADC_TASK] adc: UA=11429 UB=1043 UC=1042 UN=-41 IA=-40 IB=986 IC=1046 IN=1010 T=954
[RX] 2026-11-04T19:31:06.624+08:00 [2026-11-04 19:31:05][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:31:06.635+08:00 [2026-11-04 19:31:05][ADC_TASK] meas: seq=6600 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:31:06.645+08:00 [2026-11-04 19:31:05][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:31:16.561+08:00 [2026-11-04 19:31:15][ADC_TASK] frames=1329737 idle=0 skip=133 seq=1330006 frst_err=0 ring=1329604 adc1_rc=0 adc1_err=0 adc1_seq=1330005 adc1_gap=400 adc1_hw=0 tgap=290
[RX] 2026-11-04T19:31:16.582+08:00 [2026-11-04 19:31:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:16.582+08:00 [2026-11-04 19:31:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:16.593+08:00 [2026-11-04 19:31:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:16.603+08:00 [2026-11-04 19:31:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:16.603+08:00 [2026-11-04 19:31:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:16.613+08:00 [2026-11-04 19:31:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:31:16.613+08:00 [2026-11-04 19:31:15][ADC_TASK] adc: UA=11429 UB=1038 UC=1042 UN=-41 IA=-40 IB=962 IC=1047 IN=1003 T=935
[RX] 2026-11-04T19:31:16.624+08:00 [2026-11-04 19:31:15][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:31:16.634+08:00 [2026-11-04 19:31:15][ADC_TASK] meas: seq=6650 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:31:16.644+08:00 [2026-11-04 19:31:15][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:31:26.566+08:00 [2026-11-04 19:31:25][ADC_TASK] frames=1339735 idle=0 skip=134 seq=1340006 frst_err=0 ring=1339601 adc1_rc=0 adc1_err=0 adc1_seq=1340005 adc1_gap=403 adc1_hw=0 tgap=292
[RX] 2026-11-04T19:31:26.576+08:00 [2026-11-04 19:31:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:26.587+08:00 [2026-11-04 19:31:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:26.597+08:00 [2026-11-04 19:31:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:26.597+08:00 [2026-11-04 19:31:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:26.608+08:00 [2026-11-04 19:31:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:26.608+08:00 [2026-11-04 19:31:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:31:26.618+08:00 [2026-11-04 19:31:25][ADC_TASK] adc: UA=11428 UB=1024 UC=1049 UN=-42 IA=-41 IB=951 IC=1049 IN=1011 T=931
[RX] 2026-11-04T19:31:26.629+08:00 [2026-11-04 19:31:25][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:31:26.639+08:00 [2026-11-04 19:31:25][ADC_TASK] meas: seq=6700 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:31:26.639+08:00 [2026-11-04 19:31:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:31:36.566+08:00 [2026-11-04 19:31:35][ADC_TASK] frames=1349733 idle=0 skip=135 seq=1350006 frst_err=0 ring=1349598 adc1_rc=0 adc1_err=0 adc1_seq=1350005 adc1_gap=406 adc1_hw=0 tgap=294
[RX] 2026-11-04T19:31:36.577+08:00 [2026-11-04 19:31:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:36.587+08:00 [2026-11-04 19:31:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:36.587+08:00 [2026-11-04 19:31:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:36.598+08:00 [2026-11-04 19:31:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:36.608+08:00 [2026-11-04 19:31:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:36.608+08:00 [2026-11-04 19:31:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:31:36.618+08:00 [2026-11-04 19:31:35][ADC_TASK] adc: UA=11428 UB=1005 UC=1054 UN=-43 IA=-42 IB=947 IC=1074 IN=1024 T=934
[RX] 2026-11-04T19:31:36.629+08:00 [2026-11-04 19:31:35][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:31:36.639+08:00 [2026-11-04 19:31:35][ADC_TASK] meas: seq=6750 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:31:36.639+08:00 [2026-11-04 19:31:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:31:46.560+08:00 [2026-11-04 19:31:45][ADC_TASK] frames=1359731 idle=0 skip=136 seq=1360006 frst_err=0 ring=1359595 adc1_rc=0 adc1_err=0 adc1_seq=1360005 adc1_gap=409 adc1_hw=0 tgap=296
[RX] 2026-11-04T19:31:46.581+08:00 [2026-11-04 19:31:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:46.581+08:00 [2026-11-04 19:31:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:46.592+08:00 [2026-11-04 19:31:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:46.602+08:00 [2026-11-04 19:31:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:46.602+08:00 [2026-11-04 19:31:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:46.613+08:00 [2026-11-04 19:31:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:31:46.613+08:00 [2026-11-04 19:31:45][ADC_TASK] adc: UA=11428 UB=0 UC=1014 UN=-42 IA=11450 IB=939 IC=1050 IN=1030 T=924
[RX] 2026-11-04T19:31:46.623+08:00 [2026-11-04 19:31:45][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:31:46.634+08:00 [2026-11-04 19:31:45][ADC_TASK] meas: seq=6800 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:31:46.644+08:00 [2026-11-04 19:31:45][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:31:56.563+08:00 [2026-11-04 19:31:55][ADC_TASK] frames=1369729 idle=0 skip=137 seq=1370006 frst_err=0 ring=1369592 adc1_rc=0 adc1_err=0 adc1_seq=1370005 adc1_gap=412 adc1_hw=0 tgap=298
[RX] 2026-11-04T19:31:56.574+08:00 [2026-11-04 19:31:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:56.584+08:00 [2026-11-04 19:31:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:56.595+08:00 [2026-11-04 19:31:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:56.595+08:00 [2026-11-04 19:31:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:56.605+08:00 [2026-11-04 19:31:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:56.616+08:00 [2026-11-04 19:31:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:31:56.616+08:00 [2026-11-04 19:31:55][ADC_TASK] adc: UA=11429 UB=0 UC=1018 UN=-44 IA=11452 IB=943 IC=919 IN=991 T=934
[RX] 2026-11-04T19:31:56.626+08:00 [2026-11-04 19:31:55][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:31:56.637+08:00 [2026-11-04 19:31:55][ADC_TASK] meas: seq=6850 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:31:56.637+08:00 [2026-11-04 19:31:55][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:32:06.566+08:00 [2026-11-04 19:32:05][ADC_TASK] frames=1379727 idle=0 skip=138 seq=1380006 frst_err=0 ring=1379589 adc1_rc=0 adc1_err=0 adc1_seq=1380005 adc1_gap=415 adc1_hw=0 tgap=300
[RX] 2026-11-04T19:32:06.577+08:00 [2026-11-04 19:32:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:06.587+08:00 [2026-11-04 19:32:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:06.587+08:00 [2026-11-04 19:32:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:06.598+08:00 [2026-11-04 19:32:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:06.608+08:00 [2026-11-04 19:32:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:06.608+08:00 [2026-11-04 19:32:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:32:06.618+08:00 [2026-11-04 19:32:05][ADC_TASK] adc: UA=11428 UB=0 UC=996 UN=-43 IA=11452 IB=955 IC=836 IN=947 T=946
[RX] 2026-11-04T19:32:06.629+08:00 [2026-11-04 19:32:05][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:32:06.639+08:00 [2026-11-04 19:32:05][ADC_TASK] meas: seq=6900 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:32:06.639+08:00 [2026-11-04 19:32:05][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:32:16.560+08:00 [2026-11-04 19:32:15][ADC_TASK] frames=1389725 idle=0 skip=139 seq=1390006 frst_err=0 ring=1389586 adc1_rc=0 adc1_err=0 adc1_seq=1390005 adc1_gap=418 adc1_hw=0 tgap=302
[RX] 2026-11-04T19:32:16.581+08:00 [2026-11-04 19:32:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:16.581+08:00 [2026-11-04 19:32:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:16.591+08:00 [2026-11-04 19:32:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:16.591+08:00 [2026-11-04 19:32:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:16.601+08:00 [2026-11-04 19:32:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:16.612+08:00 [2026-11-04 19:32:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:32:16.612+08:00 [2026-11-04 19:32:15][ADC_TASK] adc: UA=11429 UB=0 UC=950 UN=-42 IA=11452 IB=966 IC=805 IN=898 T=945
[RX] 2026-11-04T19:32:16.622+08:00 [2026-11-04 19:32:15][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:32:16.633+08:00 [2026-11-04 19:32:15][ADC_TASK] meas: seq=6950 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:32:16.643+08:00 [2026-11-04 19:32:15][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:32:26.566+08:00 [2026-11-04 19:32:25][ADC_TASK] frames=1399723 idle=0 skip=140 seq=1400006 frst_err=0 ring=1399583 adc1_rc=0 adc1_err=0 adc1_seq=1400005 adc1_gap=421 adc1_hw=0 tgap=304
[RX] 2026-11-04T19:32:26.577+08:00 [2026-11-04 19:32:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:26.577+08:00 [2026-11-04 19:32:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:26.588+08:00 [2026-11-04 19:32:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:26.598+08:00 [2026-11-04 19:32:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:26.608+08:00 [2026-11-04 19:32:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:26.608+08:00 [2026-11-04 19:32:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:32:26.619+08:00 [2026-11-04 19:32:25][ADC_TASK] adc: UA=11428 UB=0 UC=966 UN=-61 IA=11452 IB=959 IC=794 IN=875 T=929
[RX] 2026-11-04T19:32:26.629+08:00 [2026-11-04 19:32:25][ADC_TASK] cal: ua_mv=1743 un_mv=-9 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:32:26.639+08:00 [2026-11-04 19:32:25][ADC_TASK] meas: seq=7000 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:32:26.639+08:00 [2026-11-04 19:32:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:32:36.567+08:00 [2026-11-04 19:32:35][ADC_TASK] frames=1409721 idle=0 skip=141 seq=1410006 frst_err=0 ring=1409580 adc1_rc=0 adc1_err=0 adc1_seq=1410005 adc1_gap=424 adc1_hw=0 tgap=306
[RX] 2026-11-04T19:32:36.577+08:00 [2026-11-04 19:32:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:36.577+08:00 [2026-11-04 19:32:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:36.587+08:00 [2026-11-04 19:32:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:36.598+08:00 [2026-11-04 19:32:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:36.609+08:00 [2026-11-04 19:32:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:36.609+08:00 [2026-11-04 19:32:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:32:36.619+08:00 [2026-11-04 19:32:35][ADC_TASK] adc: UA=11427 UB=0 UC=940 UN=-44 IA=11451 IB=932 IC=784 IN=849 T=906
[RX] 2026-11-04T19:32:36.619+08:00 [2026-11-04 19:32:35][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:32:36.640+08:00 [2026-11-04 19:32:35][ADC_TASK] meas: seq=7050 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:32:36.640+08:00 [2026-11-04 19:32:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:32:46.563+08:00 [2026-11-04 19:32:45][ADC_TASK] frames=1419719 idle=0 skip=142 seq=1420006 frst_err=0 ring=1419577 adc1_rc=0 adc1_err=0 adc1_seq=1420005 adc1_gap=427 adc1_hw=0 tgap=308
[RX] 2026-11-04T19:32:46.573+08:00 [2026-11-04 19:32:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:46.584+08:00 [2026-11-04 19:32:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:46.594+08:00 [2026-11-04 19:32:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:46.594+08:00 [2026-11-04 19:32:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:46.605+08:00 [2026-11-04 19:32:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:46.605+08:00 [2026-11-04 19:32:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:32:46.615+08:00 [2026-11-04 19:32:45][ADC_TASK] adc: UA=11427 UB=0 UC=912 UN=-42 IA=11451 IB=946 IC=772 IN=831 T=873
[RX] 2026-11-04T19:32:46.626+08:00 [2026-11-04 19:32:45][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:32:46.636+08:00 [2026-11-04 19:32:45][ADC_TASK] meas: seq=7100 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:32:46.636+08:00 [2026-11-04 19:32:45][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:32:56.567+08:00 [2026-11-04 19:32:55][ADC_TASK] frames=1429717 idle=0 skip=143 seq=1430006 frst_err=0 ring=1429574 adc1_rc=0 adc1_err=0 adc1_seq=1430005 adc1_gap=430 adc1_hw=0 tgap=310
[RX] 2026-11-04T19:32:56.577+08:00 [2026-11-04 19:32:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:56.577+08:00 [2026-11-04 19:32:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:56.588+08:00 [2026-11-04 19:32:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:56.598+08:00 [2026-11-04 19:32:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:56.609+08:00 [2026-11-04 19:32:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:32:56.609+08:00 [2026-11-04 19:32:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:32:56.619+08:00 [2026-11-04 19:32:55][ADC_TASK] adc: UA=11428 UB=0 UC=903 UN=-54 IA=11450 IB=948 IC=770 IN=826 T=895
[RX] 2026-11-04T19:32:56.619+08:00 [2026-11-04 19:32:55][ADC_TASK] cal: ua_mv=1743 un_mv=-8 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:32:56.630+08:00 [2026-11-04 19:32:55][ADC_TASK] meas: seq=7150 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:32:56.640+08:00 [2026-11-04 19:32:55][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:33:06.557+08:00 [2026-11-04 19:33:05][ADC_TASK] frames=1439715 idle=0 skip=144 seq=1440006 frst_err=0 ring=1439571 adc1_rc=0 adc1_err=0 adc1_seq=1440005 adc1_gap=433 adc1_hw=0 tgap=312
[RX] 2026-11-04T19:33:06.577+08:00 [2026-11-04 19:33:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:06.577+08:00 [2026-11-04 19:33:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:06.588+08:00 [2026-11-04 19:33:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:06.599+08:00 [2026-11-04 19:33:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:06.599+08:00 [2026-11-04 19:33:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:06.609+08:00 [2026-11-04 19:33:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:33:06.620+08:00 [2026-11-04 19:33:05][ADC_TASK] adc: UA=11427 UB=0 UC=900 UN=-54 IA=11451 IB=923 IC=772 IN=827 T=903
[RX] 2026-11-04T19:33:06.620+08:00 [2026-11-04 19:33:05][ADC_TASK] cal: ua_mv=1743 un_mv=-8 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:33:06.630+08:00 [2026-11-04 19:33:05][ADC_TASK] meas: seq=7200 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:33:06.641+08:00 [2026-11-04 19:33:05][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:33:16.557+08:00 [2026-11-04 19:33:15][ADC_TASK] frames=1449713 idle=0 skip=145 seq=1450006 frst_err=0 ring=1449568 adc1_rc=0 adc1_err=0 adc1_seq=1450005 adc1_gap=436 adc1_hw=0 tgap=314
[RX] 2026-11-04T19:33:16.577+08:00 [2026-11-04 19:33:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:16.577+08:00 [2026-11-04 19:33:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:16.587+08:00 [2026-11-04 19:33:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:16.598+08:00 [2026-11-04 19:33:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:16.608+08:00 [2026-11-04 19:33:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:16.608+08:00 [2026-11-04 19:33:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:33:16.619+08:00 [2026-11-04 19:33:15][ADC_TASK] adc: UA=11427 UB=0 UC=895 UN=-53 IA=11451 IB=914 IC=773 IN=827 T=907
[RX] 2026-11-04T19:33:16.619+08:00 [2026-11-04 19:33:15][ADC_TASK] cal: ua_mv=1743 un_mv=-8 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:33:16.629+08:00 [2026-11-04 19:33:15][ADC_TASK] meas: seq=7250 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:33:16.640+08:00 [2026-11-04 19:33:15][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:33:26.563+08:00 [2026-11-04 19:33:25][ADC_TASK] frames=1459711 idle=0 skip=146 seq=1460006 frst_err=0 ring=1459565 adc1_rc=0 adc1_err=0 adc1_seq=1460005 adc1_gap=439 adc1_hw=0 tgap=316
[RX] 2026-11-04T19:33:26.574+08:00 [2026-11-04 19:33:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:26.584+08:00 [2026-11-04 19:33:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:26.584+08:00 [2026-11-04 19:33:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:26.595+08:00 [2026-11-04 19:33:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:26.605+08:00 [2026-11-04 19:33:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:26.605+08:00 [2026-11-04 19:33:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:33:26.615+08:00 [2026-11-04 19:33:25][ADC_TASK] adc: UA=11429 UB=0 UC=895 UN=-49 IA=11451 IB=915 IC=775 IN=828 T=900
[RX] 2026-11-04T19:33:26.626+08:00 [2026-11-04 19:33:25][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:33:26.636+08:00 [2026-11-04 19:33:25][ADC_TASK] meas: seq=7300 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:33:26.636+08:00 [2026-11-04 19:33:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:33:36.558+08:00 [2026-11-04 19:33:35][ADC_TASK] frames=1469709 idle=0 skip=147 seq=1470006 frst_err=0 ring=1469562 adc1_rc=0 adc1_err=0 adc1_seq=1470005 adc1_gap=442 adc1_hw=0 tgap=318
[RX] 2026-11-04T19:33:36.579+08:00 [2026-11-04 19:33:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:36.579+08:00 [2026-11-04 19:33:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:36.589+08:00 [2026-11-04 19:33:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:36.599+08:00 [2026-11-04 19:33:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:36.599+08:00 [2026-11-04 19:33:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:36.610+08:00 [2026-11-04 19:33:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:33:36.610+08:00 [2026-11-04 19:33:35][ADC_TASK] adc: UA=11428 UB=0 UC=901 UN=-50 IA=11451 IB=952 IC=780 IN=833 T=881
[RX] 2026-11-04T19:33:36.621+08:00 [2026-11-04 19:33:35][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:33:36.631+08:00 [2026-11-04 19:33:35][ADC_TASK] meas: seq=7350 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:33:36.642+08:00 [2026-11-04 19:33:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:33:46.566+08:00 [2026-11-04 19:33:45][ADC_TASK] frames=1479707 idle=0 skip=148 seq=1480006 frst_err=0 ring=1479559 adc1_rc=0 adc1_err=0 adc1_seq=1480005 adc1_gap=445 adc1_hw=0 tgap=320
[RX] 2026-11-04T19:33:46.576+08:00 [2026-11-04 19:33:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:46.576+08:00 [2026-11-04 19:33:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:46.586+08:00 [2026-11-04 19:33:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:46.596+08:00 [2026-11-04 19:33:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:46.607+08:00 [2026-11-04 19:33:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:46.607+08:00 [2026-11-04 19:33:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:33:46.617+08:00 [2026-11-04 19:33:45][ADC_TASK] adc: UA=11428 UB=0 UC=893 UN=-50 IA=11451 IB=947 IC=768 IN=826 T=869
[RX] 2026-11-04T19:33:46.617+08:00 [2026-11-04 19:33:45][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:33:46.628+08:00 [2026-11-04 19:33:45][ADC_TASK] meas: seq=7400 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:33:46.639+08:00 [2026-11-04 19:33:45][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:33:56.556+08:00 [2026-11-04 19:33:55][ADC_TASK] frames=1489705 idle=0 skip=149 seq=1490006 frst_err=0 ring=1489556 adc1_rc=0 adc1_err=0 adc1_seq=1490005 adc1_gap=448 adc1_hw=0 tgap=322
[RX] 2026-11-04T19:33:56.577+08:00 [2026-11-04 19:33:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:56.577+08:00 [2026-11-04 19:33:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:56.588+08:00 [2026-11-04 19:33:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:56.598+08:00 [2026-11-04 19:33:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:56.598+08:00 [2026-11-04 19:33:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:33:56.609+08:00 [2026-11-04 19:33:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:33:56.609+08:00 [2026-11-04 19:33:55][ADC_TASK] adc: UA=11426 UB=0 UC=906 UN=-51 IA=11451 IB=962 IC=776 IN=840 T=895
[RX] 2026-11-04T19:33:56.619+08:00 [2026-11-04 19:33:55][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:33:56.630+08:00 [2026-11-04 19:33:55][ADC_TASK] meas: seq=7450 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:33:56.640+08:00 [2026-11-04 19:33:55][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:34:06.562+08:00 [2026-11-04 19:34:05][ADC_TASK] frames=1499703 idle=0 skip=150 seq=1500006 frst_err=0 ring=1499553 adc1_rc=0 adc1_err=0 adc1_seq=1500005 adc1_gap=451 adc1_hw=0 tgap=324
[RX] 2026-11-04T19:34:06.572+08:00 [2026-11-04 19:34:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:06.583+08:00 [2026-11-04 19:34:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:06.583+08:00 [2026-11-04 19:34:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:06.593+08:00 [2026-11-04 19:34:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:06.604+08:00 [2026-11-04 19:34:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:06.604+08:00 [2026-11-04 19:34:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:34:06.614+08:00 [2026-11-04 19:34:05][ADC_TASK] adc: UA=11428 UB=0 UC=908 UN=-38 IA=11451 IB=934 IC=673 IN=838 T=899
[RX] 2026-11-04T19:34:06.624+08:00 [2026-11-04 19:34:05][ADC_TASK] cal: ua_mv=1743 un_mv=-5 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:34:06.634+08:00 [2026-11-04 19:34:05][ADC_TASK] meas: seq=7500 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:34:06.634+08:00 [2026-11-04 19:34:05][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:34:16.555+08:00 [2026-11-04 19:34:15][ADC_TASK] frames=1509701 idle=0 skip=151 seq=1510006 frst_err=0 ring=1509550 adc1_rc=0 adc1_err=0 adc1_seq=1510005 adc1_gap=454 adc1_hw=0 tgap=326
[RX] 2026-11-04T19:34:16.575+08:00 [2026-11-04 19:34:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:16.575+08:00 [2026-11-04 19:34:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:16.586+08:00 [2026-11-04 19:34:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:16.596+08:00 [2026-11-04 19:34:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:16.606+08:00 [2026-11-04 19:34:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:16.606+08:00 [2026-11-04 19:34:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:34:16.617+08:00 [2026-11-04 19:34:15][ADC_TASK] adc: UA=11427 UB=0 UC=874 UN=-38 IA=11451 IB=938 IC=432 IN=735 T=898
[RX] 2026-11-04T19:34:16.617+08:00 [2026-11-04 19:34:15][ADC_TASK] cal: ua_mv=1743 un_mv=-5 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:34:16.637+08:00 [2026-11-04 19:34:15][ADC_TASK] meas: seq=7550 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:34:16.637+08:00 [2026-11-04 19:34:15][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:34:26.561+08:00 [2026-11-04 19:34:25][ADC_TASK] frames=1519699 idle=0 skip=152 seq=1520006 frst_err=0 ring=1519547 adc1_rc=0 adc1_err=0 adc1_seq=1520005 adc1_gap=457 adc1_hw=0 tgap=328
[RX] 2026-11-04T19:34:26.571+08:00 [2026-11-04 19:34:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:26.582+08:00 [2026-11-04 19:34:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:26.593+08:00 [2026-11-04 19:34:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:26.593+08:00 [2026-11-04 19:34:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:26.603+08:00 [2026-11-04 19:34:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:26.603+08:00 [2026-11-04 19:34:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:34:26.613+08:00 [2026-11-04 19:34:25][ADC_TASK] adc: UA=11429 UB=0 UC=811 UN=-35 IA=11451 IB=933 IC=361 IN=663 T=896
[RX] 2026-11-04T19:34:26.624+08:00 [2026-11-04 19:34:25][ADC_TASK] cal: ua_mv=1743 un_mv=-5 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:34:26.634+08:00 [2026-11-04 19:34:25][ADC_TASK] meas: seq=7600 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:34:26.634+08:00 [2026-11-04 19:34:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:34:36.556+08:00 [2026-11-04 19:34:35][ADC_TASK] frames=1529697 idle=0 skip=153 seq=1530006 frst_err=0 ring=1529544 adc1_rc=0 adc1_err=0 adc1_seq=1530005 adc1_gap=460 adc1_hw=0 tgap=330
[RX] 2026-11-04T19:34:36.577+08:00 [2026-11-04 19:34:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:36.577+08:00 [2026-11-04 19:34:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:36.587+08:00 [2026-11-04 19:34:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:36.598+08:00 [2026-11-04 19:34:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:36.598+08:00 [2026-11-04 19:34:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:36.608+08:00 [2026-11-04 19:34:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:34:36.608+08:00 [2026-11-04 19:34:35][ADC_TASK] adc: UA=11428 UB=0 UC=789 UN=-38 IA=11451 IB=933 IC=340 IN=631 T=851
[RX] 2026-11-04T19:34:36.619+08:00 [2026-11-04 19:34:35][ADC_TASK] cal: ua_mv=1743 un_mv=-5 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:34:36.629+08:00 [2026-11-04 19:34:35][ADC_TASK] meas: seq=7650 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:34:36.640+08:00 [2026-11-04 19:34:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:34:46.555+08:00 [2026-11-04 19:34:45][ADC_TASK] frames=1539695 idle=0 skip=154 seq=1540006 frst_err=0 ring=1539541 adc1_rc=0 adc1_err=0 adc1_seq=1540005 adc1_gap=463 adc1_hw=0 tgap=332
[RX] 2026-11-04T19:34:46.576+08:00 [2026-11-04 19:34:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:46.576+08:00 [2026-11-04 19:34:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:46.586+08:00 [2026-11-04 19:34:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:46.596+08:00 [2026-11-04 19:34:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:46.596+08:00 [2026-11-04 19:34:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:46.607+08:00 [2026-11-04 19:34:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:34:46.607+08:00 [2026-11-04 19:34:45][ADC_TASK] adc: UA=11429 UB=0 UC=781 UN=-40 IA=11450 IB=887 IC=367 IN=613 T=813
[RX] 2026-11-04T19:34:46.618+08:00 [2026-11-04 19:34:45][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:34:46.628+08:00 [2026-11-04 19:34:45][ADC_TASK] meas: seq=7700 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:34:46.639+08:00 [2026-11-04 19:34:45][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:34:56.556+08:00 [2026-11-04 19:34:55][ADC_TASK] frames=1549693 idle=0 skip=155 seq=1550006 frst_err=0 ring=1549538 adc1_rc=0 adc1_err=0 adc1_seq=1550005 adc1_gap=466 adc1_hw=0 tgap=334
[RX] 2026-11-04T19:34:56.578+08:00 [2026-11-04 19:34:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:56.578+08:00 [2026-11-04 19:34:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:56.588+08:00 [2026-11-04 19:34:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:56.588+08:00 [2026-11-04 19:34:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:56.599+08:00 [2026-11-04 19:34:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:34:56.609+08:00 [2026-11-04 19:34:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:34:56.609+08:00 [2026-11-04 19:34:55][ADC_TASK] adc: UA=11427 UB=0 UC=783 UN=-41 IA=11450 IB=884 IC=518 IN=660 T=818
[RX] 2026-11-04T19:34:56.619+08:00 [2026-11-04 19:34:55][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:34:56.630+08:00 [2026-11-04 19:34:55][ADC_TASK] meas: seq=7750 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:34:56.640+08:00 [2026-11-04 19:34:55][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:35:06.556+08:00 [2026-11-04 19:35:05][ADC_TASK] frames=1559691 idle=0 skip=156 seq=1560006 frst_err=0 ring=1559535 adc1_rc=0 adc1_err=0 adc1_seq=1560005 adc1_gap=469 adc1_hw=0 tgap=336
[RX] 2026-11-04T19:35:06.577+08:00 [2026-11-04 19:35:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:06.577+08:00 [2026-11-04 19:35:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:06.587+08:00 [2026-11-04 19:35:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:06.587+08:00 [2026-11-04 19:35:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:06.597+08:00 [2026-11-04 19:35:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:06.608+08:00 [2026-11-04 19:35:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:35:06.608+08:00 [2026-11-04 19:35:05][ADC_TASK] adc: UA=11428 UB=0 UC=801 UN=-38 IA=11451 IB=888 IC=571 IN=704 T=826
[RX] 2026-11-04T19:35:06.618+08:00 [2026-11-04 19:35:05][ADC_TASK] cal: ua_mv=1743 un_mv=-5 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:35:06.629+08:00 [2026-11-04 19:35:05][ADC_TASK] meas: seq=7800 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:35:06.639+08:00 [2026-11-04 19:35:05][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:35:16.559+08:00 [2026-11-04 19:35:15][ADC_TASK] frames=1569689 idle=0 skip=157 seq=1570006 frst_err=0 ring=1569532 adc1_rc=0 adc1_err=0 adc1_seq=1570005 adc1_gap=472 adc1_hw=0 tgap=338
[RX] 2026-11-04T19:35:16.570+08:00 [2026-11-04 19:35:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:16.581+08:00 [2026-11-04 19:35:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:16.591+08:00 [2026-11-04 19:35:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:16.591+08:00 [2026-11-04 19:35:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:16.602+08:00 [2026-11-04 19:35:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:16.602+08:00 [2026-11-04 19:35:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:35:16.612+08:00 [2026-11-04 19:35:15][ADC_TASK] adc: UA=11428 UB=0 UC=832 UN=-40 IA=11451 IB=891 IC=577 IN=729 T=832
[RX] 2026-11-04T19:35:16.623+08:00 [2026-11-04 19:35:15][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:35:16.633+08:00 [2026-11-04 19:35:15][ADC_TASK] meas: seq=7850 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:35:16.633+08:00 [2026-11-04 19:35:15][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:35:26.561+08:00 [2026-11-04 19:35:25][ADC_TASK] frames=1579687 idle=0 skip=158 seq=1580006 frst_err=0 ring=1579529 adc1_rc=0 adc1_err=0 adc1_seq=1580005 adc1_gap=475 adc1_hw=0 tgap=340
[RX] 2026-11-04T19:35:26.572+08:00 [2026-11-04 19:35:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:26.582+08:00 [2026-11-04 19:35:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:26.582+08:00 [2026-11-04 19:35:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:26.593+08:00 [2026-11-04 19:35:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:26.603+08:00 [2026-11-04 19:35:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:26.603+08:00 [2026-11-04 19:35:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:35:26.614+08:00 [2026-11-04 19:35:25][ADC_TASK] adc: UA=11429 UB=0 UC=842 UN=-41 IA=11451 IB=895 IC=576 IN=730 T=844
[RX] 2026-11-04T19:35:26.624+08:00 [2026-11-04 19:35:25][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:35:26.634+08:00 [2026-11-04 19:35:25][ADC_TASK] meas: seq=7900 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:35:26.634+08:00 [2026-11-04 19:35:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:35:36.562+08:00 [2026-11-04 19:35:35][ADC_TASK] frames=1589685 idle=0 skip=159 seq=1590006 frst_err=0 ring=1589526 adc1_rc=0 adc1_err=0 adc1_seq=1590005 adc1_gap=478 adc1_hw=0 tgap=342
[RX] 2026-11-04T19:35:36.573+08:00 [2026-11-04 19:35:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:36.573+08:00 [2026-11-04 19:35:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:36.583+08:00 [2026-11-04 19:35:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:36.593+08:00 [2026-11-04 19:35:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:36.604+08:00 [2026-11-04 19:35:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:36.604+08:00 [2026-11-04 19:35:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:35:36.614+08:00 [2026-11-04 19:35:35][ADC_TASK] adc: UA=11427 UB=0 UC=847 UN=-41 IA=11450 IB=912 IC=575 IN=731 T=861
[RX] 2026-11-04T19:35:36.614+08:00 [2026-11-04 19:35:35][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:35:36.635+08:00 [2026-11-04 19:35:35][ADC_TASK] meas: seq=7950 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:35:36.635+08:00 [2026-11-04 19:35:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:35:46.560+08:00 [2026-11-04 19:35:45][ADC_TASK] frames=1599683 idle=0 skip=160 seq=1600006 frst_err=0 ring=1599523 adc1_rc=0 adc1_err=0 adc1_seq=1600005 adc1_gap=481 adc1_hw=0 tgap=344
[RX] 2026-11-04T19:35:46.571+08:00 [2026-11-04 19:35:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:46.581+08:00 [2026-11-04 19:35:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:46.581+08:00 [2026-11-04 19:35:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:46.592+08:00 [2026-11-04 19:35:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:46.602+08:00 [2026-11-04 19:35:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:46.602+08:00 [2026-11-04 19:35:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:35:46.613+08:00 [2026-11-04 19:35:45][ADC_TASK] adc: UA=11428 UB=0 UC=853 UN=-41 IA=11451 IB=937 IC=589 IN=738 T=877
[RX] 2026-11-04T19:35:46.624+08:00 [2026-11-04 19:35:45][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:35:46.634+08:00 [2026-11-04 19:35:45][ADC_TASK] meas: seq=8000 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:35:46.634+08:00 [2026-11-04 19:35:45][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:35:56.555+08:00 [2026-11-04 19:35:55][ADC_TASK] frames=1609681 idle=0 skip=161 seq=1610006 frst_err=0 ring=1609520 adc1_rc=0 adc1_err=0 adc1_seq=1610005 adc1_gap=484 adc1_hw=0 tgap=346
[RX] 2026-11-04T19:35:56.575+08:00 [2026-11-04 19:35:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:56.575+08:00 [2026-11-04 19:35:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:56.585+08:00 [2026-11-04 19:35:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:56.596+08:00 [2026-11-04 19:35:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:56.596+08:00 [2026-11-04 19:35:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:35:56.606+08:00 [2026-11-04 19:35:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:35:56.606+08:00 [2026-11-04 19:35:55][ADC_TASK] adc: UA=11427 UB=0 UC=868 UN=-41 IA=11452 IB=953 IC=609 IN=758 T=892
[RX] 2026-11-04T19:35:56.617+08:00 [2026-11-04 19:35:55][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:35:56.627+08:00 [2026-11-04 19:35:55][ADC_TASK] meas: seq=8050 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:35:56.637+08:00 [2026-11-04 19:35:55][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:36:06.560+08:00 [2026-11-04 19:36:05][ADC_TASK] frames=1619679 idle=0 skip=162 seq=1620006 frst_err=0 ring=1619517 adc1_rc=0 adc1_err=0 adc1_seq=1620005 adc1_gap=487 adc1_hw=0 tgap=348
[RX] 2026-11-04T19:36:06.570+08:00 [2026-11-04 19:36:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:06.581+08:00 [2026-11-04 19:36:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:06.581+08:00 [2026-11-04 19:36:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:06.591+08:00 [2026-11-04 19:36:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:06.602+08:00 [2026-11-04 19:36:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:06.602+08:00 [2026-11-04 19:36:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:36:06.612+08:00 [2026-11-04 19:36:05][ADC_TASK] adc: UA=11429 UB=0 UC=875 UN=-41 IA=11451 IB=949 IC=604 IN=768 T=898
[RX] 2026-11-04T19:36:06.622+08:00 [2026-11-04 19:36:05][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:36:06.633+08:00 [2026-11-04 19:36:05][ADC_TASK] meas: seq=8100 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:36:06.633+08:00 [2026-11-04 19:36:05][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:36:16.553+08:00 [2026-11-04 19:36:15][ADC_TASK] frames=1629677 idle=0 skip=163 seq=1630006 frst_err=0 ring=1629514 adc1_rc=0 adc1_err=0 adc1_seq=1630005 adc1_gap=490 adc1_hw=0 tgap=350
[RX] 2026-11-04T19:36:16.574+08:00 [2026-11-04 19:36:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:16.574+08:00 [2026-11-04 19:36:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:16.585+08:00 [2026-11-04 19:36:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:16.595+08:00 [2026-11-04 19:36:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:16.595+08:00 [2026-11-04 19:36:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:16.606+08:00 [2026-11-04 19:36:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:36:16.606+08:00 [2026-11-04 19:36:15][ADC_TASK] adc: UA=11428 UB=0 UC=881 UN=-43 IA=11452 IB=945 IC=600 IN=764 T=898
[RX] 2026-11-04T19:36:16.617+08:00 [2026-11-04 19:36:15][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:36:16.627+08:00 [2026-11-04 19:36:15][ADC_TASK] meas: seq=8150 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:36:16.637+08:00 [2026-11-04 19:36:15][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:36:26.557+08:00 [2026-11-04 19:36:25][ADC_TASK] frames=1639675 idle=0 skip=164 seq=1640006 frst_err=0 ring=1639511 adc1_rc=0 adc1_err=0 adc1_seq=1640005 adc1_gap=493 adc1_hw=0 tgap=352
[RX] 2026-11-04T19:36:26.567+08:00 [2026-11-04 19:36:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:26.578+08:00 [2026-11-04 19:36:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:26.588+08:00 [2026-11-04 19:36:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:26.588+08:00 [2026-11-04 19:36:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:26.599+08:00 [2026-11-04 19:36:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:26.609+08:00 [2026-11-04 19:36:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:36:26.609+08:00 [2026-11-04 19:36:25][ADC_TASK] adc: UA=11428 UB=0 UC=878 UN=-42 IA=11452 IB=947 IC=591 IN=753 T=873
[RX] 2026-11-04T19:36:26.619+08:00 [2026-11-04 19:36:25][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:36:26.630+08:00 [2026-11-04 19:36:25][ADC_TASK] meas: seq=8200 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:36:26.630+08:00 [2026-11-04 19:36:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:36:36.554+08:00 [2026-11-04 19:36:35][ADC_TASK] frames=1649673 idle=0 skip=165 seq=1650006 frst_err=0 ring=1649508 adc1_rc=0 adc1_err=0 adc1_seq=1650005 adc1_gap=496 adc1_hw=0 tgap=354
[RX] 2026-11-04T19:36:36.575+08:00 [2026-11-04 19:36:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:36.575+08:00 [2026-11-04 19:36:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:36.585+08:00 [2026-11-04 19:36:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:36.585+08:00 [2026-11-04 19:36:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:36.596+08:00 [2026-11-04 19:36:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:36.606+08:00 [2026-11-04 19:36:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:36:36.606+08:00 [2026-11-04 19:36:35][ADC_TASK] adc: UA=11429 UB=0 UC=884 UN=-41 IA=11452 IB=945 IC=599 IN=759 T=866
[RX] 2026-11-04T19:36:36.617+08:00 [2026-11-04 19:36:35][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:36:36.627+08:00 [2026-11-04 19:36:35][ADC_TASK] meas: seq=8250 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:36:36.638+08:00 [2026-11-04 19:36:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:36:42.752+08:00 [2026-11-04 19:36:41] [WAVE][WARN] seg held 886 ms (idx=12)
[RX] 2026-11-04T19:36:46.556+08:00 [2026-11-04 19:36:45][ADC_TASK] frames=1659671 idle=0 skip=166 seq=1660006 frst_err=0 ring=1659505 adc1_rc=0 adc1_err=0 adc1_seq=1660005 adc1_gap=499 adc1_hw=0 tgap=356
[RX] 2026-11-04T19:36:46.566+08:00 [2026-11-04 19:36:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:46.577+08:00 [2026-11-04 19:36:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:46.587+08:00 [2026-11-04 19:36:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:46.587+08:00 [2026-11-04 19:36:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:46.597+08:00 [2026-11-04 19:36:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:46.608+08:00 [2026-11-04 19:36:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:36:46.608+08:00 [2026-11-04 19:36:45][ADC_TASK] adc: UA=11428 UB=0 UC=878 UN=-41 IA=11452 IB=930 IC=611 IN=760 T=855
[RX] 2026-11-04T19:36:46.618+08:00 [2026-11-04 19:36:45][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:36:46.628+08:00 [2026-11-04 19:36:45][ADC_TASK] meas: seq=8300 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:36:46.639+08:00 [2026-11-04 19:36:45][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:36:56.556+08:00 [2026-11-04 19:36:55][ADC_TASK] frames=1669669 idle=0 skip=167 seq=1670006 frst_err=0 ring=1669502 adc1_rc=0 adc1_err=0 adc1_seq=1670005 adc1_gap=502 adc1_hw=0 tgap=358
[RX] 2026-11-04T19:36:56.567+08:00 [2026-11-04 19:36:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:56.577+08:00 [2026-11-04 19:36:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:56.588+08:00 [2026-11-04 19:36:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:56.588+08:00 [2026-11-04 19:36:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:56.598+08:00 [2026-11-04 19:36:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:36:56.598+08:00 [2026-11-04 19:36:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:36:56.608+08:00 [2026-11-04 19:36:55][ADC_TASK] adc: UA=11428 UB=0 UC=863 UN=-42 IA=11451 IB=926 IC=614 IN=773 T=866
[RX] 2026-11-04T19:36:56.619+08:00 [2026-11-04 19:36:55][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:36:56.629+08:00 [2026-11-04 19:36:55][ADC_TASK] meas: seq=8350 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:36:56.629+08:00 [2026-11-04 19:36:55][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:37:06.553+08:00 [2026-11-04 19:37:05][ADC_TASK] frames=1679667 idle=0 skip=168 seq=1680006 frst_err=0 ring=1679499 adc1_rc=0 adc1_err=0 adc1_seq=1680005 adc1_gap=505 adc1_hw=0 tgap=360
[RX] 2026-11-04T19:37:06.574+08:00 [2026-11-04 19:37:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:06.574+08:00 [2026-11-04 19:37:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:06.584+08:00 [2026-11-04 19:37:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:06.584+08:00 [2026-11-04 19:37:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:06.595+08:00 [2026-11-04 19:37:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:06.605+08:00 [2026-11-04 19:37:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:37:06.605+08:00 [2026-11-04 19:37:05][ADC_TASK] adc: UA=11428 UB=0 UC=855 UN=-42 IA=11451 IB=949 IC=596 IN=767 T=891
[RX] 2026-11-04T19:37:06.616+08:00 [2026-11-04 19:37:05][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:37:06.626+08:00 [2026-11-04 19:37:05][ADC_TASK] meas: seq=8400 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:37:06.637+08:00 [2026-11-04 19:37:05][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:37:16.556+08:00 [2026-11-04 19:37:15][ADC_TASK] frames=1689665 idle=0 skip=169 seq=1690006 frst_err=0 ring=1689496 adc1_rc=0 adc1_err=0 adc1_seq=1690005 adc1_gap=508 adc1_hw=0 tgap=362
[RX] 2026-11-04T19:37:16.567+08:00 [2026-11-04 19:37:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:16.577+08:00 [2026-11-04 19:37:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:16.588+08:00 [2026-11-04 19:37:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:16.588+08:00 [2026-11-04 19:37:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:16.599+08:00 [2026-11-04 19:37:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:16.599+08:00 [2026-11-04 19:37:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:37:16.609+08:00 [2026-11-04 19:37:15][ADC_TASK] adc: UA=11429 UB=0 UC=866 UN=-43 IA=11452 IB=941 IC=583 IN=748 T=889
[RX] 2026-11-04T19:37:16.619+08:00 [2026-11-04 19:37:15][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:37:16.630+08:00 [2026-11-04 19:37:15][ADC_TASK] meas: seq=8450 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:37:16.630+08:00 [2026-11-04 19:37:15][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:37:26.554+08:00 [2026-11-04 19:37:25][ADC_TASK] frames=1699663 idle=0 skip=170 seq=1700006 frst_err=0 ring=1699493 adc1_rc=0 adc1_err=0 adc1_seq=1700005 adc1_gap=511 adc1_hw=0 tgap=364
[RX] 2026-11-04T19:37:26.564+08:00 [2026-11-04 19:37:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:26.575+08:00 [2026-11-04 19:37:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:26.586+08:00 [2026-11-04 19:37:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:26.586+08:00 [2026-11-04 19:37:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:26.596+08:00 [2026-11-04 19:37:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:26.607+08:00 [2026-11-04 19:37:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:37:26.607+08:00 [2026-11-04 19:37:25][ADC_TASK] adc: UA=11429 UB=0 UC=872 UN=-40 IA=11452 IB=936 IC=592 IN=746 T=886
[RX] 2026-11-04T19:37:26.617+08:00 [2026-11-04 19:37:25][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:37:26.628+08:00 [2026-11-04 19:37:25][ADC_TASK] meas: seq=8500 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:37:26.628+08:00 [2026-11-04 19:37:25][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:37:36.554+08:00 [2026-11-04 19:37:35][ADC_TASK] frames=1709661 idle=0 skip=171 seq=1710006 frst_err=0 ring=1709490 adc1_rc=0 adc1_err=0 adc1_seq=1710005 adc1_gap=514 adc1_hw=0 tgap=366
[RX] 2026-11-04T19:37:36.565+08:00 [2026-11-04 19:37:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:36.575+08:00 [2026-11-04 19:37:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:36.586+08:00 [2026-11-04 19:37:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:36.586+08:00 [2026-11-04 19:37:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:36.596+08:00 [2026-11-04 19:37:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:36.606+08:00 [2026-11-04 19:37:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:37:36.606+08:00 [2026-11-04 19:37:35][ADC_TASK] adc: UA=11429 UB=0 UC=872 UN=-42 IA=11452 IB=947 IC=595 IN=751 T=882
[RX] 2026-11-04T19:37:36.617+08:00 [2026-11-04 19:37:35][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:37:36.627+08:00 [2026-11-04 19:37:35][ADC_TASK] meas: seq=8550 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:37:36.638+08:00 [2026-11-04 19:37:35][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:37:46.551+08:00 [2026-11-04 19:37:45][ADC_TASK] frames=1719659 idle=0 skip=172 seq=1720006 frst_err=0 ring=1719487 adc1_rc=0 adc1_err=0 adc1_seq=1720005 adc1_gap=517 adc1_hw=0 tgap=368
[RX] 2026-11-04T19:37:46.572+08:00 [2026-11-04 19:37:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:46.572+08:00 [2026-11-04 19:37:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:46.583+08:00 [2026-11-04 19:37:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:46.583+08:00 [2026-11-04 19:37:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:46.593+08:00 [2026-11-04 19:37:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:46.604+08:00 [2026-11-04 19:37:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:37:46.604+08:00 [2026-11-04 19:37:45][ADC_TASK] adc: UA=11427 UB=0 UC=869 UN=-47 IA=11451 IB=943 IC=588 IN=748 T=870
[RX] 2026-11-04T19:37:46.614+08:00 [2026-11-04 19:37:45][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:37:46.625+08:00 [2026-11-04 19:37:45][ADC_TASK] meas: seq=8600 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:37:46.635+08:00 [2026-11-04 19:37:45][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:37:56.559+08:00 [2026-11-04 19:37:55][ADC_TASK] frames=1729657 idle=0 skip=173 seq=1730006 frst_err=0 ring=1729484 adc1_rc=0 adc1_err=0 adc1_seq=1730005 adc1_gap=520 adc1_hw=0 tgap=370
[RX] 2026-11-04T19:37:56.569+08:00 [2026-11-04 19:37:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:56.569+08:00 [2026-11-04 19:37:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:56.580+08:00 [2026-11-04 19:37:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:56.590+08:00 [2026-11-04 19:37:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:56.601+08:00 [2026-11-04 19:37:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:37:56.601+08:00 [2026-11-04 19:37:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:37:56.611+08:00 [2026-11-04 19:37:55][ADC_TASK] adc: UA=11428 UB=0 UC=879 UN=-48 IA=11452 IB=950 IC=624 IN=762 T=870
[RX] 2026-11-04T19:37:56.611+08:00 [2026-11-04 19:37:55][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:37:56.622+08:00 [2026-11-04 19:37:55][ADC_TASK] meas: seq=8650 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:37:56.632+08:00 [2026-11-04 19:37:55][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:38:06.551+08:00 [2026-11-04 19:38:05][ADC_TASK] frames=1739655 idle=0 skip=174 seq=1740006 frst_err=0 ring=1739481 adc1_rc=0 adc1_err=0 adc1_seq=1740005 adc1_gap=523 adc1_hw=0 tgap=372
[RX] 2026-11-04T19:38:06.571+08:00 [2026-11-04 19:38:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:06.571+08:00 [2026-11-04 19:38:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:06.581+08:00 [2026-11-04 19:38:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=9 Im=0 rms=9 (x0.1)
[RX] 2026-11-04T19:38:06.592+08:00 [2026-11-04 19:38:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:06.592+08:00 [2026-11-04 19:38:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:06.602+08:00 [2026-11-04 19:38:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:38:06.602+08:00 [2026-11-04 19:38:05][ADC_TASK] adc: UA=11428 UB=0 UC=864 UN=-3515 IA=11453 IB=943 IC=722 IN=786 T=868
[RX] 2026-11-04T19:38:06.613+08:00 [2026-11-04 19:38:05][ADC_TASK] cal: ua_mv=1743 un_mv=-536 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:38:06.623+08:00 [2026-11-04 19:38:05][ADC_TASK] meas: seq=8700 v=1 ua_mv=0 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:38:06.634+08:00 [2026-11-04 19:38:05][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:38:16.550+08:00 [2026-11-04 19:38:15][ADC_TASK] frames=1749653 idle=0 skip=175 seq=1750006 frst_err=0 ring=1749478 adc1_rc=0 adc1_err=0 adc1_seq=1750005 adc1_gap=526 adc1_hw=0 tgap=374
[RX] 2026-11-04T19:38:16.571+08:00 [2026-11-04 19:38:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:16.571+08:00 [2026-11-04 19:38:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:16.582+08:00 [2026-11-04 19:38:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=9 Im=-1 rms=9 (x0.1)
[RX] 2026-11-04T19:38:16.592+08:00 [2026-11-04 19:38:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:16.592+08:00 [2026-11-04 19:38:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:16.602+08:00 [2026-11-04 19:38:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:38:16.602+08:00 [2026-11-04 19:38:15][ADC_TASK] adc: UA=11428 UB=0 UC=852 UN=-4359 IA=11451 IB=946 IC=676 IN=797 T=889
[RX] 2026-11-04T19:38:16.612+08:00 [2026-11-04 19:38:15][ADC_TASK] cal: ua_mv=1743 un_mv=-665 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:38:16.623+08:00 [2026-11-04 19:38:15][ADC_TASK] meas: seq=8750 v=1 ua_mv=0 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:38:16.633+08:00 [2026-11-04 19:38:15][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:38:26.557+08:00 [2026-11-04 19:38:25][ADC_TASK] frames=1759651 idle=0 skip=176 seq=1760006 frst_err=0 ring=1759475 adc1_rc=0 adc1_err=0 adc1_seq=1760005 adc1_gap=529 adc1_hw=0 tgap=377
[RX] 2026-11-04T19:38:26.567+08:00 [2026-11-04 19:38:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:26.578+08:00 [2026-11-04 19:38:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:26.578+08:00 [2026-11-04 19:38:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:26.588+08:00 [2026-11-04 19:38:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:26.598+08:00 [2026-11-04 19:38:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:26.598+08:00 [2026-11-04 19:38:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:38:26.609+08:00 [2026-11-04 19:38:25][ADC_TASK] adc: UA=11427 UB=0 UC=841 UN=-49 IA=11450 IB=937 IC=692 IN=784 T=889
[RX] 2026-11-04T19:38:26.619+08:00 [2026-11-04 19:38:25][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:38:26.630+08:00 [2026-11-04 19:38:25][ADC_TASK] meas: seq=8800 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:38:26.630+08:00 [2026-11-04 19:38:25][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:38:36.548+08:00 [2026-11-04 19:38:35][ADC_TASK] frames=1769649 idle=0 skip=177 seq=1770006 frst_err=0 ring=1769472 adc1_rc=0 adc1_err=0 adc1_seq=1770005 adc1_gap=532 adc1_hw=0 tgap=379
[RX] 2026-11-04T19:38:36.569+08:00 [2026-11-04 19:38:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:36.569+08:00 [2026-11-04 19:38:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:36.580+08:00 [2026-11-04 19:38:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:36.590+08:00 [2026-11-04 19:38:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:36.600+08:00 [2026-11-04 19:38:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:36.600+08:00 [2026-11-04 19:38:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:38:36.611+08:00 [2026-11-04 19:38:35][ADC_TASK] adc: UA=11428 UB=0 UC=864 UN=-51 IA=11452 IB=948 IC=742 IN=829 T=894
[RX] 2026-11-04T19:38:36.611+08:00 [2026-11-04 19:38:35][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:38:36.621+08:00 [2026-11-04 19:38:35][ADC_TASK] meas: seq=8850 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:38:36.631+08:00 [2026-11-04 19:38:35][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:38:46.551+08:00 [2026-11-04 19:38:45][ADC_TASK] frames=1779647 idle=0 skip=178 seq=1780006 frst_err=0 ring=1779469 adc1_rc=0 adc1_err=0 adc1_seq=1780005 adc1_gap=535 adc1_hw=0 tgap=381
[RX] 2026-11-04T19:38:46.571+08:00 [2026-11-04 19:38:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:46.571+08:00 [2026-11-04 19:38:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:46.582+08:00 [2026-11-04 19:38:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:46.582+08:00 [2026-11-04 19:38:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:46.592+08:00 [2026-11-04 19:38:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:46.603+08:00 [2026-11-04 19:38:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:38:46.603+08:00 [2026-11-04 19:38:45][ADC_TASK] adc: UA=11428 UB=0 UC=896 UN=-51 IA=11451 IB=940 IC=737 IN=846 T=893
[RX] 2026-11-04T19:38:46.613+08:00 [2026-11-04 19:38:45][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:38:46.623+08:00 [2026-11-04 19:38:45][ADC_TASK] meas: seq=8900 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:38:46.634+08:00 [2026-11-04 19:38:45][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:38:56.549+08:00 [2026-11-04 19:38:55][ADC_TASK] frames=1789645 idle=0 skip=179 seq=1790006 frst_err=0 ring=1789466 adc1_rc=0 adc1_err=0 adc1_seq=1790005 adc1_gap=538 adc1_hw=0 tgap=383
[RX] 2026-11-04T19:38:56.570+08:00 [2026-11-04 19:38:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:56.570+08:00 [2026-11-04 19:38:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:56.581+08:00 [2026-11-04 19:38:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:56.591+08:00 [2026-11-04 19:38:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:56.591+08:00 [2026-11-04 19:38:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:38:56.601+08:00 [2026-11-04 19:38:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:38:56.601+08:00 [2026-11-04 19:38:55][ADC_TASK] adc: UA=11428 UB=0 UC=909 UN=-49 IA=11451 IB=941 IC=734 IN=849 T=891
[RX] 2026-11-04T19:38:56.612+08:00 [2026-11-04 19:38:55][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:38:56.623+08:00 [2026-11-04 19:38:55][ADC_TASK] meas: seq=8950 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:38:56.633+08:00 [2026-11-04 19:38:55][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:39:06.553+08:00 [2026-11-04 19:39:05][ADC_TASK] frames=1799643 idle=0 skip=180 seq=1800006 frst_err=0 ring=1799463 adc1_rc=0 adc1_err=0 adc1_seq=1800005 adc1_gap=541 adc1_hw=0 tgap=385
[RX] 2026-11-04T19:39:06.563+08:00 [2026-11-04 19:39:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:06.573+08:00 [2026-11-04 19:39:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:06.584+08:00 [2026-11-04 19:39:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:06.584+08:00 [2026-11-04 19:39:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:06.594+08:00 [2026-11-04 19:39:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:06.605+08:00 [2026-11-04 19:39:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:39:06.605+08:00 [2026-11-04 19:39:05][ADC_TASK] adc: UA=11429 UB=0 UC=920 UN=-49 IA=11452 IB=950 IC=734 IN=853 T=890
[RX] 2026-11-04T19:39:06.615+08:00 [2026-11-04 19:39:05][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:39:06.626+08:00 [2026-11-04 19:39:05][ADC_TASK] meas: seq=9000 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:39:06.626+08:00 [2026-11-04 19:39:05][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:39:16.549+08:00 [2026-11-04 19:39:15][ADC_TASK] frames=1809641 idle=0 skip=181 seq=1810006 frst_err=0 ring=1809460 adc1_rc=0 adc1_err=0 adc1_seq=1810005 adc1_gap=544 adc1_hw=0 tgap=387
[RX] 2026-11-04T19:39:16.570+08:00 [2026-11-04 19:39:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:16.570+08:00 [2026-11-04 19:39:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:16.581+08:00 [2026-11-04 19:39:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:16.581+08:00 [2026-11-04 19:39:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:16.591+08:00 [2026-11-04 19:39:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:16.602+08:00 [2026-11-04 19:39:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:39:16.602+08:00 [2026-11-04 19:39:15][ADC_TASK] adc: UA=11429 UB=0 UC=911 UN=-51 IA=11453 IB=954 IC=730 IN=844 T=883
[RX] 2026-11-04T19:39:16.612+08:00 [2026-11-04 19:39:15][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:39:16.623+08:00 [2026-11-04 19:39:15][ADC_TASK] meas: seq=9050 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:39:16.633+08:00 [2026-11-04 19:39:15][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:39:26.557+08:00 [2026-11-04 19:39:25][ADC_TASK] frames=1819639 idle=0 skip=182 seq=1820006 frst_err=0 ring=1819457 adc1_rc=0 adc1_err=0 adc1_seq=1820005 adc1_gap=547 adc1_hw=0 tgap=389
[RX] 2026-11-04T19:39:26.567+08:00 [2026-11-04 19:39:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:26.567+08:00 [2026-11-04 19:39:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:26.577+08:00 [2026-11-04 19:39:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:26.588+08:00 [2026-11-04 19:39:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:26.598+08:00 [2026-11-04 19:39:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:26.598+08:00 [2026-11-04 19:39:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:39:26.609+08:00 [2026-11-04 19:39:25][ADC_TASK] adc: UA=11429 UB=0 UC=901 UN=-51 IA=11452 IB=945 IC=726 IN=837 T=872
[RX] 2026-11-04T19:39:26.609+08:00 [2026-11-04 19:39:25][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:39:26.620+08:00 [2026-11-04 19:39:25][ADC_TASK] meas: seq=9100 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:39:26.631+08:00 [2026-11-04 19:39:25][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:39:36.552+08:00 [2026-11-04 19:39:35][ADC_TASK] frames=1829637 idle=0 skip=183 seq=1830006 frst_err=0 ring=1829454 adc1_rc=0 adc1_err=0 adc1_seq=1830005 adc1_gap=550 adc1_hw=0 tgap=391
[RX] 2026-11-04T19:39:36.562+08:00 [2026-11-04 19:39:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:36.573+08:00 [2026-11-04 19:39:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:36.583+08:00 [2026-11-04 19:39:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:36.583+08:00 [2026-11-04 19:39:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:36.593+08:00 [2026-11-04 19:39:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:36.604+08:00 [2026-11-04 19:39:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:39:36.604+08:00 [2026-11-04 19:39:35][ADC_TASK] adc: UA=11429 UB=0 UC=907 UN=-49 IA=11453 IB=951 IC=734 IN=846 T=876
[RX] 2026-11-04T19:39:36.614+08:00 [2026-11-04 19:39:35][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:39:36.624+08:00 [2026-11-04 19:39:35][ADC_TASK] meas: seq=9150 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:39:36.635+08:00 [2026-11-04 19:39:35][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:39:46.549+08:00 [2026-11-04 19:39:45][ADC_TASK] frames=1839635 idle=0 skip=184 seq=1840006 frst_err=0 ring=1839451 adc1_rc=0 adc1_err=0 adc1_seq=1840005 adc1_gap=553 adc1_hw=0 tgap=393
[RX] 2026-11-04T19:39:46.570+08:00 [2026-11-04 19:39:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:46.570+08:00 [2026-11-04 19:39:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:46.581+08:00 [2026-11-04 19:39:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:46.581+08:00 [2026-11-04 19:39:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:46.591+08:00 [2026-11-04 19:39:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:46.602+08:00 [2026-11-04 19:39:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:39:46.602+08:00 [2026-11-04 19:39:45][ADC_TASK] adc: UA=11429 UB=0 UC=902 UN=-49 IA=11452 IB=940 IC=728 IN=839 T=868
[RX] 2026-11-04T19:39:46.612+08:00 [2026-11-04 19:39:45][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:39:46.622+08:00 [2026-11-04 19:39:45][ADC_TASK] meas: seq=9200 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:39:46.633+08:00 [2026-11-04 19:39:45][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:39:56.547+08:00 [2026-11-04 19:39:55][ADC_TASK] frames=1849633 idle=0 skip=185 seq=1850006 frst_err=0 ring=1849448 adc1_rc=0 adc1_err=0 adc1_seq=1850005 adc1_gap=556 adc1_hw=0 tgap=395
[RX] 2026-11-04T19:39:56.568+08:00 [2026-11-04 19:39:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:56.568+08:00 [2026-11-04 19:39:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:56.579+08:00 [2026-11-04 19:39:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:56.589+08:00 [2026-11-04 19:39:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:56.589+08:00 [2026-11-04 19:39:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:39:56.599+08:00 [2026-11-04 19:39:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:39:56.599+08:00 [2026-11-04 19:39:55][ADC_TASK] adc: UA=11429 UB=0 UC=905 UN=-52 IA=11451 IB=941 IC=730 IN=840 T=868
[RX] 2026-11-04T19:39:56.609+08:00 [2026-11-04 19:39:55][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:39:56.620+08:00 [2026-11-04 19:39:55][ADC_TASK] meas: seq=9250 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:39:56.631+08:00 [2026-11-04 19:39:55][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:40:06.549+08:00 [2026-11-04 19:40:05][ADC_TASK] frames=1859631 idle=0 skip=186 seq=1860006 frst_err=0 ring=1859445 adc1_rc=0 adc1_err=0 adc1_seq=1860005 adc1_gap=559 adc1_hw=0 tgap=397
[RX] 2026-11-04T19:40:06.560+08:00 [2026-11-04 19:40:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:06.571+08:00 [2026-11-04 19:40:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:06.581+08:00 [2026-11-04 19:40:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:06.581+08:00 [2026-11-04 19:40:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:06.591+08:00 [2026-11-04 19:40:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:06.602+08:00 [2026-11-04 19:40:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:40:06.602+08:00 [2026-11-04 19:40:05][ADC_TASK] adc: UA=11429 UB=0 UC=922 UN=-51 IA=11451 IB=959 IC=742 IN=856 T=888
[RX] 2026-11-04T19:40:06.612+08:00 [2026-11-04 19:40:05][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:40:06.623+08:00 [2026-11-04 19:40:05][ADC_TASK] meas: seq=9300 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:40:06.633+08:00 [2026-11-04 19:40:05][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:40:16.547+08:00 [2026-11-04 19:40:15][ADC_TASK] frames=1869629 idle=0 skip=187 seq=1870006 frst_err=0 ring=1869442 adc1_rc=0 adc1_err=0 adc1_seq=1870005 adc1_gap=562 adc1_hw=0 tgap=399
[RX] 2026-11-04T19:40:16.568+08:00 [2026-11-04 19:40:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:16.568+08:00 [2026-11-04 19:40:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:16.578+08:00 [2026-11-04 19:40:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:16.589+08:00 [2026-11-04 19:40:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:16.589+08:00 [2026-11-04 19:40:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:16.599+08:00 [2026-11-04 19:40:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:40:16.599+08:00 [2026-11-04 19:40:15][ADC_TASK] adc: UA=11428 UB=0 UC=909 UN=-50 IA=11451 IB=947 IC=730 IN=844 T=874
[RX] 2026-11-04T19:40:16.610+08:00 [2026-11-04 19:40:15][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:40:16.620+08:00 [2026-11-04 19:40:15][ADC_TASK] meas: seq=9350 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:40:16.630+08:00 [2026-11-04 19:40:15][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:40:26.551+08:00 [2026-11-04 19:40:25][ADC_TASK] frames=1879627 idle=0 skip=188 seq=1880006 frst_err=0 ring=1879439 adc1_rc=0 adc1_err=0 adc1_seq=1880005 adc1_gap=565 adc1_hw=0 tgap=401
[RX] 2026-11-04T19:40:26.561+08:00 [2026-11-04 19:40:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:26.572+08:00 [2026-11-04 19:40:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:26.582+08:00 [2026-11-04 19:40:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:26.582+08:00 [2026-11-04 19:40:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:26.593+08:00 [2026-11-04 19:40:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:26.603+08:00 [2026-11-04 19:40:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:40:26.603+08:00 [2026-11-04 19:40:25][ADC_TASK] adc: UA=11429 UB=0 UC=916 UN=-48 IA=11453 IB=954 IC=735 IN=848 T=880
[RX] 2026-11-04T19:40:26.614+08:00 [2026-11-04 19:40:25][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:40:26.624+08:00 [2026-11-04 19:40:25][ADC_TASK] meas: seq=9400 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:40:26.624+08:00 [2026-11-04 19:40:25][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:40:36.547+08:00 [2026-11-04 19:40:35][ADC_TASK] frames=1889625 idle=0 skip=189 seq=1890006 frst_err=0 ring=1889436 adc1_rc=0 adc1_err=0 adc1_seq=1890005 adc1_gap=568 adc1_hw=0 tgap=403
[RX] 2026-11-04T19:40:36.568+08:00 [2026-11-04 19:40:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:36.568+08:00 [2026-11-04 19:40:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:36.578+08:00 [2026-11-04 19:40:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:36.589+08:00 [2026-11-04 19:40:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:36.589+08:00 [2026-11-04 19:40:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:36.599+08:00 [2026-11-04 19:40:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:40:36.599+08:00 [2026-11-04 19:40:35][ADC_TASK] adc: UA=11428 UB=0 UC=917 UN=-50 IA=11452 IB=955 IC=733 IN=848 T=883
[RX] 2026-11-04T19:40:36.610+08:00 [2026-11-04 19:40:35][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:40:36.620+08:00 [2026-11-04 19:40:35][ADC_TASK] meas: seq=9450 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:40:36.630+08:00 [2026-11-04 19:40:35][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:40:46.547+08:00 [2026-11-04 19:40:45][ADC_TASK] frames=1899623 idle=0 skip=190 seq=1900006 frst_err=0 ring=1899433 adc1_rc=0 adc1_err=0 adc1_seq=1900005 adc1_gap=571 adc1_hw=0 tgap=405
[RX] 2026-11-04T19:40:46.567+08:00 [2026-11-04 19:40:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:46.567+08:00 [2026-11-04 19:40:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:46.577+08:00 [2026-11-04 19:40:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:46.588+08:00 [2026-11-04 19:40:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:46.588+08:00 [2026-11-04 19:40:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:46.599+08:00 [2026-11-04 19:40:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:40:46.599+08:00 [2026-11-04 19:40:45][ADC_TASK] adc: UA=11429 UB=0 UC=911 UN=-48 IA=11453 IB=955 IC=730 IN=846 T=883
[RX] 2026-11-04T19:40:46.609+08:00 [2026-11-04 19:40:45][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:40:46.620+08:00 [2026-11-04 19:40:45][ADC_TASK] meas: seq=9500 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:40:46.631+08:00 [2026-11-04 19:40:45][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:40:56.546+08:00 [2026-11-04 19:40:55][ADC_TASK] frames=1909621 idle=0 skip=191 seq=1910006 frst_err=0 ring=1909430 adc1_rc=0 adc1_err=0 adc1_seq=1910005 adc1_gap=574 adc1_hw=0 tgap=407
[RX] 2026-11-04T19:40:56.566+08:00 [2026-11-04 19:40:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:56.566+08:00 [2026-11-04 19:40:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:56.577+08:00 [2026-11-04 19:40:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:56.587+08:00 [2026-11-04 19:40:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:56.587+08:00 [2026-11-04 19:40:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:40:56.597+08:00 [2026-11-04 19:40:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:40:56.608+08:00 [2026-11-04 19:40:55][ADC_TASK] adc: UA=11427 UB=0 UC=915 UN=-50 IA=11453 IB=961 IC=736 IN=849 T=886
[RX] 2026-11-04T19:40:56.608+08:00 [2026-11-04 19:40:55][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:40:56.618+08:00 [2026-11-04 19:40:55][ADC_TASK] meas: seq=9550 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:40:56.628+08:00 [2026-11-04 19:40:55][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:41:06.546+08:00 [2026-11-04 19:41:05][ADC_TASK] frames=1919619 idle=0 skip=192 seq=1920006 frst_err=0 ring=1919427 adc1_rc=0 adc1_err=0 adc1_seq=1920005 adc1_gap=577 adc1_hw=0 tgap=409
[RX] 2026-11-04T19:41:06.567+08:00 [2026-11-04 19:41:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:06.567+08:00 [2026-11-04 19:41:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:06.578+08:00 [2026-11-04 19:41:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:06.578+08:00 [2026-11-04 19:41:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:06.588+08:00 [2026-11-04 19:41:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:06.599+08:00 [2026-11-04 19:41:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:41:06.599+08:00 [2026-11-04 19:41:05][ADC_TASK] adc: UA=11429 UB=0 UC=915 UN=-48 IA=11451 IB=960 IC=734 IN=848 T=883
[RX] 2026-11-04T19:41:06.609+08:00 [2026-11-04 19:41:05][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:41:06.619+08:00 [2026-11-04 19:41:05][ADC_TASK] meas: seq=9600 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:41:06.630+08:00 [2026-11-04 19:41:05][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:41:16.550+08:00 [2026-11-04 19:41:15][ADC_TASK] frames=1929617 idle=0 skip=193 seq=1930006 frst_err=0 ring=1929424 adc1_rc=0 adc1_err=0 adc1_seq=1930005 adc1_gap=580 adc1_hw=0 tgap=411
[RX] 2026-11-04T19:41:16.560+08:00 [2026-11-04 19:41:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:16.570+08:00 [2026-11-04 19:41:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:16.581+08:00 [2026-11-04 19:41:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:16.581+08:00 [2026-11-04 19:41:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:16.591+08:00 [2026-11-04 19:41:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:16.602+08:00 [2026-11-04 19:41:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:41:16.602+08:00 [2026-11-04 19:41:15][ADC_TASK] adc: UA=11428 UB=0 UC=904 UN=-49 IA=11451 IB=951 IC=727 IN=839 T=875
[RX] 2026-11-04T19:41:16.612+08:00 [2026-11-04 19:41:15][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:41:16.622+08:00 [2026-11-04 19:41:15][ADC_TASK] meas: seq=9650 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:41:16.632+08:00 [2026-11-04 19:41:15][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:41:26.548+08:00 [2026-11-04 19:41:25][ADC_TASK] frames=1939615 idle=0 skip=194 seq=1940006 frst_err=0 ring=1939421 adc1_rc=0 adc1_err=0 adc1_seq=1940005 adc1_gap=583 adc1_hw=0 tgap=413
[RX] 2026-11-04T19:41:26.558+08:00 [2026-11-04 19:41:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:26.568+08:00 [2026-11-04 19:41:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:26.579+08:00 [2026-11-04 19:41:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:26.579+08:00 [2026-11-04 19:41:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:26.589+08:00 [2026-11-04 19:41:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:26.600+08:00 [2026-11-04 19:41:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:41:26.600+08:00 [2026-11-04 19:41:25][ADC_TASK] adc: UA=11428 UB=0 UC=923 UN=-50 IA=11452 IB=960 IC=755 IN=864 T=885
[RX] 2026-11-04T19:41:26.610+08:00 [2026-11-04 19:41:25][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:41:26.621+08:00 [2026-11-04 19:41:25][ADC_TASK] meas: seq=9700 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:41:26.631+08:00 [2026-11-04 19:41:25][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:41:36.544+08:00 [2026-11-04 19:41:35][ADC_TASK] frames=1949613 idle=0 skip=195 seq=1950006 frst_err=0 ring=1949418 adc1_rc=0 adc1_err=0 adc1_seq=1950005 adc1_gap=586 adc1_hw=0 tgap=415
[RX] 2026-11-04T19:41:36.564+08:00 [2026-11-04 19:41:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:36.564+08:00 [2026-11-04 19:41:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:36.575+08:00 [2026-11-04 19:41:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:36.586+08:00 [2026-11-04 19:41:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:36.586+08:00 [2026-11-04 19:41:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:36.596+08:00 [2026-11-04 19:41:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:41:36.607+08:00 [2026-11-04 19:41:35][ADC_TASK] adc: UA=11429 UB=0 UC=928 UN=-49 IA=11452 IB=960 IC=738 IN=858 T=889
[RX] 2026-11-04T19:41:36.607+08:00 [2026-11-04 19:41:35][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:41:36.617+08:00 [2026-11-04 19:41:35][ADC_TASK] meas: seq=9750 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:41:36.627+08:00 [2026-11-04 19:41:35][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:41:46.545+08:00 [2026-11-04 19:41:45][ADC_TASK] frames=1959611 idle=0 skip=196 seq=1960006 frst_err=0 ring=1959415 adc1_rc=0 adc1_err=0 adc1_seq=1960005 adc1_gap=589 adc1_hw=0 tgap=417
[RX] 2026-11-04T19:41:46.565+08:00 [2026-11-04 19:41:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:46.565+08:00 [2026-11-04 19:41:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:46.576+08:00 [2026-11-04 19:41:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:46.587+08:00 [2026-11-04 19:41:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:46.587+08:00 [2026-11-04 19:41:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:46.597+08:00 [2026-11-04 19:41:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:41:46.597+08:00 [2026-11-04 19:41:45][ADC_TASK] adc: UA=11428 UB=0 UC=928 UN=-50 IA=11452 IB=957 IC=736 IN=854 T=898
[RX] 2026-11-04T19:41:46.607+08:00 [2026-11-04 19:41:45][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:41:46.618+08:00 [2026-11-04 19:41:45][ADC_TASK] meas: seq=9800 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:41:46.628+08:00 [2026-11-04 19:41:45][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:41:56.553+08:00 [2026-11-04 19:41:55][ADC_TASK] frames=1969609 idle=0 skip=197 seq=1970006 frst_err=0 ring=1969412 adc1_rc=0 adc1_err=0 adc1_seq=1970005 adc1_gap=592 adc1_hw=0 tgap=419
[RX] 2026-11-04T19:41:56.563+08:00 [2026-11-04 19:41:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:56.563+08:00 [2026-11-04 19:41:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:56.574+08:00 [2026-11-04 19:41:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:56.584+08:00 [2026-11-04 19:41:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:56.595+08:00 [2026-11-04 19:41:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:41:56.595+08:00 [2026-11-04 19:41:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:41:56.605+08:00 [2026-11-04 19:41:55][ADC_TASK] adc: UA=11428 UB=0 UC=916 UN=-50 IA=11453 IB=951 IC=734 IN=847 T=893
[RX] 2026-11-04T19:41:56.605+08:00 [2026-11-04 19:41:55][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:41:56.626+08:00 [2026-11-04 19:41:55][ADC_TASK] meas: seq=9850 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:41:56.626+08:00 [2026-11-04 19:41:55][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:42:06.543+08:00 [2026-11-04 19:42:05][ADC_TASK] frames=1979607 idle=0 skip=198 seq=1980006 frst_err=0 ring=1979409 adc1_rc=0 adc1_err=0 adc1_seq=1980005 adc1_gap=595 adc1_hw=0 tgap=421
[RX] 2026-11-04T19:42:06.564+08:00 [2026-11-04 19:42:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:06.564+08:00 [2026-11-04 19:42:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:06.574+08:00 [2026-11-04 19:42:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:06.585+08:00 [2026-11-04 19:42:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:06.585+08:00 [2026-11-04 19:42:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:06.595+08:00 [2026-11-04 19:42:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:42:06.606+08:00 [2026-11-04 19:42:05][ADC_TASK] adc: UA=11428 UB=0 UC=905 UN=-48 IA=11451 IB=949 IC=726 IN=839 T=881
[RX] 2026-11-04T19:42:06.606+08:00 [2026-11-04 19:42:05][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:42:06.617+08:00 [2026-11-04 19:42:05][ADC_TASK] meas: seq=9900 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:42:06.627+08:00 [2026-11-04 19:42:05][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:42:16.553+08:00 [2026-11-04 19:42:15][ADC_TASK] frames=1989605 idle=0 skip=199 seq=1990006 frst_err=0 ring=1989406 adc1_rc=0 adc1_err=0 adc1_seq=1990005 adc1_gap=598 adc1_hw=0 tgap=423
[RX] 2026-11-04T19:42:16.563+08:00 [2026-11-04 19:42:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:16.563+08:00 [2026-11-04 19:42:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:16.574+08:00 [2026-11-04 19:42:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:16.584+08:00 [2026-11-04 19:42:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:16.594+08:00 [2026-11-04 19:42:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:16.594+08:00 [2026-11-04 19:42:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:42:16.605+08:00 [2026-11-04 19:42:15][ADC_TASK] adc: UA=11429 UB=0 UC=899 UN=-50 IA=11452 IB=943 IC=726 IN=834 T=871
[RX] 2026-11-04T19:42:16.605+08:00 [2026-11-04 19:42:15][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:42:16.615+08:00 [2026-11-04 19:42:15][ADC_TASK] meas: seq=9950 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:42:16.625+08:00 [2026-11-04 19:42:15][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:42:26.547+08:00 [2026-11-04 19:42:25][ADC_TASK] frames=1999603 idle=0 skip=200 seq=2000006 frst_err=0 ring=1999403 adc1_rc=0 adc1_err=0 adc1_seq=2000005 adc1_gap=601 adc1_hw=0 tgap=425
[RX] 2026-11-04T19:42:26.557+08:00 [2026-11-04 19:42:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:26.568+08:00 [2026-11-04 19:42:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:26.578+08:00 [2026-11-04 19:42:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:26.578+08:00 [2026-11-04 19:42:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:26.589+08:00 [2026-11-04 19:42:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:26.599+08:00 [2026-11-04 19:42:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:42:26.599+08:00 [2026-11-04 19:42:25][ADC_TASK] adc: UA=11428 UB=0 UC=913 UN=-49 IA=11451 IB=954 IC=734 IN=847 T=878
[RX] 2026-11-04T19:42:26.610+08:00 [2026-11-04 19:42:25][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:42:26.621+08:00 [2026-11-04 19:42:25][ADC_TASK] meas: seq=10000 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:42:26.621+08:00 [2026-11-04 19:42:25][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:42:36.550+08:00 [2026-11-04 19:42:35][ADC_TASK] frames=2009601 idle=0 skip=201 seq=2010006 frst_err=0 ring=2009400 adc1_rc=0 adc1_err=0 adc1_seq=2010005 adc1_gap=604 adc1_hw=0 tgap=427
[RX] 2026-11-04T19:42:36.560+08:00 [2026-11-04 19:42:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:36.571+08:00 [2026-11-04 19:42:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:36.571+08:00 [2026-11-04 19:42:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:36.581+08:00 [2026-11-04 19:42:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:36.592+08:00 [2026-11-04 19:42:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:36.592+08:00 [2026-11-04 19:42:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:42:36.602+08:00 [2026-11-04 19:42:35][ADC_TASK] adc: UA=11429 UB=0 UC=911 UN=-51 IA=11450 IB=949 IC=732 IN=846 T=875
[RX] 2026-11-04T19:42:36.613+08:00 [2026-11-04 19:42:35][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:42:36.624+08:00 [2026-11-04 19:42:35][ADC_TASK] meas: seq=10050 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:42:36.624+08:00 [2026-11-04 19:42:35][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:42:46.546+08:00 [2026-11-04 19:42:45][ADC_TASK] frames=2019599 idle=0 skip=202 seq=2020006 frst_err=0 ring=2019397 adc1_rc=0 adc1_err=0 adc1_seq=2020005 adc1_gap=607 adc1_hw=0 tgap=429
[RX] 2026-11-04T19:42:46.556+08:00 [2026-11-04 19:42:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:46.567+08:00 [2026-11-04 19:42:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:46.577+08:00 [2026-11-04 19:42:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:46.577+08:00 [2026-11-04 19:42:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:46.587+08:00 [2026-11-04 19:42:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:46.598+08:00 [2026-11-04 19:42:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:42:46.598+08:00 [2026-11-04 19:42:45][ADC_TASK] adc: UA=11428 UB=0 UC=903 UN=-49 IA=11452 IB=939 IC=727 IN=839 T=868
[RX] 2026-11-04T19:42:46.608+08:00 [2026-11-04 19:42:45][ADC_TASK] cal: ua_mv=1743 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:42:46.619+08:00 [2026-11-04 19:42:45][ADC_TASK] meas: seq=10100 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:42:46.629+08:00 [2026-11-04 19:42:45][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
[RX] 2026-11-04T19:42:56.549+08:00 [2026-11-04 19:42:55][ADC_TASK] frames=2029597 idle=0 skip=203 seq=2030006 frst_err=0 ring=2029394 adc1_rc=0 adc1_err=0 adc1_seq=2030005 adc1_gap=610 adc1_hw=0 tgap=431
[RX] 2026-11-04T19:42:56.559+08:00 [2026-11-04 19:42:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:56.570+08:00 [2026-11-04 19:42:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:56.570+08:00 [2026-11-04 19:42:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:56.581+08:00 [2026-11-04 19:42:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:56.591+08:00 [2026-11-04 19:42:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:42:56.591+08:00 [2026-11-04 19:42:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:42:56.602+08:00 [2026-11-04 19:42:55][ADC_TASK] adc: UA=11430 UB=0 UC=908 UN=-49 IA=11452 IB=944 IC=732 IN=844 T=873
[RX] 2026-11-04T19:42:56.612+08:00 [2026-11-04 19:42:55][ADC_TASK] cal: ua_mv=1744 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:42:56.623+08:00 [2026-11-04 19:42:55][ADC_TASK] meas: seq=10150 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:42:56.623+08:00 [2026-11-04 19:42:55][ADC_TASK] wave: seg=3 armed=0 src=M pts=320 err=0 ovf=0 drop=14264
@@ -0,0 +1,469 @@
# 2026-11-04 交流补测轮串口日志摘录(源:serial-assistant serial.log,gen=328,daemon 打戳 +08:00)
# 板固件: fw build: Nov 4 2026 19:05:57 suite=NONE dstr=off(HEAD 87fa0276 构建,烧录回读一致)
# 完整原始日志本机备份: ci-artifacts/ac-20261104/serial_full_backup.log(本机产物,daemon 20MB 截头保险)
# 取证注意: 19:56:47 三条 [ERR][LFT_IO]/[FTP] 是 PC 侧 FTP 探测不存在文件 V5_UP.BIN 所致(操作自归因),非固件缺陷
# 通道静态位观察: 未接线的 TPAFE 输入浮空读数 ≈1743/1747 mV(撤线后 UA/IA 出现,非损伤、非零点漂移)
# # 谐波轮 IA 复测窗(IA 满幅 50Hz → Vpp0.453/50Hz 屏显 0.160 → 250Hz 屏显 0.153 心跳带外不可见)
[RX] 2026-11-04T19:25:06.576+08:00 [2026-11-04 19:25:05][ADC_TASK] frames=959811 idle=0 skip=96 seq=960006 frst_err=0 ring=959715 adc1_rc=0 adc1_err=0 adc1_seq=960005 adc1_gap=289 adc1_hw=0 tgap=216
[RX] 2026-11-04T19:25:06.587+08:00 [2026-11-04 19:25:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:06.597+08:00 [2026-11-04 19:25:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:06.597+08:00 [2026-11-04 19:25:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:06.608+08:00 [2026-11-04 19:25:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:06.618+08:00 [2026-11-04 19:25:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:06.618+08:00 [2026-11-04 19:25:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:25:06.629+08:00 [2026-11-04 19:25:05][ADC_TASK] adc: UA=-721 UB=976 UC=1011 UN=-94 IA=11453 IB=961 IC=1030 IN=1029 T=951
[RX] 2026-11-04T19:25:06.639+08:00 [2026-11-04 19:25:05][ADC_TASK] cal: ua_mv=-110 un_mv=-14 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:25:06.649+08:00 [2026-11-04 19:25:05][ADC_TASK] meas: seq=4800 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:25:06.649+08:00 [2026-11-04 19:25:05][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:25:16.577+08:00 [2026-11-04 19:25:15][ADC_TASK] frames=969809 idle=0 skip=97 seq=970006 frst_err=0 ring=969712 adc1_rc=0 adc1_err=0 adc1_seq=970005 adc1_gap=292 adc1_hw=0 tgap=218
[RX] 2026-11-04T19:25:16.587+08:00 [2026-11-04 19:25:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:16.598+08:00 [2026-11-04 19:25:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:16.598+08:00 [2026-11-04 19:25:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:16.609+08:00 [2026-11-04 19:25:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:16.609+08:00 [2026-11-04 19:25:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:16.619+08:00 [2026-11-04 19:25:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:25:16.629+08:00 [2026-11-04 19:25:15][ADC_TASK] adc: UA=-684 UB=975 UC=1028 UN=-94 IA=11452 IB=954 IC=1030 IN=1003 T=942
[RX] 2026-11-04T19:25:16.640+08:00 [2026-11-04 19:25:15][ADC_TASK] cal: ua_mv=-104 un_mv=-14 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:25:16.650+08:00 [2026-11-04 19:25:15][ADC_TASK] meas: seq=4850 v=1 ua_mv=80 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:25:16.650+08:00 [2026-11-04 19:25:15][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:25:26.578+08:00 [2026-11-04 19:25:25][ADC_TASK] frames=979807 idle=0 skip=98 seq=980006 frst_err=0 ring=979709 adc1_rc=0 adc1_err=0 adc1_seq=980005 adc1_gap=295 adc1_hw=0 tgap=220
[RX] 2026-11-04T19:25:26.592+08:00 [2026-11-04 19:25:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:26.592+08:00 [2026-11-04 19:25:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:26.603+08:00 [2026-11-04 19:25:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:26.603+08:00 [2026-11-04 19:25:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:26.613+08:00 [2026-11-04 19:25:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:26.624+08:00 [2026-11-04 19:25:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:25:26.624+08:00 [2026-11-04 19:25:25][ADC_TASK] adc: UA=11426 UB=950 UC=1006 UN=-94 IA=-646 IB=920 IC=1010 IN=989 T=909
[RX] 2026-11-04T19:25:26.634+08:00 [2026-11-04 19:25:25][ADC_TASK] cal: ua_mv=1743 un_mv=-14 ia_mv=-98 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:25:26.644+08:00 [2026-11-04 19:25:25][ADC_TASK] meas: seq=4900 v=1 ua_mv=0 un_mv=0 ia_mv=79 f=0 fv=0
[RX] 2026-11-04T19:25:26.655+08:00 [2026-11-04 19:25:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:25:36.577+08:00 [2026-11-04 19:25:35][ADC_TASK] frames=989805 idle=0 skip=99 seq=990006 frst_err=0 ring=989706 adc1_rc=0 adc1_err=0 adc1_seq=990005 adc1_gap=298 adc1_hw=0 tgap=222
[RX] 2026-11-04T19:25:36.588+08:00 [2026-11-04 19:25:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:36.588+08:00 [2026-11-04 19:25:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:36.598+08:00 [2026-11-04 19:25:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:36.609+08:00 [2026-11-04 19:25:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:36.609+08:00 [2026-11-04 19:25:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:36.619+08:00 [2026-11-04 19:25:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:25:36.630+08:00 [2026-11-04 19:25:35][ADC_TASK] adc: UA=11427 UB=944 UC=1019 UN=-95 IA=-609 IB=923 IC=1007 IN=1024 T=923
[RX] 2026-11-04T19:25:36.630+08:00 [2026-11-04 19:25:35][ADC_TASK] cal: ua_mv=1743 un_mv=-14 ia_mv=-92 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:25:36.640+08:00 [2026-11-04 19:25:35][ADC_TASK] meas: seq=4950 v=1 ua_mv=0 un_mv=0 ia_mv=79 f=0 fv=0
[RX] 2026-11-04T19:25:36.651+08:00 [2026-11-04 19:25:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:25:46.571+08:00 [2026-11-04 19:25:45][ADC_TASK] frames=999803 idle=0 skip=100 seq=1000006 frst_err=0 ring=999703 adc1_rc=0 adc1_err=0 adc1_seq=1000005 adc1_gap=301 adc1_hw=0 tgap=224
[RX] 2026-11-04T19:25:46.592+08:00 [2026-11-04 19:25:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:46.592+08:00 [2026-11-04 19:25:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:46.602+08:00 [2026-11-04 19:25:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:46.602+08:00 [2026-11-04 19:25:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:46.613+08:00 [2026-11-04 19:25:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:46.623+08:00 [2026-11-04 19:25:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:25:46.623+08:00 [2026-11-04 19:25:45][ADC_TASK] adc: UA=11429 UB=952 UC=1003 UN=-95 IA=-573 IB=942 IC=1011 IN=1041 T=944
[RX] 2026-11-04T19:25:46.633+08:00 [2026-11-04 19:25:45][ADC_TASK] cal: ua_mv=1743 un_mv=-14 ia_mv=-87 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:25:46.644+08:00 [2026-11-04 19:25:45][ADC_TASK] meas: seq=5000 v=1 ua_mv=0 un_mv=0 ia_mv=79 f=0 fv=0
[RX] 2026-11-04T19:25:46.655+08:00 [2026-11-04 19:25:45][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:25:56.576+08:00 [2026-11-04 19:25:55][ADC_TASK] frames=1009801 idle=0 skip=101 seq=1010006 frst_err=0 ring=1009700 adc1_rc=0 adc1_err=0 adc1_seq=1010005 adc1_gap=304 adc1_hw=0 tgap=226
[RX] 2026-11-04T19:25:56.587+08:00 [2026-11-04 19:25:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=-6 Im=-7 rms=9 (x0.1)
[RX] 2026-11-04T19:25:56.597+08:00 [2026-11-04 19:25:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:56.597+08:00 [2026-11-04 19:25:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:56.608+08:00 [2026-11-04 19:25:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:56.618+08:00 [2026-11-04 19:25:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:25:56.618+08:00 [2026-11-04 19:25:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:25:56.629+08:00 [2026-11-04 19:25:55][ADC_TASK] adc: UA=11428 UB=972 UC=1016 UN=-67 IA=-4402 IB=970 IC=1026 IN=1051 T=967
[RX] 2026-11-04T19:25:56.639+08:00 [2026-11-04 19:25:55][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=-671 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:25:56.649+08:00 [2026-11-04 19:25:55][ADC_TASK] meas: seq=5050 v=1 ua_mv=0 un_mv=0 ia_mv=996 f=0 fv=0
[RX] 2026-11-04T19:25:56.649+08:00 [2026-11-04 19:25:55][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:26:06.572+08:00 [2026-11-04 19:26:05][ADC_TASK] frames=1019799 idle=0 skip=102 seq=1020006 frst_err=0 ring=1019697 adc1_rc=0 adc1_err=0 adc1_seq=1020005 adc1_gap=307 adc1_hw=0 tgap=228
[RX] 2026-11-04T19:26:06.582+08:00 [2026-11-04 19:26:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:06.593+08:00 [2026-11-04 19:26:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:06.604+08:00 [2026-11-04 19:26:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:06.604+08:00 [2026-11-04 19:26:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:06.614+08:00 [2026-11-04 19:26:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=-9 Im=1 rms=9 (x0.1)
[RX] 2026-11-04T19:26:06.624+08:00 [2026-11-04 19:26:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:26:06.624+08:00 [2026-11-04 19:26:05][ADC_TASK] adc: UA=11427 UB=993 UC=1015 UN=-73 IA=8606 IB=981 IC=1037 IN=1018 T=968
[RX] 2026-11-04T19:26:06.635+08:00 [2026-11-04 19:26:05][ADC_TASK] cal: ua_mv=1743 un_mv=-11 ia_mv=1313 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:26:06.645+08:00 [2026-11-04 19:26:05][ADC_TASK] meas: seq=5100 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:26:06.645+08:00 [2026-11-04 19:26:05][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:26:16.568+08:00 [2026-11-04 19:26:15][ADC_TASK] frames=1029797 idle=0 skip=103 seq=1030006 frst_err=0 ring=1029694 adc1_rc=0 adc1_err=0 adc1_seq=1030005 adc1_gap=310 adc1_hw=0 tgap=230
[RX] 2026-11-04T19:26:16.589+08:00 [2026-11-04 19:26:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:16.589+08:00 [2026-11-04 19:26:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:16.599+08:00 [2026-11-04 19:26:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:16.610+08:00 [2026-11-04 19:26:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:16.610+08:00 [2026-11-04 19:26:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=-7 Im=5 rms=9 (x0.1)
[RX] 2026-11-04T19:26:16.620+08:00 [2026-11-04 19:26:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:26:16.630+08:00 [2026-11-04 19:26:15][ADC_TASK] adc: UA=11427 UB=1017 UC=1043 UN=-74 IA=6925 IB=985 IC=1066 IN=1016 T=958
[RX] 2026-11-04T19:26:16.630+08:00 [2026-11-04 19:26:15][ADC_TASK] cal: ua_mv=1743 un_mv=-11 ia_mv=1056 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:26:16.641+08:00 [2026-11-04 19:26:15][ADC_TASK] meas: seq=5150 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:26:16.651+08:00 [2026-11-04 19:26:15][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:26:26.576+08:00 [2026-11-04 19:26:25][ADC_TASK] frames=1039795 idle=0 skip=104 seq=1040006 frst_err=0 ring=1039691 adc1_rc=0 adc1_err=0 adc1_seq=1040005 adc1_gap=313 adc1_hw=0 tgap=232
[RX] 2026-11-04T19:26:26.586+08:00 [2026-11-04 19:26:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:26.597+08:00 [2026-11-04 19:26:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:26.597+08:00 [2026-11-04 19:26:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:26.607+08:00 [2026-11-04 19:26:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:26.617+08:00 [2026-11-04 19:26:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=-3 Im=8 rms=9 (x0.1)
[RX] 2026-11-04T19:26:26.617+08:00 [2026-11-04 19:26:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:26:26.628+08:00 [2026-11-04 19:26:25][ADC_TASK] adc: UA=11428 UB=1024 UC=1016 UN=-70 IA=3574 IB=962 IC=1071 IN=1029 T=932
[RX] 2026-11-04T19:26:26.638+08:00 [2026-11-04 19:26:25][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=545 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:26:26.648+08:00 [2026-11-04 19:26:25][ADC_TASK] meas: seq=5200 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:26:26.648+08:00 [2026-11-04 19:26:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:26:36.575+08:00 [2026-11-04 19:26:35][ADC_TASK] frames=1049793 idle=0 skip=105 seq=1050006 frst_err=0 ring=1049688 adc1_rc=0 adc1_err=0 adc1_seq=1050005 adc1_gap=316 adc1_hw=0 tgap=234
[RX] 2026-11-04T19:26:36.585+08:00 [2026-11-04 19:26:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:36.596+08:00 [2026-11-04 19:26:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:36.596+08:00 [2026-11-04 19:26:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:36.607+08:00 [2026-11-04 19:26:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:36.617+08:00 [2026-11-04 19:26:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=9 rms=9 (x0.1)
[RX] 2026-11-04T19:26:36.617+08:00 [2026-11-04 19:26:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:26:36.628+08:00 [2026-11-04 19:26:35][ADC_TASK] adc: UA=11428 UB=1020 UC=1008 UN=-73 IA=-668 IB=959 IC=1072 IN=1039 T=948
[RX] 2026-11-04T19:26:36.638+08:00 [2026-11-04 19:26:35][ADC_TASK] cal: ua_mv=1743 un_mv=-11 ia_mv=-101 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:26:36.648+08:00 [2026-11-04 19:26:35][ADC_TASK] meas: seq=5250 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:26:36.648+08:00 [2026-11-04 19:26:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:26:46.567+08:00 [2026-11-04 19:26:45][ADC_TASK] frames=1059791 idle=0 skip=106 seq=1060006 frst_err=0 ring=1059685 adc1_rc=0 adc1_err=0 adc1_seq=1060005 adc1_gap=319 adc1_hw=0 tgap=236
[RX] 2026-11-04T19:26:46.588+08:00 [2026-11-04 19:26:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:46.588+08:00 [2026-11-04 19:26:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:46.598+08:00 [2026-11-04 19:26:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:46.608+08:00 [2026-11-04 19:26:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:46.608+08:00 [2026-11-04 19:26:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=5 Im=7 rms=9 (x0.1)
[RX] 2026-11-04T19:26:46.619+08:00 [2026-11-04 19:26:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:26:46.629+08:00 [2026-11-04 19:26:45][ADC_TASK] adc: UA=11428 UB=1016 UC=1009 UN=-71 IA=-4770 IB=972 IC=1091 IN=1051 T=963
[RX] 2026-11-04T19:26:46.629+08:00 [2026-11-04 19:26:45][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=-727 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:26:46.639+08:00 [2026-11-04 19:26:45][ADC_TASK] meas: seq=5300 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:26:46.650+08:00 [2026-11-04 19:26:45][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:26:56.575+08:00 [2026-11-04 19:26:55][ADC_TASK] frames=1069789 idle=0 skip=107 seq=1070006 frst_err=0 ring=1069682 adc1_rc=0 adc1_err=0 adc1_seq=1070005 adc1_gap=322 adc1_hw=0 tgap=238
[RX] 2026-11-04T19:26:56.585+08:00 [2026-11-04 19:26:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:56.595+08:00 [2026-11-04 19:26:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:56.595+08:00 [2026-11-04 19:26:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:56.605+08:00 [2026-11-04 19:26:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:26:56.616+08:00 [2026-11-04 19:26:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=8 Im=4 rms=9 (x0.1)
[RX] 2026-11-04T19:26:56.616+08:00 [2026-11-04 19:26:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:26:56.626+08:00 [2026-11-04 19:26:55][ADC_TASK] adc: UA=11428 UB=1018 UC=1019 UN=-70 IA=-7743 IB=980 IC=1101 IN=1063 T=965
[RX] 2026-11-04T19:26:56.637+08:00 [2026-11-04 19:26:55][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=-1181 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:26:56.647+08:00 [2026-11-04 19:26:55][ADC_TASK] meas: seq=5350 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:26:56.647+08:00 [2026-11-04 19:26:55][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:27:06.575+08:00 [2026-11-04 19:27:05][ADC_TASK] frames=1079787 idle=0 skip=108 seq=1080006 frst_err=0 ring=1079679 adc1_rc=0 adc1_err=0 adc1_seq=1080005 adc1_gap=325 adc1_hw=0 tgap=240
[RX] 2026-11-04T19:27:06.585+08:00 [2026-11-04 19:27:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:06.585+08:00 [2026-11-04 19:27:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:06.596+08:00 [2026-11-04 19:27:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:06.607+08:00 [2026-11-04 19:27:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:06.617+08:00 [2026-11-04 19:27:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=9 Im=0 rms=9 (x0.1)
[RX] 2026-11-04T19:27:06.617+08:00 [2026-11-04 19:27:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:27:06.628+08:00 [2026-11-04 19:27:05][ADC_TASK] adc: UA=11429 UB=1018 UC=1026 UN=-69 IA=-8862 IB=977 IC=1091 IN=1065 T=955
[RX] 2026-11-04T19:27:06.628+08:00 [2026-11-04 19:27:05][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=-1352 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:27:06.639+08:00 [2026-11-04 19:27:05][ADC_TASK] meas: seq=5400 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:27:06.649+08:00 [2026-11-04 19:27:05][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:27:16.573+08:00 [2026-11-04 19:27:15][ADC_TASK] frames=1089785 idle=0 skip=109 seq=1090006 frst_err=0 ring=1089676 adc1_rc=0 adc1_err=0 adc1_seq=1090005 adc1_gap=328 adc1_hw=0 tgap=242
[RX] 2026-11-04T19:27:16.583+08:00 [2026-11-04 19:27:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:16.593+08:00 [2026-11-04 19:27:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:16.593+08:00 [2026-11-04 19:27:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:16.604+08:00 [2026-11-04 19:27:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:16.614+08:00 [2026-11-04 19:27:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=1 Im=0 rms=1 (x0.1)
[RX] 2026-11-04T19:27:16.614+08:00 [2026-11-04 19:27:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:27:16.625+08:00 [2026-11-04 19:27:15][ADC_TASK] adc: UA=11427 UB=1033 UC=1040 UN=-72 IA=-1264 IB=972 IC=1079 IN=1065 T=939
[RX] 2026-11-04T19:27:16.635+08:00 [2026-11-04 19:27:15][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=-192 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:27:16.646+08:00 [2026-11-04 19:27:15][ADC_TASK] meas: seq=5450 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:27:16.646+08:00 [2026-11-04 19:27:15][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:27:26.571+08:00 [2026-11-04 19:27:25][ADC_TASK] frames=1099783 idle=0 skip=110 seq=1100006 frst_err=0 ring=1099673 adc1_rc=0 adc1_err=0 adc1_seq=1100005 adc1_gap=331 adc1_hw=0 tgap=244
[RX] 2026-11-04T19:27:26.582+08:00 [2026-11-04 19:27:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:26.592+08:00 [2026-11-04 19:27:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:26.602+08:00 [2026-11-04 19:27:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:26.602+08:00 [2026-11-04 19:27:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:26.613+08:00 [2026-11-04 19:27:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=-1 rms=1 (x0.1)
[RX] 2026-11-04T19:27:26.613+08:00 [2026-11-04 19:27:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:27:26.623+08:00 [2026-11-04 19:27:25][ADC_TASK] adc: UA=11429 UB=1028 UC=1023 UN=-69 IA=-876 IB=952 IC=1061 IN=1043 T=925
[RX] 2026-11-04T19:27:26.634+08:00 [2026-11-04 19:27:25][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=-133 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:27:26.644+08:00 [2026-11-04 19:27:25][ADC_TASK] meas: seq=5500 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:27:26.644+08:00 [2026-11-04 19:27:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:27:36.568+08:00 [2026-11-04 19:27:35][ADC_TASK] frames=1109781 idle=0 skip=111 seq=1110006 frst_err=0 ring=1109670 adc1_rc=0 adc1_err=0 adc1_seq=1110005 adc1_gap=334 adc1_hw=0 tgap=246
[RX] 2026-11-04T19:27:36.589+08:00 [2026-11-04 19:27:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:36.589+08:00 [2026-11-04 19:27:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:36.599+08:00 [2026-11-04 19:27:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:36.599+08:00 [2026-11-04 19:27:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:36.609+08:00 [2026-11-04 19:27:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=-1 rms=1 (x0.1)
[RX] 2026-11-04T19:27:36.620+08:00 [2026-11-04 19:27:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:27:36.620+08:00 [2026-11-04 19:27:35][ADC_TASK] adc: UA=11429 UB=998 UC=999 UN=-70 IA=-228 IB=942 IC=1066 IN=1029 T=937
[RX] 2026-11-04T19:27:36.631+08:00 [2026-11-04 19:27:35][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=-34 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:27:36.641+08:00 [2026-11-04 19:27:35][ADC_TASK] meas: seq=5550 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:27:36.651+08:00 [2026-11-04 19:27:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:27:46.573+08:00 [2026-11-04 19:27:45][ADC_TASK] frames=1119779 idle=0 skip=112 seq=1120006 frst_err=0 ring=1119667 adc1_rc=0 adc1_err=0 adc1_seq=1120005 adc1_gap=337 adc1_hw=0 tgap=248
[RX] 2026-11-04T19:27:46.583+08:00 [2026-11-04 19:27:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:46.593+08:00 [2026-11-04 19:27:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:46.593+08:00 [2026-11-04 19:27:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:46.604+08:00 [2026-11-04 19:27:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:46.615+08:00 [2026-11-04 19:27:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=-1 rms=1 (x0.1)
[RX] 2026-11-04T19:27:46.615+08:00 [2026-11-04 19:27:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:27:46.625+08:00 [2026-11-04 19:27:45][ADC_TASK] adc: UA=11429 UB=994 UC=1007 UN=-72 IA=458 IB=963 IC=1085 IN=1048 T=958
[RX] 2026-11-04T19:27:46.636+08:00 [2026-11-04 19:27:45][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=69 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:27:46.646+08:00 [2026-11-04 19:27:45][ADC_TASK] meas: seq=5600 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:27:46.646+08:00 [2026-11-04 19:27:45][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:27:56.570+08:00 [2026-11-04 19:27:55][ADC_TASK] frames=1129777 idle=0 skip=113 seq=1130006 frst_err=0 ring=1129664 adc1_rc=0 adc1_err=0 adc1_seq=1130005 adc1_gap=340 adc1_hw=0 tgap=250
[RX] 2026-11-04T19:27:56.580+08:00 [2026-11-04 19:27:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:56.591+08:00 [2026-11-04 19:27:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:56.601+08:00 [2026-11-04 19:27:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:56.601+08:00 [2026-11-04 19:27:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:27:56.612+08:00 [2026-11-04 19:27:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=-1 Im=0 rms=1 (x0.1)
[RX] 2026-11-04T19:27:56.622+08:00 [2026-11-04 19:27:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:27:56.622+08:00 [2026-11-04 19:27:55][ADC_TASK] adc: UA=11429 UB=995 UC=1009 UN=-71 IA=1015 IB=971 IC=1077 IN=1046 T=957
[RX] 2026-11-04T19:27:56.632+08:00 [2026-11-04 19:27:55][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=154 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:27:56.643+08:00 [2026-11-04 19:27:55][ADC_TASK] meas: seq=5650 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:27:56.643+08:00 [2026-11-04 19:27:55][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:28:06.574+08:00 [2026-11-04 19:28:05][ADC_TASK] frames=1139775 idle=0 skip=114 seq=1140006 frst_err=0 ring=1139661 adc1_rc=0 adc1_err=0 adc1_seq=1140005 adc1_gap=343 adc1_hw=0 tgap=252
[RX] 2026-11-04T19:28:06.584+08:00 [2026-11-04 19:28:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:06.584+08:00 [2026-11-04 19:28:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:06.595+08:00 [2026-11-04 19:28:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:06.606+08:00 [2026-11-04 19:28:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:06.616+08:00 [2026-11-04 19:28:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=-1 Im=0 rms=1 (x0.1)
[RX] 2026-11-04T19:28:06.616+08:00 [2026-11-04 19:28:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:28:06.626+08:00 [2026-11-04 19:28:05][ADC_TASK] adc: UA=11428 UB=1006 UC=1006 UN=-72 IA=1311 IB=973 IC=1075 IN=1042 T=959
[RX] 2026-11-04T19:28:06.626+08:00 [2026-11-04 19:28:05][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=200 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:28:06.637+08:00 [2026-11-04 19:28:05][ADC_TASK] meas: seq=5700 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:28:06.648+08:00 [2026-11-04 19:28:05][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:28:16.570+08:00 [2026-11-04 19:28:15][ADC_TASK] frames=1149773 idle=0 skip=115 seq=1150006 frst_err=0 ring=1149658 adc1_rc=0 adc1_err=0 adc1_seq=1150005 adc1_gap=346 adc1_hw=0 tgap=254
[RX] 2026-11-04T19:28:16.581+08:00 [2026-11-04 19:28:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:16.591+08:00 [2026-11-04 19:28:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:16.601+08:00 [2026-11-04 19:28:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:16.601+08:00 [2026-11-04 19:28:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:16.611+08:00 [2026-11-04 19:28:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=-1 Im=0 rms=1 (x0.1)
[RX] 2026-11-04T19:28:16.622+08:00 [2026-11-04 19:28:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:28:16.622+08:00 [2026-11-04 19:28:15][ADC_TASK] adc: UA=11429 UB=1035 UC=1028 UN=-74 IA=1275 IB=995 IC=1093 IN=1065 T=975
[RX] 2026-11-04T19:28:16.633+08:00 [2026-11-04 19:28:15][ADC_TASK] cal: ua_mv=1743 un_mv=-11 ia_mv=194 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:28:16.643+08:00 [2026-11-04 19:28:15][ADC_TASK] meas: seq=5750 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:28:16.643+08:00 [2026-11-04 19:28:15][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:28:26.566+08:00 [2026-11-04 19:28:25][ADC_TASK] frames=1159771 idle=0 skip=116 seq=1160006 frst_err=0 ring=1159655 adc1_rc=0 adc1_err=0 adc1_seq=1160005 adc1_gap=349 adc1_hw=0 tgap=256
[RX] 2026-11-04T19:28:26.587+08:00 [2026-11-04 19:28:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:26.587+08:00 [2026-11-04 19:28:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:26.598+08:00 [2026-11-04 19:28:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:26.598+08:00 [2026-11-04 19:28:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:26.608+08:00 [2026-11-04 19:28:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=-1 Im=1 rms=1 (x0.1)
[RX] 2026-11-04T19:28:26.619+08:00 [2026-11-04 19:28:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:28:26.619+08:00 [2026-11-04 19:28:25][ADC_TASK] adc: UA=11427 UB=1047 UC=1027 UN=-75 IA=915 IB=989 IC=1071 IN=1054 T=960
[RX] 2026-11-04T19:28:26.629+08:00 [2026-11-04 19:28:25][ADC_TASK] cal: ua_mv=1743 un_mv=-11 ia_mv=139 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:28:26.640+08:00 [2026-11-04 19:28:25][ADC_TASK] meas: seq=5800 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:28:26.650+08:00 [2026-11-04 19:28:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:28:36.566+08:00 [2026-11-04 19:28:35][ADC_TASK] frames=1169769 idle=0 skip=117 seq=1170006 frst_err=0 ring=1169652 adc1_rc=0 adc1_err=0 adc1_seq=1170005 adc1_gap=352 adc1_hw=0 tgap=258
[RX] 2026-11-04T19:28:36.587+08:00 [2026-11-04 19:28:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=-1 rms=1 (x0.1)
[RX] 2026-11-04T19:28:36.587+08:00 [2026-11-04 19:28:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:36.597+08:00 [2026-11-04 19:28:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:36.597+08:00 [2026-11-04 19:28:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:36.608+08:00 [2026-11-04 19:28:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:36.618+08:00 [2026-11-04 19:28:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:28:36.618+08:00 [2026-11-04 19:28:35][ADC_TASK] adc: UA=11428 UB=1038 UC=1002 UN=-75 IA=-1555 IB=970 IC=1054 IN=1028 T=946
[RX] 2026-11-04T19:28:36.628+08:00 [2026-11-04 19:28:35][ADC_TASK] cal: ua_mv=1743 un_mv=-11 ia_mv=-237 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:28:36.639+08:00 [2026-11-04 19:28:35][ADC_TASK] meas: seq=5850 v=1 ua_mv=0 un_mv=0 ia_mv=159 f=0 fv=0
[RX] 2026-11-04T19:28:36.649+08:00 [2026-11-04 19:28:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:28:46.570+08:00 [2026-11-04 19:28:45][ADC_TASK] frames=1179767 idle=0 skip=118 seq=1180006 frst_err=0 ring=1179649 adc1_rc=0 adc1_err=0 adc1_seq=1180005 adc1_gap=355 adc1_hw=0 tgap=260
[RX] 2026-11-04T19:28:46.580+08:00 [2026-11-04 19:28:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=-1 rms=1 (x0.1)
[RX] 2026-11-04T19:28:46.590+08:00 [2026-11-04 19:28:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:46.601+08:00 [2026-11-04 19:28:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:46.601+08:00 [2026-11-04 19:28:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:46.611+08:00 [2026-11-04 19:28:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:46.611+08:00 [2026-11-04 19:28:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:28:46.622+08:00 [2026-11-04 19:28:45][ADC_TASK] adc: UA=11428 UB=1035 UC=1002 UN=-72 IA=-1540 IB=973 IC=1052 IN=1022 T=955
[RX] 2026-11-04T19:28:46.632+08:00 [2026-11-04 19:28:45][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=-234 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:28:46.643+08:00 [2026-11-04 19:28:45][ADC_TASK] meas: seq=5900 v=1 ua_mv=0 un_mv=0 ia_mv=160 f=0 fv=0
[RX] 2026-11-04T19:28:46.643+08:00 [2026-11-04 19:28:45][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:28:56.566+08:00 [2026-11-04 19:28:55][ADC_TASK] frames=1189765 idle=0 skip=119 seq=1190006 frst_err=0 ring=1189646 adc1_rc=0 adc1_err=0 adc1_seq=1190005 adc1_gap=358 adc1_hw=0 tgap=262
[RX] 2026-11-04T19:28:56.588+08:00 [2026-11-04 19:28:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=-1 rms=1 (x0.1)
[RX] 2026-11-04T19:28:56.588+08:00 [2026-11-04 19:28:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:56.598+08:00 [2026-11-04 19:28:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:56.598+08:00 [2026-11-04 19:28:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:56.609+08:00 [2026-11-04 19:28:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:28:56.619+08:00 [2026-11-04 19:28:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:28:56.619+08:00 [2026-11-04 19:28:55][ADC_TASK] adc: UA=11427 UB=1042 UC=1032 UN=-74 IA=-1509 IB=989 IC=1058 IN=1026 T=971
[RX] 2026-11-04T19:28:56.629+08:00 [2026-11-04 19:28:55][ADC_TASK] cal: ua_mv=1743 un_mv=-11 ia_mv=-230 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:28:56.640+08:00 [2026-11-04 19:28:55][ADC_TASK] meas: seq=5950 v=1 ua_mv=0 un_mv=0 ia_mv=160 f=0 fv=0
[RX] 2026-11-04T19:28:56.650+08:00 [2026-11-04 19:28:55][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:29:06.565+08:00 [2026-11-04 19:29:05][ADC_TASK] frames=1199763 idle=0 skip=120 seq=1200006 frst_err=0 ring=1199643 adc1_rc=0 adc1_err=0 adc1_seq=1200005 adc1_gap=361 adc1_hw=0 tgap=264
[RX] 2026-11-04T19:29:06.585+08:00 [2026-11-04 19:29:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=-1 rms=1 (x0.1)
[RX] 2026-11-04T19:29:06.585+08:00 [2026-11-04 19:29:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:06.596+08:00 [2026-11-04 19:29:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:06.596+08:00 [2026-11-04 19:29:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:06.607+08:00 [2026-11-04 19:29:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:06.617+08:00 [2026-11-04 19:29:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:29:06.617+08:00 [2026-11-04 19:29:05][ADC_TASK] adc: UA=11427 UB=1033 UC=1038 UN=-72 IA=-1464 IB=973 IC=1041 IN=1007 T=942
[RX] 2026-11-04T19:29:06.627+08:00 [2026-11-04 19:29:05][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=-223 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:29:06.638+08:00 [2026-11-04 19:29:05][ADC_TASK] meas: seq=6000 v=1 ua_mv=0 un_mv=0 ia_mv=160 f=0 fv=0
[RX] 2026-11-04T19:29:06.648+08:00 [2026-11-04 19:29:05][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:29:16.570+08:00 [2026-11-04 19:29:15][ADC_TASK] frames=1209761 idle=0 skip=121 seq=1210006 frst_err=0 ring=1209640 adc1_rc=0 adc1_err=0 adc1_seq=1210005 adc1_gap=364 adc1_hw=0 tgap=266
[RX] 2026-11-04T19:29:16.580+08:00 [2026-11-04 19:29:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=-1 rms=1 (x0.1)
[RX] 2026-11-04T19:29:16.591+08:00 [2026-11-04 19:29:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:16.591+08:00 [2026-11-04 19:29:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:16.601+08:00 [2026-11-04 19:29:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:16.612+08:00 [2026-11-04 19:29:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:16.612+08:00 [2026-11-04 19:29:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:29:16.622+08:00 [2026-11-04 19:29:15][ADC_TASK] adc: UA=11429 UB=1038 UC=1052 UN=-69 IA=-1406 IB=965 IC=1051 IN=1012 T=939
[RX] 2026-11-04T19:29:16.632+08:00 [2026-11-04 19:29:15][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=-214 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:29:16.643+08:00 [2026-11-04 19:29:15][ADC_TASK] meas: seq=6050 v=1 ua_mv=0 un_mv=0 ia_mv=160 f=0 fv=0
[RX] 2026-11-04T19:29:16.643+08:00 [2026-11-04 19:29:15][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:29:26.564+08:00 [2026-11-04 19:29:25][ADC_TASK] frames=1219759 idle=0 skip=122 seq=1220006 frst_err=0 ring=1219637 adc1_rc=0 adc1_err=0 adc1_seq=1220005 adc1_gap=367 adc1_hw=0 tgap=268
[RX] 2026-11-04T19:29:26.584+08:00 [2026-11-04 19:29:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=-1 rms=1 (x0.1)
[RX] 2026-11-04T19:29:26.584+08:00 [2026-11-04 19:29:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:26.595+08:00 [2026-11-04 19:29:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:26.606+08:00 [2026-11-04 19:29:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:26.606+08:00 [2026-11-04 19:29:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:26.616+08:00 [2026-11-04 19:29:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:29:26.616+08:00 [2026-11-04 19:29:25][ADC_TASK] adc: UA=11428 UB=1007 UC=1037 UN=-69 IA=-1333 IB=942 IC=1049 IN=1000 T=923
[RX] 2026-11-04T19:29:26.626+08:00 [2026-11-04 19:29:25][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=-203 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:29:26.637+08:00 [2026-11-04 19:29:25][ADC_TASK] meas: seq=6100 v=1 ua_mv=0 un_mv=0 ia_mv=159 f=0 fv=0
[RX] 2026-11-04T19:29:26.647+08:00 [2026-11-04 19:29:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:29:36.564+08:00 [2026-11-04 19:29:35][ADC_TASK] frames=1229757 idle=0 skip=123 seq=1230006 frst_err=0 ring=1229634 adc1_rc=0 adc1_err=0 adc1_seq=1230005 adc1_gap=370 adc1_hw=0 tgap=270
[RX] 2026-11-04T19:29:36.585+08:00 [2026-11-04 19:29:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:36.585+08:00 [2026-11-04 19:29:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:36.596+08:00 [2026-11-04 19:29:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:36.596+08:00 [2026-11-04 19:29:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:36.606+08:00 [2026-11-04 19:29:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:36.617+08:00 [2026-11-04 19:29:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:29:36.617+08:00 [2026-11-04 19:29:35][ADC_TASK] adc: UA=11428 UB=1003 UC=1050 UN=-42 IA=-42 IB=948 IC=1078 IN=1034 T=932
[RX] 2026-11-04T19:29:36.627+08:00 [2026-11-04 19:29:35][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:29:36.638+08:00 [2026-11-04 19:29:35][ADC_TASK] meas: seq=6150 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:29:36.648+08:00 [2026-11-04 19:29:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:29:46.565+08:00 [2026-11-04 19:29:45][ADC_TASK] frames=1239755 idle=0 skip=124 seq=1240006 frst_err=0 ring=1239631 adc1_rc=0 adc1_err=0 adc1_seq=1240005 adc1_gap=373 adc1_hw=0 tgap=272
[RX] 2026-11-04T19:29:46.586+08:00 [2026-11-04 19:29:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:46.586+08:00 [2026-11-04 19:29:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:46.596+08:00 [2026-11-04 19:29:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:46.596+08:00 [2026-11-04 19:29:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:46.606+08:00 [2026-11-04 19:29:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:46.617+08:00 [2026-11-04 19:29:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:29:46.617+08:00 [2026-11-04 19:29:45][ADC_TASK] adc: UA=11428 UB=990 UC=1018 UN=-41 IA=-41 IB=945 IC=1083 IN=1045 T=934
[RX] 2026-11-04T19:29:46.628+08:00 [2026-11-04 19:29:45][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:29:46.638+08:00 [2026-11-04 19:29:45][ADC_TASK] meas: seq=6200 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:29:46.649+08:00 [2026-11-04 19:29:45][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:29:56.570+08:00 [2026-11-04 19:29:55][ADC_TASK] frames=1249753 idle=0 skip=125 seq=1250006 frst_err=0 ring=1249628 adc1_rc=0 adc1_err=0 adc1_seq=1250005 adc1_gap=376 adc1_hw=0 tgap=274
[RX] 2026-11-04T19:29:56.580+08:00 [2026-11-04 19:29:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:56.591+08:00 [2026-11-04 19:29:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:56.591+08:00 [2026-11-04 19:29:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:56.602+08:00 [2026-11-04 19:29:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:56.612+08:00 [2026-11-04 19:29:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:29:56.612+08:00 [2026-11-04 19:29:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:29:56.622+08:00 [2026-11-04 19:29:55][ADC_TASK] adc: UA=11430 UB=985 UC=1017 UN=-70 IA=-85 IB=959 IC=1079 IN=1054 T=958
[RX] 2026-11-04T19:29:56.633+08:00 [2026-11-04 19:29:55][ADC_TASK] cal: ua_mv=1744 un_mv=-10 ia_mv=-12 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:29:56.643+08:00 [2026-11-04 19:29:55][ADC_TASK] meas: seq=6250 v=1 ua_mv=0 un_mv=0 ia_mv=3 f=0 fv=0
[RX] 2026-11-04T19:29:56.643+08:00 [2026-11-04 19:29:55][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:30:06.563+08:00 [2026-11-04 19:30:05][ADC_TASK] frames=1259751 idle=0 skip=126 seq=1260006 frst_err=0 ring=1259625 adc1_rc=0 adc1_err=0 adc1_seq=1260005 adc1_gap=379 adc1_hw=0 tgap=276
[RX] 2026-11-04T19:30:06.584+08:00 [2026-11-04 19:30:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=1 (x0.1)
[RX] 2026-11-04T19:30:06.584+08:00 [2026-11-04 19:30:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:06.594+08:00 [2026-11-04 19:30:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:06.605+08:00 [2026-11-04 19:30:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=-1 rms=1 (x0.1)
[RX] 2026-11-04T19:30:06.605+08:00 [2026-11-04 19:30:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:06.615+08:00 [2026-11-04 19:30:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:30:06.615+08:00 [2026-11-04 19:30:05][ADC_TASK] adc: UA=11429 UB=989 UC=1006 UN=-68 IA=-1469 IB=972 IC=1066 IN=1038 T=964
[RX] 2026-11-04T19:30:06.626+08:00 [2026-11-04 19:30:05][ADC_TASK] cal: ua_mv=1743 un_mv=-10 ia_mv=-224 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:30:06.637+08:00 [2026-11-04 19:30:05][ADC_TASK] meas: seq=6300 v=1 ua_mv=0 un_mv=0 ia_mv=109 f=0 fv=0
[RX] 2026-11-04T19:30:06.647+08:00 [2026-11-04 19:30:05][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:30:16.562+08:00 [2026-11-04 19:30:15][ADC_TASK] frames=1269749 idle=0 skip=127 seq=1270006 frst_err=0 ring=1269622 adc1_rc=0 adc1_err=0 adc1_seq=1270005 adc1_gap=382 adc1_hw=0 tgap=278
[RX] 2026-11-04T19:30:16.583+08:00 [2026-11-04 19:30:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:16.583+08:00 [2026-11-04 19:30:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:16.594+08:00 [2026-11-04 19:30:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:16.604+08:00 [2026-11-04 19:30:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:16.604+08:00 [2026-11-04 19:30:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:16.615+08:00 [2026-11-04 19:30:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:30:16.615+08:00 [2026-11-04 19:30:15][ADC_TASK] adc: UA=11428 UB=1001 UC=991 UN=-41 IA=-41 IB=973 IC=1062 IN=1028 T=954
[RX] 2026-11-04T19:30:16.626+08:00 [2026-11-04 19:30:15][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:30:16.636+08:00 [2026-11-04 19:30:15][ADC_TASK] meas: seq=6350 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:30:16.647+08:00 [2026-11-04 19:30:15][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:30:26.570+08:00 [2026-11-04 19:30:25][ADC_TASK] frames=1279747 idle=0 skip=128 seq=1280006 frst_err=0 ring=1279619 adc1_rc=0 adc1_err=0 adc1_seq=1280005 adc1_gap=385 adc1_hw=0 tgap=280
[RX] 2026-11-04T19:30:26.581+08:00 [2026-11-04 19:30:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:26.581+08:00 [2026-11-04 19:30:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:26.591+08:00 [2026-11-04 19:30:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:26.602+08:00 [2026-11-04 19:30:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:26.612+08:00 [2026-11-04 19:30:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:26.612+08:00 [2026-11-04 19:30:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:30:26.622+08:00 [2026-11-04 19:30:25][ADC_TASK] adc: UA=11429 UB=1019 UC=997 UN=-43 IA=-41 IB=975 IC=1079 IN=1045 T=954
[RX] 2026-11-04T19:30:26.622+08:00 [2026-11-04 19:30:25][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:30:26.643+08:00 [2026-11-04 19:30:25][ADC_TASK] meas: seq=6400 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:30:26.643+08:00 [2026-11-04 19:30:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:30:36.564+08:00 [2026-11-04 19:30:35][ADC_TASK] frames=1289745 idle=0 skip=129 seq=1290006 frst_err=0 ring=1289616 adc1_rc=0 adc1_err=0 adc1_seq=1290005 adc1_gap=388 adc1_hw=0 tgap=282
[RX] 2026-11-04T19:30:36.574+08:00 [2026-11-04 19:30:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:36.585+08:00 [2026-11-04 19:30:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:36.595+08:00 [2026-11-04 19:30:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:36.595+08:00 [2026-11-04 19:30:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:36.606+08:00 [2026-11-04 19:30:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:36.616+08:00 [2026-11-04 19:30:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:30:36.616+08:00 [2026-11-04 19:30:35][ADC_TASK] adc: UA=11429 UB=1037 UC=1018 UN=-41 IA=-40 IB=983 IC=1082 IN=1057 T=966
[RX] 2026-11-04T19:30:36.627+08:00 [2026-11-04 19:30:35][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:30:36.637+08:00 [2026-11-04 19:30:35][ADC_TASK] meas: seq=6450 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:30:36.648+08:00 [2026-11-04 19:30:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:30:46.570+08:00 [2026-11-04 19:30:45][ADC_TASK] frames=1299743 idle=0 skip=130 seq=1300006 frst_err=0 ring=1299613 adc1_rc=0 adc1_err=0 adc1_seq=1300005 adc1_gap=391 adc1_hw=0 tgap=284
[RX] 2026-11-04T19:30:46.580+08:00 [2026-11-04 19:30:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:46.580+08:00 [2026-11-04 19:30:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:46.591+08:00 [2026-11-04 19:30:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:46.601+08:00 [2026-11-04 19:30:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:46.612+08:00 [2026-11-04 19:30:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:46.612+08:00 [2026-11-04 19:30:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:30:46.622+08:00 [2026-11-04 19:30:45][ADC_TASK] adc: UA=11428 UB=1029 UC=1003 UN=-43 IA=-41 IB=978 IC=1054 IN=1032 T=963
[RX] 2026-11-04T19:30:46.622+08:00 [2026-11-04 19:30:45][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:30:46.643+08:00 [2026-11-04 19:30:45][ADC_TASK] meas: seq=6500 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:30:46.643+08:00 [2026-11-04 19:30:45][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:30:56.566+08:00 [2026-11-04 19:30:55][ADC_TASK] frames=1309741 idle=0 skip=131 seq=1310006 frst_err=0 ring=1309610 adc1_rc=0 adc1_err=0 adc1_seq=1310005 adc1_gap=394 adc1_hw=0 tgap=286
[RX] 2026-11-04T19:30:56.576+08:00 [2026-11-04 19:30:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:56.586+08:00 [2026-11-04 19:30:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:56.596+08:00 [2026-11-04 19:30:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:56.596+08:00 [2026-11-04 19:30:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:56.607+08:00 [2026-11-04 19:30:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:30:56.618+08:00 [2026-11-04 19:30:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:30:56.618+08:00 [2026-11-04 19:30:55][ADC_TASK] adc: UA=11429 UB=1043 UC=1020 UN=-43 IA=-42 IB=993 IC=1053 IN=1026 T=971
[RX] 2026-11-04T19:30:56.628+08:00 [2026-11-04 19:30:55][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:30:56.639+08:00 [2026-11-04 19:30:55][ADC_TASK] meas: seq=6550 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:30:56.639+08:00 [2026-11-04 19:30:55][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:31:06.562+08:00 [2026-11-04 19:31:05][ADC_TASK] frames=1319739 idle=0 skip=132 seq=1320006 frst_err=0 ring=1319607 adc1_rc=0 adc1_err=0 adc1_seq=1320005 adc1_gap=397 adc1_hw=0 tgap=288
[RX] 2026-11-04T19:31:06.583+08:00 [2026-11-04 19:31:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:06.583+08:00 [2026-11-04 19:31:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:06.593+08:00 [2026-11-04 19:31:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:06.603+08:00 [2026-11-04 19:31:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:06.603+08:00 [2026-11-04 19:31:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:06.614+08:00 [2026-11-04 19:31:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:31:06.614+08:00 [2026-11-04 19:31:05][ADC_TASK] adc: UA=11429 UB=1043 UC=1042 UN=-41 IA=-40 IB=986 IC=1046 IN=1010 T=954
[RX] 2026-11-04T19:31:06.624+08:00 [2026-11-04 19:31:05][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:31:06.635+08:00 [2026-11-04 19:31:05][ADC_TASK] meas: seq=6600 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:31:06.645+08:00 [2026-11-04 19:31:05][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:31:16.561+08:00 [2026-11-04 19:31:15][ADC_TASK] frames=1329737 idle=0 skip=133 seq=1330006 frst_err=0 ring=1329604 adc1_rc=0 adc1_err=0 adc1_seq=1330005 adc1_gap=400 adc1_hw=0 tgap=290
[RX] 2026-11-04T19:31:16.582+08:00 [2026-11-04 19:31:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:16.582+08:00 [2026-11-04 19:31:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:16.593+08:00 [2026-11-04 19:31:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:16.603+08:00 [2026-11-04 19:31:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:16.603+08:00 [2026-11-04 19:31:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:16.613+08:00 [2026-11-04 19:31:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:31:16.613+08:00 [2026-11-04 19:31:15][ADC_TASK] adc: UA=11429 UB=1038 UC=1042 UN=-41 IA=-40 IB=962 IC=1047 IN=1003 T=935
[RX] 2026-11-04T19:31:16.624+08:00 [2026-11-04 19:31:15][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:31:16.634+08:00 [2026-11-04 19:31:15][ADC_TASK] meas: seq=6650 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:31:16.644+08:00 [2026-11-04 19:31:15][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:31:26.566+08:00 [2026-11-04 19:31:25][ADC_TASK] frames=1339735 idle=0 skip=134 seq=1340006 frst_err=0 ring=1339601 adc1_rc=0 adc1_err=0 adc1_seq=1340005 adc1_gap=403 adc1_hw=0 tgap=292
[RX] 2026-11-04T19:31:26.576+08:00 [2026-11-04 19:31:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:26.587+08:00 [2026-11-04 19:31:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:26.597+08:00 [2026-11-04 19:31:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:26.597+08:00 [2026-11-04 19:31:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:26.608+08:00 [2026-11-04 19:31:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:26.608+08:00 [2026-11-04 19:31:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:31:26.618+08:00 [2026-11-04 19:31:25][ADC_TASK] adc: UA=11428 UB=1024 UC=1049 UN=-42 IA=-41 IB=951 IC=1049 IN=1011 T=931
[RX] 2026-11-04T19:31:26.629+08:00 [2026-11-04 19:31:25][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:31:26.639+08:00 [2026-11-04 19:31:25][ADC_TASK] meas: seq=6700 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:31:26.639+08:00 [2026-11-04 19:31:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:31:36.566+08:00 [2026-11-04 19:31:35][ADC_TASK] frames=1349733 idle=0 skip=135 seq=1350006 frst_err=0 ring=1349598 adc1_rc=0 adc1_err=0 adc1_seq=1350005 adc1_gap=406 adc1_hw=0 tgap=294
[RX] 2026-11-04T19:31:36.577+08:00 [2026-11-04 19:31:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:36.587+08:00 [2026-11-04 19:31:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:36.587+08:00 [2026-11-04 19:31:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:36.598+08:00 [2026-11-04 19:31:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:36.608+08:00 [2026-11-04 19:31:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:36.608+08:00 [2026-11-04 19:31:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:31:36.618+08:00 [2026-11-04 19:31:35][ADC_TASK] adc: UA=11428 UB=1005 UC=1054 UN=-43 IA=-42 IB=947 IC=1074 IN=1024 T=934
[RX] 2026-11-04T19:31:36.629+08:00 [2026-11-04 19:31:35][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=-6 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:31:36.639+08:00 [2026-11-04 19:31:35][ADC_TASK] meas: seq=6750 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:31:36.639+08:00 [2026-11-04 19:31:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:31:46.560+08:00 [2026-11-04 19:31:45][ADC_TASK] frames=1359731 idle=0 skip=136 seq=1360006 frst_err=0 ring=1359595 adc1_rc=0 adc1_err=0 adc1_seq=1360005 adc1_gap=409 adc1_hw=0 tgap=296
[RX] 2026-11-04T19:31:46.581+08:00 [2026-11-04 19:31:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:46.581+08:00 [2026-11-04 19:31:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:46.592+08:00 [2026-11-04 19:31:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:46.602+08:00 [2026-11-04 19:31:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:46.602+08:00 [2026-11-04 19:31:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:46.613+08:00 [2026-11-04 19:31:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:31:46.613+08:00 [2026-11-04 19:31:45][ADC_TASK] adc: UA=11428 UB=0 UC=1014 UN=-42 IA=11450 IB=939 IC=1050 IN=1030 T=924
[RX] 2026-11-04T19:31:46.623+08:00 [2026-11-04 19:31:45][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:31:46.634+08:00 [2026-11-04 19:31:45][ADC_TASK] meas: seq=6800 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:31:46.644+08:00 [2026-11-04 19:31:45][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:31:56.563+08:00 [2026-11-04 19:31:55][ADC_TASK] frames=1369729 idle=0 skip=137 seq=1370006 frst_err=0 ring=1369592 adc1_rc=0 adc1_err=0 adc1_seq=1370005 adc1_gap=412 adc1_hw=0 tgap=298
[RX] 2026-11-04T19:31:56.574+08:00 [2026-11-04 19:31:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:56.584+08:00 [2026-11-04 19:31:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:56.595+08:00 [2026-11-04 19:31:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:56.595+08:00 [2026-11-04 19:31:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:56.605+08:00 [2026-11-04 19:31:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:31:56.616+08:00 [2026-11-04 19:31:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:31:56.616+08:00 [2026-11-04 19:31:55][ADC_TASK] adc: UA=11429 UB=0 UC=1018 UN=-44 IA=11452 IB=943 IC=919 IN=991 T=934
[RX] 2026-11-04T19:31:56.626+08:00 [2026-11-04 19:31:55][ADC_TASK] cal: ua_mv=1743 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x002 edge=0x002
[RX] 2026-11-04T19:31:56.637+08:00 [2026-11-04 19:31:55][ADC_TASK] meas: seq=6850 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:31:56.637+08:00 [2026-11-04 19:31:55][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
@@ -0,0 +1,17 @@
fc = 795.8 Hz (R19+R21 = 2000 Ω, C35 = 100 nF)
f/Hz |H|衰减% 相位° 实测偏差% 残差% 备注
50.0 -0.20 -3.6 -0.63 -0.43 C 行 纯基波(复测 0.160 → 0.0 %)
100.0 -0.78 -7.2 -1.25 -0.47 A 行 单注二次
250.0 -4.60 -17.4 -4.38 0.22 B 行 单注五次(11-02 初读 0.152 = −5.0 %)
产品含义外推(同一 1k+1k+100n 拓扑,按谐波次数):
5 次 = 250 Hz → 衰减 -4.6 %
7 次 = 350 Hz → 衰减 -8.5 %
9 次 = 450 Hz → 衰减 -13.0 %
11 次 = 550 Hz → 衰减 -17.7 %
13 次 = 650 Hz → 衰减 -22.6 %
15 次 = 750 Hz → 衰减 -27.2 %
21 次 = 1050 Hz → 衰减 -39.6 %
若 C 改小 10×(10 nF):fc = 7958 Hz,21 次(1050 Hz) 衰减仅 -0.9 %
@@ -0,0 +1,13 @@
# 2026-11-04 交流补测轮证据清单(md5 = 入库 LF 形态值,checkout 后直接可比对;
# BIN 为二进制不受行尾归一化影响)
# 本机全量备份(不入库): serial.log 与 ci-artifacts/ac-20261104/*
9f7d5f6b3243d62c5d75cfca0a8711e8 108603 B 20261104_ac_clip_rail_log.txt
8475adc49a5ff4693f2f3d2ae054c2fb 削顶锁存态观察段(触发 19:36:41,八路≈0、UB 恒钉零码、段头 clip_mask 0x00E6) 5250 B 20261104_ac_clip_sealed_wave11.BIN
8cdf7afd3e0e3c63240d6eeca55d2610 58923 B 20261104_ac_harm_ia_log.txt
ac5edc10399c9e8bd1d03762d7e645c2 92255 B 20261104_ac_phase_log.txt
e5dc076bc4c975eac92f93b2db8e0e81 相位轮 0°/90° 段原件(触发 19:15:32,fft 见 20261104_ac_wave09_scriptout.txt) 5250 B 20261104_ac_phase_wave09.BIN
b853cd0c34d3698184782a32cb34c2d2 无归属切换瞬态段(触发 19:22:19,UA 1408 mVpk 瞬态,不判任何行,留证溯源) 5250 B 20261104_ac_unattributed_wave10.BIN
599e8c5b79a590089f3bd47134c2e1be 6442 B 20261104_ac_wave09_scriptout.txt
783b45fe3fcf5034a0a84954c34a2d5d 6033 B 20261104_ac_wave10_11_scriptout.txt
236c34c4f33105d7c653f7939d3a2e3c 谐波 B 行归因证据:前端差分 RC 三点拟合模型输出(脚本 ia_rc_model.py,见登记簿 §3 与通道映射 §8.2) 818 B 20261104_ac_ia_rc_model.txt
@@ -0,0 +1,734 @@
# 2026-11-04 交流补测轮串口日志摘录(源:serial-assistant serial.log,gen=328,daemon 打戳 +08:00)
# 板固件: fw build: Nov 4 2026 19:05:57 suite=NONE dstr=off(HEAD 87fa0276 构建,烧录回读一致)
# 完整原始日志本机备份: ci-artifacts/ac-20261104/serial_full_backup.log(本机产物,daemon 20MB 截头保险)
# 取证注意: 19:56:47 三条 [ERR][LFT_IO]/[FTP] 是 PC 侧 FTP 探测不存在文件 V5_UP.BIN 所致(操作自归因),非固件缺陷
# 通道静态位观察: 未接线的 TPAFE 输入浮空读数 ≈1743/1747 mV(撤线后 UA/IA 出现,非损伤、非零点漂移)
# # 相位轮 0°/90° 复测窗(UA+UN 双路 Vpp 2.828 V / 50 Hz、相位差 90°);录波段 WAVE09 触发 @19:15:32
[RX] 2026-11-04T19:13:06.594+08:00 [2026-11-04 19:13:05][ADC_TASK] frames=239955 idle=0 skip=24 seq=240006 frst_err=0 ring=239931 adc1_rc=0 adc1_err=0 adc1_seq=240005 adc1_gap=73 adc1_hw=0 tgap=46
[RX] 2026-11-04T19:13:06.604+08:00 [2026-11-04 19:13:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:06.615+08:00 [2026-11-04 19:13:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:06.615+08:00 [2026-11-04 19:13:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:06.625+08:00 [2026-11-04 19:13:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:06.636+08:00 [2026-11-04 19:13:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:06.636+08:00 [2026-11-04 19:13:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:13:06.646+08:00 [2026-11-04 19:13:05][ADC_TASK] adc: UA=-46 UB=914 UC=1024 UN=-46 IA=11453 IB=907 IC=994 IN=1019 T=898
[RX] 2026-11-04T19:13:06.657+08:00 [2026-11-04 19:13:05][ADC_TASK] cal: ua_mv=-7 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:13:06.657+08:00 [2026-11-04 19:13:05][ADC_TASK] meas: seq=1200 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:13:06.668+08:00 [2026-11-04 19:13:05][ADC_TASK] wave: seg=0 armed=0 src=- pts=320 err=0 ovf=0 drop=0
[RX] 2026-11-04T19:13:16.590+08:00 [2026-11-04 19:13:15][ADC_TASK] frames=249953 idle=0 skip=25 seq=250006 frst_err=0 ring=249928 adc1_rc=0 adc1_err=0 adc1_seq=250005 adc1_gap=76 adc1_hw=0 tgap=48
[RX] 2026-11-04T19:13:16.610+08:00 [2026-11-04 19:13:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:16.610+08:00 [2026-11-04 19:13:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:16.621+08:00 [2026-11-04 19:13:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:16.621+08:00 [2026-11-04 19:13:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:16.631+08:00 [2026-11-04 19:13:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:16.642+08:00 [2026-11-04 19:13:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:13:16.642+08:00 [2026-11-04 19:13:15][ADC_TASK] adc: UA=-48 UB=914 UC=1014 UN=-45 IA=11451 IB=910 IC=1007 IN=1029 T=911
[RX] 2026-11-04T19:13:16.652+08:00 [2026-11-04 19:13:15][ADC_TASK] cal: ua_mv=-7 un_mv=-6 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:13:16.663+08:00 [2026-11-04 19:13:15][ADC_TASK] meas: seq=1250 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:13:16.673+08:00 [2026-11-04 19:13:15][ADC_TASK] wave: seg=0 armed=0 src=- pts=320 err=0 ovf=0 drop=0
[RX] 2026-11-04T19:13:26.589+08:00 [2026-11-04 19:13:25][ADC_TASK] frames=259951 idle=0 skip=26 seq=260006 frst_err=0 ring=259925 adc1_rc=0 adc1_err=0 adc1_seq=260005 adc1_gap=79 adc1_hw=0 tgap=50
[RX] 2026-11-04T19:13:26.610+08:00 [2026-11-04 19:13:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:26.610+08:00 [2026-11-04 19:13:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:26.620+08:00 [2026-11-04 19:13:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:26.620+08:00 [2026-11-04 19:13:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:26.631+08:00 [2026-11-04 19:13:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:26.641+08:00 [2026-11-04 19:13:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:13:26.641+08:00 [2026-11-04 19:13:25][ADC_TASK] adc: UA=-46 UB=921 UC=1004 UN=-47 IA=11452 IB=929 IC=1020 IN=1037 T=935
[RX] 2026-11-04T19:13:26.652+08:00 [2026-11-04 19:13:25][ADC_TASK] cal: ua_mv=-7 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:13:26.662+08:00 [2026-11-04 19:13:25][ADC_TASK] meas: seq=1300 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:13:26.673+08:00 [2026-11-04 19:13:25][ADC_TASK] wave: seg=0 armed=0 src=- pts=320 err=0 ovf=0 drop=0
[RX] 2026-11-04T19:13:36.594+08:00 [2026-11-04 19:13:35][ADC_TASK] frames=269949 idle=0 skip=27 seq=270006 frst_err=0 ring=269922 adc1_rc=0 adc1_err=0 adc1_seq=270005 adc1_gap=82 adc1_hw=0 tgap=52
[RX] 2026-11-04T19:13:36.605+08:00 [2026-11-04 19:13:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:36.615+08:00 [2026-11-04 19:13:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:36.615+08:00 [2026-11-04 19:13:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:36.626+08:00 [2026-11-04 19:13:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:36.626+08:00 [2026-11-04 19:13:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:36.636+08:00 [2026-11-04 19:13:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:13:36.647+08:00 [2026-11-04 19:13:35][ADC_TASK] adc: UA=-45 UB=941 UC=1008 UN=-47 IA=11452 IB=953 IC=1030 IN=1043 T=952
[RX] 2026-11-04T19:13:36.657+08:00 [2026-11-04 19:13:35][ADC_TASK] cal: ua_mv=-6 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:13:36.657+08:00 [2026-11-04 19:13:35][ADC_TASK] meas: seq=1350 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:13:36.668+08:00 [2026-11-04 19:13:35][ADC_TASK] wave: seg=0 armed=0 src=- pts=320 err=0 ovf=0 drop=0
[RX] 2026-11-04T19:13:46.588+08:00 [2026-11-04 19:13:45][ADC_TASK] frames=279947 idle=0 skip=28 seq=280006 frst_err=0 ring=279919 adc1_rc=0 adc1_err=0 adc1_seq=280005 adc1_gap=85 adc1_hw=0 tgap=54
[RX] 2026-11-04T19:13:46.609+08:00 [2026-11-04 19:13:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:46.609+08:00 [2026-11-04 19:13:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:46.620+08:00 [2026-11-04 19:13:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:46.630+08:00 [2026-11-04 19:13:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:46.630+08:00 [2026-11-04 19:13:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:46.641+08:00 [2026-11-04 19:13:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:13:46.641+08:00 [2026-11-04 19:13:45][ADC_TASK] adc: UA=-47 UB=977 UC=1021 UN=-46 IA=11452 IB=977 IC=1028 IN=1047 T=967
[RX] 2026-11-04T19:13:46.651+08:00 [2026-11-04 19:13:45][ADC_TASK] cal: ua_mv=-7 un_mv=-7 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:13:46.662+08:00 [2026-11-04 19:13:45][ADC_TASK] meas: seq=1400 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:13:46.672+08:00 [2026-11-04 19:13:45][ADC_TASK] wave: seg=0 armed=0 src=- pts=320 err=0 ovf=0 drop=0
[RX] 2026-11-04T19:13:56.591+08:00 [2026-11-04 19:13:55][ADC_TASK] frames=289945 idle=0 skip=29 seq=290006 frst_err=0 ring=289916 adc1_rc=0 adc1_err=0 adc1_seq=290005 adc1_gap=88 adc1_hw=0 tgap=56
[RX] 2026-11-04T19:13:56.602+08:00 [2026-11-04 19:13:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:56.612+08:00 [2026-11-04 19:13:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=5 Im=8 rms=9 (x0.1)
[RX] 2026-11-04T19:13:56.612+08:00 [2026-11-04 19:13:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=8 Im=-5 rms=9 (x0.1)
[RX] 2026-11-04T19:13:56.623+08:00 [2026-11-04 19:13:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:56.634+08:00 [2026-11-04 19:13:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:13:56.634+08:00 [2026-11-04 19:13:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:13:56.644+08:00 [2026-11-04 19:13:55][ADC_TASK] adc: UA=5882 UB=986 UC=1030 UN=-7149 IA=11453 IB=968 IC=1024 IN=1045 T=954
[RX] 2026-11-04T19:13:56.654+08:00 [2026-11-04 19:13:55][ADC_TASK] cal: ua_mv=897 un_mv=-1090 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:13:56.665+08:00 [2026-11-04 19:13:55][ADC_TASK] meas: seq=1450 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:13:56.665+08:00 [2026-11-04 19:13:55][ADC_TASK] wave: seg=0 armed=0 src=- pts=320 err=0 ovf=0 drop=0
[RX] 2026-11-04T19:14:06.588+08:00 [2026-11-04 19:14:05][ADC_TASK] frames=299943 idle=0 skip=30 seq=300006 frst_err=0 ring=299913 adc1_rc=0 adc1_err=0 adc1_seq=300005 adc1_gap=91 adc1_hw=0 tgap=58
[RX] 2026-11-04T19:14:06.609+08:00 [2026-11-04 19:14:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:06.609+08:00 [2026-11-04 19:14:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=6 Im=7 rms=9 (x0.1)
[RX] 2026-11-04T19:14:06.620+08:00 [2026-11-04 19:14:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=7 Im=-6 rms=9 (x0.1)
[RX] 2026-11-04T19:14:06.620+08:00 [2026-11-04 19:14:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:06.631+08:00 [2026-11-04 19:14:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:06.641+08:00 [2026-11-04 19:14:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:14:06.641+08:00 [2026-11-04 19:14:05][ADC_TASK] adc: UA=5159 UB=968 UC=1012 UN=-7703 IA=11452 IB=943 IC=1018 IN=1017 T=933
[RX] 2026-11-04T19:14:06.651+08:00 [2026-11-04 19:14:05][ADC_TASK] cal: ua_mv=787 un_mv=-1175 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:14:06.662+08:00 [2026-11-04 19:14:05][ADC_TASK] meas: seq=1500 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:14:06.672+08:00 [2026-11-04 19:14:05][ADC_TASK] wave: seg=0 armed=0 src=- pts=320 err=0 ovf=0 drop=0
[RX] 2026-11-04T19:14:16.590+08:00 [2026-11-04 19:14:15][ADC_TASK] frames=309941 idle=0 skip=31 seq=310006 frst_err=0 ring=309910 adc1_rc=0 adc1_err=0 adc1_seq=310005 adc1_gap=94 adc1_hw=0 tgap=60
[RX] 2026-11-04T19:14:16.601+08:00 [2026-11-04 19:14:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:16.611+08:00 [2026-11-04 19:14:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=6 Im=7 rms=9 (x0.1)
[RX] 2026-11-04T19:14:16.611+08:00 [2026-11-04 19:14:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=7 Im=-6 rms=9 (x0.1)
[RX] 2026-11-04T19:14:16.622+08:00 [2026-11-04 19:14:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:16.632+08:00 [2026-11-04 19:14:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:16.643+08:00 [2026-11-04 19:14:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:14:16.643+08:00 [2026-11-04 19:14:15][ADC_TASK] adc: UA=4385 UB=970 UC=1022 UN=-8183 IA=11452 IB=942 IC=1028 IN=1015 T=932
[RX] 2026-11-04T19:14:16.653+08:00 [2026-11-04 19:14:15][ADC_TASK] cal: ua_mv=669 un_mv=-1248 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:14:16.663+08:00 [2026-11-04 19:14:15][ADC_TASK] meas: seq=1550 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:14:16.674+08:00 [2026-11-04 19:14:15][ADC_TASK] wave: seg=0 armed=0 src=- pts=320 err=0 ovf=0 drop=0
[RX] 2026-11-04T19:14:26.594+08:00 [2026-11-04 19:14:25][ADC_TASK] frames=319939 idle=0 skip=32 seq=320006 frst_err=0 ring=319907 adc1_rc=0 adc1_err=0 adc1_seq=320005 adc1_gap=97 adc1_hw=0 tgap=62
[RX] 2026-11-04T19:14:26.605+08:00 [2026-11-04 19:14:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:26.615+08:00 [2026-11-04 19:14:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=7 Im=6 rms=9 (x0.1)
[RX] 2026-11-04T19:14:26.615+08:00 [2026-11-04 19:14:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=6 Im=-7 rms=9 (x0.1)
[RX] 2026-11-04T19:14:26.626+08:00 [2026-11-04 19:14:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:26.626+08:00 [2026-11-04 19:14:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:26.636+08:00 [2026-11-04 19:14:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:14:26.647+08:00 [2026-11-04 19:14:25][ADC_TASK] adc: UA=3564 UB=950 UC=1012 UN=-8582 IA=11451 IB=923 IC=1013 IN=994 T=915
[RX] 2026-11-04T19:14:26.647+08:00 [2026-11-04 19:14:25][ADC_TASK] cal: ua_mv=543 un_mv=-1309 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:14:26.658+08:00 [2026-11-04 19:14:25][ADC_TASK] meas: seq=1600 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:14:26.668+08:00 [2026-11-04 19:14:25][ADC_TASK] wave: seg=0 armed=0 src=- pts=320 err=0 ovf=0 drop=0
[RX] 2026-11-04T19:14:36.586+08:00 [2026-11-04 19:14:35][ADC_TASK] frames=329937 idle=0 skip=33 seq=330006 frst_err=0 ring=329904 adc1_rc=0 adc1_err=0 adc1_seq=330005 adc1_gap=100 adc1_hw=0 tgap=64
[RX] 2026-11-04T19:14:36.606+08:00 [2026-11-04 19:14:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:36.606+08:00 [2026-11-04 19:14:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=8 Im=5 rms=9 (x0.1)
[RX] 2026-11-04T19:14:36.617+08:00 [2026-11-04 19:14:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=5 Im=-8 rms=9 (x0.1)
[RX] 2026-11-04T19:14:36.627+08:00 [2026-11-04 19:14:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:36.627+08:00 [2026-11-04 19:14:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:36.638+08:00 [2026-11-04 19:14:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:14:36.648+08:00 [2026-11-04 19:14:35][ADC_TASK] adc: UA=2709 UB=962 UC=1037 UN=-8905 IA=11452 IB=938 IC=1032 IN=1024 T=929
[RX] 2026-11-04T19:14:36.648+08:00 [2026-11-04 19:14:35][ADC_TASK] cal: ua_mv=413 un_mv=-1358 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:14:36.659+08:00 [2026-11-04 19:14:35][ADC_TASK] meas: seq=1650 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:14:36.669+08:00 [2026-11-04 19:14:35][ADC_TASK] wave: seg=0 armed=0 src=- pts=320 err=0 ovf=0 drop=0
[RX] 2026-11-04T19:14:46.594+08:00 [2026-11-04 19:14:45][ADC_TASK] frames=339935 idle=0 skip=34 seq=340006 frst_err=0 ring=339901 adc1_rc=0 adc1_err=0 adc1_seq=340005 adc1_gap=103 adc1_hw=0 tgap=66
[RX] 2026-11-04T19:14:46.604+08:00 [2026-11-04 19:14:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:46.615+08:00 [2026-11-04 19:14:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=8 Im=4 rms=9 (x0.1)
[RX] 2026-11-04T19:14:46.615+08:00 [2026-11-04 19:14:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=4 Im=-8 rms=9 (x0.1)
[RX] 2026-11-04T19:14:46.625+08:00 [2026-11-04 19:14:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:46.625+08:00 [2026-11-04 19:14:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:46.635+08:00 [2026-11-04 19:14:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:14:46.646+08:00 [2026-11-04 19:14:45][ADC_TASK] adc: UA=1822 UB=952 UC=1034 UN=-9133 IA=11452 IB=927 IC=1018 IN=1026 T=923
[RX] 2026-11-04T19:14:46.656+08:00 [2026-11-04 19:14:45][ADC_TASK] cal: ua_mv=278 un_mv=-1393 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:14:46.667+08:00 [2026-11-04 19:14:45][ADC_TASK] meas: seq=1700 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:14:46.667+08:00 [2026-11-04 19:14:45][ADC_TASK] wave: seg=0 armed=0 src=- pts=320 err=0 ovf=0 drop=0
[RX] 2026-11-04T19:14:56.590+08:00 [2026-11-04 19:14:55][ADC_TASK] frames=349933 idle=0 skip=35 seq=350006 frst_err=0 ring=349898 adc1_rc=0 adc1_err=0 adc1_seq=350005 adc1_gap=106 adc1_hw=0 tgap=68
[RX] 2026-11-04T19:14:56.601+08:00 [2026-11-04 19:14:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:56.611+08:00 [2026-11-04 19:14:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=9 Im=4 rms=9 (x0.1)
[RX] 2026-11-04T19:14:56.622+08:00 [2026-11-04 19:14:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=4 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:14:56.622+08:00 [2026-11-04 19:14:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:56.632+08:00 [2026-11-04 19:14:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:14:56.642+08:00 [2026-11-04 19:14:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:14:56.642+08:00 [2026-11-04 19:14:55][ADC_TASK] adc: UA=917 UB=955 UC=1042 UN=-9276 IA=11454 IB=941 IC=1024 IN=1045 T=938
[RX] 2026-11-04T19:14:56.653+08:00 [2026-11-04 19:14:55][ADC_TASK] cal: ua_mv=139 un_mv=-1415 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:14:56.663+08:00 [2026-11-04 19:14:55][ADC_TASK] meas: seq=1750 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:14:56.663+08:00 [2026-11-04 19:14:55][ADC_TASK] wave: seg=0 armed=0 src=- pts=320 err=0 ovf=0 drop=0
[RX] 2026-11-04T19:15:06.585+08:00 [2026-11-04 19:15:05][ADC_TASK] frames=359931 idle=0 skip=36 seq=360006 frst_err=0 ring=359895 adc1_rc=0 adc1_err=0 adc1_seq=360005 adc1_gap=109 adc1_hw=0 tgap=70
[RX] 2026-11-04T19:15:06.606+08:00 [2026-11-04 19:15:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:06.606+08:00 [2026-11-04 19:15:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=9 Im=3 rms=9 (x0.1)
[RX] 2026-11-04T19:15:06.617+08:00 [2026-11-04 19:15:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=3 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:15:06.627+08:00 [2026-11-04 19:15:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:06.627+08:00 [2026-11-04 19:15:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:06.638+08:00 [2026-11-04 19:15:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:15:06.638+08:00 [2026-11-04 19:15:05][ADC_TASK] adc: UA=-1 UB=946 UC=1031 UN=-9323 IA=11453 IB=936 IC=1015 IN=1041 T=935
[RX] 2026-11-04T19:15:06.648+08:00 [2026-11-04 19:15:05][ADC_TASK] cal: ua_mv=0 un_mv=-1422 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:15:06.659+08:00 [2026-11-04 19:15:05][ADC_TASK] meas: seq=1800 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:15:06.669+08:00 [2026-11-04 19:15:05][ADC_TASK] wave: seg=0 armed=0 src=- pts=320 err=0 ovf=0 drop=0
[RX] 2026-11-04T19:15:16.586+08:00 [2026-11-04 19:15:15][ADC_TASK] frames=369929 idle=0 skip=37 seq=370006 frst_err=0 ring=369892 adc1_rc=0 adc1_err=0 adc1_seq=370005 adc1_gap=112 adc1_hw=0 tgap=72
[RX] 2026-11-04T19:15:16.607+08:00 [2026-11-04 19:15:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:16.607+08:00 [2026-11-04 19:15:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=9 Im=2 rms=9 (x0.1)
[RX] 2026-11-04T19:15:16.617+08:00 [2026-11-04 19:15:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=2 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:15:16.628+08:00 [2026-11-04 19:15:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:16.628+08:00 [2026-11-04 19:15:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:16.638+08:00 [2026-11-04 19:15:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:15:16.638+08:00 [2026-11-04 19:15:15][ADC_TASK] adc: UA=-916 UB=935 UC=1034 UN=-9283 IA=11453 IB=933 IC=1016 IN=1032 T=934
[RX] 2026-11-04T19:15:16.648+08:00 [2026-11-04 19:15:15][ADC_TASK] cal: ua_mv=-139 un_mv=-1416 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:15:16.659+08:00 [2026-11-04 19:15:15][ADC_TASK] meas: seq=1850 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:15:16.669+08:00 [2026-11-04 19:15:15][ADC_TASK] wave: seg=0 armed=0 src=- pts=320 err=0 ovf=0 drop=0
[RX] 2026-11-04T19:15:26.588+08:00 [2026-11-04 19:15:25][ADC_TASK] frames=379927 idle=0 skip=38 seq=380006 frst_err=0 ring=379889 adc1_rc=0 adc1_err=0 adc1_seq=380005 adc1_gap=115 adc1_hw=0 tgap=74
[RX] 2026-11-04T19:15:26.598+08:00 [2026-11-04 19:15:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:26.609+08:00 [2026-11-04 19:15:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=9 Im=1 rms=9 (x0.1)
[RX] 2026-11-04T19:15:26.619+08:00 [2026-11-04 19:15:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=1 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:15:26.619+08:00 [2026-11-04 19:15:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:26.629+08:00 [2026-11-04 19:15:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:26.640+08:00 [2026-11-04 19:15:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:15:26.640+08:00 [2026-11-04 19:15:25][ADC_TASK] adc: UA=-1828 UB=932 UC=1007 UN=-9152 IA=11452 IB=933 IC=997 IN=1027 T=931
[RX] 2026-11-04T19:15:26.650+08:00 [2026-11-04 19:15:25][ADC_TASK] cal: ua_mv=-278 un_mv=-1396 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:15:26.661+08:00 [2026-11-04 19:15:25][ADC_TASK] meas: seq=1900 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:15:26.671+08:00 [2026-11-04 19:15:25][ADC_TASK] wave: seg=0 armed=0 src=- pts=320 err=0 ovf=0 drop=0
[RX] 2026-11-04T19:15:33.908+08:00 [2026-11-04 19:15:32] [WAVE][WARN] seg held 804 ms (idx=10)
[RX] 2026-11-04T19:15:36.587+08:00 [2026-11-04 19:15:35][ADC_TASK] frames=389925 idle=0 skip=39 seq=390006 frst_err=0 ring=389886 adc1_rc=0 adc1_err=0 adc1_seq=390005 adc1_gap=118 adc1_hw=0 tgap=76
[RX] 2026-11-04T19:15:36.598+08:00 [2026-11-04 19:15:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:36.608+08:00 [2026-11-04 19:15:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=9 Im=0 rms=9 (x0.1)
[RX] 2026-11-04T19:15:36.619+08:00 [2026-11-04 19:15:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:15:36.619+08:00 [2026-11-04 19:15:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:36.629+08:00 [2026-11-04 19:15:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:36.639+08:00 [2026-11-04 19:15:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:15:36.639+08:00 [2026-11-04 19:15:35][ADC_TASK] adc: UA=-2711 UB=924 UC=998 UN=-8929 IA=11453 IB=923 IC=986 IN=1010 T=921
[RX] 2026-11-04T19:15:36.650+08:00 [2026-11-04 19:15:35][ADC_TASK] cal: ua_mv=-413 un_mv=-1362 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:15:36.660+08:00 [2026-11-04 19:15:35][ADC_TASK] meas: seq=1950 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:15:36.670+08:00 [2026-11-04 19:15:35][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:15:46.592+08:00 [2026-11-04 19:15:45][ADC_TASK] frames=399923 idle=0 skip=40 seq=400006 frst_err=0 ring=399883 adc1_rc=0 adc1_err=0 adc1_seq=400005 adc1_gap=121 adc1_hw=0 tgap=78
[RX] 2026-11-04T19:15:46.602+08:00 [2026-11-04 19:15:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:46.612+08:00 [2026-11-04 19:15:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=9 Im=0 rms=9 (x0.1)
[RX] 2026-11-04T19:15:46.612+08:00 [2026-11-04 19:15:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:15:46.623+08:00 [2026-11-04 19:15:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:46.623+08:00 [2026-11-04 19:15:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:46.633+08:00 [2026-11-04 19:15:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:15:46.644+08:00 [2026-11-04 19:15:45][ADC_TASK] adc: UA=-3575 UB=932 UC=1000 UN=-8621 IA=11451 IB=930 IC=990 IN=1011 T=931
[RX] 2026-11-04T19:15:46.655+08:00 [2026-11-04 19:15:45][ADC_TASK] cal: ua_mv=-545 un_mv=-1315 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:15:46.665+08:00 [2026-11-04 19:15:45][ADC_TASK] meas: seq=2000 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:15:46.665+08:00 [2026-11-04 19:15:45][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:15:56.589+08:00 [2026-11-04 19:15:55][ADC_TASK] frames=409921 idle=0 skip=41 seq=410006 frst_err=0 ring=409880 adc1_rc=0 adc1_err=0 adc1_seq=410005 adc1_gap=124 adc1_hw=0 tgap=80
[RX] 2026-11-04T19:15:56.600+08:00 [2026-11-04 19:15:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:56.610+08:00 [2026-11-04 19:15:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=9 Im=-1 rms=9 (x0.1)
[RX] 2026-11-04T19:15:56.620+08:00 [2026-11-04 19:15:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=-1 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:15:56.620+08:00 [2026-11-04 19:15:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:56.631+08:00 [2026-11-04 19:15:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:15:56.631+08:00 [2026-11-04 19:15:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:15:56.642+08:00 [2026-11-04 19:15:55][ADC_TASK] adc: UA=-4406 UB=936 UC=1000 UN=-8224 IA=11451 IB=930 IC=986 IN=1010 T=922
[RX] 2026-11-04T19:15:56.652+08:00 [2026-11-04 19:15:55][ADC_TASK] cal: ua_mv=-672 un_mv=-1254 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:15:56.663+08:00 [2026-11-04 19:15:55][ADC_TASK] meas: seq=2050 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:15:56.663+08:00 [2026-11-04 19:15:55][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:16:06.586+08:00 [2026-11-04 19:16:05][ADC_TASK] frames=419919 idle=0 skip=42 seq=420006 frst_err=0 ring=419877 adc1_rc=0 adc1_err=0 adc1_seq=420005 adc1_gap=127 adc1_hw=0 tgap=83
[RX] 2026-11-04T19:16:06.607+08:00 [2026-11-04 19:16:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:06.607+08:00 [2026-11-04 19:16:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=9 Im=-2 rms=9 (x0.1)
[RX] 2026-11-04T19:16:06.617+08:00 [2026-11-04 19:16:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=-2 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:16:06.617+08:00 [2026-11-04 19:16:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:06.627+08:00 [2026-11-04 19:16:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:06.638+08:00 [2026-11-04 19:16:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:16:06.638+08:00 [2026-11-04 19:16:05][ADC_TASK] adc: UA=-5192 UB=934 UC=1028 UN=-7751 IA=11452 IB=926 IC=983 IN=1006 T=924
[RX] 2026-11-04T19:16:06.649+08:00 [2026-11-04 19:16:05][ADC_TASK] cal: ua_mv=-792 un_mv=-1182 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:16:06.659+08:00 [2026-11-04 19:16:05][ADC_TASK] meas: seq=2100 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:16:06.669+08:00 [2026-11-04 19:16:05][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:16:16.588+08:00 [2026-11-04 19:16:15][ADC_TASK] frames=429917 idle=0 skip=43 seq=430006 frst_err=0 ring=429874 adc1_rc=0 adc1_err=0 adc1_seq=430005 adc1_gap=130 adc1_hw=0 tgap=85
[RX] 2026-11-04T19:16:16.598+08:00 [2026-11-04 19:16:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:16.609+08:00 [2026-11-04 19:16:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=9 Im=-3 rms=9 (x0.1)
[RX] 2026-11-04T19:16:16.620+08:00 [2026-11-04 19:16:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=-3 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:16:16.620+08:00 [2026-11-04 19:16:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:16.630+08:00 [2026-11-04 19:16:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:16.641+08:00 [2026-11-04 19:16:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:16:16.641+08:00 [2026-11-04 19:16:15][ADC_TASK] adc: UA=-5929 UB=939 UC=1042 UN=-7203 IA=11453 IB=928 IC=990 IN=1011 T=917
[RX] 2026-11-04T19:16:16.651+08:00 [2026-11-04 19:16:15][ADC_TASK] cal: ua_mv=-904 un_mv=-1099 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:16:16.661+08:00 [2026-11-04 19:16:15][ADC_TASK] meas: seq=2150 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:16:16.661+08:00 [2026-11-04 19:16:15][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:16:26.589+08:00 [2026-11-04 19:16:25][ADC_TASK] frames=439915 idle=0 skip=44 seq=440006 frst_err=0 ring=439871 adc1_rc=0 adc1_err=0 adc1_seq=440005 adc1_gap=133 adc1_hw=0 tgap=88
[RX] 2026-11-04T19:16:26.599+08:00 [2026-11-04 19:16:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:26.610+08:00 [2026-11-04 19:16:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=8 Im=-4 rms=9 (x0.1)
[RX] 2026-11-04T19:16:26.620+08:00 [2026-11-04 19:16:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=-4 Im=-8 rms=9 (x0.1)
[RX] 2026-11-04T19:16:26.620+08:00 [2026-11-04 19:16:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:26.631+08:00 [2026-11-04 19:16:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:26.631+08:00 [2026-11-04 19:16:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:16:26.641+08:00 [2026-11-04 19:16:25][ADC_TASK] adc: UA=-6607 UB=941 UC=1046 UN=-6586 IA=11452 IB=923 IC=994 IN=1018 T=916
[RX] 2026-11-04T19:16:26.652+08:00 [2026-11-04 19:16:25][ADC_TASK] cal: ua_mv=-1008 un_mv=-1004 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:16:26.662+08:00 [2026-11-04 19:16:25][ADC_TASK] meas: seq=2200 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:16:26.673+08:00 [2026-11-04 19:16:25][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:16:36.584+08:00 [2026-11-04 19:16:35][ADC_TASK] frames=449913 idle=0 skip=45 seq=450006 frst_err=0 ring=449868 adc1_rc=0 adc1_err=0 adc1_seq=450005 adc1_gap=136 adc1_hw=0 tgap=91
[RX] 2026-11-04T19:16:36.605+08:00 [2026-11-04 19:16:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:36.605+08:00 [2026-11-04 19:16:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=8 Im=-5 rms=9 (x0.1)
[RX] 2026-11-04T19:16:36.615+08:00 [2026-11-04 19:16:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=-5 Im=-8 rms=9 (x0.1)
[RX] 2026-11-04T19:16:36.626+08:00 [2026-11-04 19:16:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:36.626+08:00 [2026-11-04 19:16:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:36.636+08:00 [2026-11-04 19:16:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:16:36.636+08:00 [2026-11-04 19:16:35][ADC_TASK] adc: UA=-7218 UB=955 UC=1030 UN=-5906 IA=11451 IB=937 IC=1015 IN=1041 T=929
[RX] 2026-11-04T19:16:36.647+08:00 [2026-11-04 19:16:35][ADC_TASK] cal: ua_mv=-1101 un_mv=-901 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:16:36.657+08:00 [2026-11-04 19:16:35][ADC_TASK] meas: seq=2250 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:16:36.668+08:00 [2026-11-04 19:16:35][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:16:46.590+08:00 [2026-11-04 19:16:45][ADC_TASK] frames=459911 idle=0 skip=46 seq=460006 frst_err=0 ring=459865 adc1_rc=0 adc1_err=0 adc1_seq=460005 adc1_gap=139 adc1_hw=0 tgap=94
[RX] 2026-11-04T19:16:46.600+08:00 [2026-11-04 19:16:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:46.610+08:00 [2026-11-04 19:16:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=7 Im=-6 rms=9 (x0.1)
[RX] 2026-11-04T19:16:46.610+08:00 [2026-11-04 19:16:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=-6 Im=-7 rms=9 (x0.1)
[RX] 2026-11-04T19:16:46.621+08:00 [2026-11-04 19:16:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:46.631+08:00 [2026-11-04 19:16:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:46.631+08:00 [2026-11-04 19:16:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:16:46.642+08:00 [2026-11-04 19:16:45][ADC_TASK] adc: UA=-7762 UB=928 UC=1032 UN=-5165 IA=11451 IB=916 IC=991 IN=1019 T=920
[RX] 2026-11-04T19:16:46.652+08:00 [2026-11-04 19:16:45][ADC_TASK] cal: ua_mv=-1184 un_mv=-788 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:16:46.663+08:00 [2026-11-04 19:16:45][ADC_TASK] meas: seq=2300 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:16:46.663+08:00 [2026-11-04 19:16:45][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:16:56.589+08:00 [2026-11-04 19:16:55][ADC_TASK] frames=469909 idle=0 skip=47 seq=470006 frst_err=0 ring=469862 adc1_rc=0 adc1_err=0 adc1_seq=470005 adc1_gap=142 adc1_hw=0 tgap=97
[RX] 2026-11-04T19:16:56.599+08:00 [2026-11-04 19:16:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:56.609+08:00 [2026-11-04 19:16:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=7 Im=-6 rms=9 (x0.1)
[RX] 2026-11-04T19:16:56.620+08:00 [2026-11-04 19:16:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=-6 Im=-7 rms=9 (x0.1)
[RX] 2026-11-04T19:16:56.620+08:00 [2026-11-04 19:16:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:56.630+08:00 [2026-11-04 19:16:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:16:56.630+08:00 [2026-11-04 19:16:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:16:56.641+08:00 [2026-11-04 19:16:55][ADC_TASK] adc: UA=-8233 UB=917 UC=1037 UN=-4376 IA=11452 IB=916 IC=989 IN=1013 T=912
[RX] 2026-11-04T19:16:56.652+08:00 [2026-11-04 19:16:55][ADC_TASK] cal: ua_mv=-1256 un_mv=-667 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:16:56.662+08:00 [2026-11-04 19:16:55][ADC_TASK] meas: seq=2350 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:16:56.662+08:00 [2026-11-04 19:16:55][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:17:06.584+08:00 [2026-11-04 19:17:05][ADC_TASK] frames=479907 idle=0 skip=48 seq=480006 frst_err=0 ring=479859 adc1_rc=0 adc1_err=0 adc1_seq=480005 adc1_gap=145 adc1_hw=0 tgap=100
[RX] 2026-11-04T19:17:06.605+08:00 [2026-11-04 19:17:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:06.605+08:00 [2026-11-04 19:17:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=6 Im=-7 rms=9 (x0.1)
[RX] 2026-11-04T19:17:06.615+08:00 [2026-11-04 19:17:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=-7 Im=-6 rms=9 (x0.1)
[RX] 2026-11-04T19:17:06.615+08:00 [2026-11-04 19:17:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:06.626+08:00 [2026-11-04 19:17:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:06.637+08:00 [2026-11-04 19:17:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:17:06.637+08:00 [2026-11-04 19:17:05][ADC_TASK] adc: UA=-8624 UB=938 UC=1043 UN=-3541 IA=11452 IB=932 IC=1012 IN=1039 T=925
[RX] 2026-11-04T19:17:06.647+08:00 [2026-11-04 19:17:05][ADC_TASK] cal: ua_mv=-1315 un_mv=-540 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:17:06.657+08:00 [2026-11-04 19:17:05][ADC_TASK] meas: seq=2400 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:17:06.668+08:00 [2026-11-04 19:17:05][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:17:16.589+08:00 [2026-11-04 19:17:15][ADC_TASK] frames=489905 idle=0 skip=49 seq=490006 frst_err=0 ring=489856 adc1_rc=0 adc1_err=0 adc1_seq=490005 adc1_gap=148 adc1_hw=0 tgap=102
[RX] 2026-11-04T19:17:16.599+08:00 [2026-11-04 19:17:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:16.610+08:00 [2026-11-04 19:17:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=5 Im=-8 rms=9 (x0.1)
[RX] 2026-11-04T19:17:16.610+08:00 [2026-11-04 19:17:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=-8 Im=-5 rms=9 (x0.1)
[RX] 2026-11-04T19:17:16.620+08:00 [2026-11-04 19:17:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:16.631+08:00 [2026-11-04 19:17:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:16.631+08:00 [2026-11-04 19:17:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:17:16.641+08:00 [2026-11-04 19:17:15][ADC_TASK] adc: UA=-8926 UB=924 UC=1011 UN=-2681 IA=11451 IB=912 IC=996 IN=1022 T=908
[RX] 2026-11-04T19:17:16.652+08:00 [2026-11-04 19:17:15][ADC_TASK] cal: ua_mv=-1361 un_mv=-409 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:17:16.662+08:00 [2026-11-04 19:17:15][ADC_TASK] meas: seq=2450 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:17:16.662+08:00 [2026-11-04 19:17:15][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:17:26.589+08:00 [2026-11-04 19:17:25][ADC_TASK] frames=499903 idle=0 skip=50 seq=500006 frst_err=0 ring=499853 adc1_rc=0 adc1_err=0 adc1_seq=500005 adc1_gap=151 adc1_hw=0 tgap=105
[RX] 2026-11-04T19:17:26.599+08:00 [2026-11-04 19:17:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:26.609+08:00 [2026-11-04 19:17:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=4 Im=-8 rms=9 (x0.1)
[RX] 2026-11-04T19:17:26.609+08:00 [2026-11-04 19:17:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=-8 Im=-4 rms=9 (x0.1)
[RX] 2026-11-04T19:17:26.619+08:00 [2026-11-04 19:17:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:26.630+08:00 [2026-11-04 19:17:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:26.630+08:00 [2026-11-04 19:17:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:17:26.641+08:00 [2026-11-04 19:17:25][ADC_TASK] adc: UA=-9140 UB=918 UC=1013 UN=-1797 IA=11451 IB=920 IC=1016 IN=1035 T=928
[RX] 2026-11-04T19:17:26.651+08:00 [2026-11-04 19:17:25][ADC_TASK] cal: ua_mv=-1394 un_mv=-274 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:17:26.661+08:00 [2026-11-04 19:17:25][ADC_TASK] meas: seq=2500 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:17:26.672+08:00 [2026-11-04 19:17:25][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:17:36.583+08:00 [2026-11-04 19:17:35][ADC_TASK] frames=509901 idle=0 skip=51 seq=510006 frst_err=0 ring=509850 adc1_rc=0 adc1_err=0 adc1_seq=510005 adc1_gap=154 adc1_hw=0 tgap=108
[RX] 2026-11-04T19:17:36.604+08:00 [2026-11-04 19:17:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:36.604+08:00 [2026-11-04 19:17:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=3 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:17:36.614+08:00 [2026-11-04 19:17:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=-9 Im=-3 rms=9 (x0.1)
[RX] 2026-11-04T19:17:36.614+08:00 [2026-11-04 19:17:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:36.625+08:00 [2026-11-04 19:17:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:36.635+08:00 [2026-11-04 19:17:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:17:36.635+08:00 [2026-11-04 19:17:35][ADC_TASK] adc: UA=-9268 UB=917 UC=991 UN=-895 IA=11452 IB=932 IC=1015 IN=1021 T=936
[RX] 2026-11-04T19:17:36.646+08:00 [2026-11-04 19:17:35][ADC_TASK] cal: ua_mv=-1414 un_mv=-136 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:17:36.656+08:00 [2026-11-04 19:17:35][ADC_TASK] meas: seq=2550 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:17:36.667+08:00 [2026-11-04 19:17:35][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:17:46.589+08:00 [2026-11-04 19:17:45][ADC_TASK] frames=519899 idle=0 skip=52 seq=520006 frst_err=0 ring=519847 adc1_rc=0 adc1_err=0 adc1_seq=520005 adc1_gap=157 adc1_hw=0 tgap=111
[RX] 2026-11-04T19:17:46.600+08:00 [2026-11-04 19:17:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:46.610+08:00 [2026-11-04 19:17:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=2 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:17:46.610+08:00 [2026-11-04 19:17:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=-9 Im=-2 rms=9 (x0.1)
[RX] 2026-11-04T19:17:46.620+08:00 [2026-11-04 19:17:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:46.631+08:00 [2026-11-04 19:17:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:46.631+08:00 [2026-11-04 19:17:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:17:46.641+08:00 [2026-11-04 19:17:45][ADC_TASK] adc: UA=-9301 UB=949 UC=1011 UN=23 IA=11452 IB=957 IC=1020 IN=1042 T=952
[RX] 2026-11-04T19:17:46.652+08:00 [2026-11-04 19:17:45][ADC_TASK] cal: ua_mv=-1419 un_mv=3 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:17:46.662+08:00 [2026-11-04 19:17:45][ADC_TASK] meas: seq=2600 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:17:46.662+08:00 [2026-11-04 19:17:45][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:17:56.584+08:00 [2026-11-04 19:17:55][ADC_TASK] frames=529897 idle=0 skip=53 seq=530006 frst_err=0 ring=529844 adc1_rc=0 adc1_err=0 adc1_seq=530005 adc1_gap=160 adc1_hw=0 tgap=113
[RX] 2026-11-04T19:17:56.595+08:00 [2026-11-04 19:17:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:56.605+08:00 [2026-11-04 19:17:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=2 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:17:56.616+08:00 [2026-11-04 19:17:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=-9 Im=-2 rms=9 (x0.1)
[RX] 2026-11-04T19:17:56.616+08:00 [2026-11-04 19:17:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:56.626+08:00 [2026-11-04 19:17:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:17:56.637+08:00 [2026-11-04 19:17:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:17:56.637+08:00 [2026-11-04 19:17:55][ADC_TASK] adc: UA=-9248 UB=957 UC=995 UN=942 IA=11453 IB=950 IC=996 IN=1016 T=937
[RX] 2026-11-04T19:17:56.647+08:00 [2026-11-04 19:17:55][ADC_TASK] cal: ua_mv=-1411 un_mv=143 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:17:56.658+08:00 [2026-11-04 19:17:55][ADC_TASK] meas: seq=2650 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:17:56.668+08:00 [2026-11-04 19:17:55][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:18:06.582+08:00 [2026-11-04 19:18:05][ADC_TASK] frames=539895 idle=0 skip=54 seq=540006 frst_err=0 ring=539841 adc1_rc=0 adc1_err=0 adc1_seq=540005 adc1_gap=163 adc1_hw=0 tgap=116
[RX] 2026-11-04T19:18:06.603+08:00 [2026-11-04 19:18:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:06.603+08:00 [2026-11-04 19:18:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=1 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:18:06.613+08:00 [2026-11-04 19:18:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=-9 Im=-1 rms=9 (x0.1)
[RX] 2026-11-04T19:18:06.623+08:00 [2026-11-04 19:18:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:06.623+08:00 [2026-11-04 19:18:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:06.634+08:00 [2026-11-04 19:18:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:18:06.634+08:00 [2026-11-04 19:18:05][ADC_TASK] adc: UA=-9102 UB=971 UC=993 UN=1847 IA=11451 IB=950 IC=1008 IN=1006 T=936
[RX] 2026-11-04T19:18:06.644+08:00 [2026-11-04 19:18:05][ADC_TASK] cal: ua_mv=-1388 un_mv=281 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:18:06.655+08:00 [2026-11-04 19:18:05][ADC_TASK] meas: seq=2700 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:18:06.665+08:00 [2026-11-04 19:18:05][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:18:16.589+08:00 [2026-11-04 19:18:15][ADC_TASK] frames=549893 idle=0 skip=55 seq=550006 frst_err=0 ring=549838 adc1_rc=0 adc1_err=0 adc1_seq=550005 adc1_gap=166 adc1_hw=0 tgap=118
[RX] 2026-11-04T19:18:16.599+08:00 [2026-11-04 19:18:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:16.609+08:00 [2026-11-04 19:18:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:18:16.609+08:00 [2026-11-04 19:18:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=-9 Im=0 rms=9 (x0.1)
[RX] 2026-11-04T19:18:16.620+08:00 [2026-11-04 19:18:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:16.620+08:00 [2026-11-04 19:18:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:16.630+08:00 [2026-11-04 19:18:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:18:16.641+08:00 [2026-11-04 19:18:15][ADC_TASK] adc: UA=-8863 UB=979 UC=1021 UN=2731 IA=11452 IB=953 IC=1030 IN=1027 T=945
[RX] 2026-11-04T19:18:16.651+08:00 [2026-11-04 19:18:15][ADC_TASK] cal: ua_mv=-1352 un_mv=416 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:18:16.661+08:00 [2026-11-04 19:18:15][ADC_TASK] meas: seq=2750 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:18:16.661+08:00 [2026-11-04 19:18:15][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:18:26.586+08:00 [2026-11-04 19:18:25][ADC_TASK] frames=559891 idle=0 skip=56 seq=560006 frst_err=0 ring=559835 adc1_rc=0 adc1_err=0 adc1_seq=560005 adc1_gap=169 adc1_hw=0 tgap=121
[RX] 2026-11-04T19:18:26.597+08:00 [2026-11-04 19:18:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:26.607+08:00 [2026-11-04 19:18:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:18:26.607+08:00 [2026-11-04 19:18:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=-9 Im=0 rms=9 (x0.1)
[RX] 2026-11-04T19:18:26.618+08:00 [2026-11-04 19:18:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:26.628+08:00 [2026-11-04 19:18:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:26.628+08:00 [2026-11-04 19:18:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:18:26.638+08:00 [2026-11-04 19:18:25][ADC_TASK] adc: UA=-8544 UB=975 UC=1032 UN=3589 IA=11451 IB=952 IC=1034 IN=1001 T=939
[RX] 2026-11-04T19:18:26.649+08:00 [2026-11-04 19:18:25][ADC_TASK] cal: ua_mv=-1303 un_mv=547 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:18:26.659+08:00 [2026-11-04 19:18:25][ADC_TASK] meas: seq=2800 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:18:26.659+08:00 [2026-11-04 19:18:25][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:18:36.583+08:00 [2026-11-04 19:18:35][ADC_TASK] frames=569889 idle=0 skip=57 seq=570006 frst_err=0 ring=569832 adc1_rc=0 adc1_err=0 adc1_seq=570005 adc1_gap=172 adc1_hw=0 tgap=124
[RX] 2026-11-04T19:18:36.593+08:00 [2026-11-04 19:18:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:36.604+08:00 [2026-11-04 19:18:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=-1 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:18:36.614+08:00 [2026-11-04 19:18:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=-9 Im=1 rms=9 (x0.1)
[RX] 2026-11-04T19:18:36.614+08:00 [2026-11-04 19:18:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:36.625+08:00 [2026-11-04 19:18:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:36.635+08:00 [2026-11-04 19:18:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:18:36.635+08:00 [2026-11-04 19:18:35][ADC_TASK] adc: UA=-8136 UB=976 UC=1029 UN=4414 IA=11451 IB=939 IC=1038 IN=994 T=919
[RX] 2026-11-04T19:18:36.646+08:00 [2026-11-04 19:18:35][ADC_TASK] cal: ua_mv=-1241 un_mv=673 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:18:36.656+08:00 [2026-11-04 19:18:35][ADC_TASK] meas: seq=2850 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:18:36.667+08:00 [2026-11-04 19:18:35][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:18:46.585+08:00 [2026-11-04 19:18:45][ADC_TASK] frames=579887 idle=0 skip=58 seq=580006 frst_err=0 ring=579829 adc1_rc=0 adc1_err=0 adc1_seq=580005 adc1_gap=175 adc1_hw=0 tgap=127
[RX] 2026-11-04T19:18:46.595+08:00 [2026-11-04 19:18:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:46.606+08:00 [2026-11-04 19:18:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=-2 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:18:46.616+08:00 [2026-11-04 19:18:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=-9 Im=2 rms=9 (x0.1)
[RX] 2026-11-04T19:18:46.616+08:00 [2026-11-04 19:18:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:46.627+08:00 [2026-11-04 19:18:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:46.627+08:00 [2026-11-04 19:18:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:18:46.637+08:00 [2026-11-04 19:18:45][ADC_TASK] adc: UA=-7649 UB=970 UC=1033 UN=5193 IA=11452 IB=927 IC=1046 IN=1001 T=913
[RX] 2026-11-04T19:18:46.648+08:00 [2026-11-04 19:18:45][ADC_TASK] cal: ua_mv=-1167 un_mv=792 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:18:46.658+08:00 [2026-11-04 19:18:45][ADC_TASK] meas: seq=2900 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:18:46.658+08:00 [2026-11-04 19:18:45][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:18:56.588+08:00 [2026-11-04 19:18:55][ADC_TASK] frames=589885 idle=0 skip=59 seq=590006 frst_err=0 ring=589826 adc1_rc=0 adc1_err=0 adc1_seq=590005 adc1_gap=178 adc1_hw=0 tgap=130
[RX] 2026-11-04T19:18:56.598+08:00 [2026-11-04 19:18:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:56.598+08:00 [2026-11-04 19:18:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=-3 Im=-9 rms=9 (x0.1)
[RX] 2026-11-04T19:18:56.609+08:00 [2026-11-04 19:18:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=-9 Im=3 rms=9 (x0.1)
[RX] 2026-11-04T19:18:56.619+08:00 [2026-11-04 19:18:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:56.629+08:00 [2026-11-04 19:18:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:18:56.629+08:00 [2026-11-04 19:18:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:18:56.640+08:00 [2026-11-04 19:18:55][ADC_TASK] adc: UA=-7087 UB=950 UC=1031 UN=5918 IA=11451 IB=916 IC=1035 IN=997 T=911
[RX] 2026-11-04T19:18:56.640+08:00 [2026-11-04 19:18:55][ADC_TASK] cal: ua_mv=-1081 un_mv=903 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:18:56.660+08:00 [2026-11-04 19:18:55][ADC_TASK] meas: seq=2950 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:18:56.660+08:00 [2026-11-04 19:18:55][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:19:06.583+08:00 [2026-11-04 19:19:05][ADC_TASK] frames=599883 idle=0 skip=60 seq=600006 frst_err=0 ring=599823 adc1_rc=0 adc1_err=0 adc1_seq=600005 adc1_gap=181 adc1_hw=0 tgap=133
[RX] 2026-11-04T19:19:06.594+08:00 [2026-11-04 19:19:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:06.604+08:00 [2026-11-04 19:19:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=-4 Im=-8 rms=9 (x0.1)
[RX] 2026-11-04T19:19:06.615+08:00 [2026-11-04 19:19:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=-8 Im=4 rms=9 (x0.1)
[RX] 2026-11-04T19:19:06.615+08:00 [2026-11-04 19:19:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:06.625+08:00 [2026-11-04 19:19:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:06.636+08:00 [2026-11-04 19:19:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:19:06.636+08:00 [2026-11-04 19:19:05][ADC_TASK] adc: UA=-6456 UB=930 UC=1034 UN=6589 IA=11451 IB=912 IC=1013 IN=1012 T=912
[RX] 2026-11-04T19:19:06.646+08:00 [2026-11-04 19:19:05][ADC_TASK] cal: ua_mv=-985 un_mv=1005 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:19:06.657+08:00 [2026-11-04 19:19:05][ADC_TASK] meas: seq=3000 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:19:06.657+08:00 [2026-11-04 19:19:05][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:19:16.584+08:00 [2026-11-04 19:19:15][ADC_TASK] frames=609881 idle=0 skip=61 seq=610006 frst_err=0 ring=609820 adc1_rc=0 adc1_err=0 adc1_seq=610005 adc1_gap=184 adc1_hw=0 tgap=135
[RX] 2026-11-04T19:19:16.594+08:00 [2026-11-04 19:19:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:16.605+08:00 [2026-11-04 19:19:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=-5 Im=-8 rms=9 (x0.1)
[RX] 2026-11-04T19:19:16.615+08:00 [2026-11-04 19:19:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=-8 Im=5 rms=9 (x0.1)
[RX] 2026-11-04T19:19:16.615+08:00 [2026-11-04 19:19:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:16.626+08:00 [2026-11-04 19:19:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:16.626+08:00 [2026-11-04 19:19:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:19:16.636+08:00 [2026-11-04 19:19:15][ADC_TASK] adc: UA=-5767 UB=916 UC=1017 UN=7187 IA=11451 IB=904 IC=989 IN=1020 T=903
[RX] 2026-11-04T19:19:16.646+08:00 [2026-11-04 19:19:15][ADC_TASK] cal: ua_mv=-879 un_mv=1096 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:19:16.657+08:00 [2026-11-04 19:19:15][ADC_TASK] meas: seq=3050 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:19:16.657+08:00 [2026-11-04 19:19:15][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:19:26.582+08:00 [2026-11-04 19:19:25][ADC_TASK] frames=619879 idle=0 skip=62 seq=620006 frst_err=0 ring=619817 adc1_rc=0 adc1_err=0 adc1_seq=620005 adc1_gap=187 adc1_hw=0 tgap=138
[RX] 2026-11-04T19:19:26.593+08:00 [2026-11-04 19:19:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:26.603+08:00 [2026-11-04 19:19:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=-6 Im=-7 rms=9 (x0.1)
[RX] 2026-11-04T19:19:26.614+08:00 [2026-11-04 19:19:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=-7 Im=6 rms=9 (x0.1)
[RX] 2026-11-04T19:19:26.614+08:00 [2026-11-04 19:19:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:26.624+08:00 [2026-11-04 19:19:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:26.635+08:00 [2026-11-04 19:19:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:19:26.635+08:00 [2026-11-04 19:19:25][ADC_TASK] adc: UA=-5016 UB=909 UC=1011 UN=7715 IA=11452 IB=909 IC=997 IN=1019 T=914
[RX] 2026-11-04T19:19:26.645+08:00 [2026-11-04 19:19:25][ADC_TASK] cal: ua_mv=-765 un_mv=1177 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:19:26.656+08:00 [2026-11-04 19:19:25][ADC_TASK] meas: seq=3100 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:19:26.656+08:00 [2026-11-04 19:19:25][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:19:36.581+08:00 [2026-11-04 19:19:35][ADC_TASK] frames=629877 idle=0 skip=63 seq=630006 frst_err=0 ring=629814 adc1_rc=0 adc1_err=0 adc1_seq=630005 adc1_gap=190 adc1_hw=0 tgap=141
[RX] 2026-11-04T19:19:36.602+08:00 [2026-11-04 19:19:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:36.602+08:00 [2026-11-04 19:19:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=-7 Im=-7 rms=9 (x0.1)
[RX] 2026-11-04T19:19:36.612+08:00 [2026-11-04 19:19:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=-7 Im=7 rms=9 (x0.1)
[RX] 2026-11-04T19:19:36.623+08:00 [2026-11-04 19:19:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:36.623+08:00 [2026-11-04 19:19:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:36.633+08:00 [2026-11-04 19:19:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:19:36.633+08:00 [2026-11-04 19:19:35][ADC_TASK] adc: UA=-4219 UB=926 UC=1007 UN=8168 IA=11452 IB=937 IC=1022 IN=1043 T=943
[RX] 2026-11-04T19:19:36.644+08:00 [2026-11-04 19:19:35][ADC_TASK] cal: ua_mv=-643 un_mv=1246 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:19:36.654+08:00 [2026-11-04 19:19:35][ADC_TASK] meas: seq=3150 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:19:36.665+08:00 [2026-11-04 19:19:35][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:19:46.585+08:00 [2026-11-04 19:19:45][ADC_TASK] frames=639875 idle=0 skip=64 seq=640006 frst_err=0 ring=639811 adc1_rc=0 adc1_err=0 adc1_seq=640005 adc1_gap=193 adc1_hw=0 tgap=144
[RX] 2026-11-04T19:19:46.596+08:00 [2026-11-04 19:19:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:46.606+08:00 [2026-11-04 19:19:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=-7 Im=-6 rms=9 (x0.1)
[RX] 2026-11-04T19:19:46.606+08:00 [2026-11-04 19:19:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=-6 Im=7 rms=9 (x0.1)
[RX] 2026-11-04T19:19:46.617+08:00 [2026-11-04 19:19:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:46.627+08:00 [2026-11-04 19:19:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:46.627+08:00 [2026-11-04 19:19:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:19:46.638+08:00 [2026-11-04 19:19:45][ADC_TASK] adc: UA=-3384 UB=933 UC=994 UN=8544 IA=11450 IB=944 IC=1007 IN=1036 T=941
[RX] 2026-11-04T19:19:46.648+08:00 [2026-11-04 19:19:45][ADC_TASK] cal: ua_mv=-516 un_mv=1303 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:19:46.658+08:00 [2026-11-04 19:19:45][ADC_TASK] meas: seq=3200 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:19:46.658+08:00 [2026-11-04 19:19:45][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:19:56.581+08:00 [2026-11-04 19:19:55][ADC_TASK] frames=649873 idle=0 skip=65 seq=650006 frst_err=0 ring=649808 adc1_rc=0 adc1_err=0 adc1_seq=650005 adc1_gap=196 adc1_hw=0 tgap=147
[RX] 2026-11-04T19:19:56.592+08:00 [2026-11-04 19:19:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:56.602+08:00 [2026-11-04 19:19:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=-8 Im=-5 rms=9 (x0.1)
[RX] 2026-11-04T19:19:56.613+08:00 [2026-11-04 19:19:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=-5 Im=8 rms=9 (x0.1)
[RX] 2026-11-04T19:19:56.613+08:00 [2026-11-04 19:19:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:56.623+08:00 [2026-11-04 19:19:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:19:56.634+08:00 [2026-11-04 19:19:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:19:56.634+08:00 [2026-11-04 19:19:55][ADC_TASK] adc: UA=-2511 UB=959 UC=999 UN=8831 IA=11452 IB=957 IC=1003 IN=1033 T=947
[RX] 2026-11-04T19:19:56.644+08:00 [2026-11-04 19:19:55][ADC_TASK] cal: ua_mv=-383 un_mv=1347 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:19:56.654+08:00 [2026-11-04 19:19:55][ADC_TASK] meas: seq=3250 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:19:56.665+08:00 [2026-11-04 19:19:55][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:20:06.586+08:00 [2026-11-04 19:20:05][ADC_TASK] frames=659871 idle=0 skip=66 seq=660006 frst_err=0 ring=659805 adc1_rc=0 adc1_err=0 adc1_seq=660005 adc1_gap=199 adc1_hw=0 tgap=150
[RX] 2026-11-04T19:20:06.597+08:00 [2026-11-04 19:20:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:06.597+08:00 [2026-11-04 19:20:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=-8 Im=-4 rms=9 (x0.1)
[RX] 2026-11-04T19:20:06.607+08:00 [2026-11-04 19:20:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=-4 Im=8 rms=9 (x0.1)
[RX] 2026-11-04T19:20:06.618+08:00 [2026-11-04 19:20:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:06.628+08:00 [2026-11-04 19:20:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:06.628+08:00 [2026-11-04 19:20:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:20:06.638+08:00 [2026-11-04 19:20:05][ADC_TASK] adc: UA=-1622 UB=970 UC=995 UN=9029 IA=11452 IB=950 IC=1007 IN=1030 T=939
[RX] 2026-11-04T19:20:06.638+08:00 [2026-11-04 19:20:05][ADC_TASK] cal: ua_mv=-247 un_mv=1377 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:20:06.659+08:00 [2026-11-04 19:20:05][ADC_TASK] meas: seq=3300 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:20:06.659+08:00 [2026-11-04 19:20:05][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:20:16.576+08:00 [2026-11-04 19:20:15][ADC_TASK] frames=669869 idle=0 skip=67 seq=670006 frst_err=0 ring=669802 adc1_rc=0 adc1_err=0 adc1_seq=670005 adc1_gap=202 adc1_hw=0 tgap=152
[RX] 2026-11-04T19:20:16.597+08:00 [2026-11-04 19:20:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:16.597+08:00 [2026-11-04 19:20:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=-9 Im=-3 rms=9 (x0.1)
[RX] 2026-11-04T19:20:16.608+08:00 [2026-11-04 19:20:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=-3 Im=9 rms=9 (x0.1)
[RX] 2026-11-04T19:20:16.618+08:00 [2026-11-04 19:20:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:16.618+08:00 [2026-11-04 19:20:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:16.629+08:00 [2026-11-04 19:20:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:20:16.639+08:00 [2026-11-04 19:20:15][ADC_TASK] adc: UA=-710 UB=977 UC=999 UN=9138 IA=11452 IB=955 IC=1028 IN=1038 T=942
[RX] 2026-11-04T19:20:16.639+08:00 [2026-11-04 19:20:15][ADC_TASK] cal: ua_mv=-108 un_mv=1394 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:20:16.649+08:00 [2026-11-04 19:20:15][ADC_TASK] meas: seq=3350 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:20:16.660+08:00 [2026-11-04 19:20:15][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:20:26.581+08:00 [2026-11-04 19:20:25][ADC_TASK] frames=679867 idle=0 skip=68 seq=680006 frst_err=0 ring=679799 adc1_rc=0 adc1_err=0 adc1_seq=680005 adc1_gap=205 adc1_hw=0 tgap=155
[RX] 2026-11-04T19:20:26.592+08:00 [2026-11-04 19:20:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:26.603+08:00 [2026-11-04 19:20:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=-9 Im=-2 rms=9 (x0.1)
[RX] 2026-11-04T19:20:26.613+08:00 [2026-11-04 19:20:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=-2 Im=9 rms=9 (x0.1)
[RX] 2026-11-04T19:20:26.613+08:00 [2026-11-04 19:20:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:26.624+08:00 [2026-11-04 19:20:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:26.624+08:00 [2026-11-04 19:20:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:20:26.634+08:00 [2026-11-04 19:20:25][ADC_TASK] adc: UA=203 UB=978 UC=1024 UN=9154 IA=11452 IB=953 IC=1038 IN=1012 T=943
[RX] 2026-11-04T19:20:26.645+08:00 [2026-11-04 19:20:25][ADC_TASK] cal: ua_mv=30 un_mv=1396 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:20:26.655+08:00 [2026-11-04 19:20:25][ADC_TASK] meas: seq=3400 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:20:26.655+08:00 [2026-11-04 19:20:25][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:20:36.578+08:00 [2026-11-04 19:20:35][ADC_TASK] frames=689865 idle=0 skip=69 seq=690006 frst_err=0 ring=689796 adc1_rc=0 adc1_err=0 adc1_seq=690005 adc1_gap=208 adc1_hw=0 tgap=158
[RX] 2026-11-04T19:20:36.599+08:00 [2026-11-04 19:20:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:36.599+08:00 [2026-11-04 19:20:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=-9 Im=-1 rms=9 (x0.1)
[RX] 2026-11-04T19:20:36.609+08:00 [2026-11-04 19:20:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=-1 Im=9 rms=9 (x0.1)
[RX] 2026-11-04T19:20:36.609+08:00 [2026-11-04 19:20:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:36.620+08:00 [2026-11-04 19:20:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:36.630+08:00 [2026-11-04 19:20:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:20:36.630+08:00 [2026-11-04 19:20:35][ADC_TASK] adc: UA=1125 UB=978 UC=1032 UN=9086 IA=11452 IB=953 IC=1040 IN=999 T=938
[RX] 2026-11-04T19:20:36.641+08:00 [2026-11-04 19:20:35][ADC_TASK] cal: ua_mv=171 un_mv=1386 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:20:36.652+08:00 [2026-11-04 19:20:35][ADC_TASK] meas: seq=3450 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:20:36.662+08:00 [2026-11-04 19:20:35][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:20:46.578+08:00 [2026-11-04 19:20:45][ADC_TASK] frames=699863 idle=0 skip=70 seq=700006 frst_err=0 ring=699793 adc1_rc=0 adc1_err=0 adc1_seq=700005 adc1_gap=211 adc1_hw=0 tgap=161
[RX] 2026-11-04T19:20:46.599+08:00 [2026-11-04 19:20:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:46.599+08:00 [2026-11-04 19:20:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=-9 Im=0 rms=9 (x0.1)
[RX] 2026-11-04T19:20:46.609+08:00 [2026-11-04 19:20:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=9 rms=9 (x0.1)
[RX] 2026-11-04T19:20:46.609+08:00 [2026-11-04 19:20:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:46.620+08:00 [2026-11-04 19:20:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:46.630+08:00 [2026-11-04 19:20:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:20:46.630+08:00 [2026-11-04 19:20:45][ADC_TASK] adc: UA=2031 UB=974 UC=1028 UN=8919 IA=11452 IB=940 IC=1040 IN=995 T=923
[RX] 2026-11-04T19:20:46.641+08:00 [2026-11-04 19:20:45][ADC_TASK] cal: ua_mv=309 un_mv=1360 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:20:46.651+08:00 [2026-11-04 19:20:45][ADC_TASK] meas: seq=3500 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:20:46.661+08:00 [2026-11-04 19:20:45][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:20:56.583+08:00 [2026-11-04 19:20:55][ADC_TASK] frames=709861 idle=0 skip=71 seq=710006 frst_err=0 ring=709790 adc1_rc=0 adc1_err=0 adc1_seq=710005 adc1_gap=214 adc1_hw=0 tgap=164
[RX] 2026-11-04T19:20:56.593+08:00 [2026-11-04 19:20:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:56.603+08:00 [2026-11-04 19:20:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=-9 Im=0 rms=9 (x0.1)
[RX] 2026-11-04T19:20:56.614+08:00 [2026-11-04 19:20:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=9 rms=9 (x0.1)
[RX] 2026-11-04T19:20:56.614+08:00 [2026-11-04 19:20:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:56.624+08:00 [2026-11-04 19:20:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:20:56.624+08:00 [2026-11-04 19:20:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:20:56.635+08:00 [2026-11-04 19:20:55][ADC_TASK] adc: UA=2918 UB=967 UC=1027 UN=8667 IA=11451 IB=931 IC=1040 IN=995 T=922
[RX] 2026-11-04T19:20:56.645+08:00 [2026-11-04 19:20:55][ADC_TASK] cal: ua_mv=445 un_mv=1322 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:20:56.655+08:00 [2026-11-04 19:20:55][ADC_TASK] meas: seq=3550 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:20:56.655+08:00 [2026-11-04 19:20:55][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:21:06.585+08:00 [2026-11-04 19:21:05][ADC_TASK] frames=719859 idle=0 skip=72 seq=720006 frst_err=0 ring=719787 adc1_rc=0 adc1_err=0 adc1_seq=720005 adc1_gap=217 adc1_hw=0 tgap=167
[RX] 2026-11-04T19:21:06.595+08:00 [2026-11-04 19:21:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:06.595+08:00 [2026-11-04 19:21:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=-9 Im=1 rms=9 (x0.1)
[RX] 2026-11-04T19:21:06.605+08:00 [2026-11-04 19:21:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=1 Im=9 rms=9 (x0.1)
[RX] 2026-11-04T19:21:06.616+08:00 [2026-11-04 19:21:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:06.616+08:00 [2026-11-04 19:21:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:06.626+08:00 [2026-11-04 19:21:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:21:06.636+08:00 [2026-11-04 19:21:05][ADC_TASK] adc: UA=3771 UB=956 UC=1028 UN=8327 IA=11451 IB=934 IC=1034 IN=997 T=933
[RX] 2026-11-04T19:21:06.636+08:00 [2026-11-04 19:21:05][ADC_TASK] cal: ua_mv=575 un_mv=1270 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:21:06.657+08:00 [2026-11-04 19:21:05][ADC_TASK] meas: seq=3600 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:21:06.657+08:00 [2026-11-04 19:21:05][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:21:16.580+08:00 [2026-11-04 19:21:15][ADC_TASK] frames=729857 idle=0 skip=73 seq=730006 frst_err=0 ring=729784 adc1_rc=0 adc1_err=0 adc1_seq=730005 adc1_gap=220 adc1_hw=0 tgap=169
[RX] 2026-11-04T19:21:16.591+08:00 [2026-11-04 19:21:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:16.601+08:00 [2026-11-04 19:21:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=-9 Im=2 rms=9 (x0.1)
[RX] 2026-11-04T19:21:16.611+08:00 [2026-11-04 19:21:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=2 Im=9 rms=9 (x0.1)
[RX] 2026-11-04T19:21:16.611+08:00 [2026-11-04 19:21:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:16.622+08:00 [2026-11-04 19:21:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:16.632+08:00 [2026-11-04 19:21:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:21:16.632+08:00 [2026-11-04 19:21:15][ADC_TASK] adc: UA=4586 UB=945 UC=1021 UN=7902 IA=11452 IB=933 IC=1015 IN=1008 T=927
[RX] 2026-11-04T19:21:16.643+08:00 [2026-11-04 19:21:15][ADC_TASK] cal: ua_mv=699 un_mv=1205 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:21:16.653+08:00 [2026-11-04 19:21:15][ADC_TASK] meas: seq=3650 v=1 ua_mv=995 un_mv=996 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:21:16.653+08:00 [2026-11-04 19:21:15][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:21:26.579+08:00 [2026-11-04 19:21:25][ADC_TASK] frames=739855 idle=0 skip=74 seq=740006 frst_err=0 ring=739781 adc1_rc=0 adc1_err=0 adc1_seq=740005 adc1_gap=223 adc1_hw=0 tgap=172
[RX] 2026-11-04T19:21:26.590+08:00 [2026-11-04 19:21:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:26.601+08:00 [2026-11-04 19:21:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:26.611+08:00 [2026-11-04 19:21:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:26.611+08:00 [2026-11-04 19:21:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:26.621+08:00 [2026-11-04 19:21:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:26.632+08:00 [2026-11-04 19:21:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:21:26.632+08:00 [2026-11-04 19:21:25][ADC_TASK] adc: UA=9106 UB=953 UC=1048 UN=-104 IA=11451 IB=946 IC=1018 IN=1037 T=940
[RX] 2026-11-04T19:21:26.643+08:00 [2026-11-04 19:21:25][ADC_TASK] cal: ua_mv=1389 un_mv=-15 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:21:26.653+08:00 [2026-11-04 19:21:25][ADC_TASK] meas: seq=3700 v=1 ua_mv=0 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:21:26.653+08:00 [2026-11-04 19:21:25][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:21:36.581+08:00 [2026-11-04 19:21:35][ADC_TASK] frames=749853 idle=0 skip=75 seq=750006 frst_err=0 ring=749778 adc1_rc=0 adc1_err=0 adc1_seq=750005 adc1_gap=226 adc1_hw=0 tgap=174
[RX] 2026-11-04T19:21:36.591+08:00 [2026-11-04 19:21:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:36.602+08:00 [2026-11-04 19:21:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:36.612+08:00 [2026-11-04 19:21:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:36.612+08:00 [2026-11-04 19:21:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:36.623+08:00 [2026-11-04 19:21:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:36.623+08:00 [2026-11-04 19:21:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:21:36.633+08:00 [2026-11-04 19:21:35][ADC_TASK] adc: UA=-1490 UB=948 UC=1002 UN=-92 IA=11451 IB=934 IC=1004 IN=1032 T=926
[RX] 2026-11-04T19:21:36.644+08:00 [2026-11-04 19:21:35][ADC_TASK] cal: ua_mv=-227 un_mv=-14 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:21:36.654+08:00 [2026-11-04 19:21:35][ADC_TASK] meas: seq=3750 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:21:36.654+08:00 [2026-11-04 19:21:35][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:21:46.579+08:00 [2026-11-04 19:21:45][ADC_TASK] frames=759851 idle=0 skip=76 seq=760006 frst_err=0 ring=759775 adc1_rc=0 adc1_err=0 adc1_seq=760005 adc1_gap=229 adc1_hw=0 tgap=176
[RX] 2026-11-04T19:21:46.589+08:00 [2026-11-04 19:21:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:46.600+08:00 [2026-11-04 19:21:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:46.610+08:00 [2026-11-04 19:21:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:46.610+08:00 [2026-11-04 19:21:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:46.621+08:00 [2026-11-04 19:21:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:46.631+08:00 [2026-11-04 19:21:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:21:46.631+08:00 [2026-11-04 19:21:45][ADC_TASK] adc: UA=-1453 UB=956 UC=998 UN=-91 IA=11452 IB=941 IC=1011 IN=1033 T=942
[RX] 2026-11-04T19:21:46.642+08:00 [2026-11-04 19:21:45][ADC_TASK] cal: ua_mv=-221 un_mv=-13 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:21:46.652+08:00 [2026-11-04 19:21:45][ADC_TASK] meas: seq=3800 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:21:46.652+08:00 [2026-11-04 19:21:45][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:21:56.575+08:00 [2026-11-04 19:21:55][ADC_TASK] frames=769849 idle=0 skip=77 seq=770006 frst_err=0 ring=769772 adc1_rc=0 adc1_err=0 adc1_seq=770005 adc1_gap=232 adc1_hw=0 tgap=178
[RX] 2026-11-04T19:21:56.596+08:00 [2026-11-04 19:21:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:56.596+08:00 [2026-11-04 19:21:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:56.607+08:00 [2026-11-04 19:21:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:56.617+08:00 [2026-11-04 19:21:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:56.617+08:00 [2026-11-04 19:21:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:21:56.628+08:00 [2026-11-04 19:21:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:21:56.628+08:00 [2026-11-04 19:21:55][ADC_TASK] adc: UA=-1415 UB=977 UC=1005 UN=-88 IA=11452 IB=966 IC=1029 IN=1025 T=954
[RX] 2026-11-04T19:21:56.638+08:00 [2026-11-04 19:21:55][ADC_TASK] cal: ua_mv=-215 un_mv=-13 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:21:56.648+08:00 [2026-11-04 19:21:55][ADC_TASK] meas: seq=3850 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:21:56.659+08:00 [2026-11-04 19:21:55][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:22:06.582+08:00 [2026-11-04 19:22:05][ADC_TASK] frames=779847 idle=0 skip=78 seq=780006 frst_err=0 ring=779769 adc1_rc=0 adc1_err=0 adc1_seq=780005 adc1_gap=235 adc1_hw=0 tgap=180
[RX] 2026-11-04T19:22:06.593+08:00 [2026-11-04 19:22:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:06.603+08:00 [2026-11-04 19:22:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:06.603+08:00 [2026-11-04 19:22:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:06.613+08:00 [2026-11-04 19:22:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:06.613+08:00 [2026-11-04 19:22:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:06.623+08:00 [2026-11-04 19:22:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:22:06.634+08:00 [2026-11-04 19:22:05][ADC_TASK] adc: UA=-1379 UB=977 UC=1022 UN=-90 IA=11452 IB=953 IC=1027 IN=998 T=942
[RX] 2026-11-04T19:22:06.644+08:00 [2026-11-04 19:22:05][ADC_TASK] cal: ua_mv=-210 un_mv=-13 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:22:06.655+08:00 [2026-11-04 19:22:05][ADC_TASK] meas: seq=3900 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:22:06.655+08:00 [2026-11-04 19:22:05][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:22:16.583+08:00 [2026-11-04 19:22:15][ADC_TASK] frames=789845 idle=0 skip=79 seq=790006 frst_err=0 ring=789766 adc1_rc=0 adc1_err=0 adc1_seq=790005 adc1_gap=238 adc1_hw=0 tgap=182
[RX] 2026-11-04T19:22:16.593+08:00 [2026-11-04 19:22:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:16.593+08:00 [2026-11-04 19:22:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:16.604+08:00 [2026-11-04 19:22:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:16.614+08:00 [2026-11-04 19:22:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:16.614+08:00 [2026-11-04 19:22:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:16.625+08:00 [2026-11-04 19:22:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:22:16.635+08:00 [2026-11-04 19:22:15][ADC_TASK] adc: UA=-1343 UB=980 UC=1021 UN=-88 IA=11451 IB=940 IC=1034 IN=989 T=918
[RX] 2026-11-04T19:22:16.635+08:00 [2026-11-04 19:22:15][ADC_TASK] cal: ua_mv=-204 un_mv=-13 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:22:16.656+08:00 [2026-11-04 19:22:15][ADC_TASK] meas: seq=3950 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:22:16.656+08:00 [2026-11-04 19:22:15][ADC_TASK] wave: seg=1 armed=0 src=M pts=320 err=0 ovf=0 drop=6632
[RX] 2026-11-04T19:22:26.583+08:00 [2026-11-04 19:22:25][ADC_TASK] frames=799843 idle=0 skip=80 seq=800006 frst_err=0 ring=799763 adc1_rc=0 adc1_err=0 adc1_seq=800005 adc1_gap=241 adc1_hw=0 tgap=184
[RX] 2026-11-04T19:22:26.593+08:00 [2026-11-04 19:22:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:26.593+08:00 [2026-11-04 19:22:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:26.604+08:00 [2026-11-04 19:22:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:26.614+08:00 [2026-11-04 19:22:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:26.614+08:00 [2026-11-04 19:22:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:26.624+08:00 [2026-11-04 19:22:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:22:26.635+08:00 [2026-11-04 19:22:25][ADC_TASK] adc: UA=-1307 UB=979 UC=1035 UN=-90 IA=11453 IB=933 IC=1055 IN=1005 T=916
[RX] 2026-11-04T19:22:26.635+08:00 [2026-11-04 19:22:25][ADC_TASK] cal: ua_mv=-199 un_mv=-13 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:22:26.655+08:00 [2026-11-04 19:22:25][ADC_TASK] meas: seq=4000 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:22:26.655+08:00 [2026-11-04 19:22:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:22:36.581+08:00 [2026-11-04 19:22:35][ADC_TASK] frames=809841 idle=0 skip=81 seq=810006 frst_err=0 ring=809760 adc1_rc=0 adc1_err=0 adc1_seq=810005 adc1_gap=244 adc1_hw=0 tgap=186
[RX] 2026-11-04T19:22:36.591+08:00 [2026-11-04 19:22:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:36.602+08:00 [2026-11-04 19:22:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:36.602+08:00 [2026-11-04 19:22:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:36.612+08:00 [2026-11-04 19:22:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:36.612+08:00 [2026-11-04 19:22:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:36.623+08:00 [2026-11-04 19:22:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:22:36.633+08:00 [2026-11-04 19:22:35][ADC_TASK] adc: UA=-1271 UB=936 UC=1013 UN=-90 IA=11451 IB=908 IC=1019 IN=987 T=899
[RX] 2026-11-04T19:22:36.644+08:00 [2026-11-04 19:22:35][ADC_TASK] cal: ua_mv=-193 un_mv=-13 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:22:36.654+08:00 [2026-11-04 19:22:35][ADC_TASK] meas: seq=4050 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:22:36.654+08:00 [2026-11-04 19:22:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:22:46.579+08:00 [2026-11-04 19:22:45][ADC_TASK] frames=819839 idle=0 skip=82 seq=820006 frst_err=0 ring=819757 adc1_rc=0 adc1_err=0 adc1_seq=820005 adc1_gap=247 adc1_hw=0 tgap=188
[RX] 2026-11-04T19:22:46.589+08:00 [2026-11-04 19:22:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:46.600+08:00 [2026-11-04 19:22:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:46.610+08:00 [2026-11-04 19:22:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:46.610+08:00 [2026-11-04 19:22:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:46.621+08:00 [2026-11-04 19:22:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:46.621+08:00 [2026-11-04 19:22:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:22:46.631+08:00 [2026-11-04 19:22:45][ADC_TASK] adc: UA=-1234 UB=940 UC=1045 UN=-91 IA=11452 IB=925 IC=1021 IN=1026 T=919
[RX] 2026-11-04T19:22:46.642+08:00 [2026-11-04 19:22:45][ADC_TASK] cal: ua_mv=-188 un_mv=-13 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:22:46.652+08:00 [2026-11-04 19:22:45][ADC_TASK] meas: seq=4100 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:22:46.652+08:00 [2026-11-04 19:22:45][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:22:56.573+08:00 [2026-11-04 19:22:55][ADC_TASK] frames=829837 idle=0 skip=83 seq=830006 frst_err=0 ring=829754 adc1_rc=0 adc1_err=0 adc1_seq=830005 adc1_gap=250 adc1_hw=0 tgap=190
[RX] 2026-11-04T19:22:56.593+08:00 [2026-11-04 19:22:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:56.593+08:00 [2026-11-04 19:22:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:56.604+08:00 [2026-11-04 19:22:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:56.614+08:00 [2026-11-04 19:22:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:56.614+08:00 [2026-11-04 19:22:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:22:56.625+08:00 [2026-11-04 19:22:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:22:56.635+08:00 [2026-11-04 19:22:55][ADC_TASK] adc: UA=-1197 UB=919 UC=1032 UN=-90 IA=11451 IB=914 IC=1002 IN=1024 T=900
[RX] 2026-11-04T19:22:56.635+08:00 [2026-11-04 19:22:55][ADC_TASK] cal: ua_mv=-182 un_mv=-13 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:22:56.646+08:00 [2026-11-04 19:22:55][ADC_TASK] meas: seq=4150 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:22:56.656+08:00 [2026-11-04 19:22:55][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:23:06.580+08:00 [2026-11-04 19:23:05][ADC_TASK] frames=839835 idle=0 skip=84 seq=840006 frst_err=0 ring=839751 adc1_rc=0 adc1_err=0 adc1_seq=840005 adc1_gap=253 adc1_hw=0 tgap=192
[RX] 2026-11-04T19:23:06.590+08:00 [2026-11-04 19:23:05][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:06.600+08:00 [2026-11-04 19:23:05][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:06.600+08:00 [2026-11-04 19:23:05][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:06.611+08:00 [2026-11-04 19:23:05][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:06.621+08:00 [2026-11-04 19:23:05][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:06.621+08:00 [2026-11-04 19:23:05][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:23:06.632+08:00 [2026-11-04 19:23:05][ADC_TASK] adc: UA=-1162 UB=915 UC=1009 UN=-90 IA=11453 IB=914 IC=1019 IN=1035 T=908
[RX] 2026-11-04T19:23:06.642+08:00 [2026-11-04 19:23:05][ADC_TASK] cal: ua_mv=-177 un_mv=-13 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:23:06.653+08:00 [2026-11-04 19:23:05][ADC_TASK] meas: seq=4200 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:23:06.653+08:00 [2026-11-04 19:23:05][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:23:16.581+08:00 [2026-11-04 19:23:15][ADC_TASK] frames=849833 idle=0 skip=85 seq=850006 frst_err=0 ring=849748 adc1_rc=0 adc1_err=0 adc1_seq=850005 adc1_gap=256 adc1_hw=0 tgap=194
[RX] 2026-11-04T19:23:16.592+08:00 [2026-11-04 19:23:15][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:16.592+08:00 [2026-11-04 19:23:15][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:16.602+08:00 [2026-11-04 19:23:15][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:16.612+08:00 [2026-11-04 19:23:15][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:16.612+08:00 [2026-11-04 19:23:15][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:16.622+08:00 [2026-11-04 19:23:15][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:23:16.633+08:00 [2026-11-04 19:23:15][ADC_TASK] adc: UA=-1123 UB=912 UC=1015 UN=-94 IA=11452 IB=915 IC=1030 IN=1019 T=923
[RX] 2026-11-04T19:23:16.643+08:00 [2026-11-04 19:23:15][ADC_TASK] cal: ua_mv=-171 un_mv=-14 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:23:16.654+08:00 [2026-11-04 19:23:15][ADC_TASK] meas: seq=4250 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:23:16.654+08:00 [2026-11-04 19:23:15][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:23:26.574+08:00 [2026-11-04 19:23:25][ADC_TASK] frames=859831 idle=0 skip=86 seq=860006 frst_err=0 ring=859745 adc1_rc=0 adc1_err=0 adc1_seq=860005 adc1_gap=259 adc1_hw=0 tgap=196
[RX] 2026-11-04T19:23:26.595+08:00 [2026-11-04 19:23:25][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:26.595+08:00 [2026-11-04 19:23:25][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:26.605+08:00 [2026-11-04 19:23:25][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:26.605+08:00 [2026-11-04 19:23:25][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:26.615+08:00 [2026-11-04 19:23:25][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:26.626+08:00 [2026-11-04 19:23:25][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:23:26.626+08:00 [2026-11-04 19:23:25][ADC_TASK] adc: UA=-1084 UB=912 UC=1033 UN=-91 IA=11452 IB=929 IC=1035 IN=1003 T=931
[RX] 2026-11-04T19:23:26.637+08:00 [2026-11-04 19:23:25][ADC_TASK] cal: ua_mv=-165 un_mv=-13 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:23:26.647+08:00 [2026-11-04 19:23:25][ADC_TASK] meas: seq=4300 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:23:26.658+08:00 [2026-11-04 19:23:25][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:23:36.573+08:00 [2026-11-04 19:23:35][ADC_TASK] frames=869829 idle=0 skip=87 seq=870006 frst_err=0 ring=869742 adc1_rc=0 adc1_err=0 adc1_seq=870005 adc1_gap=262 adc1_hw=0 tgap=198
[RX] 2026-11-04T19:23:36.594+08:00 [2026-11-04 19:23:35][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:36.594+08:00 [2026-11-04 19:23:35][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:36.604+08:00 [2026-11-04 19:23:35][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:36.615+08:00 [2026-11-04 19:23:35][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:36.615+08:00 [2026-11-04 19:23:35][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:36.625+08:00 [2026-11-04 19:23:35][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:23:36.625+08:00 [2026-11-04 19:23:35][ADC_TASK] adc: UA=-1052 UB=911 UC=1018 UN=-94 IA=11452 IB=916 IC=1027 IN=986 T=910
[RX] 2026-11-04T19:23:36.636+08:00 [2026-11-04 19:23:35][ADC_TASK] cal: ua_mv=-160 un_mv=-14 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:23:36.646+08:00 [2026-11-04 19:23:35][ADC_TASK] meas: seq=4350 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:23:36.657+08:00 [2026-11-04 19:23:35][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:23:46.572+08:00 [2026-11-04 19:23:45][ADC_TASK] frames=879827 idle=0 skip=88 seq=880006 frst_err=0 ring=879739 adc1_rc=0 adc1_err=0 adc1_seq=880005 adc1_gap=265 adc1_hw=0 tgap=200
[RX] 2026-11-04T19:23:46.593+08:00 [2026-11-04 19:23:45][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:46.593+08:00 [2026-11-04 19:23:45][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:46.603+08:00 [2026-11-04 19:23:45][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:46.614+08:00 [2026-11-04 19:23:45][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:46.614+08:00 [2026-11-04 19:23:45][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:46.624+08:00 [2026-11-04 19:23:45][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:23:46.624+08:00 [2026-11-04 19:23:45][ADC_TASK] adc: UA=-1015 UB=922 UC=1027 UN=-92 IA=11452 IB=924 IC=1040 IN=996 T=930
[RX] 2026-11-04T19:23:46.635+08:00 [2026-11-04 19:23:45][ADC_TASK] cal: ua_mv=-154 un_mv=-14 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:23:46.645+08:00 [2026-11-04 19:23:45][ADC_TASK] meas: seq=4400 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:23:46.655+08:00 [2026-11-04 19:23:45][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
[RX] 2026-11-04T19:23:56.578+08:00 [2026-11-04 19:23:55][ADC_TASK] frames=889825 idle=0 skip=89 seq=890006 frst_err=0 ring=889736 adc1_rc=0 adc1_err=0 adc1_seq=890005 adc1_gap=268 adc1_hw=0 tgap=202
[RX] 2026-11-04T19:23:56.589+08:00 [2026-11-04 19:23:55][ADC_TASK] phasor(hb) C01-IA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:56.599+08:00 [2026-11-04 19:23:55][ADC_TASK] phasor(hb) C02-UA-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:56.599+08:00 [2026-11-04 19:23:55][ADC_TASK] phasor(hb) C03-UN-F1: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:56.609+08:00 [2026-11-04 19:23:55][ADC_TASK] phasor(hb) C04-IA-F2: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:56.620+08:00 [2026-11-04 19:23:55][ADC_TASK] phasor(hb) C05-IA-F5: Re=0 Im=0 rms=0 (x0.1)
[RX] 2026-11-04T19:23:56.620+08:00 [2026-11-04 19:23:55][ADC_TASK] freq(hb): f=0 valid=0 (x0.01)
[RX] 2026-11-04T19:23:56.630+08:00 [2026-11-04 19:23:55][ADC_TASK] adc: UA=-979 UB=916 UC=1012 UN=-93 IA=11451 IB=924 IC=1028 IN=983 T=924
[RX] 2026-11-04T19:23:56.640+08:00 [2026-11-04 19:23:55][ADC_TASK] cal: ua_mv=-149 un_mv=-14 ia_mv=1747 vl=0x00 cl=0xe6 rail=0x000 edge=0x000
[RX] 2026-11-04T19:23:56.651+08:00 [2026-11-04 19:23:55][ADC_TASK] meas: seq=4450 v=1 ua_mv=79 un_mv=0 ia_mv=0 f=0 fv=0
[RX] 2026-11-04T19:23:56.651+08:00 [2026-11-04 19:23:55][ADC_TASK] wave: seg=2 armed=0 src=M pts=320 err=0 ovf=0 drop=7128
@@ -0,0 +1,92 @@
# WAVE09(相位轮 0°/90°,2026-11-04 19:15:32 触发)wave_read.py 输出全套
## dump
FILE : WAVE09.BIN (5250 bytes)
magic : 57 52 01 ('WR' + version byte 1)
ver : 1
fs_hz : 1000
pts_per_cycle : 20
ch_count : 8
pts_per_ch : 320 (320 ms at 1000 Hz)
pre_pts : 160
trig_src : 1 (MANUAL)
trig_elm : 0
t0_ms : 386333 (ms since power-on)
wall : 1793819731 (epoch s)
eng : 0 (pin-domain)
flags_seq : 0x00 VALID bits: (none)
clip_mask : 0x00E6 [UB UC IB IC IN]
frame_seq : 386258
CRC16(hdr) : 0xB00D OK covers [0,126), low byte first
CRC16(data) : 0xF8AA OK covers 5120 bytes, low byte first
-- channel table (8 entries x 12 B) --
IDX SEM NAME SRC BITS AVAIL K_Q16 B_CODES LSB_uV FLAG
0 0 UA TPAFE5160 16 0x00 10000000 0 152.587891 .
1 1 UB STM32-ADC1 12 0x02 52800000 0 805.664062 CLIPPED
2 2 UC STM32-ADC1 12 0x02 52800000 0 805.664062 CLIPPED
3 3 UN TPAFE5160 16 0x00 10000000 0 152.587891 .
4 4 IA TPAFE5160 16 0x00 10000000 0 152.587891 .
5 5 IB STM32-ADC1 12 0x02 52800000 0 805.664062 CLIPPED
6 6 IC STM32-ADC1 12 0x02 52800000 0 805.664062 CLIPPED
7 7 IN STM32-ADC1 12 0x02 52800000 0 805.664062 CLIPPED
## fft --ch 0 --all
unit: mV eng=0 (pin-domain) [pin-domain = ADC pin voltage, NOT calibrated secondary]
CH NAME SRC CYCLE RMS-f[mV] ANG-f[deg] RMS-2x[mV] RMS-5x[mV] NOTE
(f = fundamental; 2x/5x = 2nd and 5th harmonic; angle reference = first sample of this window, not a phase lock to the signal generator)
0 UA TPAFE5160 0 995.94 -122.50 0.81 0.43
0 UA TPAFE5160 1 995.90 -122.50 0.98 0.40
0 UA TPAFE5160 2 995.91 -122.52 0.88 0.44
0 UA TPAFE5160 3 995.92 -122.52 0.87 0.48
0 UA TPAFE5160 4 995.83 -122.54 0.85 0.48
0 UA TPAFE5160 5 995.92 -122.54 0.88 0.40
0 UA TPAFE5160 6 995.91 -122.56 0.90 0.41
0 UA TPAFE5160 7 995.85 -122.57 0.88 0.36
0 UA TPAFE5160 8 995.88 -122.58 0.89 0.39
0 UA TPAFE5160 9 995.86 -122.60 0.87 0.35
0 UA TPAFE5160 10 995.88 -122.61 0.84 0.35
0 UA TPAFE5160 11 995.95 -122.62 0.88 0.36
0 UA TPAFE5160 12 995.91 -122.63 0.89 0.39
0 UA TPAFE5160 13 995.90 -122.64 0.87 0.41
0 UA TPAFE5160 14 995.89 -122.65 0.88 0.40
0 UA TPAFE5160 15 995.83 -122.66 0.82 0.41
0 UA TPAFE5160 ALL mean= 995.89 min= 995.83 max= 995.95 over 16 cycles
note: mV = (code + b_codes) * k_q16/65536/1000 (adc_cal_apply formula, unit labeled by header eng, never re-guessed); full-cycle window, coefficients = sin/cos(2*pi*k/N)*sqrt(2)/N as in App/algo/phasor.c; phase = atan2(im,re) deg
## fft --ch 3 --all
unit: mV eng=0 (pin-domain) [pin-domain = ADC pin voltage, NOT calibrated secondary]
CH NAME SRC CYCLE RMS-f[mV] ANG-f[deg] RMS-2x[mV] RMS-5x[mV] NOTE
(f = fundamental; 2x/5x = 2nd and 5th harmonic; angle reference = first sample of this window, not a phase lock to the signal generator)
3 UN TPAFE5160 0 996.92 +147.46 0.67 0.36
3 UN TPAFE5160 1 996.75 +147.45 0.72 0.33
3 UN TPAFE5160 2 996.78 +147.44 0.70 0.35
3 UN TPAFE5160 3 996.84 +147.44 0.74 0.31
3 UN TPAFE5160 4 996.85 +147.42 0.63 0.37
3 UN TPAFE5160 5 996.84 +147.41 0.69 0.33
3 UN TPAFE5160 6 996.84 +147.40 0.67 0.30
3 UN TPAFE5160 7 996.78 +147.39 0.71 0.30
3 UN TPAFE5160 8 996.81 +147.37 0.69 0.31
3 UN TPAFE5160 9 996.91 +147.36 0.65 0.32
3 UN TPAFE5160 10 996.86 +147.35 0.71 0.38
3 UN TPAFE5160 11 996.85 +147.34 0.66 0.39
3 UN TPAFE5160 12 996.80 +147.33 0.68 0.39
3 UN TPAFE5160 13 996.85 +147.31 0.65 0.37
3 UN TPAFE5160 14 996.86 +147.30 0.75 0.33
3 UN TPAFE5160 15 996.84 +147.29 0.72 0.34
3 UN TPAFE5160 ALL mean= 996.84 min= 996.75 max= 996.92 over 16 cycles
note: mV = (code + b_codes) * k_q16/65536/1000 (adc_cal_apply formula, unit labeled by header eng, never re-guessed); full-cycle window, coefficients = sin/cos(2*pi*k/N)*sqrt(2)/N as in App/algo/phasor.c; phase = atan2(im,re) deg
## shape
unit: mV eng=0(pin-domain) min-run for rail pin = 4 samples
CH NAME SRC CYCLES AMP[mVpk] POL SYM PIN_LO PIN_HI RAIL
0 UA TPAFE5160 16.00 1406.25 - 0.002 0 0 .
1 UB STM32-ADC1 23.50 14.90 + 1.614 0 0 .
2 UC STM32-ADC1 21.50 15.71 + 1.625 0 0 .
3 UN TPAFE5160 16.00 1408.16 + 0.001 0 0 .
4 IA TPAFE5160 52.00 0.31 + 1.582 0 0 .
5 IB STM32-ADC1 21.50 14.10 + 1.622 0 0 .
6 IC STM32-ADC1 24.50 15.31 + 1.603 0 0 .
7 IN STM32-ADC1 20.50 16.11 + 1.604 0 0 .
clip reconcile: measured=0x0000 [-] header=0x00E6 [UB UC IB IC IN] MISMATCH
yardstick: equality (default card check) -- measured rail pins must equal the sealed clip_mask
note: header clip_mask is the seal-time CLIPPED STAMP, source-derived in V0.1 (App/algo/adc_cal.c: s_rom_k_stm32 -> CLIPPED, unipolar no-bias), NOT measured from samples; measured is this segment's rail pins. Real V0.1 AC waves bottom-rail the 5 stamped channels, so equality is expected on-board; a non-railed measurement means synthetic fixture (e.g. column ramps) or wiring change -- investigate, do not auto-blame the seal
@@ -0,0 +1,84 @@
# WAVE11(削顶锁存态观察段,2026-11-04 19:36:41 触发)与 WAVE10(无归属切换瞬态段)wave_read.py 输出
## WAVE11 dump
FILE : WAVE11.BIN (5250 bytes)
magic : 57 52 01 ('WR' + version byte 1)
ver : 1
fs_hz : 1000
pts_per_cycle : 20
ch_count : 8
pts_per_ch : 320 (320 ms at 1000 Hz)
pre_pts : 160
trig_src : 1 (MANUAL)
trig_elm : 0
t0_ms : 1655148 (ms since power-on)
wall : 1793821000 (epoch s)
eng : 0 (pin-domain)
flags_seq : 0x00 VALID bits: (none)
clip_mask : 0x00E6 [UB UC IB IC IN]
frame_seq : 1654819
CRC16(hdr) : 0xC99C OK covers [0,126), low byte first
CRC16(data) : 0x5122 OK covers 5120 bytes, low byte first
-- channel table (8 entries x 12 B) --
IDX SEM NAME SRC BITS AVAIL K_Q16 B_CODES LSB_uV FLAG
0 0 UA TPAFE5160 16 0x00 10000000 0 152.587891 .
1 1 UB STM32-ADC1 12 0x02 52800000 0 805.664062 CLIPPED
2 2 UC STM32-ADC1 12 0x02 52800000 0 805.664062 CLIPPED
3 3 UN TPAFE5160 16 0x00 10000000 0 152.587891 .
4 4 IA TPAFE5160 16 0x00 10000000 0 152.587891 .
5 5 IB STM32-ADC1 12 0x02 52800000 0 805.664062 CLIPPED
6 6 IC STM32-ADC1 12 0x02 52800000 0 805.664062 CLIPPED
7 7 IN STM32-ADC1 12 0x02 52800000 0 805.664062 CLIPPED
## WAVE11 shape
unit: mV eng=0(pin-domain) min-run for rail pin = 4 samples
CH NAME SRC CYCLES AMP[mVpk] POL SYM PIN_LO PIN_HI RAIL
0 UA TPAFE5160 71.50 0.31 + 1.467 0 0 .
1 UB STM32-ADC1 0.00 0.00 0 1.000 320 0 YES
2 UC STM32-ADC1 48.00 10.88 + 1.406 0 0 .
3 UN TPAFE5160 57.50 0.38 - 1.497 0 0 .
4 IA TPAFE5160 63.00 0.31 + 1.369 0 0 .
5 IB STM32-ADC1 46.00 9.67 + 1.372 0 0 .
6 IC STM32-ADC1 52.00 6.85 + 1.415 0 0 .
7 IN STM32-ADC1 48.00 8.46 + 1.397 0 0 .
clip reconcile: measured=0x0002 [UB] header=0x00E6 [UB UC IB IC IN] MISMATCH
yardstick: equality (default card check) -- measured rail pins must equal the sealed clip_mask
note: header clip_mask is the seal-time CLIPPED STAMP, source-derived in V0.1 (App/algo/adc_cal.c: s_rom_k_stm32 -> CLIPPED, unipolar no-bias), NOT measured from samples; measured is this segment's rail pins. Real V0.1 AC waves bottom-rail the 5 stamped channels, so equality is expected on-board; a non-railed measurement means synthetic fixture (e.g. column ramps) or wiring change -- investigate, do not auto-blame the seal
## WAVE10 shape
unit: mV eng=0(pin-domain) min-run for rail pin = 4 samples
CH NAME SRC CYCLES AMP[mVpk] POL SYM PIN_LO PIN_HI RAIL
0 UA TPAFE5160 0.50 1408.39 + 1.978 0 0 .
1 UB STM32-ADC1 60.50 10.07 + 1.501 0 0 .
2 UC STM32-ADC1 52.50 10.47 + 1.510 0 0 .
3 UN TPAFE5160 0.50 6.03 - 2.029 0 0 .
4 IA TPAFE5160 55.00 0.31 + 1.491 0 0 .
5 IB STM32-ADC1 51.50 9.67 + 1.501 0 0 .
6 IC STM32-ADC1 59.50 10.07 + 1.501 0 0 .
7 IN STM32-ADC1 62.50 10.07 + 1.446 0 0 .
clip reconcile: measured=0x0000 [-] header=0x00E6 [UB UC IB IC IN] MISMATCH
yardstick: equality (default card check) -- measured rail pins must equal the sealed clip_mask
note: header clip_mask is the seal-time CLIPPED STAMP, source-derived in V0.1 (App/algo/adc_cal.c: s_rom_k_stm32 -> CLIPPED, unipolar no-bias), NOT measured from samples; measured is this segment's rail pins. Real V0.1 AC waves bottom-rail the 5 stamped channels, so equality is expected on-board; a non-railed measurement means synthetic fixture (e.g. column ramps) or wiring change -- investigate, do not auto-blame the seal
## WAVE10 fft ch0
unit: mV eng=0 (pin-domain) [pin-domain = ADC pin voltage, NOT calibrated secondary]
CH NAME SRC CYCLE RMS-f[mV] ANG-f[deg] RMS-2x[mV] RMS-5x[mV] NOTE
(f = fundamental; 2x/5x = 2nd and 5th harmonic; angle reference = first sample of this window, not a phase lock to the signal generator)
0 UA TPAFE5160 0 5.84 -139.52 2.44 0.99
0 UA TPAFE5160 1 15.51 -3.23 7.70 3.32
0 UA TPAFE5160 2 34.58 +4.50 17.43 7.66
0 UA TPAFE5160 3 51.19 +6.65 25.83 11.18
0 UA TPAFE5160 4 65.00 +7.38 32.69 14.36
0 UA TPAFE5160 5 74.50 +7.99 37.69 16.46
0 UA TPAFE5160 6 79.59 +8.70 40.07 17.62
0 UA TPAFE5160 7 79.39 +9.29 40.10 17.47
0 UA TPAFE5160 8 74.51 +9.87 37.56 16.41
0 UA TPAFE5160 9 64.92 +10.63 32.72 14.33
0 UA TPAFE5160 10 50.99 +11.42 25.81 11.22
0 UA TPAFE5160 11 34.17 +13.62 16.93 7.45
0 UA TPAFE5160 12 14.93 +20.84 7.48 3.33
0 UA TPAFE5160 13 5.76 +157.00 2.59 1.09
0 UA TPAFE5160 14 25.10 -177.39 12.59 5.53
0 UA TPAFE5160 15 43.38 -174.63 22.02 9.64
0 UA TPAFE5160 ALL mean= 44.96 min= 5.76 max= 79.59 over 16 cycles
note: mV = (code + b_codes) * k_q16/65536/1000 (adc_cal_apply formula, unit labeled by header eng, never re-guessed); full-cycle window, coefficients = sin/cos(2*pi*k/N)*sqrt(2)/N as in App/algo/phasor.c; phase = atan2(im,re) deg
@@ -0,0 +1,74 @@
# 回放页坏段/空态画面闭环证据(2026-11-06,台架远程轮)
本目录是 `docs/子系统设计/故障录波设计说明.md` §10「回放页坏段/空态画面闭环记录」的图源留档,
执行 `docs/测试说明/专项验证/故障录波板级到场轮执行手册.md` 第二幕 §4 步 7 与其空态收尾:
**真机回放页上把「坏段拒收」与「无录波段」两种画面拍下来存证,判据 = 绝不许画成一条直线**。
台架远程操作、bench 锁全程持有(`remote-shoot-68-274d2d56da74`,17:03:38 起);固件身份
`Nov 6 2026 00:17:43 suite=NONE`(#53 台架轮复核构建,回放页代码自 2026-11-02 修复后未再改动);
所有画面帧由 `scripts/board_ui_nav.py` 的 7003 链路取 `LCDMEM` 原帧(160×160 1bpp 3200 B,
本目录 PNG 按 **4×** 放大渲染,与 wave_enum_20261102 同法),同一次上电、同一块板。
## 三态画面(判据对照)
| 文件 | 画面 | 说明 |
|---|---|---|
| `good_wave06_sec6_ua.png` | `UA SEG6 M` 阶梯正弦 + 0 线 + 触发光标,Pk≈1423 mV | **覆盖前**:WAVE06 原件在盘、回放页正常放波(对照基准) |
| `bad_segment_reject_wave06.png` | 仅「录波回放」标题 + 「该段不可读」 | **覆盖后同号翻位坏段的拒收态**:零波形元素、零顶行/底行字段——绝不许画直线,判据过 |
| `empty_state_no_segments.png` | 仅「录波回放」标题 + 「无录波段」 | **真·空态**:FTP 把 `/WAVE` 十件全删后开页;串口同刻 `[ERR][UI_TASK] ui wave head idx=8 open fail fr=4`(FR_NO_FILE=卷上真没有) |
| `empty_state_recheck.png` | 同上 | 空态下按 `r`(再探盘)画面逐字节不变(两 `_raw3200.bin` sha 相同) |
| `after_restore_page_normal.png` | 网格 + 0 线 + 光标恢复绘制 | 九件原件逐件 RETR+sha256 复验后重开页,正常态回归;页面回落到 RAM 记忆的 SEC5 段,故该帧与 `arrival_open_waveplay.png` **逐字节相同**——收工画面 = 到场画面,正是想要的巧合 |
| `arrival_open_waveplay.png` | `UA SEC5 M` 平线 + PK1744mV | 到场首帧(开页落数值最大段前身的 SEC5;平线是该段真实数据,非缺陷) |
各 PNG 附同屏 `_raw3200.bin` 原始帧,供逐比特复核。
## 坏段制造口径(手册 §4 步 7 原文流)
`RETR WAVE06.BIN → byte[130] ^= 0x01(数据区内翻一位)→ STOR 同号覆盖`。页开着覆盖、
`r` 走满一圈(周期 9)再入该段即触发读侧判废:`ui_task_wave_load_head()` 头 CRC+长度等式+
数据区流式 CRC 全量验(`App/task/ui_task.c`),任一不符即 `UI_WAVE_BAD` → 页面显式文案。
样本在 `samples/`:`WAVE06_original.BIN`(sha256 `9f88ee34…`,与覆盖后板上现行字节复验一致)
与 `WAVE06_bitflip_reject.BIN`(sha256 `a9e097bf…`),两件只差第 131 字节一比特。
PC 侧同件判据实录见 `pc_side_dump.txt`:`test/host/wave_read.py dump` 对坏件打印
`REJECT: … data CRC16 mismatch: stored 0xF991 calc 0xB111 over 5120 bytes at offset 128 --
segment rejected, nothing drawn`(rc=1),对原件双 CRC OK(rc=0)——板上画面与 PC 解码器
**同一判据、两份独立实现**互证。
## 串口与时间线
`serial_excerpt.txt` 为 serial-assistant 日志摘录(原样、剔除 `seg=0` 心跳行),关键锚点:
- 18:11:18 开页 → 18:11:38 `[FTP] UPLOAD '/WAVE/WAVE06.BIN' 5250 bytes OK`(坏版覆盖)→
18:11:39 RETR 复验 sha=坏 → **18:12:02 抓屏拒收态** → 18:12:01 `UPLOAD '/WAVE/WAVE06.BIN' OK`(原字节恢复);
- 18:14:42–47 `DELE WAVE00…09.BIN` ×10 → 18:14:55/58 三次 `open fail fr=4`(段表记忆 idx=8、
盘上已无文件 → FR_NO_FILE,正是留痕本意)→ **18:14:59 抓屏空态** →
18:15:04–13 `STOR` 九件恢复(每件后随 RETR 复验 sha256);
- 两窗之间全程 `wave:` 心跳 `err=0 ovf=0`,无一轮 [ERR] 越界(空态那次 fr=4 是留痕本意,见修复记录小节)。
自动化事件日志(含每步帧名/ink/位差判定):`shoot_phase2c.py` / `shoot_phase3b.py` 产物在会话
`ci-artifacts/shoot/phase2c.json`、`phase3b.json`(一次性产物,随会话留存不入台账;本目录即台账面)。
## 两条现场发现
- **F1(已知缓存纪律的实面)**:开机后 `STOR` 新文件(先攻用 `WAVE09.BIN`,坏版与有效版都试过)
**不进回放页段表**——表只在 `manual_req` 或「当前段消失」时重扫(`ui_task_wave_scan` 钉表纪律,
2026-11-02 v1.6),页开关不触发重扫。故本幕尾步按手册原文改用**列内既有段同号覆盖**,一次即中。
这不是缺陷(写侧轮转覆盖走 find-失败重扫路,天然收敛),但 FTP 手工投放段要让回放页看见,
需同号顶掉当前段或触发一次手动录波——记此免得后人重踩。
- **F2(拒收留痕口径确认)**:数据 CRC 判废在串口**静默**(留痕只给「表上有、开档失败」的
`open fail fr=` 一类,判废靠画面自证)——与 2026-11-02 修复记录的留痕设计一致,本轮实测无违和。
## 收工处置(手册 §7 二选一)
**不留常设负样本**:坏段样本已从板上删除(`WAVE09.BIN` 为本轮投放件、一并删除),`/WAVE` 恢复
到场时的九件原件且逐件 sha256 复验一致(清单见 `manifest_sha256.json` 与 §10 记录);`samples/`
两件即「删除」分支的点名留档。固件仍为在场构建、UI 停 STANDBY、bench 锁收工释放。
## 复现口令(台架同环境)
1. `& .venv\Scripts\python.exe scripts\board_ui_nav.py --where --i-hold-bench-lock`(身份互证)
2. FTP `admin` 登录 → `CWD /WAVE` → `RETR WAVE06.BIN` → 翻 `byte[130]` → `STOR WAVE06.BIN`(页开着覆盖)
3. `& .venv\Scripts\python.exe test\host\wave_read.py dump <坏件>`(应 REJECT rc=1)
4. 7003 开回放页(记录查询列第 10 行)→ `r` 走满一圈回踩该段 → `LCDMEM` 取帧(本目录坏段帧生成法)
5. `DELE` 全部段 → 关开页 → 取空态帧 → `STOR` 九件原件恢复(逐件 RETR+sha 复验)
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 949 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 949 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

@@ -0,0 +1,20 @@
{
"README.md": "bbffa3ed7ea5c1fb25d7d63f1ea5b10c37e8fd8ff7bffefe71605e649c503ad8",
"after_restore_page_normal.png": "d0fd54629f7b597a24247ee4d5707d80528da87bf68d9016cbf0199ec6c43cb8",
"after_restore_page_normal_raw3200.bin": "4deecb9373f766e3263e4b890bd7882798b91374aec43b7fc6e96dba3f353704",
"arrival_open_waveplay.png": "d0fd54629f7b597a24247ee4d5707d80528da87bf68d9016cbf0199ec6c43cb8",
"arrival_open_waveplay_raw3200.bin": "4deecb9373f766e3263e4b890bd7882798b91374aec43b7fc6e96dba3f353704",
"bad_segment_reject_wave06.png": "a013fdf6dbab1068a7b72b8239ac573c70cea5e8de8df9214ddc5cf153586b83",
"bad_segment_reject_wave06_raw3200.bin": "17291a0068f2d4ab099f636888e809941ad9bba52cad942ff6341a8677b72889",
"empty_state_no_segments.png": "ecb6151668b0d5ef0578576dd449d9d9a7f41031fd7c9f035a98de7132853d1b",
"empty_state_no_segments_raw3200.bin": "a76c41cfd7f38cecf1092777371869a0a28a4c0ca09eb6963e17afc94d713f66",
"empty_state_recheck.png": "ecb6151668b0d5ef0578576dd449d9d9a7f41031fd7c9f035a98de7132853d1b",
"empty_state_recheck_raw3200.bin": "a76c41cfd7f38cecf1092777371869a0a28a4c0ca09eb6963e17afc94d713f66",
"good_wave06_sec6_ua.png": "db205b08fb77ac51350b802b3541dd310de1eb7ec9529d9867f64794c1aa7d6b",
"good_wave06_sec6_ua_raw3200.bin": "d6a3ac65e04d5e62007d1f13b84be38982f0b217a4e4730037a54c1864854261",
"pc_side_dump.txt": "44890852d5560073359f6e7adad03fb8c7e06e24605dfe5b1c18d4fbf8985ae6",
"serial_excerpt.txt": "f4cf0ba2eada42917abc6d2347b2e3bde041a1ff4034b48d751f5d4f6f5a66a3",
"samples/WAVE06_bitflip_reject.BIN": "a9e097bfaa0e3df8542c637c29f120d1dee347956cf0013478448861f13c40ae",
"samples/WAVE06_original.BIN": "9f88ee3490c40867299e624a2eb2323ec33bb9ca5957737d2018b9e60205a6cc",
"samples/WAVE09_seed_bitflip_reject.BIN": "b4016966c6feed92b8a7f42ce42c109dbb8a608b9531f9bad35595c22d3d6471"
}
@@ -0,0 +1,44 @@
### dump WAVE06_original.BIN(覆盖前原件,板上现行字节) → rc=0
```
FILE : WAVE06_original.BIN (5250 bytes)
magic : 57 52 01 ('WR' + version byte 1)
ver : 1
fs_hz : 1000
pts_per_cycle : 20
ch_count : 8
pts_per_ch : 320 (320 ms at 1000 Hz)
pre_pts : 160
trig_src : 1 (MANUAL)
trig_elm : 0
t0_ms : 1246139 (ms since power-on)
wall : 1793609165 (epoch s)
eng : 0 (pin-domain)
flags_seq : 0x00 VALID bits: (none)
clip_mask : 0x00E6 [UB UC IB IC IN]
frame_seq : 1245891
CRC16(hdr) : 0x0C3B OK covers [0,126), low byte first
CRC16(data) : 0xF991 OK covers 5120 bytes, low byte first
-- channel table (8 entries x 12 B) --
IDX SEM NAME SRC BITS AVAIL K_Q16 B_CODES LSB_uV FLAG
0 0 UA TPAFE5160 16 0x00 10000000 0 152.587891 .
1 1 UB STM32-ADC1 12 0x02 52800000 0 805.664062 CLIPPED
2 2 UC STM32-ADC1 12 0x02 52800000 0 805.664062 CLIPPED
3 3 UN TPAFE5160 16 0x00 10000000 0 152.587891 .
4 4 IA TPAFE5160 16 0x00 10000000 0 152.587891 .
5 5 IB STM32-ADC1 12 0x02 52800000 0 805.664062 CLIPPED
6 6 IC STM32-ADC1 12 0x02 52800000 0 805.664062 CLIPPED
7 7 IN STM32-ADC1 12 0x02 52800000 0 805.664062 CLIPPED
```
### dump WAVE06_bitflip_reject.BIN(byte[130]^=0x01 同号覆盖件) → rc=1
```
REJECT: WAVE06_bitflip_reject.BIN: data CRC16 mismatch: stored 0xF991 calc 0xB111 over 5120 bytes at offset 128 -- segment rejected, nothing drawn
```
### dump WAVE09_seed_bitflip_reject.BIN(第二幕首攻样本:20261104 真段种子翻位,未进枚举见 README 发现 F1) → rc=1
```
REJECT: WAVE09_seed_bitflip_reject.BIN: data CRC16 mismatch: stored 0xF8AA calc 0xB02A over 5120 bytes at offset 128 -- segment rejected, nothing drawn
```
@@ -0,0 +1,180 @@
串口实录摘录(serial-assistant 日志原样,剔除 seg=0 心跳行)——2026-11-06 第二幕尾步两窗:
窗一 17:52:3x–17:54:5x:WAVE09 新文件首攻(坏版 STOR + 关开页,见 README 发现 F1)
窗二 18:10:0x–18:16:0x:同号覆盖主链(18:11:38 坏版 STOR→18:12:01 原字节恢复)+ 全删空态(18:14:4x DELE×10 → 18:14:55 open fail fr=4 → 18:15:0x-14 STOR 恢复×9 RETR sha 验)
[RX] 2026-11-06T17:52:35.660+08:00 [2026-11-06 17:52:34] [FTP] connection received from 192.168.31.161:60945...
[RX] 2026-11-06T17:52:35.670+08:00 [2026-11-06 17:52:34] [FTP] CMD USER admin
[RX] 2026-11-06T17:52:35.670+08:00 [2026-11-06 17:52:34] [FTP] CMD PASS admin
[RX] 2026-11-06T17:52:35.670+08:00 [2026-11-06 17:52:34] [FTP] CMD CWD /WAVE
[RX] 2026-11-06T17:52:35.680+08:00 [2026-11-06 17:52:34] [FTP] CMD TYPE A
[RX] 2026-11-06T17:52:35.691+08:00 [2026-11-06 17:52:34] [FTP] CMD PASV
[RX] 2026-11-06T17:52:35.742+08:00 [2026-11-06 17:52:34] [FTP] CMD NLST
[RX] 2026-11-06T17:52:35.918+08:00 [2026-11-06 17:52:34] [FTP] CMD TYPE I
[RX] 2026-11-06T17:52:35.918+08:00 [2026-11-06 17:52:34] [FTP] CMD PASV
[RX] 2026-11-06T17:52:35.969+08:00 [2026-11-06 17:52:34] [FTP] CMD STOR WAVE09.BIN
[RX] 2026-11-06T17:52:36.052+08:00 [2026-11-06 17:52:34] [FTP] UPLOAD '/WAVE/WAVE09.BIN' 5250 bytes OK
[RX] 2026-11-06T17:52:36.661+08:00 [2026-11-06 17:52:35] [FTP] CMD TYPE A
[RX] 2026-11-06T17:52:36.661+08:00 [2026-11-06 17:52:35] [FTP] CMD PASV
[RX] 2026-11-06T17:52:36.724+08:00 [2026-11-06 17:52:35] [FTP] CMD NLST
[RX] 2026-11-06T17:52:36.910+08:00 [2026-11-06 17:52:35] [FTP] CMD TYPE I
[RX] 2026-11-06T17:52:36.910+08:00 [2026-11-06 17:52:35] [FTP] CMD PASV
[RX] 2026-11-06T17:52:36.962+08:00 [2026-11-06 17:52:35] [FTP] CMD RETR WAVE09.BIN
[RX] 2026-11-06T17:52:37.128+08:00 [2026-11-06 17:52:36] [FTP] DOWNLOAD '/WAVE/WAVE09.BIN' OK
[RX] 2026-11-06T17:52:37.128+08:00 [2026-11-06 17:52:36] [FTP] CMD QUIT
[RX] 2026-11-06T17:52:37.149+08:00 [2026-11-06 17:52:36] [FTP] waiting for connection...
[RX] 2026-11-06T17:52:39.623+08:00 [2026-11-06 17:52:38][UI_CONTENT_PAGE] page close: id=wave_play
[RX] 2026-11-06T17:52:43.461+08:00 [2026-11-06 17:52:42][UI_CONTENT_PAGE] page open: id=wave_play rows=0
[RX] 2026-11-06T18:10:04.225+08:00 [2026-11-06 18:10:03] [FTP] connection received from 192.168.31.161:54991...
[RX] 2026-11-06T18:10:04.225+08:00 [2026-11-06 18:10:03] [FTP] CMD USER admin
[RX] 2026-11-06T18:10:04.246+08:00 [2026-11-06 18:10:03] [FTP] CMD PASS admin
[RX] 2026-11-06T18:10:04.257+08:00 [2026-11-06 18:10:03] [FTP] CMD CWD /WAVE
[RX] 2026-11-06T18:10:04.278+08:00 [2026-11-06 18:10:03] [FTP] CMD TYPE I
[RX] 2026-11-06T18:10:04.289+08:00 [2026-11-06 18:10:03] [FTP] CMD PASV
[RX] 2026-11-06T18:10:04.424+08:00 [2026-11-06 18:10:03] [FTP] CMD STOR WAVE06.BIN
[RX] 2026-11-06T18:10:04.487+08:00 [2026-11-06 18:10:03] [FTP] UPLOAD '/WAVE/WAVE06.BIN' 5250 bytes OK
[RX] 2026-11-06T18:10:05.098+08:00 [2026-11-06 18:10:03] [FTP] CMD TYPE I
[RX] 2026-11-06T18:10:05.098+08:00 [2026-11-06 18:10:04] [FTP] CMD PASV
[RX] 2026-11-06T18:10:05.171+08:00 [2026-11-06 18:10:04] [FTP] CMD RETR WAVE06.BIN
[RX] 2026-11-06T18:10:05.346+08:00 [2026-11-06 18:10:04] [FTP] DOWNLOAD '/WAVE/WAVE06.BIN' OK
[RX] 2026-11-06T18:10:05.357+08:00 [2026-11-06 18:10:04] [FTP] CMD QUIT
[RX] 2026-11-06T18:10:05.367+08:00 [2026-11-06 18:10:04] [FTP] waiting for connection...
[RX] 2026-11-06T18:11:20.089+08:00 [2026-11-06 18:11:18][UI_CONTENT_PAGE] page open: id=wave_play rows=0
[RX] 2026-11-06T18:11:38.915+08:00 [2026-11-06 18:11:37] [FTP] connection received from 192.168.31.161:54867...
[RX] 2026-11-06T18:11:38.936+08:00 [2026-11-06 18:11:37] [FTP] CMD USER admin
[RX] 2026-11-06T18:11:38.946+08:00 [2026-11-06 18:11:37] [FTP] CMD PASS admin
[RX] 2026-11-06T18:11:38.967+08:00 [2026-11-06 18:11:37] [FTP] CMD CWD /WAVE
[RX] 2026-11-06T18:11:38.967+08:00 [2026-11-06 18:11:37] [FTP] CMD TYPE I
[RX] 2026-11-06T18:11:38.998+08:00 [2026-11-06 18:11:37] [FTP] CMD PASV
[RX] 2026-11-06T18:11:39.122+08:00 [2026-11-06 18:11:38] [FTP] CMD STOR WAVE06.BIN
[RX] 2026-11-06T18:11:39.216+08:00 [2026-11-06 18:11:38] [FTP] UPLOAD '/WAVE/WAVE06.BIN' 5250 bytes OK
[RX] 2026-11-06T18:11:39.837+08:00 [2026-11-06 18:11:38] [FTP] CMD TYPE I
[RX] 2026-11-06T18:11:39.837+08:00 [2026-11-06 18:11:38] [FTP] CMD PASV
[RX] 2026-11-06T18:11:39.879+08:00 [2026-11-06 18:11:38] [FTP] CMD RETR WAVE06.BIN
[RX] 2026-11-06T18:11:40.013+08:00 [2026-11-06 18:11:38] [FTP] DOWNLOAD '/WAVE/WAVE06.BIN' OK
[RX] 2026-11-06T18:11:40.013+08:00 [2026-11-06 18:11:38] [FTP] CMD QUIT
[RX] 2026-11-06T18:11:40.023+08:00 [2026-11-06 18:11:38] [FTP] waiting for connection...
[RX] 2026-11-06T18:12:02.780+08:00 [2026-11-06 18:12:01] [FTP] connection received from 192.168.31.161:53103...
[RX] 2026-11-06T18:12:02.802+08:00 [2026-11-06 18:12:01] [FTP] CMD USER admin
[RX] 2026-11-06T18:12:02.812+08:00 [2026-11-06 18:12:01] [FTP] CMD PASS admin
[RX] 2026-11-06T18:12:02.895+08:00 [2026-11-06 18:12:01] [FTP] CMD CWD /WAVE
[RX] 2026-11-06T18:12:02.895+08:00 [2026-11-06 18:12:01] [FTP] CMD TYPE I
[RX] 2026-11-06T18:12:02.895+08:00 [2026-11-06 18:12:01] [FTP] CMD PASV
[RX] 2026-11-06T18:12:02.957+08:00 [2026-11-06 18:12:01] [FTP] CMD STOR WAVE06.BIN
[RX] 2026-11-06T18:12:03.030+08:00 [2026-11-06 18:12:01] [FTP] UPLOAD '/WAVE/WAVE06.BIN' 5250 bytes OK
[RX] 2026-11-06T18:12:03.633+08:00 [2026-11-06 18:12:02] [FTP] CMD TYPE I
[RX] 2026-11-06T18:12:03.643+08:00 [2026-11-06 18:12:02] [FTP] CMD PASV
[RX] 2026-11-06T18:12:03.705+08:00 [2026-11-06 18:12:02] [FTP] CMD RETR WAVE06.BIN
[RX] 2026-11-06T18:12:03.839+08:00 [2026-11-06 18:12:02] [FTP] DOWNLOAD '/WAVE/WAVE06.BIN' OK
[RX] 2026-11-06T18:12:03.839+08:00 [2026-11-06 18:12:02] [FTP] CMD QUIT
[RX] 2026-11-06T18:12:03.860+08:00 [2026-11-06 18:12:02] [FTP] waiting for connection...
[RX] 2026-11-06T18:14:44.047+08:00 [2026-11-06 18:14:42] [FTP] connection received from 192.168.31.161:58594...
[RX] 2026-11-06T18:14:44.057+08:00 [2026-11-06 18:14:42] [FTP] CMD USER admin
[RX] 2026-11-06T18:14:44.057+08:00 [2026-11-06 18:14:42] [FTP] CMD PASS admin
[RX] 2026-11-06T18:14:44.067+08:00 [2026-11-06 18:14:42] [FTP] CMD CWD /WAVE
[RX] 2026-11-06T18:14:44.067+08:00 [2026-11-06 18:14:42] [FTP] CMD TYPE A
[RX] 2026-11-06T18:14:44.078+08:00 [2026-11-06 18:14:42] [FTP] CMD PASV
[RX] 2026-11-06T18:14:44.151+08:00 [2026-11-06 18:14:43] [FTP] CMD LIST
[RX] 2026-11-06T18:14:44.285+08:00 [2026-11-06 18:14:43] [FTP] CMD DELE WAVE00.BIN
[RX] 2026-11-06T18:14:44.627+08:00 [2026-11-06 18:14:43] [FTP] CMD DELE WAVE01.BIN
[RX] 2026-11-06T18:14:44.969+08:00 [2026-11-06 18:14:43] [FTP] CMD DELE WAVE02.BIN
[RX] 2026-11-06T18:14:45.312+08:00 [2026-11-06 18:14:44] [FTP] CMD DELE WAVE03.BIN
[RX] 2026-11-06T18:14:45.644+08:00 [2026-11-06 18:14:44] [FTP] CMD DELE WAVE04.BIN
[RX] 2026-11-06T18:14:45.997+08:00 [2026-11-06 18:14:44] [FTP] CMD DELE WAVE05.BIN
[RX] 2026-11-06T18:14:46.340+08:00 [2026-11-06 18:14:45] [FTP] CMD DELE WAVE06.BIN
[RX] 2026-11-06T18:14:46.672+08:00 [2026-11-06 18:14:45] [FTP] CMD DELE WAVE07.BIN
[RX] 2026-11-06T18:14:47.016+08:00 [2026-11-06 18:14:45] [FTP] CMD DELE WAVE08.BIN
[RX] 2026-11-06T18:14:47.358+08:00 [2026-11-06 18:14:46] [FTP] CMD DELE WAVE09.BIN
[RX] 2026-11-06T18:14:48.292+08:00 [2026-11-06 18:14:47] [FTP] CMD TYPE A
[RX] 2026-11-06T18:14:48.292+08:00 [2026-11-06 18:14:47] [FTP] CMD PASV
[RX] 2026-11-06T18:14:48.364+08:00 [2026-11-06 18:14:47] [FTP] CMD LIST
[RX] 2026-11-06T18:14:48.560+08:00 [2026-11-06 18:14:47] [FTP] CMD QUIT
[RX] 2026-11-06T18:14:48.602+08:00 [2026-11-06 18:14:47] [FTP] waiting for connection...
[RX] 2026-11-06T18:14:52.299+08:00 [2026-11-06 18:14:51][UI_CONTENT_PAGE] page close: id=wave_play
[RX] 2026-11-06T18:14:56.144+08:00 [2026-11-06 18:14:55][UI_CONTENT_PAGE] page open: id=wave_play rows=0
[RX] 2026-11-06T18:14:56.155+08:00 [2026-11-06 18:14:55][ERR][UI_TASK] ui wave head idx=8 open fail fr=4
[RX] 2026-11-06T18:14:59.703+08:00 [2026-11-06 18:14:58][ERR][UI_TASK] ui wave head idx=8 open fail fr=4
[RX] 2026-11-06T18:14:59.724+08:00 [2026-11-06 18:14:58][ERR][UI_TASK] ui wave head idx=8 open fail fr=4
[RX] 2026-11-06T18:15:02.069+08:00 [2026-11-06 18:15:00][UI_CONTENT_PAGE] page close: id=wave_play
[RX] 2026-11-06T18:15:05.361+08:00 [2026-11-06 18:15:04] [FTP] connection received from 192.168.31.161:60925...
[RX] 2026-11-06T18:15:05.372+08:00 [2026-11-06 18:15:04] [FTP] CMD USER admin
[RX] 2026-11-06T18:15:05.372+08:00 [2026-11-06 18:15:04] [FTP] CMD PASS admin
[RX] 2026-11-06T18:15:05.382+08:00 [2026-11-06 18:15:04] [FTP] CMD CWD /WAVE
[RX] 2026-11-06T18:15:05.382+08:00 [2026-11-06 18:15:04] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:05.393+08:00 [2026-11-06 18:15:04] [FTP] CMD PASV
[RX] 2026-11-06T18:15:05.466+08:00 [2026-11-06 18:15:04] [FTP] CMD STOR WAVE00.BIN
[RX] 2026-11-06T18:15:05.529+08:00 [2026-11-06 18:15:04] [FTP] UPLOAD '/WAVE/WAVE00.BIN' 5250 bytes OK
[RX] 2026-11-06T18:15:06.130+08:00 [2026-11-06 18:15:05] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:06.140+08:00 [2026-11-06 18:15:05] [FTP] CMD PASV
[RX] 2026-11-06T18:15:06.203+08:00 [2026-11-06 18:15:05] [FTP] CMD RETR WAVE00.BIN
[RX] 2026-11-06T18:15:06.367+08:00 [2026-11-06 18:15:05] [FTP] DOWNLOAD '/WAVE/WAVE00.BIN' OK
[RX] 2026-11-06T18:15:06.367+08:00 [2026-11-06 18:15:05] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:06.377+08:00 [2026-11-06 18:15:05] [FTP] CMD PASV
[RX] 2026-11-06T18:15:06.449+08:00 [2026-11-06 18:15:05] [FTP] CMD STOR WAVE01.BIN
[RX] 2026-11-06T18:15:06.522+08:00 [2026-11-06 18:15:05] [FTP] UPLOAD '/WAVE/WAVE01.BIN' 5250 bytes OK
[RX] 2026-11-06T18:15:07.135+08:00 [2026-11-06 18:15:06] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:07.135+08:00 [2026-11-06 18:15:06] [FTP] CMD PASV
[RX] 2026-11-06T18:15:07.197+08:00 [2026-11-06 18:15:06] [FTP] CMD RETR WAVE01.BIN
[RX] 2026-11-06T18:15:07.363+08:00 [2026-11-06 18:15:06] [FTP] DOWNLOAD '/WAVE/WAVE01.BIN' OK
[RX] 2026-11-06T18:15:07.363+08:00 [2026-11-06 18:15:06] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:07.373+08:00 [2026-11-06 18:15:06] [FTP] CMD PASV
[RX] 2026-11-06T18:15:07.445+08:00 [2026-11-06 18:15:06] [FTP] CMD STOR WAVE02.BIN
[RX] 2026-11-06T18:15:07.519+08:00 [2026-11-06 18:15:06] [FTP] UPLOAD '/WAVE/WAVE02.BIN' 5250 bytes OK
[RX] 2026-11-06T18:15:08.141+08:00 [2026-11-06 18:15:07] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:08.152+08:00 [2026-11-06 18:15:07] [FTP] CMD PASV
[RX] 2026-11-06T18:15:08.193+08:00 [2026-11-06 18:15:07] [FTP] CMD RETR WAVE02.BIN
[RX] 2026-11-06T18:15:08.370+08:00 [2026-11-06 18:15:07] [FTP] DOWNLOAD '/WAVE/WAVE02.BIN' OK
[RX] 2026-11-06T18:15:08.381+08:00 [2026-11-06 18:15:07] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:08.381+08:00 [2026-11-06 18:15:07] [FTP] CMD PASV
[RX] 2026-11-06T18:15:08.454+08:00 [2026-11-06 18:15:07] [FTP] CMD STOR WAVE03.BIN
[RX] 2026-11-06T18:15:08.538+08:00 [2026-11-06 18:15:07] [FTP] UPLOAD '/WAVE/WAVE03.BIN' 5250 bytes OK
[RX] 2026-11-06T18:15:09.139+08:00 [2026-11-06 18:15:08] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:09.150+08:00 [2026-11-06 18:15:08] [FTP] CMD PASV
[RX] 2026-11-06T18:15:09.191+08:00 [2026-11-06 18:15:08] [FTP] CMD RETR WAVE03.BIN
[RX] 2026-11-06T18:15:09.366+08:00 [2026-11-06 18:15:08] [FTP] DOWNLOAD '/WAVE/WAVE03.BIN' OK
[RX] 2026-11-06T18:15:09.366+08:00 [2026-11-06 18:15:08] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:09.377+08:00 [2026-11-06 18:15:08] [FTP] CMD PASV
[RX] 2026-11-06T18:15:09.461+08:00 [2026-11-06 18:15:08] [FTP] CMD STOR WAVE04.BIN
[RX] 2026-11-06T18:15:09.512+08:00 [2026-11-06 18:15:08] [FTP] UPLOAD '/WAVE/WAVE04.BIN' 5250 bytes OK
[RX] 2026-11-06T18:15:10.117+08:00 [2026-11-06 18:15:09] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:10.127+08:00 [2026-11-06 18:15:09] [FTP] CMD PASV
[RX] 2026-11-06T18:15:10.191+08:00 [2026-11-06 18:15:09] [FTP] CMD RETR WAVE04.BIN
[RX] 2026-11-06T18:15:10.367+08:00 [2026-11-06 18:15:09] [FTP] DOWNLOAD '/WAVE/WAVE04.BIN' OK
[RX] 2026-11-06T18:15:10.367+08:00 [2026-11-06 18:15:09] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:10.378+08:00 [2026-11-06 18:15:09] [FTP] CMD PASV
[RX] 2026-11-06T18:15:10.450+08:00 [2026-11-06 18:15:09] [FTP] CMD STOR WAVE05.BIN
[RX] 2026-11-06T18:15:10.513+08:00 [2026-11-06 18:15:09] [FTP] UPLOAD '/WAVE/WAVE05.BIN' 5250 bytes OK
[RX] 2026-11-06T18:15:11.117+08:00 [2026-11-06 18:15:10] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:11.127+08:00 [2026-11-06 18:15:10] [FTP] CMD PASV
[RX] 2026-11-06T18:15:11.190+08:00 [2026-11-06 18:15:10] [FTP] CMD RETR WAVE05.BIN
[RX] 2026-11-06T18:15:11.366+08:00 [2026-11-06 18:15:10] [FTP] DOWNLOAD '/WAVE/WAVE05.BIN' OK
[RX] 2026-11-06T18:15:11.366+08:00 [2026-11-06 18:15:10] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:11.377+08:00 [2026-11-06 18:15:10] [FTP] CMD PASV
[RX] 2026-11-06T18:15:11.555+08:00 [2026-11-06 18:15:10] [FTP] CMD STOR WAVE06.BIN
[RX] 2026-11-06T18:15:11.576+08:00 [2026-11-06 18:15:10] [FTP] UPLOAD '/WAVE/WAVE06.BIN' 5250 bytes OK
[RX] 2026-11-06T18:15:12.180+08:00 [2026-11-06 18:15:11] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:12.191+08:00 [2026-11-06 18:15:11] [FTP] CMD PASV
[RX] 2026-11-06T18:15:12.253+08:00 [2026-11-06 18:15:11] [FTP] CMD RETR WAVE06.BIN
[RX] 2026-11-06T18:15:12.398+08:00 [2026-11-06 18:15:11] [FTP] DOWNLOAD '/WAVE/WAVE06.BIN' OK
[RX] 2026-11-06T18:15:12.398+08:00 [2026-11-06 18:15:11] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:12.408+08:00 [2026-11-06 18:15:11] [FTP] CMD PASV
[RX] 2026-11-06T18:15:12.470+08:00 [2026-11-06 18:15:11] [FTP] CMD STOR WAVE07.BIN
[RX] 2026-11-06T18:15:12.554+08:00 [2026-11-06 18:15:11] [FTP] UPLOAD '/WAVE/WAVE07.BIN' 5250 bytes OK
[RX] 2026-11-06T18:15:13.156+08:00 [2026-11-06 18:15:12] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:13.156+08:00 [2026-11-06 18:15:12] [FTP] CMD PASV
[RX] 2026-11-06T18:15:13.207+08:00 [2026-11-06 18:15:12] [FTP] CMD RETR WAVE07.BIN
[RX] 2026-11-06T18:15:13.363+08:00 [2026-11-06 18:15:12] [FTP] DOWNLOAD '/WAVE/WAVE07.BIN' OK
[RX] 2026-11-06T18:15:13.363+08:00 [2026-11-06 18:15:12] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:13.374+08:00 [2026-11-06 18:15:12] [FTP] CMD PASV
[RX] 2026-11-06T18:15:13.447+08:00 [2026-11-06 18:15:12] [FTP] CMD STOR WAVE08.BIN
[RX] 2026-11-06T18:15:13.519+08:00 [2026-11-06 18:15:12] [FTP] UPLOAD '/WAVE/WAVE08.BIN' 5250 bytes OK
[RX] 2026-11-06T18:15:14.145+08:00 [2026-11-06 18:15:13] [FTP] CMD TYPE I
[RX] 2026-11-06T18:15:14.145+08:00 [2026-11-06 18:15:13] [FTP] CMD PASV
[RX] 2026-11-06T18:15:14.186+08:00 [2026-11-06 18:15:13] [FTP] CMD RETR WAVE08.BIN
[RX] 2026-11-06T18:15:14.363+08:00 [2026-11-06 18:15:13] [FTP] DOWNLOAD '/WAVE/WAVE08.BIN' OK
[RX] 2026-11-06T18:15:14.363+08:00 [2026-11-06 18:15:13] [FTP] CMD TYPE A
[RX] 2026-11-06T18:15:14.374+08:00 [2026-11-06 18:15:13] [FTP] CMD PASV
[RX] 2026-11-06T18:15:14.436+08:00 [2026-11-06 18:15:13] [FTP] CMD LIST
[RX] 2026-11-06T18:15:14.561+08:00 [2026-11-06 18:15:13] [FTP] CMD QUIT
[RX] 2026-11-06T18:15:14.571+08:00 [2026-11-06 18:15:13] [FTP] waiting for connection...
[RX] 2026-11-06T18:15:18.286+08:00 [2026-11-06 18:15:17][UI_CONTENT_PAGE] page open: id=wave_play rows=0
[RX] 2026-11-06T18:15:21.817+08:00 [2026-11-06 18:15:20][UI_CONTENT_PAGE] page close: id=wave_play
@@ -35,7 +35,8 @@ flowchart LR
DEV -- "USB:下载器(ST-Link 等)" --> TGT
DEV -- "USB 串口 USART1<br/>COMx @115200 调试日志" --> TGT
TGT -- "以太网(CH395F)<br/>FTP:21 / 对时:8888 / 显示:7003" --> RMT
TGT -- "以太网(CH395F)<br/>FTP:21 / 远程显示:7003" --> RMT
TGT -. "对时:SNTP 客户端 UDP 123 出向(原 :8888 推送已退役)" .-> NTP["现场 NTP / 时间源"]
```
| 环境 | 角色 | 必需性 |
@@ -567,7 +568,7 @@ $env:DTU_KEIL_UV4 = 'D:\NotExist\UV4.exe' # 仅当前会话,不动用户级
| 服务 | 协议/端口 | 用途 | 核对方法 |
|---|---|---|---|
| 远程显示(RemoDispBus) | TCP **7003** | 远端看图(160×160 1bpp,3200 B/帧,客户端 LCDMEM 拉取)+ 远端导航按键 | DTU-RemoteLCD 或任意 TCP 客户端连 7003 收帧 |
| 墙钟对时 | TCP **8888** | PC 主动推送时间到设备 | 对时推送后核对设备时间 / 日志时间戳 |
| 墙钟对时(SNTP 客户端) | UDP **123**(出向;主/备服务器配 `[sntp]` 段,enable 默认关) | 设备作 SNTP 客户端从时间源取时写回 RTC(原 PC 推送 TCP :8888 已于 2026-11-04 退役删除) | 使能对时后核对设备时间 / 日志时间戳 |
| FTP | TCP **21** | 文件上传/下载(根目录 `/`,NAND 存储) | 任意 FTP 客户端列目录/读写 |
> 现场组网要求:设备与客户端**同网段**(默认 .100/24、网关 .1);跨网段部署先按 §4.1 改 IP 再上线。
@@ -575,7 +576,7 @@ $env:DTU_KEIL_UV4 = 'D:\NotExist\UV4.exe' # 仅当前会话,不动用户级
### 4.3 存储与运行时
- 文件系统:FatFS(FAT32)挂 NAND;**上电无卷自动格式化**(`f_mkfs`);格式化会清除卷上全部文件(含网口配置 `/config.ini`)
- RTC:SD2506 芯片(驱动 `Drivers/BSP/SD2506/`)提供墙钟基准与日志时间戳;首次使用建议先经 8888 对时
- RTC:SD2506 芯片(驱动 `Drivers/BSP/SD2506/`)提供墙钟基准与日志时间戳;首次使用建议配 `[sntp]` 段启用 SNTP 对时(或 UI 手工对时)
- 启动时序:`app_main_init`(存储 → 时钟 → RS485 → NAND → ADC → 启动转换)→ 就绪屏障(STORAGE / NET / FTP / TIMESYNC 事件)→ 六任务运行;详见 `docs/架构设计/项目启动顺序管理.md`、`docs/架构设计/项目架构总览.md`
### 4.4 现场验收清单
@@ -587,7 +588,7 @@ $env:DTU_KEIL_UV4 = 'D:\NotExist\UV4.exe' # 仅当前会话,不动用户级
| 3 | 远程显示 | DTU-RemoteLCD 连 7003 | 出图(160×160 1bpp)+ 远端菜单导航可用 |
| 4 | FTP | FTP 客户端连 :21 | 列目录 / 读写 `/` 下文件 |
| 5 | UI 功能 | 屏幕 / 远端操作 | 菜单 7 项导航、内容页、密码(查看 `000` / 修改 `123`)、网口设置保存后立即生效 |
| 6 | 对时 | PC 推送 8888 | 设备墙钟更新、日志时间戳正确 |
| 6 | 对时 | 配 `[sntp]` 段启用 SNTP(或 UI 手工对时;原 PC 推送 8888 已退役) | 设备墙钟更新、日志时间戳正确 |
| 7 | 掉电保持 | 写文件 / 改网口配置 → 重启 | 数据仍在(`/config.ini` 按新值生效) |
| 8 | LED 状态 | 目检 | 6 路 LED 随系统状态变化(低电平点亮) |
@@ -599,7 +600,7 @@ $env:DTU_KEIL_UV4 = 'D:\NotExist\UV4.exe' # 仅当前会话,不动用户级
|---|---|---|
| 操作系统 | 任意(Windows / Linux / macOS,有浏览器或 Python 即可) | 与设备同网段 |
| 远程显示客户端 | **DTU-RemoteLCD**(独立项目:Flask + WebSocket 参考实现)或任意符合 RemoDispBus 协议的 TCP 客户端 | 连设备 **TCP 7003**;协议见 `docs/UI设计/RemoDispBus协议与接收设计说明.md` |
| 对时工具 | 任意可 TCP 推送的工具/脚本 | 向设备 **8888** 推送 |
| 对时时间源 | 现场可达的 SNTP/NTP 服务器(配 `[sntp]` 段 server1/server2) | 设备作客户端 UDP/123 出向取时;原「向设备 8888 推送」的 TCP 工具随退役不再需要 |
| FTP 客户端 | 任意(资源管理器 / FileZilla 等) | 设备端 lftpd,端口 21 |
| 浏览器 | Chrome / Edge | 查看参考客户端 Web 页;开发期浏览文档 SVG 图 |
+102 -7
View File
@@ -142,7 +142,7 @@ STM32(U17)为 LQFP144 脚号。
> 出处:`docs/任务规划/数据可信.md` §2.1(量程口径冻结)。本节把 **语义端子(二次侧)→ 子板/端子板 → 网名 `AINn` → 主板电阻网络 → 板级网名 `ADCn` → 转换器引脚 → 码值 → 满量程** 的链路**逐段**定口径。
> ③ 段(`AINn` ↔ 转换器引脚)已有台架实测数值——变比 **1:1**,斜率实测见 §8.1;④ 段(语义端子 ↔ `AINn` 的子板/
> 端子板变比)仓库内没有任何数据,只给口径与判据。
> 端子板变比)已于 **2026-11-06 按用户现场报参算定**(#41,登记与复核边界见 §7.2;子板原理图仍不在仓库内)。
**芯片级口径(定死,与前端网络无关)**:
@@ -171,19 +171,77 @@ STM32(U17)为 LQFP144 脚号。
| ① 语义 ↔ 网名 ↔ 板级网名 ↔ 转换器代码通道 | §2/§3/§4/§5 的 17 路映射表 | **定死**(本文件为唯一权威) |
| ② 转换器引脚电压 ↔ 码值 | TPAFE `U_pin = code × 152.59 µV`(code 带符号);STM32 `U_pin = code × 805.66 µV` | **定死**(纯转换器事实,上表) |
| ③ `AINn`(串联电阻子板侧)↔ `ADCn`/转换器引脚 | **变比 = 1:1(2026-10-27 定死)**:`ADCn` 节点只有 {串阻.2, 滤波 C, 转换器引脚},无对地元件(拓扑图见上)。旧"读法 A(2:1 分压 → 305.18 / 1611.3 µV/码)"**作废**——它是把接在差分负端的 1k 误读成对地分压 | **定死**(网表级结论 + **2026-10-27 台架实测确认**,见 §8.1:端子侧注入斜率 6544.2 码/V,与引脚侧理论 6553.6 差 0.14 %,不存在 2:1 分压)。已知电压注入验证已闭环 |
| ④ 语义端子(二次端子)↔ `AINn` | 子板/端子板变比:仓库内**无任何文档**(`docs/硬件平台/` 只有 `.tel` 网表与分析报告,无子板原理图;§8 步骤 4) | **缺口**——待「端子/子板变比确认」实测确认;拿不到变比则"端子二次值"不成立、`eng` 保持 0 |
| ④ 语义端子(二次端子)↔ `AINn` | 子板/端子板变比:**电压族(UA/UB/UC/UN)= 606.06 : 1(V/V)**、**电流族(IA/IB/IC/IN)= 29.4118 A/V**;由用户现场报参(2026-11-06,#41)按式算定,算式与复核边界见 §7.2 | **定死**(参数算定,非本板双表同测;数值确认归两点标定)——"端子二次值"口径成立;但 `eng` 在电气 8 路 `ADC_CAL_F_VALID` 全置位(两点标定卡)前**保持 0** |
**可评审结论**:
1. **ROM 默认系数按 ② 引脚口径冻结**:TPAFE 通道 `k = 152.59 µV/码`、STM32 通道 `k = 805.66 µV/码`;标定折算的输出单位 = **ADC 引脚电压 V**(`eng = 0`)。该口径**不依赖** ③④ 两个未决项,自本节点死即成立——这就是 M4 承诺边界止于“引脚电压”的依据(`docs/任务规划/数据可信.md` §2.6)。
1. **ROM 默认系数按 ② 引脚口径冻结**:TPAFE 通道 `k = 152.59 µV/码`、STM32 通道 `k = 805.66 µV/码`;标定折算的输出单位 = **ADC 引脚电压 V**(`eng = 0`)。该口径与 ③④ 变比何时定死**无关**,冻结当日即成立且此后不因 ④ 到手而改动——这就是 M4 承诺边界止于“引脚电压”的依据(`docs/任务规划/数据可信.md` §2.6)。
2. `docs/任务规划/数据可信.md` §2.1 旧表的“板级系数(输入侧)305.18 / 1611.3 µV/码”**已随 ③ 段定死而删除**(2026-10-27):该值按 2:1 分压折算,而网表证明 `ADCn` 节点无对地元件。板级系数 = 引脚侧系数(152.59 / 805.66);305.18 / 1611.3 今后只允许出现在“±10 V 档 LSB”语境(芯片手册口径),不得再当本板系数。
3. **满量程必须写明参考点**:TPAFE 通道满量程 = ±5 V **@ 引脚**(跨度 10 V);③ 已定 1:1、④ 仍未知,故端子侧满量程只允许写“引脚侧数值 × ④ 比”,**严禁**把“码 × 152.59 µV”当端子二次值写进代码/文档(那是引脚电压)。
3. **满量程必须写明参考点**:TPAFE 通道满量程 = ±5 V **@ 引脚**(跨度 10 V);③④ 现均已定死(④ 值见 §7.2),端子侧换算已允许写“引脚侧数值 × ④ 比”;但两点标定置 `VALID` 之前,**严禁**把“码 × 152.59 µV”当端子二次值写进代码/文档(那是引脚电压),§7.2 的标称系数只是算定值、不是已验证二次值。
4. **已知电压注入验证已于 2026-10-27 闭环**(六项判据全 PASS,实测见 §8.1):③ 段 1:1 由台架直接证实,
② 引脚侧 LSB 与实测斜率差 0.14 %,逐通道映射与极性均已验。**仍待实测的是 ④**(端子→引脚
变比,即端子/子板变比确认)与两点标定;两者完成前 `eng` 保持 0、输出单位仍是 ADC 引脚电压。
② 引脚侧 LSB 与实测斜率差 0.14 %,逐通道映射与极性均已验。**④ 变比已于 2026-11-06 按用户现场报参算定**
(§7.2;子板原理图仍不在仓库内,本板双表同测未做)。**仍待实测的是两点标定**(给端子域系数、置 `VALID`,
`eng` 随之升 1);标定完成前 `eng` 保持 0、输出单位仍是 ADC 引脚电压。
实测斜率与 ② 理论值偏差 >2 % 时**先查前端**(分压/变比/焊接),不得用系数凑错斜率
(`docs/任务规划/数据可信.md` §8 风险表)。
### 7.2 ④ 段变比登记(2026-11-06 定死)
> **来源**:用户现场报的子板参数(2026-11-06,Issue #41),按 `docs/任务规划/数据可信.md` §7 #2 的路 ①「按图(参数)直接算」
> 算得;子板原理图仍不在仓库内,路 ②「万用表同时量端子与引脚」未做——数值上的理想化偏差与逐路差归两点标定
> (见本节末「复核口径」)。
**电压族 UA/UB/UC/UN——子板 PT:2 mA/2 mA,输入侧 200 kΩ,输出侧 330 Ω**:
- 变比 = U端子 ÷ UAINn = (2 mA × 200 kΩ) ÷ (2 mA × 330 Ω):电流比 1:1 电流相消,只剩两侧负担电阻之比 =
200000 ÷ 330 = **606.060606… ≈ 606.06 : 1**(V/V,无量纲);
- 额定点(按参数推读):端子 **≈400 V**(2 mA × 200 kΩ)→ `AINn` 侧 **0.66 V**(2 mA × 330 Ω)。
**电流族 IA/IB/IC/IN——子板 CT:5 A/2.5 mA,输出侧负担电阻 68 Ω**:
- ADC 读的是负担电阻两端电压,所以这个"变比"是**带单位的比**:I端子 ÷ UAINn = 5 A ÷ (2.5 mA × 68 Ω) =
5 ÷ 0.17 = **29.4118 A/V**(= 匝比 2000 ÷ 68);与 V/V 无量纲量不可混写,进系数表须分注单位;
- 额定点:端子 **5 A** → `AINn` 侧 **0.17 V**。
**算术复核**:200000 ÷ 330 = 606.060606… ✓(用户给值 606.0606060606061);5 ÷ 0.17 = 29.41176470… ✓
(用户给值 29.41176470588235,与 2000 ÷ 68 同源)。两数与报参口径一致,未发现算误。
**②×③×④ 端到端标称系数**(③ 已定 1:1)——只作两点标定的初值与量级核对用,**ROM 不动**(ROM 出厂表
仍按 ② 引脚口径,§7.1 可评审结论 1):
| 族 | 转换器 | 端子域系数(标称) | 额定点码数(RMS) | 占转换器跨度 |
|---|---|---|---|---|
| 电压 UA/UN | TPAFE | 152.59 µV/码 × 606.06 = **92.48 mV/码** | 0.66 V ≈ 4325 码 | 10 V 跨度的 6.6 % |
| 电压 UB/UC | STM32 | 805.66 µV/码 × 606.06 = **488.28 mV/码** | 0.66 V ≈ 819 码 | 3.3 V 跨度的 20 % |
| 电流 IA | TPAFE | 152.59 µV/码 × 29.4118 A/V = **4.488 mA/码** | 0.17 V ≈ 1114 码 | 10 V 跨度的 1.7 % |
| 电流 IB/IC/IN | STM32 | 805.66 µV/码 × 29.4118 A/V = **23.70 mA/码** | 0.17 V ≈ 211 码 | 3.3 V 跨度的 5.2 % |
补一句:额定点正弦峰值 = RMS × √2(电压族 ≈0.93 V、电流族 ≈0.24 V),两片转换器的量程都装得下;STM32
五路交流负半周削到 0 的问题仍是 §7「前端偏置」行的 V0.1 既有口径,不是本节新发现。变比口径只圈电气 8 路,
温度与备用路不进 ④ 换算。
**eng 判定(「端子/子板变比确认」卡(#41)的完成判据)**:
- `eng = 1`(出端子二次值)两条件:④ 变比到手——**已满足**(本节,电压/电流两族);电气 8 路
`ADC_CAL_F_VALID` 全置位——**未满足**(`App/app/ui_data_feed.c` 的 `feed_eng()` 门,「两点标定与精度验收」卡承担)。
- 判定:**`eng` 保持 0**,输出单位仍是 ADC 引脚电压,M4 承诺边界不变。本节改变的是:两点标定从
「开不了工」变成「可开工」——端子侧参照已定死,本节标称系数即其起点。
**复核口径(别把本节数值当本板实测)**:
- 参数是铭牌/板面值:不含理想变压器偏差(励磁电流、绕组阻抗、负担误差),不含负担电阻容差,也不含逐路差
(电压 4 路共用 606.06、电流 4 路共用 29.4118,逐路真值以标定实测为准)。
- 下游机器面核对跟着在:两点标定的逐路实测系数吸收 ④ 段实际偏差;`App/algo/adc_cal.c` 合法带哨兵
(k ∉ ROM×[0.5, 2.0] → 回退 ROM)是「④ 数量级错了」的兜底。
- **本节标称系数是给「两点标定与精度验收」卡的输入,且带着两道存储口径题**(本卡不替它定案):
k 按 µV/码 int32 Q16 存储、上限 32767 µV/码(`docs/任务规划/数据可信.md` §4.1 的"远够"论断做在引脚域
假设上)——电压族端子域标称已越上限(92.48 mV/码 ≈ 92479 µV/码,UB/UC 达 488.28 mV/码 ≈ 488278 µV/码),
电流族两档(4488 / 23696 µV 等效)尚在带内;且合法带基准读 ROM 出厂表(现为引脚域系数),端子域 k
会被 [0.5, 2.0] 哨兵顶回。标定写入端子域系数之前,存储单位(或每路标度因子)与出厂表基准须一并换血,
否则正确的标定值也会被拒。
- 端子级上额定电压仍是独立动作:变比已从"没到手"变"到手",但"先量端子对地通断"的前置与风险次序不变
(`docs/任务规划/数据可信.md` §8),本卡不动高压。
---
## 8. 逐通道验证方法(上板自检口径)
@@ -191,7 +249,7 @@ STM32(U17)为 LQFP144 脚号。
1. **TPAFE 侧**:对目标 `AIN` 注入 1 V DC → 观察对应 `buf[i]` 变化(UA→`buf[6]`、UN→`buf[5]`、IA→`buf[2]`),同时 U3.14 `BUSY` 有脉冲;**语义与下标不符即映射错**。✅ **2026-10-27 已执行**(原 2026-10-23 挂账的"无执行记录"已消除;`docs/硬件平台/V0.0_网表详细分析报告.md` §5.1 第 6 条的同一验证随之关闭)。判据按已知电压注入验证的**不需要示波器**口径执行:① "`BUSY` 有脉冲"改用固件帧计数——注入前后 `tpafe5160_frame_seq()` 仍严格 1000 Hz 递增即等价;② 幅值判据改用万用表读注入点实际电压 + 同时读 `adc_input_raw()` 码值,三点线性拟合(R² ≥ 0.999)。
2. **STM32 侧**:对目标引脚(如 PC4=UB)注入 0.5 V → 读 `ADC_CHANNEL_14` 应变化;若不变而相邻通道变化 → 通道宏写错(见 §5 警告)。✅ **2026-10-27 已执行**(原 2026-10-10 的"尚未执行"已消除;当时台架只验证了"9 通道全部转换成功 + 零超时 + 互异非饱和 + 跨次开机读数不同",台架无信号源);映射的**代码侧**一致性有两道保证:① `App/algo/adc_input.c` 的 `k_adc_map[]` 与 CubeMX 标签(`ADC17_UB`=PC4 等)逐条对齐;② 开机自检 `adc_input_init()` 校验每个 STM32 语义通道都落在 `k_stm32_rank_ch[]` 扫描序列内(挡"映射到不扫描的通道 → 恒读陈旧值")。
3. **备用通道**:RESERVED 路不接入任何语义,UI 与上报里不得出现;若实测有读数漂移,只记录不消费。
4. **端子侧变比(2026-10-23 补,2026-10-27 收窄)**:上面 1/2 两条都只到 **ADC 引脚**。③ 段(`AINn` ↔ 转换器引脚)已由网表追线定死为 **1:1**(`ADCn` 节点无对地元件,拓扑图见 §7.1),**板内不再有未知比值**;剩下的未知量只有 ④ **子板/端子板变比**——它在仓库里没有任何文档给出(`docs/硬件平台/` 只有 `.tel` 网表与分析报告,无子板原理图)。故**不得**用"2:1 分压"换算出二次值;该变比由「端子/子板变比确认」实测确认。
4. **端子侧变比(2026-10-23 补,2026-10-27 收窄)**:上面 1/2 两条都只到 **ADC 引脚**。③ 段(`AINn` ↔ 转换器引脚)已由网表追线定死为 **1:1**(`ADCn` 节点无对地元件,拓扑图见 §7.1),**板内不再有未知比值**;剩下的未知量只有 ④ **子板/端子板变比**,已于 2026-11-06 按用户现场报参算定收口(电压族 606.06 : 1、电流族 29.4118 A/V,算式与复核边界见 §7.2;子板原理图仍不在仓库内,数值确认归两点标定)。故**不得**用"2:1 分压"换算出二次值;端子口径一律按 §7.1 分段表与 §7.2 登记写。
### 8.1 2026-10-27 实测记录(首次执行,六项判据全 PASS)
@@ -218,3 +276,40 @@ STM32(U17)为 LQFP144 脚号。
**两项残留口径**(不影响本轮 PASS,但别当成已验证):**串扰**未单独证(零点步骤时其余七路浮空、
本身在漂,小幅串扰看不出来);**节奏**只测了注入前后、没测注入进行中。
(澄清一句:本节标题里的"六项"= 上表六个**静态**判据项,与 §8.2 交流**动态六轮**不是同一套数。)
### 8.2 交流(正弦)动态验证实测记录(2026-11-02 台架首轮 + 2026-11-04 补测轮)
**执行手册与逐轮记录表**在 `docs/测试说明/专项验证/ADC前端注入验证流程.md` §8;证据归档
`docs/测试说明/测试数据/boot_log_data/20261104_ac_*`(含录波段原件与 `wave_read.py` 输出)。
两轮固件分别为 `fw build: Nov 2 2026 14:21:24` 与 `fw build: Nov 4 2026 19:05:57`(均产品构建、
未标定 `eng=0`)——**以下全部是引脚域电压口径,不是端子二次值**。发生器 VICTOR 2026H(设定一律
Vpp,端接高阻),万用表 FNIRST-DMT-99(判为真有效值档,判别依据见执行手册设备表)。
| 轮 | 实测结论 | 关键数 |
|---|---|---|
| 幅值 | **过**:三档幅值两点复现全落 ±2 % | −0.20 % / −0.20 % / +0.40 %(996 : 498 : 249 ≈ 4:2:1,无隐藏触底) |
| 波形 | **过**:非正弦也能读对,证数条是真有效值档 | 方波 −0.70 %、三角 −1.22 %;反推峰值两波形互合(1404 / 1410 mV vs 设定 1414 mV) |
| 相位 | **过(录波档 ≤2°)**:同段 `UA`(表序 0)vs `UN`(表序 3),同片 TPAFE 内比 | 0°/0° 段 Δφ = **0.07°**(WAVE06,11-02);0°/90° 段 Δφ = **90.05°**、偏差 0.05°、逐周波漂移 ≤0.01°(WAVE09,11-04,16 整周波全过);段与发生器无绝对相位锁,只比同段相对差 |
| 测频 | **如实报不可测成立**(现状判据就是不出数) | 两轮合计 561 行 `freq(hb)` 全部 `f=0 valid=0`(含满幅注入段);幅值门 `FREQ_AMP_MIN=50.0f`(`App/algo/freq.h:62`)在引脚域恒不过——标定态或改门限前测频轮不出数是**预期** |
| 削顶 | **直流档锁存成立、sticky 实证**;低频档与复位复核按裁定关闭 | UB 注 DC −1.00 V:`rail=0x002 edge=0x002`、唯一 `[ERR] rail: edge=0x2 sticky=0x2`、`adc: UB` 钉 0 码;撤注后恒持 ≥30 min(sticky 只有 `adc_health_rail_init()` 清,即复位)。50 Hz 同幅不锁存=预期(≈11 拍<20)。2.0 Hz 低频档与"复位清 sticky"复核**用户裁定 2026-11-04 不做**(判据链已被直流档闭合) |
| 谐波 | **选择性两轮成立**;幅值 A/C 过、B 已归因板端前端 RC 并关闭 | 单注 100 Hz → `Ia2` −1.25 %;纯基波 → `Ia` 0.0 %(复测)/ −0.6 %(初测)、两谐波桶=0;单注 250 Hz → `Ia5` **−4.4 %**(两轮复现 −4 ~ −5 %)——归因:差分滤波 C35 = 100 nF(用户确认)+ R19/R21 各 1 k(`docs/硬件平台/V0.1.tel`:49;拓扑 = 1 k 串联 + 1 k 接差分负端、不分压,`docs/产品需求/产品需求设计文档.md` FR-ADC-5)→ IA 差分传递 = 一阶低通 **fc ≈ 796 Hz**,该 −4.4 % 是前端在此频点的**真实衰减,板端读数忠实**;工频 50 Hz 仅 −0.2 %,不受影响(模型与数据见下段) |
**观察项(都判读过、非缺陷)**:TPAFE 输入浮空读数钉在 ≈1743/1747 mV 静态(撤线后 UA/IA 出现——
读 `meas:` 时先确认接线);未接线的 STM32 侧引脚码值随环境缓漂(UC/IC/IN/T),不消费即可;
录波触发后 `drop` 涨一截是 SEALED 窗口设计内(`App/algo/wave_ring.c:50`,涨完冻结,判失败只看
`err`/`ovf`);采集链健康两轮全程 Δ9998/10 s、`idle=0`、`adc1_err=0`(前置门 8 条全过)。
**IA 前端差分滤波 = 低通 fc ≈ 796 Hz(2026-11-04,谐波 B 行定量归因)**:工频测量够用、
谐波测量不够用——同拓扑外推 5 次 ≈ −4.6 %(出 ±2 % 判据)、7 次 −8.5 %、9 次 −13.0 %、11 次
−17.7 %、13 次 −22.6 %、15 次 −27.2 %、21 次(1050 Hz)−39.6 %;C35 若改 10 nF 则 fc ≈ 8 kHz,
21 次仅 −0.9 %。谐波功能产品化的硬件前置 = 板改小 C35 + 清点其余各路差分滤波电容容值(已登记
`docs/任务规划/登记簿.md` §3)。**为什么改板而不是软件逐阶修正**:修正系数依赖这颗电容的实际容值,
而电容有容差、随温度漂,每块板、每个温度都不一样,修正表跟不上;二次谐波制动这类"拿某次谐波幅值
与基波比值"的判据,比值被前端畸变后判定就不可信。换 10 nF 后测量带内是平的,板端读数直接可信,
不需要修正。证伪条件(将来有示波器再复核):该低通预测 250 Hz 差分分量额外滞后
≈17°;模型与三点拟合 `docs/测试说明/测试数据/boot_log_data/20261104_ac_ia_rc_model.txt`。
**边界**:本节不证端子二次值 / 精度等级 / 跨转换器相位(V0.1 硬件缺陷)/ THD——见
`docs/任务规划/数据可信.md` §4.6.5。
@@ -87,7 +87,7 @@
| 遥信 | 双位置遥信上**双点**,其余**单点**;点号 `0+` |
| 遥控 | **双点命令**,合闸选择 `82H`、执行 `02H`;点号 `6000H+` |
| **RS-485** | **对下 ModBus RTU 采集**(下行采集口,非上行口) |
| 对时 | 点表要求 **SNTP `192.168.1.121:5105`**;本项目**保留自定义 TCP 8888**,SNTP 本期不实现(产品定义中的对时方式) |
| 对时 | 点表要求 **SNTP `192.168.1.121:5105`**;本项目 **SNTP 客户端已落地**(2026-11-04,#73:`[sntp]` 段配服务器、**固定 UDP/123**),原自定义 TCP 8888 **已退役删除**(#78)——点表的**非标端口 5105 尚不满足**(客户端端口不可配),要按点表对接需给 `[sntp]` 增「服务器端口可配」小改 |
| 固有参数 | `8001H~800AH`:终端类型/操作系统/制造商/硬件版本/软件版本/校验码/规约类型/型号/ID/MAC |
| 运行参数 | `8020H~8058H`:死区(电流/交流电压/直流电压/功率/频率/功率因数)、PT/CT 变比、负荷越限/重载/过载报警、录波投退与定值、功率置负 |
| 定值 | `8820H~8882H`:过流 I/II/III 段、零序过流 I/II 段、重合闸、低压/低频、励磁涌流闭锁、小电流接地等 |
@@ -127,7 +127,7 @@
| # | 事项 | 处置 |
| --- | --- | --- |
| 产品定义中的后备电源与直流遥测裁剪 | `UBA` 后备电源电压、`V1/V2` 直流量三路遥测的硬件来源 | **本期不做**——V0.1 无对应硬件通道,不加子板/通道;点表此三项本期空缺 |
| 产品定义中的对时方式 | 对时 | **保留自定义 TCP 8888**;点表要求的 **SNTP 5105 本期不实现** |
| 产品定义中的对时方式 | 对时 | **SNTP 客户端已落地**(2026-11-04,#73);原自定义 TCP 8888 已退役删除(#78);点表要求的 **SNTP 5105 非标端口仍未实现**(客户端固定 UDP/123,端口不可配) |
| 产品定义中的本期保护范围 | 保护/控制范围 | **本期 = 骨架全做 + 有效通道子集闭环**(2026-10-10 用户确认),评估见 §1.6 |
> **产品定义 至此全部闭环**:上行 IEC 60870-5-104 / 持续采集 / 1000 Hz 已定(§1.5 表 1~4);产品定义中的后备电源与直流遥测裁剪 / 产品定义中的对时方式 本期不做或维持现状;产品定义中的本期保护范围 的范围裁剪见 §1.6。
+1 -1
View File
@@ -890,7 +890,7 @@ void net_generation_inc(void);
| `net_get_generation` | 获取当前网络代次号(首次 `net_init` 成功前为 0,每次网络重建 +1) |
| `net_generation_inc` | 代次号加 1(netTask 重建成功、网络已可用后调用) |
**用途**:长驻 TCP 服务(FTP :21 / 对时 :8888 / 远程显示 :7003)在监听循环中检测代次号变化后主动重建监听 Socket,网口配置立即生效后可自动在新 IP 上恢复(重建会断开既有连接,属预期行为)。详见 `docs/子系统设计/网络配置说明.md` §4。
**用途**:长驻 TCP 服务(FTP :21 / 远程显示 :7003;对时 :8888 已退役,2026-11-04)与 UDP 出向客户端(SNTP,代次变化弃旧 socket 懒重建)在循环中检测代次号变化后主动重建,网口配置立即生效后可自动在新 IP 上恢复(重建会断开既有连接,属预期行为)。详见 `docs/子系统设计/网络配置说明.md` §4。
#### net_poll - 状态轮询
@@ -613,7 +613,7 @@ net_pending_capture_owner() ← 捕获执行者
| 指标 | 值 | 来源 / 条件 |
|---|---|---|
| 队列响应性(挂起连接下) | **92.5 ms** | `test/host/e02_probe.py`:挂起对时客户端 + FTP banner 探测 |
| 队列响应性(挂起连接下) | **92.5 ms** | 台架实测(探针 `e02_probe.py` 已删除——2026-11-04 随 :8888 退役,正文见 git 历史):挂起对时客户端 + FTP banner 探测 |
| M3 静默档帧周期 | med 58.9 / p95 69.9 / max 72.1 ms | `docs/测试说明/专项验证/链路延迟测试说明.md` §6.3(零尖峰) |
| M3 压力档帧周期 | med 60.1 / p95 66.4 / max 69.3 ms | 同上(零尖峰) |
| netTask 栈峰值 | **1116 B / 3840 B(余 70%)**,FTP 传输期峰 **1164 B**;静态最坏链 ≈1.9 KB | `docs/内存管理/RAM使用分析与优化方案.md` §2.3 |
+14 -7
View File
@@ -32,7 +32,8 @@
> - 带连字符的 `E-<nn>` = **历史审计发现**编号(属主文档已于 2026-10-15 删除,
> 编号冻结于 `docs/编号规范.md` §4.3)——
> §5.2 末行引用它是为了记录该发现的**收口台架**,**不是**实验编号
> (证据:`test/host/e02_probe.py` 的文档串自述它是该审计发现的 timeSync 触发形态探针);
> (证据:`test/host/e02_probe.py`(已随 :8888 退役于 2026-11-04 删除,正文见 git 历史)
> 的文档串自述它是该审计发现的 timeSync 触发形态探针);
> - 该审计编号族已冻结、不再新增,引用一律改说人话。
## 1. 为什么是这个架构
@@ -111,7 +112,8 @@ fd 别名让这个边沿**必须有人接**,而"谁重建监听"在类型上
1. **不支持多监听**——`docs/问题记录/CH395F_Trap_Records.md` 附 FTP 改造清单第 4 条
「CH395F 多连接模式不支持多监听(类型:架构)」,处置即 `fun_para=0x00`。
本产品有 21/8888/7003 **三个常驻监听** + 会话期动态 PASV 监听。
本产品有 21/7003/2404 **三个常驻监听** + 会话期动态 PASV 监听(当时第三个是 :8888 对时,
2026-11-04 退役后由 104 :2404 在列——结论不依赖具体端口组合,见墙钟说明 §15)。
2. 池分配按**源端口匹配**(`docs/芯片手册/CH395F.md` §9.2.6 L1295),多监听器的池会互相串。
3. 实测:「多连接模式下最多接受 3 个客户端(Socket 1~3),Socket 4~7 的 CONNECT 中断从不触发」、
「多个 Socket 数据互相覆盖」——即 TRAP-NET-02/-11。
@@ -612,8 +614,9 @@ DISCONNECT 会被 `(void)` 丢掉。但 RECV_OK 是条件位(下轮补回)
> 「假设 → 方法 → 判据 → 它门禁哪个决策」四段式;本表只给**方法与结论**,原始记录(假设、
> 原始日志、统计)已归档,取用命令见 §12。
> ⚠ **这些编号是冻结标识**:`net_socket.c` / `net_events.c` / `net_listener.c` 注释、
> `test/host/e02_probe.py`、`test/host/e6_soak.py`、`docs/问题记录/CH395F_Trap_Records.md`
> 都直接引用它们,**重排或改名会断链**。
> `test/host/e6_soak.py`、`docs/问题记录/CH395F_Trap_Records.md`
> 都直接引用它们(原 `test/host/e02_probe.py` 已删除——2026-11-04 随 :8888 退役,正文见 git 历史),
> **重排或改名会断链**。
> ⚠ 末行 **不是实验编号**——它记录的是**历史审计发现**
> (带连字符的 `E-<nn>` 族,属主文档已于 2026-10-15 删除并冻结),列在此处只为记录该发现的**收口台架**。
> 区分规则:**带连字符 = 审计发现,无连字符 = 自愈实验**。
@@ -640,7 +643,8 @@ DISCONNECT 会被 `(void)` 丢掉。但 RECV_OK 是条件位(下轮补回)
| **E17** | **单一所有者收口**:`net_listener_try`(当场动作、**无状态门**,各调用点自带门)改为 `net_listener_request`(只登记意图)+ `net_listener_tick`(唯一执行者,门集含"芯片已在 LISTEN 即了结"),同板全量回归 | 全绿;**延后一轮(≤1 ms)执行不伤即时性**(恢复窗 p50 与当场动作持平);relisten 留痕减半 | §4.2 登记/执行分离;§9.2 门集;§11.1 判据 |
| **E18** | **负向注入打靶 · 三轮**(注入代码不入库):① 吞掉 DISCONNECT(在 i104 的 200 ms accept 轮询窗内 RST);③ 绕过本层簿记直接 close 芯片空闲监听;⑤ 开盲区吞掉芯片自发的中断 + 等芯片真 CLOSED 再 open+listen | **①③⑤ 全部命中并救回**;①⑤ 的前提会被更快的消费者路径消解 → 常态 0 命中;⑤ 还要先越过芯片 `FIN_WAIT_2`(E15 的 2MSL 长尾,实测 ≈1 s) | §4.1.4 / §4.1.5:**三条均不可降级为只留痕**;⑤ 的**取消挂起 recv/send** 不可省 |
| **E19** | **`force open` 反事实 A/B**(本层已收口 CLOSED + 芯片停 `FIN_WAIT_2` `0x05/0x06` + **对端挂住不关** = 队头阻塞场景;A = 现状放行,B = 只留痕不放行) | **放行与不放行的端口恢复时刻同一分布** → 动作在全部可产现场景内无可测收益;真正兜住"监听器永久失效"的是 **D10 预算 + 形态④ 重新登记**。两条实测坑:① 本层直接改 `state` **不会**进沉降窗(窗只由 `net_listener_settle` 开启);② `relisten retry budget exhausted` 在此被稳定复现 = 对端不配合拆链的签名,**非回归** | §4.3:800 ms 上限降级为**只留痕**(`keep waiting` 只留首末、隔离标志不清 → 继续排渣) |
| **队头阻塞审计**(非实验编号) | `test/host/e02_probe.py` 台架定案 `net_drop_conn` 收口后的时序 | 对端配合(收到 FIN 后其内核 close):`TIME_WAIT` ~150 ms → 形态④ relisten,恢复全程 ~500 ms;对端内核存活但不 close:芯片停 `FIN_WAIT_2` 长尾,**监听恢复受限于对端 close** | §4.6 |
| **队头阻塞审计**(非实验编号) | `net_drop_conn` 收口后的时序由台架定案(探针 `e02_probe.py` 已删除,2026-11-04 随 :8888 退役,正文见 git 历史) | 对端配合(收到 FIN 后其内核 close):`TIME_WAIT` ~150 ms → 形态④ relisten,恢复全程 ~500 ms;对端内核存活但不 close:芯片停 `FIN_WAIT_2` 长尾,**监听恢复受限于对端 close** | §4.6 |
| **台架重验(#39 子项 B)**(2026-11-06) | 新负载剖面一整轮 30 min:SNTP 请求/退避(poll_min=1,无可达服务器)+ 持续 FTP 512KB + 周期 104 GI/COV + 7003 拉帧 10Hz。看门狗 `task stall` 0 条、复位 0 次、NAND `wdev.log` 当日零新增 STALL(独立佐证);880 次瞬时节拍抖动全部 <800 ms 自恢复、均发生在网络 relisten 瞬间(阈值下抖动,非饿死);7003 最差单轮 759 ms(<800 ms 线)、18000/18000 零错零超时;FTP 188/188 全过 | 8888 reconcile/relisten 突发源退役(#78)+ 异步断连收口后,新负载下 **uiTask ≥800 ms 饿死签名无触发源**——子项 B 完成判据(台架负载下不再出现目标饿死签名)本轮达成 | §4.6;§11.1;看门狗设计说明 §11.4 |
## 6. 红线(明确不做的事)
@@ -723,15 +727,18 @@ DISCONNECT 会被 `(void)` 丢掉。但 RECV_OK 是条件位(下轮补回)
| `net_listener_armed` | 唯一监听门控;**必须放行 ESTABLISHED**(§4.2) |
| `net_listener_tick`(唯一执行者) | 门集**只在这一处**:状态 ∈ {LISTENING, CLOSED} + 监听型 + **芯片已在 LISTEN 即视为达成、绝不 open**(U12 结构性防护)+ 挂起保险。登记侧 `net_listener_request` 因此**不需要**状态门——任何"当场动作 + 调用点各自补门"的写法都会把 U12 风险复制 N 份(对已 LISTENING 的 fd 再 open+listen 会因 USE 错误走进关闭分支、**关掉正听着新 SYN 的 Socket**) |
### 9.3 三个服务的连接结束契约(现状)
### 9.3 长驻网络形态的连接结束契约(现状)
| 服务 | 连接结束信号 | 监听重建者 | 备注 |
|---|---|---|---|
| `lftpd` 控制 :21 | `read_line != 0`;阻塞挂起 recv 保证 CLOSED 时必被结束(FIN→0 / 异常→CONNRESET) | net 层;应用**永不** close 控制 fd | 契约一致,**正面样板** |
| `time_sync` :8888 | EOF / 预算耗尽 → `net_drop_conn` 拆会话保监听 | net 层(形态④) | 同 fd 即监听 fd,应用侧**不得** `net_close`(红线 8)→ 走 §4.6 |
| `ui_net_sink` :7003 | `net_recv` 返 0 或真错误;非阻塞收帧 | net 层 | 重建条件**不得**写成 `net_get_sock(g_listen)==NULL`(fd 不释放 → 恒假);靠 `session_dead` 电平 + 形态④ |
| 模拟器后端 | `recv` 0 恒可得、fd 分离 | 无需 | Winsock 原生;对上述全部失效模式**零覆盖**(D6:双模型分裂暂不消除) |
> **历史行(:8888,2026-11-04 退役删除)**:`time_sync` :8888 | EOF / 预算耗尽 → `net_drop_conn`
> 拆会话保监听 | net 层(形态④)| 同 fd 即监听 fd,应用侧**不得** `net_close`(红线 8)→ 走 §4.6。
> 退役后本表不再有应用侧 `net_drop_conn` 调用者(原全仓唯一调用者 `time_sync.c` 已随监听删除)。
## 10. 决策记录
| # | 决定 | 依据 |
+2 -1
View File
@@ -16,4 +16,5 @@ date code ro rw zi er_irom1 er_pct iram1 iram1_pct ccm ccm_pct top_rwzi
2026-10-30 246720 29836 2052 149708 276556 26.4 94336 72.0 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6432;nand_ftl.o=6216;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132
2026-11-02 247548 29836 2052 149740 277384 26.5 94368 72.0 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6802;ui_port.o=6432;nand_ftl.o=6216;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132
2026-11-03 249112 29836 2052 149996 278948 26.6 94624 72.2 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6802;ui_port.o=6432;nand_ftl.o=6216;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132
2026-11-04 254648 30152 2072 150088 284800 27.2 94736 72.3 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6802;ui_port.o=6432;nand_ftl.o=6216;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132
2026-11-04 254332 30824 2072 150104 285156 27.2 94752 72.3 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6802;ui_port.o=6432;nand_ftl.o=6236;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132
2026-11-05 254820 30896 2072 150104 285716 27.2 94752 72.3 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6802;ui_port.o=6432;nand_ftl.o=6236;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132
1 date code ro rw zi er_irom1 er_pct iram1 iram1_pct ccm ccm_pct top_rwzi
16 2026-10-30 246720 29836 2052 149708 276556 26.4 94336 72.0 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6770;ui_port.o=6432;nand_ftl.o=6216;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132
17 2026-11-02 247548 29836 2052 149740 277384 26.5 94368 72.0 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6802;ui_port.o=6432;nand_ftl.o=6216;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132
18 2026-11-03 249112 29836 2052 149996 278948 26.6 94624 72.2 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6802;ui_port.o=6432;nand_ftl.o=6216;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132
19 2026-11-04 254648 254332 30152 30824 2072 150088 150104 284800 285156 27.2 94736 94752 72.3 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6802;ui_port.o=6432;nand_ftl.o=6216;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6802;ui_port.o=6432;nand_ftl.o=6236;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132
20 2026-11-05 254820 30896 2072 150104 285716 27.2 94752 72.3 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=16384;lftpd.o=7884;ui_net_sink.o=6802;ui_port.o=6432;nand_ftl.o=6236;wave_ring.o=5296;sb_link.o=4376;ch395f.o=4162;console_log.o=4132
+11 -11
View File
@@ -1,25 +1,25 @@
{
"built_at": "2026-11-04T16:20:20+08:00",
"fingerprint": "6b401a3591de1df1ce9d532c275648650896fb04a175f90b3a0caa576c6c6359",
"built_at": "2026-11-05T16:35:16+08:00",
"fingerprint": "36fcf475ac2d01551cf21b31af98a3aa51e1dca1e3a74ae79570e7cee253b5b5",
"fingerprint_files": 1479,
"fingerprint_source": "git-index",
"gated_regions": [
"RW_IRAM1",
"RW_CCM"
],
"git_head": "10322208fd0908b2ef04292833d4bc2b417e3534",
"git_head": "d9303e05a4512defe29c0e434c20ba5e243bcc1b",
"map": "MDK-ARM/STM32F407-Demo/STM32F407-Demo.map",
"map_mtime": 1793780256,
"map_mtime": 1793867423,
"pct": {
"ER_IROM1": 27.16,
"ER_IROM1": 27.25,
"RW_CCM": 87.89,
"RW_IRAM1": 72.28,
"RW_IRAM1": 72.29,
"UNINIT_CCM": 18.75
},
"regions": {
"ER_IROM1": {
"max": 1048576,
"size": 284800
"size": 285716
},
"RW_CCM": {
"max": 65280,
@@ -27,7 +27,7 @@
},
"RW_IRAM1": {
"max": 131072,
"size": 94736
"size": 94752
},
"UNINIT_CCM": {
"max": 256,
@@ -37,10 +37,10 @@
"schema": 2,
"scope_note": "\u540c\u7801\u51ed\u8bc1\uff1a\u6307\u7eb9\u8986\u76d6\u56fa\u4ef6\u4f53\u79ef\u76f8\u5173\u6e90\u7801\uff0c\u53e3\u5f84\u89c1\u672c\u811a\u672c docstring",
"sizes": {
"code": 254648,
"ro_data": 30152,
"code": 254820,
"ro_data": 30896,
"rw_data": 2072,
"zi_data": 150088
"zi_data": 150104
},
"threshold_pct": 92.0,
"worktree_dirt_at_stamp": 0,
+16 -16
View File
@@ -218,11 +218,11 @@
},
"App/sync/time_sync.c": {
"func_rate": 1.0,
"funcs_covered": 4,
"funcs_valid": 4,
"funcs_covered": 2,
"funcs_valid": 2,
"line_rate": 1.0,
"lines_covered": 101,
"lines_valid": 101
"lines_covered": 20,
"lines_valid": 20
},
"App/task/iec104_serv.c": {
"func_rate": 0.75,
@@ -749,9 +749,9 @@
},
"time_sync": {
"files": {
"App/sync/time_sync.c": 101
"App/sync/time_sync.c": 20
},
"lines_total": 101,
"lines_total": 20,
"ok": true
},
"ui_data": {
@@ -876,12 +876,12 @@
"files_generated_excluded": 5,
"files_tested": 54,
"files_untested": 177,
"func_rate": 0.9292,
"funcs_covered": 643,
"funcs_valid": 692,
"line_rate": 0.9018,
"lines_covered": 8633,
"lines_valid": 9573,
"func_rate": 0.929,
"funcs_covered": 641,
"funcs_valid": 690,
"line_rate": 0.901,
"lines_covered": 8552,
"lines_valid": 9492,
"modules_ok": 48,
"modules_total": 48
},
@@ -1414,10 +1414,6 @@
"code_lines": 12,
"path": "Drivers/BSP/UI/ui_net_sink_backend.h"
},
{
"code_lines": 11,
"path": "App/sync/time_sync.h"
},
{
"code_lines": 11,
"path": "App/task/net_task.h"
@@ -1518,6 +1514,10 @@
"code_lines": 10,
"path": "App/fs/vol_idle_sync.h"
},
{
"code_lines": 10,
"path": "App/sync/time_sync.h"
},
{
"code_lines": 10,
"path": "App/task/default_task.h"
+1 -1
View File
@@ -33,7 +33,7 @@ void storage_test_run(void);
/* 存储套件恢复测试(默认关闭):取消注释并编译 STORAGE 套件运行一次,
* 即可重建 BBT(清除 TC-STORAGE-03 等注入的坏块)并重新格式化,恢复设备干净态。
* 恢复完成后建议重新注释并编译正常构建。 */
//#define ENABLE_STORAGE_RECOVERY_TESTS /* 台架已跑过一次恢复(2026-09-20 BBT 回出厂态),保持注释 */
//#define ENABLE_STORAGE_RECOVERY_TESTS /* #79:2026-11-04 已用本开关清除 129 个误标坏块并 format 成功,保持注释 */
/* 恢复模式的扩展(默认关闭,需与上面 ENABLE_STORAGE_RECOVERY_TESTS 同时打开):
* 把 dhara 可见区**整片擦净**(连 journal checkpoint 一起),用于**把被扣掉的容量恢复回来**。
+8 -6
View File
@@ -10,7 +10,6 @@
|---|---|
| `run_boot_test.py` | **`/serial-boot-test` 一键闭环**:开串口+清日志 → 烧录 → wait-idle → `verify_log` 校验(退出码 0=PASS) |
| `verify_log.py` | **日志标记校验**:Required / Forbidden 标记 → PASS / FAIL;可选 `--require-suite-summary` 校验套件汇总行(`=== <名称>: N/M PASSED (failed=0) ===` 且 `N>0`),抓"没跑到汇总行/断言数为 0"的盲区 |
| `e02_probe.py` | 头阻塞专项探针 |
### 网络 / FTP
@@ -38,7 +37,9 @@
| 脚本 | 作用 |
|---|---|
| `latency_peer.py` | 链路时延测试的 PC 对端(peer) |
| `time_sync_server.py` | 时间同步推送服务(对时源) |
> 原 `time_sync_server.py`(:8888 推送对时源)已随 :8888 退役删除(2026-11-04,#78);
> 对时改为板端 SNTP 客户端出向(墙钟说明 §16),台架用真实/私有 NTP 源即可。
### 主机侧单元测试(纯逻辑,无硬件)
@@ -62,9 +63,9 @@
| `vol_lock/run_unit_test.py` | **卷锁单测**:离线编译真实 `App/fs/vol_lock.c`,33 断言点覆盖创建 / 获取 / 释放契约(**fail-open 不变量**:创建失败仍返回 1 且零阻塞)/ 幂等 / 超时透传 |
| `vol_lock/vol_lock_test.c` | 测试单元本体(`#include` 生产源码 + CMSIS 互斥桩) |
| `vol_lock/stub/` | 桩头文件(`cmsis_os.h`) |
| `time_sync/run_unit_test.py` | **时间同步单测**:离线编译真实 `App/sync/time_sync.c`,80 断言点覆盖分片喂狗延时 / 监听退避 / 时间包重组(半包·粘连·EOF·真错·预算耗尽·tick 回绕)/ 任务主循环(**探针窗口心跳缺口的全部逻辑贡献者**) |
| `time_sync/run_unit_test.py` | **时间同步任务载体单测(v2.0)**:离线编译真实 `App/sync/time_sync.c`,33 断言点覆盖分片喂狗延时 / 就绪屏障(100 ms 分片、`osFlagsNoClear`、永不就绪不挂死)/ SNTP 节拍驱动与**网络代次当轮交接** / 未出网守门(:8888 退役后任务即纯校时节拍宿主) |
| `time_sync/time_sync_test.c` | 测试单元本体(`#include` 生产源码 + 网络 / 事件 / RTOS 可脚本化桩 + `longjmp` 跳出 `for(;;)` 任务循环) |
| `time_sync/stub/` | 桩头文件(`FreeRTOS.h` / `task.h` / `cmsis_os2.h` / `net_socket.h` / `sys_clock.h` / `sys_events.h` / `dbg_log.h`) |
| `time_sync/stub/` | 桩头文件(`FreeRTOS.h` / `task.h` / `cmsis_os2.h` / `net_socket.h`(裁剪至 `net_get_generation`,**编译期绊线**:生产码若再引监听类 API 立刻炸)/ `sys_events.h`) |
| `iec104/run_unit_test.py` | **IEC 60870-5-104 协议栈单测(IEC 104 上行)**:离线编译真实 `App/protocol/iec104/` 三模块 + 数据源(prot_set/prot_elm/phasor/sample_ring),**82** 用例覆盖 CP56 往返 / APCI 半帧·粘帧·坏帧 / STARTDT 握手 / 总召分片+RBT / COV 死区 / k=12 窗满 / w=8 触发 S / t1·t2·t3 / N(R) 倒退判故障 / 遥控·定值两段式与 PN / C_CS / 未知类型·地址错误应答 |
| `nand_port/run_unit_test.py` | **dhara NAND 移植层单测**:离线编译真实 `Drivers/BSP/GD5F2GQ5UE/nand_ftl.c` + 真实 `Lib/dhara/{journal,map}.c`,以 **RAM 假芯片**驱动,**149** 断言覆盖 is_free 整页扫描 / 六个 HAL 入口的越界守卫 / 故障注入 / dhara map"写入 → 重新 resume"场景 |
| `nand_port/nand_port_test.c` | 测试单元本体(`#include` 生产源码 + RAM 假芯片;内联一份"只看页首 64 B"的**旧算法对照**,证明断言能咬人) |
@@ -139,7 +140,8 @@
- 本目录**被 pre-commit 门禁的 cppcheck / 代码规范排除**(`test/` 豁免);
但各模块的 `run_unit_test.py` 自身**作为独立钩子**参与门禁(见上,共 22 个)
- 台架探针族分工(2026-10-13 起):**自愈/Trap 常备回归腿在本目录**(`relisten_stress` /
`ftp_abort_probe` / `n30_repro` / `e02_probe` / `e6_soak` 等);`MDK-ARM/*.py` 只余被文档**当作
`ftp_abort_probe` / `n30_repro` / `e6_soak` 等;`e02_probe` 已随 :8888 退役删除,2026-11-04);
`MDK-ARM/*.py` 只余被文档**当作
可信判据引用过**的三件(`ftp_freeze_probe` / `tcp_reconnect_probe` / `bench_verdict`)——
2026-10-22 清掉了一批既无人引用、又因设备侧启用鉴权而再也登录不上的历史一次性探针
(`MDK-ARM/ftp_retr_abort_probe.py` 与整个 `MDK-ARM/bench_diag/`(4 个诊断脚本)),需要时从
@@ -157,5 +159,5 @@
- `docs/测试说明/单元测试/ADC输入层单元测试说明.md` — ADC 输入层单测(逐 Rank 钉死映射)
- `docs/测试说明/单元测试/相量层单元测试说明.md` — 相量层单测(傅氏系数 / 双区交换)
- `docs/测试说明/单元测试/卷锁单元测试说明.md` — 卷锁单测(fail-open 不变量)
- `docs/测试说明/单元测试/时间同步单元测试说明.md` — 时间同步单测(探针窗口心跳缺口逻辑贡献者)
- `docs/测试说明/单元测试/时间同步单元测试说明.md` — 时间同步任务载体单测 v2.0(SNTP 节拍 / 代次交接 / 未出网守门)
- `docs/测试说明/板级测试/CH395F_Test_Guide.md`、`FTP_Test_Guide.md`
+222 -1
View File
@@ -53,12 +53,23 @@
* TC-CONFIG-043 输出超长 -> 拒绝保存(-1) 且原文件不动
* 受管键行超 CFG_LINE_TEST_MAX -> 拒绝保存(-1) 原文件不动;
* 非受管键的超长行照旧放过(原样保留)
* TC-CONFIG-059 读视图与 stat 基准不符(卷层旧/短视图)-> 拒绝保存(-1)
* 原文件一字节不动 + 自检留痕;视图追平后可再存——2026-11-05 视图一致性
* 守卫:断"短视图 → 外科重写 → 文件缩小非默认段被删"吞段链(issue #73)
* —— poll 契约(cfg_file_poll)——
* TC-CONFIG-050 首轮建立基线(不重载)
* TC-CONFIG-051 沉降去抖:连续 2 次稳定才重载
* 与基线一致不重载
* TC-CONFIG-053 变更后重载 + 挂回调段差异触发回调
* TC-CONFIG-054 溢出到文件超长 -> 工厂默认 + 重建模板 + 自检留痕(不触发回调)
* TC-CONFIG-058 卷层旧视图(读长 != stat 长)-> 拒绝应用:RAM 保旧值、
* 基线保留 2s 重试、视图追平即自愈应用 + 回调;拒绝期间无回调无二次 ERROR
* TC-CONFIG-060 读中改写(读后复 stat 令牌变)-> HELD 后重新沉降自愈;
* 持续不一致:全程仅 1 ERROR + 1 留痕,WARN 每 30 趟一条(日志限速)
* TC-CONFIG-061 同尺寸全 0 旧映射块(长度/令牌双检全过)-> 内容判据拦下:
* HELD RAM 保旧、视图刷新后自愈应用 + 回调
* TC-CONFIG-062 保存链遇同尺寸全 0 旧视图 -> 拒存 -1,文件字节/写次数不动,
* 视图恢复后同一保存重试成功落盘
*
* 通过:全部 TC PASS(main 返回 0)。
* 入口:int main(void),返回 0=PASS / 1=FAIL(由 run 脚本判读)。
@@ -98,6 +109,19 @@ static int s_fail_write = 0; /* cfg_store_write_atomic 返回 -1 */
static int s_fail_alloc = 0; /* cfg_store_alloc 返回 NULL */
static int s_fail_stat = 0; /* cfg_store_stat 返回 -1 */
/* 视图不一致注入(2026-11-05 视图一致性守卫):s_view_stale 置位时 read 返回
* s_vfs_stale 快照,stat 仍报真实盘的 (size, mtime)——等效真机 dhara/FTL 在
* stat→read 窗口给出旧视图(台架 8/8 复现形态:读到旧/短内容、解析错误行
* 一条不出)。vfs_mark_stale() 冻结当前盘为旧视图并开启注入;
* vfs_clear_stale() 视图追平 = 自愈 */
static uint8_t s_vfs_stale[VFS_CAP];
static size_t s_vfs_stale_len = 0u;
static int s_view_stale = 0;
/* 读期间文件被改写注入:read 完成后 mtime 前进 = 读到的内容不再对应变更令牌
* (一次性,复现"读中改写",由读后复 stat 检出) */
static int s_touch_on_read = 0;
/* 观测计数 */
static int s_write_count = 0;
static int s_read_count = 0;
@@ -135,8 +159,21 @@ int cfg_store_read(const char *p_path, uint8_t *p_buf, size_t cap, size_t *p_nre
if (n > cap) {
n = cap;
}
(void)memcpy(p_buf, s_vfs, n);
if (s_view_stale) {
n = s_vfs_stale_len; /* 旧视图:盘上真身已变,读仍返回冻结快照 */
if (n > cap) {
n = cap;
}
(void)memcpy(p_buf, s_vfs_stale, n);
}
else {
(void)memcpy(p_buf, s_vfs, n);
}
*p_nread = n;
if (s_touch_on_read) {
s_touch_on_read = 0; /* 一次性:读后令牌变 = 读中改写 */
s_vfs_mtime++;
}
return 0;
}
@@ -263,6 +300,10 @@ static void vfs_reset(void) {
s_vfs_mtime = 100u;
s_vfs_exists = 0;
s_fail_read = s_fail_write = s_fail_alloc = s_fail_stat = 0;
s_view_stale = 0;
s_vfs_stale_len = 0u;
memset(s_vfs_stale, 0, sizeof(s_vfs_stale));
s_touch_on_read = 0;
s_write_count = s_read_count = 0;
s_syslog_count = 0;
g_cfgtest_err_count = 0;
@@ -279,6 +320,7 @@ static void vfs_reset(void) {
memset(s_snap, 0, sizeof(s_snap));
memset(s_sec_hdr, 0, sizeof(s_sec_hdr));
memset(s_key_line, 0, sizeof(s_key_line));
s_reject_streak = 0u;
/* 段 RAM 副本复位工厂默认 */
s_net_data = s_net_def;
s_sys_data = s_sys_def;
@@ -309,6 +351,29 @@ static void vfs_put_notoken(const char *text) {
s_vfs_exists = 1;
}
/* 冻结当前盘内容为"旧视图"并开启注入:此后 read 一直返回这份快照,
* stat/盘上真身照常变化 = 复现卷层 stat→read 窗口的旧视图滞后 */
static void vfs_mark_stale(void) {
s_vfs_stale_len = s_vfs_len;
memcpy(s_vfs_stale, s_vfs, s_vfs_len);
s_view_stale = 1;
}
/* 同尺寸全 0 旧视图(2026-11-05 台架 15:21 实证形态:dhara 旧映射块恰与
* 目标同长,长度/再 stat 双检全过,只有内容判据能拦):read 返回与真实
* 盘同长的全 0 块 */
static void vfs_mark_stale_zeros(void) {
s_vfs_stale_len = s_vfs_len;
memset(s_vfs_stale, 0, s_vfs_stale_len);
s_view_stale = 1;
}
/* 视图追平盘上真身 = 卷层视图恢复(守卫自愈路径) */
static void vfs_clear_stale(void) {
s_view_stale = 0;
s_vfs_stale_len = 0u;
}
/* 取虚拟盘当前内容为 NUL 结尾字符串(供检索断言);返回静态缓冲 */
static const char *vfs_get(void) {
static char buf[VFS_CAP + 1];
@@ -974,6 +1039,34 @@ static void tc_save(void) {
CHECK(strstr(vfs_get(), "u8=9") != NULL, "managed key still rewritten");
CHECK(strstr(vfs_get(), "vendor = kkk") != NULL, "unknown long line preserved");
}
printf("[TC-CONFIG-059] save view != stat token -> reject, file untouched\n");
{
size_t before_len;
int before_writes;
/* 台架实证吞段链:卷层在 stat→read 窗口给旧/短视图 → 旧实现照视图外科
* 重写整档 → 文件变小、非默认段被静默删除(实测 1066B→986B)。
* 守卫后:读视图与 stat 基准不符 = 拒存,原文件一字节不动 */
vfs_reset();
register_std();
vfs_put("[net]\r\nu8=7\r\n[sys]\r\nbaud=115200\r\n");
s_net_data.u8 = 9u;
vfs_mark_stale(); /* 视图冻结在当前完整文件 */
vfs_put("[net]\r\nu8=7\r\n"); /* 盘上真身变短(旧视图回滚形态) */
before_len = s_vfs_len;
before_writes = s_write_count;
s_syslog_count = 0;
g_cfgtest_err_count = 0;
CHECK(cfg_file_save() == -1, "mismatched view rejected with -1");
CHECK(s_vfs_len == before_len, "file bytes untouched");
CHECK(s_write_count == before_writes, "no atomic write happened");
CHECK(s_syslog_count >= 1, "view-stale self-test logged");
CHECK(g_cfgtest_err_count == 1, "one ERROR line logged");
vfs_clear_stale(); /* 视图追平盘上真身 */
CHECK(cfg_file_save() == 0, "save succeeds again after view converges");
CHECK(strstr(vfs_get(), "u8=9") != NULL, "RAM value written after convergence");
}
}
/* TC-CONFIG-050~054:poll 契约 */
@@ -1057,6 +1150,133 @@ static void tc_poll(void) {
CHECK(s_vfs_len <= CFG_FILE_MAX_LEN, "file regenerated within limit");
CHECK(s_net_cb_count == 0, "no callback on oversized (online-repair channel kept)");
}
printf("[TC-CONFIG-058] poll stale view -> reload HELD, RAM kept, self-heals\n");
{
vfs_reset();
register_std();
vfs_put("[net]\r\nu8=5\r\n");
s_net_data.u8 = 5u; /* RAM = 旧值:既非默认(7)也非新值(88) */
cfg_file_poll(); /* 基线 = 旧令牌(台架时序:先有基线再有变更) */
vfs_mark_stale(); /* 视图冻结在 u8=5(13B) */
vfs_put("[net]\r\nu8=88\r\n"); /* 盘上真实变更(14B,读长必不符) */
cfg_file_poll(); /* st 变:s_last 记录,stable=1 */
s_syslog_count = 0;
g_cfgtest_err_count = 0;
s_net_cb_count = 0;
cfg_file_poll(); /* stable=2 -> 读视图 13B != stat 14B -> HELD */
CHECK(s_net_data.u8 == 5u, "held: RAM keeps old value (not 88, not default)");
CHECK(g_cfgtest_err_count == 1, "first reject logs one ERROR");
CHECK(s_syslog_count == 1, "first reject self-test logged once");
CHECK(s_net_cb_count == 0, "no callback while held");
CHECK(s_base_valid == 1u, "baseline kept (retry not re-baseline)");
cfg_file_poll(); /* 视图仍旧 -> 继续 HELD,静默不刷屏 */
CHECK(g_cfgtest_err_count == 1, "repeat rejects stay silent");
CHECK(s_syslog_count == 1, "self-test not spammed");
vfs_clear_stale(); /* 卷层视图恢复 */
cfg_file_poll(); /* 令牌未变 stable 饱和 -> 重试应用 */
CHECK(s_net_data.u8 == 88u, "self-heal: value applied once view converges");
CHECK(s_net_cb_count >= 1, "callback fires on healed apply");
}
printf("[TC-CONFIG-060] mid-read rewrite -> HELD; WARN cadence rate-bounded\n");
{
int i;
/* 段一:读完成后令牌被推进(读中改写)→ 读后复 stat 检出 → 拒绝且自愈 */
vfs_reset();
register_std();
vfs_put("[net]\r\nu8=5\r\n");
s_net_data.u8 = 5u;
cfg_file_poll(); /* baseline */
vfs_put("[net]\r\nu8=88\r\n"); /* 外部变更 */
cfg_file_poll(); /* stable=1 */
s_touch_on_read = 1; /* 本次 read 结束即"被改写" */
g_cfgtest_err_count = 0;
s_syslog_count = 0;
cfg_file_poll(); /* stable=2 -> 读中改写 -> HELD */
CHECK(s_net_data.u8 == 5u, "mid-read rewrite held: RAM kept");
CHECK(g_cfgtest_err_count == 1, "mid-read reject logged one ERROR");
CHECK(s_syslog_count == 1, "mid-read reject self-test logged");
cfg_file_poll(); /* 令牌已变:重新 debounce */
cfg_file_poll(); /* 再沉降 -> 视图已一致 -> 应用 */
CHECK(s_net_data.u8 == 88u, "applies after view settles again");
/* 段二:持续旧视图 -> 全程仅 1 ERROR + 1 留痕,WARN 每 30 趟一条(≈60s) */
vfs_reset();
register_std();
vfs_put("[net]\r\nu8=5\r\n");
s_net_data.u8 = 5u;
cfg_file_poll(); /* 基线 = 旧令牌 */
vfs_mark_stale();
vfs_put("[net]\r\nu8=88888\r\n"); /* 与视图长度不同 -> 持续不一致 */
g_cfgtest_err_count = 0;
g_cfgtest_info_count = 0;
s_syslog_count = 0;
for (i = 0; i < 35; i++) {
cfg_file_poll(); /* 沉降 1 + HELD 34(streak 1..34 含 30) */
}
CHECK(s_net_data.u8 == 5u, "persistent stale view never touches RAM");
CHECK(g_cfgtest_err_count == 1, "episode logs exactly one ERROR");
CHECK(s_syslog_count == 1, "episode logs exactly one self-test");
CHECK(g_cfgtest_info_count == 1, "WARN cadence: one line per 30 rounds");
}
}
/* 内容层坏视图(2026-11-05 台架 15:21 实证形态:dhara 同尺寸全 0 旧映射块,
* 长度与再 stat 双检全过,仅内容判据可拦) */
static void tc_view_content(void) {
printf("[TC-CONFIG-061] poll zero-block same-size stale view -> HELD + self-heal\n");
{
vfs_reset();
register_std();
vfs_put("[net]\r\nu8=42\r\n");
s_net_data.u8 = 5u; /* RAM = 旧值:非默认(7)非新值(88) */
cfg_file_poll(); /* 基线(台架时序:先基线后变更) */
vfs_put("[net]\r\nu8=88\r\n"); /* 盘上真实变更(与旧视图同尺寸) */
vfs_mark_stale_zeros(); /* 视图 = 与 stat 同长的全 0 块 */
cfg_file_poll(); /* st 变:stable=1 */
s_syslog_count = 0;
g_cfgtest_err_count = 0;
s_net_cb_count = 0;
cfg_file_poll(); /* stable=2 -> 长度/令牌双检过,内容判据拦下 */
CHECK(s_net_data.u8 == 5u, "zero-block view held: RAM keeps old value");
CHECK(g_cfgtest_err_count == 1, "zero-block first reject logs one ERROR");
CHECK(s_syslog_count == 1, "zero-block first reject self-test logged");
CHECK(s_net_cb_count == 0, "zero-block view never reaches callback");
cfg_file_poll(); /* 视图仍旧 -> 持续 HELD 静默 */
CHECK(g_cfgtest_err_count == 1, "zero-block repeats stay silent");
CHECK(s_net_data.u8 == 5u, "zero-block view still never touches RAM");
vfs_clear_stale(); /* 卷层视图恢复 */
cfg_file_poll(); /* 重试 -> 一致视图 -> 应用 */
CHECK(s_net_data.u8 == 88u, "self-heal: applied once zero view refreshed");
CHECK(s_net_cb_count >= 1, "callback fires on healed apply");
}
printf("[TC-CONFIG-062] save on zero-block view -> abort, file untouched\n");
{
int w_before;
size_t l_before;
vfs_reset();
register_std();
vfs_put("[net]\r\nu8=88\r\n");
s_net_data.u8 = 9u; /* 待保存的脏值 */
vfs_mark_stale_zeros(); /* 保存链读到同长全 0 旧视图 */
w_before = s_write_count;
l_before = s_vfs_len;
s_syslog_count = 0;
g_cfgtest_err_count = 0;
CHECK(cfg_file_save() == -1, "save aborts on zero-block view");
CHECK(s_write_count == w_before, "no atomic write happened");
CHECK(s_vfs_len == l_before, "file size untouched (no shrink)");
CHECK(strcmp(vfs_get(), "[net]\r\nu8=88\r\n") == 0, "file bytes untouched");
CHECK(s_syslog_count == 1, "save reject self-test logged");
CHECK(g_cfgtest_err_count == 1, "save reject logs one ERROR");
vfs_clear_stale(); /* 视图恢复 -> 同一保存链重试成功 */
CHECK(cfg_file_save() == 0, "save succeeds once view converges");
CHECK(strstr(vfs_get(), "u8=9") != NULL, "dirty value persisted on retry");
}
}
int main(void) {
@@ -1074,6 +1294,7 @@ int main(void) {
tc_load();
tc_save();
tc_poll();
tc_view_content();
printf("\n=== Config File Tests: %d/%d PASSED (failed=%d) ===\n",
s_passed, s_total, s_failed);
-112
View File
@@ -1,112 +0,0 @@
#!/usr/bin/env python3
"""头阻塞专项台架探针(timeSync 侧,A/B 对照用)。
场景(历史审计的头阻塞触发形态,属主文档已于 2026-10-15 删除):
1. 一个"挂起"的对时客户端连上 :8888 后不发任何数据(空闲/故障客户端,
常见工况)——旧固件在此触发 30s 阻塞 net_recv 独占 netTask,
全体消费者的队列消息停摆最长 30s;
2. 2s 后从 PC 发起 FTP(:21) 连接,测 banner 到达时延 = 队列响应性:
修复前 ≈ 25~30s(队头冻结),修复后 ≈ 数百 ms 内;
3. 34s 时 30s 总预算应已耗尽:设备拆掉该会话(net_drop_conn:
FIN 关闭 + 本层收口 + 重监听),随后**本探针模拟守规矩对端**:
close 自己的 socket;
4. 芯片回 CLOSED(TC-NET-204 模式 A:TIME_WAIT 过渡 ~150ms)→ relisten,
:8888 应能再接受新连接(3s 重试窗内);新连接发完整 8 字节 TIME 包 →
设备应落 "wall clock updated"。
⚠ 定案口径(TRAP-NET-07 定案更正 2026-10-11 + 《网络自愈架构设计》§5.2 E13):CH395F close
**无 RST 语义**。若对端内核存活(app 挂起但 socket 不关,内核自动 ACK FIN),
芯片停在 FIN_WAIT_2、监听恢复受限于对端 close——探针第 3 步的 close 正是
模拟"对端配合"这一可恢复边界;不配合场景的兜底是芯片 TIMEOUT/keepalive
拆僵尸会话(E13 定案,30~90s)。
用法: python e02_probe.py <run-tag>
退出码: 0 = 队列响应性 PASS;1 = FAIL;2 = 探针自身异常
"""
import socket
import sys
import time
import bench_defaults # 台架连接默认值单一真源
DEV = bench_defaults.DEVICE_IP
tag = sys.argv[1] if len(sys.argv) > 1 else "run"
t0 = time.time()
def log(msg):
print("[%s] %9.3f %s" % (tag, time.time() - t0, msg), flush=True)
def main():
# 1. 挂起对时客户端:连接后不发任何数据
ts = socket.create_connection((DEV, 8888), timeout=5)
log("time-sync conn open (hung client: sends nothing)")
# 2. 2s 后测 FTP banner 时延(队列响应性)
time.sleep(2.0)
t1 = time.time()
banner = None
try:
ftp = socket.create_connection((DEV, 21), timeout=35)
banner = ftp.recv(256)
dt = time.time() - t1
log("FTP banner after %8.1f ms: %r" % (dt * 1000, banner[:40]))
ftp.close()
except Exception as e:
dt = time.time() - t1
log("FTP connect FAIL after %8.1f ms: %r" % (dt * 1000, e))
dt = None
queue_ok = (banner is not None) and (dt is not None) and (dt < 3.0)
log("queue responsiveness: %s (banner %s ms)"
% ("PASS" if queue_ok else "FAIL",
("%.0f" % (dt * 1000)) if dt is not None else "n/a"))
# 3. 等 30s 总预算耗尽(设备应拆会话:FIN + 本层收口 + 重监听)
remain = 34.0 - (time.time() - t0)
if remain > 0:
time.sleep(remain)
# 3b. 模拟守规矩对端:设备已发 FIN(drop_conn),本端 close 配合拆链。
# CH395F close 无 RST 语义(TRAP-NET-07 定案更正):不配合的内核存活对端
# 会把芯片停在 FIN_WAIT_2,监听恢复受限于对端 close——不在本探针判据内。
try:
ts.close()
log("hung client socket closed (cooperate with device FIN)")
except OSError:
pass # 设备已先拆连,本地 close 报 ECONNRESET 属预期
# 4. 监听应已重建(芯片 TIME_WAIT 过渡 ~150ms + relisten):3s 重试窗
t2 = time.time()
listener_ok = False
ts2 = None
while time.time() - t2 < 3.0:
try:
ts2 = socket.create_connection((DEV, 8888), timeout=2)
break
except Exception as e:
log("second time-sync conn retry: %r" % (e,))
time.sleep(0.3)
if ts2 is not None:
dt2 = time.time() - t2
epoch = int(time.time())
log("new time-sync conn in %6.0f ms, sent full TIME packet (epoch=%d)"
% (dt2 * 1000, epoch))
ts2.sendall(b"TIME" + epoch.to_bytes(4, "big"))
time.sleep(1.5) # 留时间给设备处理并打日志
ts2.close()
listener_ok = True
else:
log("second time-sync conn FAIL (3s window)")
log("OVERALL: queue=%s listener=%s"
% ("PASS" if queue_ok else "FAIL", "PASS" if listener_ok else "FAIL"))
return 0 if (queue_ok and listener_ok) else 1
if __name__ == "__main__":
try:
sys.exit(main())
except Exception as e:
print("[%s] PROBE ERROR: %r" % (tag, e), flush=True)
sys.exit(2)
+2 -1
View File
@@ -14,7 +14,8 @@
T7 会话结束重连、错口令一次 → 期望 530 且计数已清零(T5 成功清零)
注意:CH395F 单连接——每步用完必须 quit() 释放 socket,否则下一步连不上;
跑之前确保 UI 远程显示(7003)/对时(8888)客户端未占用 socket。
跑之前确保 UI 远程显示(7003)客户端未占用 socket(对时 :8888 已退役,
SNTP 只占 UDP 通道,与 TCP 单连接语义无关)。
用法(设备默认见 bench_defaults.DEVICE_IP,出厂口令 admin/admin):
& '.venv\\Scripts\\python.exe' test/host/ftp_auth_bench.py
+220 -8
View File
@@ -109,6 +109,12 @@ static int s_fail_check_ecc;
static int s_fail_program_load;
static int s_fail_program_exec;
static int s_fail_block_erase;
/* 定向坏页注入(问题 #79):非 0 时,**只有**该物理页的 program_exec 失败 */
static uint32_t s_fail_program_page = 0u;
/* 传输层失败注入(问题 #79):非 0 时 erase / program_exec 返回传输/超时错误
* (GD5F_ERROR,芯片**没有**回 E_FAIL/P_FAIL),用于验证"不得标坏块"。 */
static int s_fail_erase_transport;
static int s_fail_exec_transport;
/* ---- SPI 原语(stub/gd5f2gq5ue.h 声明,签名与真实驱动逐字一致) ---- */
@@ -190,6 +196,15 @@ int32_t gd5f_program_exec(uint32_t page_addr) {
if (s_fail_program_exec != 0) {
return GD5F_PROGRAM_FAIL;
}
if (s_fail_exec_transport != 0) {
return GD5F_ERROR; /* 传输/等忙失败:芯片没回 P_FAIL */
}
/* 定向坏页注入(问题 #79):现场是**某一个 PPA 恒写不进去**,其余页正常。
* 全局 s_fail_program_exec 无法复现"只有那一页坏"的形态——它连格式化
* 之后的新写入也一起打死,反而测不出"换个页就能写"这个关键结论。 */
if ((s_fail_program_page != 0u) && (page_addr == s_fail_program_page)) {
return GD5F_PROGRAM_FAIL;
}
/* 严格语义探针:目标页已有非 0xFF 字节 = 双编程(is_free 误判的现场证据) */
for (i = 0; i < FAKE_PAGE_SIZE; i++) {
@@ -217,6 +232,9 @@ int32_t gd5f_block_erase(uint32_t block_addr) {
if (s_fail_block_erase != 0) {
return GD5F_ERASE_FAIL;
}
if (s_fail_erase_transport != 0) {
return GD5F_ERROR; /* 传输/等忙失败:芯片没回 E_FAIL */
}
(void)memset(&s_chip[block_addr * FAKE_PAGES_PER_BLOCK][0], 0xFF,
(size_t)FAKE_PAGES_PER_BLOCK * FAKE_PAGE_SIZE);
return GD5F_OK;
@@ -282,6 +300,9 @@ static void fake_chip_reset(void) {
s_fail_program_load = 0;
s_fail_program_exec = 0;
s_fail_block_erase = 0;
s_fail_program_page = 0u; /* 定向坏页注入复位(0 = 不注入,0 号页本身也不允许当靶) */
s_fail_erase_transport = 0;
s_fail_exec_transport = 0;
g_nandtest_err_count = 0;
g_nandtest_info_count = 0;
g_nandtest_debug_count = 0;
@@ -659,9 +680,10 @@ static void tc_prog(void) {
CHECK(g_fake_mark_bad_cnt == 1u, "program failure marks exactly one block bad");
CHECK(g_fake_mark_bad_log[0] == 2u, "the block marked bad is the page's own block");
/* TC-NANDPORT-207:program_load 失败(装载阶段)-> 同样 BAD_BLOCK + 标坏该块,
* 且在 exec 之前就短路(真实芯片:02h 都没成,10h 自然不发) */
printf("[TC-NANDPORT-207] program_load failure -> BAD_BLOCK + mark bad\n");
/* TC-NANDPORT-207:program_load 失败(装载阶段)-> BAD_BLOCK,但**不标坏块**。
* 【#79 修复】装载失败是传输层问题(02h 都没送达芯片),芯片从未回 P_FAIL,
* 把块标坏等于把"线抖了一下"固化成永久坏块。旧实现在此标坏,本用例把守。 */
printf("[TC-NANDPORT-207] program_load failure -> BAD_BLOCK, NO mark bad\n");
fake_chip_reset();
s_fail_program_load = 1;
err = DHARA_E_NONE;
@@ -669,8 +691,21 @@ static void tc_prog(void) {
"program_load failure -> -1");
CHECK(err == DHARA_E_BAD_BLOCK, "program_load failure -> DHARA_E_BAD_BLOCK");
CHECK(g_fake_program_exec_cnt == 0u, "load failure short-circuits before program_exec");
CHECK(g_fake_mark_bad_cnt == 1u, "load failure marks exactly one block bad");
CHECK(g_fake_mark_bad_log[0] == 3u, "the block marked bad is the page's own block");
CHECK(g_fake_mark_bad_cnt == 0u, "load failure must NOT mark bad (transport, not media)");
CHECK(fake_bad_unchanged(), "load failure leaves the BBT untouched");
/* TC-NANDPORT-208:program_exec 传输/超时失败(芯片未回 P_FAIL)-> 不标坏块。
* 【#79 核心】真机现场:出厂 0 坏块、底层写全部成功,而持久化 BBT 把
* 1016–1142 连续段判坏——正是这类失败被旧实现标坏并固化所致。 */
printf("[TC-NANDPORT-208] program_exec transport failure -> BAD_BLOCK, NO mark bad\n");
fake_chip_reset();
s_fail_exec_transport = 1;
err = DHARA_E_NONE;
CHECK(dhara_nand_prog(&s_ut_nand, 4u * 64u, page_buf, &err) == -1,
"program_exec transport failure -> -1");
CHECK(err == DHARA_E_BAD_BLOCK, "program_exec transport failure -> DHARA_E_BAD_BLOCK");
CHECK(g_fake_mark_bad_cnt == 0u, "exec transport failure must NOT mark bad");
CHECK(fake_bad_unchanged(), "exec transport failure leaves the BBT untouched");
}
/* ===================== TC-NANDPORT-300..307:dhara_nand_read ===================== */
@@ -867,15 +902,27 @@ static void tc_erase(void) {
CHECK(dhara_nand_erase(&s_ut_nand, UT_OOB_BLOCK - 1u, &err) == 0,
"erase block == num_blocks - 1 -> 0");
/* TC-NANDPORT-504:擦除失败 -> BAD_BLOCK + 标坏该块 */
printf("[TC-NANDPORT-504] erase failure -> BAD_BLOCK + mark bad\n");
/* TC-NANDPORT-504:芯片回 E_FAIL 的擦除失败 -> BAD_BLOCK + 标坏该块(正确处置) */
printf("[TC-NANDPORT-504] erase E_FAIL -> BAD_BLOCK + mark bad\n");
fake_chip_reset();
s_fail_block_erase = 1;
err = DHARA_E_NONE;
CHECK(dhara_nand_erase(&s_ut_nand, 3u, &err) == -1, "block_erase failure -> -1");
CHECK(err == DHARA_E_BAD_BLOCK, "block_erase failure -> DHARA_E_BAD_BLOCK");
CHECK(g_fake_mark_bad_cnt == 1u, "erase failure marks exactly one block bad");
CHECK(g_fake_mark_bad_cnt == 1u, "erase E_FAIL marks exactly one block bad");
CHECK(g_fake_mark_bad_log[0] == 3u, "the block marked bad is the one that failed");
/* TC-NANDPORT-505:擦除传输/超时失败(芯片未回 E_FAIL)-> 不标坏块。
* 【#79 核心】这是把 129 个好块误标并持久化的那条路径;标坏是**不可撤销**
* 的持久化动作,只有芯片明确回 E_FAIL 才允许。 */
printf("[TC-NANDPORT-505] erase transport failure -> BAD_BLOCK, NO mark bad\n");
fake_chip_reset();
s_fail_erase_transport = 1;
err = DHARA_E_NONE;
CHECK(dhara_nand_erase(&s_ut_nand, 5u, &err) == -1, "erase transport failure -> -1");
CHECK(err == DHARA_E_BAD_BLOCK, "erase transport failure -> DHARA_E_BAD_BLOCK");
CHECK(g_fake_mark_bad_cnt == 0u, "erase transport failure must NOT mark bad");
CHECK(fake_bad_unchanged(), "erase transport failure leaves the BBT untouched");
}
/* ===================== TC-NANDPORT-600..605:is_bad / mark_bad ===================== */
@@ -981,6 +1028,168 @@ static void tc_dhara_scenario(void) {
"write + resume scenario: zero double-program violations (scenario guard)");
}
/* ===================== TC-NANDPORT-800..813:问题 #79 回归 =====================
*
* 现场(2026-11-04 台架,两次独立捕获):
* 探针写 /fschk.tmp → disk_write → ftl_flush_cache 对 LPN=211 反复 TOO_BAD
* → 判卷损坏 → storage_bring_up 调 nand_ftl_format() 想重建
* → **旧版 format 先 flush 同一脏页、失败即 return** → map 从没被清过
* → f_mkfs 在旧映射上跑 → 3 轮重试耗尽 → storage disabled(每次启动必现)。
*
* 本组测三件事:
* ① 脏缓存写不进去时,format **仍然成功**并清掉映射(修复点);
* ② format 后脏缓存被丢弃,不会带着旧 LPN 幽灵继续写(配套不变量);
* ③ 失败快照(C4)真的把"操作 / 失败类 / LPN / 次数"带出函数边界(新能力)。
*
* 假芯片的失败注入是**按页**的(s_fail_program_exec 是全局开关),而现场是
* "某个 LPN 的写回恒定失败"。这里用"让 program_exec 恒失败"逼近同一形态:
* 脏页写不进去 → flush 必失败,正是旧版 return 的那个分支。
*/
/* 把脏缓存喂进去:直接经 FatFs 叶子的 disk_write 不可行(那会先触发 init),
* 故手工构一个与 disk_write 相同的前置状态:缓存里有一页待写数据。 */
static void prep_dirty_cache(uint32_t lpn, uint8_t seed) {
fake_chip_reset();
s_cached_lpn = (dhara_sector_t)lpn;
fake_fill_pattern(s_cache_buf, FTL_PAGE_SIZE, seed);
s_cache_dirty = 1u;
}
static void tc_format_survives_flush_failure(void) {
uint8_t before[FTL_PAGE_SIZE];
/* ---- 前置:一个已建好、里面真有数据的卷(模拟台架"卷原本可用") ---- */
fake_chip_reset();
s_ut_nand.log2_page_size = 11u;
s_ut_nand.log2_ppb = 6u;
s_ut_nand.num_blocks = (unsigned int)FAKE_USABLE_BLOCKS;
dhara_map_init(&s_map, &s_ut_nand, s_page_buf, 4);
memset(s_cache_buf, 0, FTL_PAGE_SIZE);
s_cached_lpn = (dhara_sector_t)-1;
s_cache_dirty = 0;
s_initialized = 1;
(void)dhara_map_clear(&s_map);
{
dhara_error_t e;
(void)dhara_map_sync(&s_map, &e);
}
fake_fill_pattern(s_cache_buf, FTL_PAGE_SIZE, 0xA5u);
{
dhara_error_t e;
CHECK(dhara_map_write(&s_map, 0u, s_cache_buf, &e) == 0,
"TC-NANDPORT-800 precondition: sector 0 written");
}
fake_fill_pattern(s_cache_buf, FTL_PAGE_SIZE, 0x5Au);
{
dhara_error_t e;
CHECK(dhara_map_write(&s_map, 1u, s_cache_buf, &e) == 0,
"TC-NANDPORT-801 precondition: sector 1 written");
}
CHECK(dhara_map_size(&s_map) == 2u, "TC-NANDPORT-802 precondition: 2 sectors used");
/* ---- 关键形态:缓存脏着(脏页写不出去),此时调 format() ----
* 阶段 A 用"介质整体写不动"逼近最坏情况:program_load 全失败 ⇒ dhara 反复
* 标坏块 + 重试 8 次后 TOO_BAD,正是 `Cache flush FAIL: LPN=211 … TOO_BAD`
* 那条日志的来源。这一阶段**只断言死锁被打破**,不断言 format 返回 OK——
* 介质真的全写不动时它本来就落不了盘,报错是诚实的。 */
memset(s_cache_buf, 0xC3, FTL_PAGE_SIZE);
s_cached_lpn = (dhara_sector_t)211u; /* 与现场 LPN=211 同形 */
s_cache_dirty = 1u;
memcpy(before, s_cache_buf, FTL_PAGE_SIZE);
s_fail_program_load = 1;
(void)nand_ftl_format();
/* ★ 本单的核心断言:**旧实现到这里 map 一个字节都没清**
* (它在 ftl_flush_cache() 失败那行就 return 了,dhara_map_clear 从未执行)。
* 新实现必须已经把 map 清空、缓存作废——这正是"恢复动作本身被永久挡住"
* 这条死锁的破点。 */
CHECK(dhara_map_size(&s_map) == 0u,
"TC-NANDPORT-804 format clears the map even when dirty-cache flush fails (fix for #79)");
CHECK(s_cache_dirty == 0u, "TC-NANDPORT-805 format discards the dirty cache flag");
CHECK(s_cached_lpn == (dhara_sector_t)-1,
"TC-NANDPORT-806 format invalidates cached LPN (no ghost page reuse)");
CHECK(memcmp(s_cache_buf, before, FTL_PAGE_SIZE) == 0,
"TC-NANDPORT-807 format does not fabricate page content");
/* ---- 阶段 B:介质可用后(新片上电 = 无坏块积累、map 重新 resume),
* format 必须产出真正可写的空卷。现场对应"下次可写的格式化"。 ---- */
fake_chip_reset(); /* 同时复位全部失败注入 */
dhara_map_init(&s_map, &s_ut_nand, s_page_buf, 4);
memset(s_cache_buf, 0, FTL_PAGE_SIZE);
s_cached_lpn = (dhara_sector_t)-1;
s_cache_dirty = 0;
s_initialized = 1;
nand_ftl_fault_clear();
{
int rc = nand_ftl_format();
CHECK(rc == GD5F_OK, "TC-NANDPORT-808 on recovered media: format returns OK");
CHECK(dhara_map_size(&s_map) == 0u,
"TC-NANDPORT-808b on recovered media: map is empty after format");
}
{
dhara_error_t e;
int wrc;
fake_fill_pattern(s_cache_buf, FTL_PAGE_SIZE, 0x11u);
wrc = dhara_map_write(&s_map, 0u, s_cache_buf, &e);
CHECK(wrc == 0, "TC-NANDPORT-809 after format: new volume accepts writes");
CHECK(dhara_map_size(&s_map) == 1u, "TC-NANDPORT-810 after format: map counts 1 sector");
}
/* ---- 失败快照(C4):新能力,把失败类带出函数边界 ---- */
nand_ftl_fault_clear();
{
nand_ftl_fault_t f;
nand_ftl_fault_get(&f);
CHECK(f.active == 0u, "TC-NANDPORT-811 fault snapshot clear -> inactive");
CHECK(f.count == 0u, "TC-NANDPORT-811b fault snapshot clear -> count reset");
}
/* 造一次可归类的失败:脏缓存 + 写不动 */
fake_chip_reset();
memset(s_cache_buf, 0x77, FTL_PAGE_SIZE);
s_cached_lpn = (dhara_sector_t)211u;
s_cache_dirty = 1u;
s_fail_program_load = 1;
{
bsp_err_t cls = ftl_flush_cache();
nand_ftl_fault_t f;
CHECK(cls != BSP_OK, "TC-NANDPORT-812a injected flush failure returns an error class");
nand_ftl_fault_get(&f);
CHECK(f.active == 1u, "TC-NANDPORT-812 fault snapshot becomes active after a failure");
CHECK(f.op == NAND_FTL_OP_FLUSH, "TC-NANDPORT-812b snapshot records the failing operation");
CHECK(f.cls == (int32_t)cls, "TC-NANDPORT-812c snapshot records the failure class");
CHECK(f.lpn == 211u, "TC-NANDPORT-812d snapshot records the failing LPN");
CHECK(f.count == 1u, "TC-NANDPORT-812e snapshot counts the failure");
}
/* 再失败一次:count 累计(现场是同一页撞 15 次) */
{
nand_ftl_fault_t f;
(void)ftl_flush_cache();
nand_ftl_fault_get(&f);
CHECK(f.count == 2u, "TC-NANDPORT-813 repeated failures accumulate (same-page retry)");
CHECK(f.lpn == 211u, "TC-NANDPORT-813b repeated failures keep the same LPN");
}
s_fail_program_load = 0;
s_fail_program_page = 0u;
nand_ftl_fault_clear();
s_initialized = 0;
s_cached_lpn = (dhara_sector_t)-1;
s_cache_dirty = 0;
}
/* ===================== main ===================== */
int main(void) {
@@ -1023,6 +1232,9 @@ int main(void) {
printf("-- dhara map scenario (real dhara, fake chip) --\n");
tc_dhara_scenario();
printf("-- format survives dirty-cache flush failure + fault snapshot (issue #79) --\n");
tc_format_survives_flush_failure();
printf("\n=== NAND Port Tests: %d/%d PASSED (failed=%d) ===\n",
s_passed, s_total, s_failed);
return (s_failed == 0) ? 0 : 1;
+11 -13
View File
@@ -5,19 +5,18 @@
做什么:
用本机 MSVC 编译 test/host/time_sync/time_sync_test.c(它以 #include 纳入
**生产源文件** App/sync/time_sync.c),在 PC 上离线跑:
分片延时(心跳节奏)/ 监听建立与退避 / 时间包重组状态机(分段 + 30s 预算 +
tick 回绕)/ 任务主循环(就绪屏障、accept 轮询、代次变化重监听)。
分片延时(心跳节奏)/ 任务主循环(就绪屏障、SNTP 节拍、代次下传)。
失败即非 0 退出。零硬件、零烧录、毫秒级。
工具链探测 / INCLUDE-LIB 拼接 / 编译运行 / 退出码判定全部委托给通用 harness
`test/host/common/unit_test_harness.py`(本文件只做声明)。
为什么要主机侧单测(而不是只用板端套件):
本模块是探针窗口心跳缺口那件事的当事方——"监听重建期间心跳缺口 800ms~1s,距 IWDG 最坏
超时 1701ms 余量仅 ~0.7s"。缺口成因全是本模块的**纯逻辑**(分片延时的喂狗
节奏、500/2000ms 监听退避、200ms accept 退避、50ms 收尾、屏障等待态喂心跳)。
真机上只能"跑起来看复位不复位",主机侧可**逐片断言**。时间包重组状态机
(分段送达 / 预算耗尽 / EOF / 真错误 / tick 回绕)同理。
本模块是探针窗口心跳缺口那件事的当事方——心跳节奏(delay_fed 的 ≤50ms
分片 + 每片前置心跳、屏障等待态 100ms 分片喂心跳)全是**纯逻辑**,真机上
只能"跑起来看复位不复位",主机侧可**逐片断言**(2026-10-02 台架根因、
第 8b 轮消抖两条教训都钉在这里)。:8888 监听/协议用例已随 2026-11-04 的
:8888 退役删除(墙钟维护说明 §15),历史覆盖见 git 历史。
用法(仓库根目录):
python test/host/time_sync/run_unit_test.py
@@ -25,8 +24,8 @@
退出码:0=PASS / 1=测试失败 / 2=环境错误(找不到编译器 / 编译失败 / 无汇总行)。
设计依据:App/sync/time_sync.c 文件头注释 + docs/网络/网络自愈架构设计.md §4.6;
创建日期:2026-10-10
设计依据:App/sync/time_sync.c 文件头注释 + docs/子系统设计/系统墙钟时间维护说明.md §15/§16;
创建日期:2026-10-10(2026-11-04 随 :8888 退役收缩)
"""
import os
import sys
@@ -39,9 +38,9 @@ sys.path.insert(0, os.path.join(ROOT, "test", "host", "common"))
from unit_test_harness import TestBuild, run_host_unit_test # noqa: E402
# 顺序敏感:stub 目录必须**先于**生产目录,才能覆盖 FreeRTOS.h / task.h /
# net_socket.h / sys_events.h / sys_clock.h / dbg_log.h(真实头会拖入整套
# FreeRTOS / CMSIS-RTOS / HAL)。task_watchdog.h 用**真实头**(App/util,只依赖
# stdint.h),time_sync.h 用真实头(接口契约原汁)。
# net_socket.h / sys_events.h(真实头会拖入整套 FreeRTOS / CMSIS-RTOS / HAL)。
# task_watchdog.h 与 time_sntp.h 用**真实头**(接口契约原汁:前者只依赖 stdint.h,
# 后者自包含——替身签名由编译器对表)。
BUILD = TestBuild(
name="Time Sync Tests",
src=os.path.join(HERE, "time_sync_test.c"),
@@ -49,7 +48,6 @@ BUILD = TestBuild(
os.path.join(HERE, "stub"),
os.path.join(ROOT, "App", "util"),
os.path.join(ROOT, "App", "sync"),
os.path.join(ROOT, "App", "log"), # sys_log.h 用真实头(纯 stdint,同 task_watchdog.h 先例)
HERE,
],
summary_marker="=== Time Sync Tests:",
-31
View File
@@ -1,31 +0,0 @@
/*
* 主机侧单测桩:dbg_log.h
* 模块功能:为 App/sync/time_sync.c 提供主机可编译的日志宏(映射到计数)。
*
* ⚠ 仅供 test/host/time_sync/ 使用,不参与 MCU 构建。
*
* 注意:time_sync.c 在 `#include "dbg_log.h"` 之前自行 `#define` 了
* DBG_LINE_BUF_MAX 与 DBG_TAG(真实头会用到它们),故本桩**不得**再定义这两个宏,
* 否则触发 C4005 宏重定义告警(/W4)。
*
* DBG_ERROR / DBG_INFO 计入计数器,供单测断言:
* - "net_socket/bind/listen FAIL"、"open listener FAIL, retry later" → ERROR
* - "no TIME packet in 30s, drop conn"、"wall clock updated"、"network re-init" → INFO
*
* 创建日期:2026-10-10
*/
#ifndef DBG_LOG_H
#define DBG_LOG_H
#include <stdio.h>
/* 计数(在 time_sync_test.c 实现) */
extern int g_tstest_err_count;
extern int g_tstest_info_count;
#define DBG_INFO(fmt, ...) do { g_tstest_info_count++; } while (0)
#define DBG_DEBUG(fmt, ...) do { } while (0)
#define DBG_ERROR(fmt, ...) do { g_tstest_err_count++; } while (0)
#endif /* DBG_LOG_H */
+10 -45
View File
@@ -1,20 +1,18 @@
/*
* 主机侧单测桩:net_socket.h(含内联 net_types.h 子集)
* 模块功能:为 App/sync/time_sync.c 提供主机可编译的网络 Socket API 声明与类型。
* 主机侧单测桩:net_socket.h(收缩版,:8888 退役后)
* 模块功能:为 App/sync/time_sync.c 提供主机可编译的 net_get_generation 声明。
*
* ⚠ 仅供 test/host/time_sync/ 使用,不参与 MCU 构建。
* 真实头(Drivers/BSP/NET/net_socket.h)包含 net_types.h → net_config.h,并经
* FreeRTOS.h / task.h 拖入整套 FreeRTOS;本桩改为包含同名桩头。
* FreeRTOS.h / task.h 拖入整套 FreeRTOS;本桩改为包含同名桩头(含 FreeRTOS/task
* 两条**保真**包含——生产源正是靠真实头的这条链拿到 vTaskDelay / pdMS_TO_TICKS)。
*
* 保真点:
* - 地址族/类型/特殊地址常量与 Drivers/BSP/NET/net_types.h 逐字一致;
* - struct net_sockaddr / net_in_addr / net_sockaddr_in 字段与真实头一致
* (被测代码写 sin_family / sin_port / sin_addr.s_addr,桩按同布局读取);
* - 7 个被测代码调用的接口签名与真实头一致(net_socket / net_bind / net_listen /
* net_accept / net_close / net_recv_to / net_get_generation / net_htons)。
* 全部由测试单元给强符号桩(脚本化返回值 + 调用记录)。
* 收缩说明(2026-11-04)::8888 退役后本任务只剩 net_get_generation 一处网络
* 调用。socket / bind / listen / accept / close / recv 族声明**刻意不列**——
* 若 time_sync 循环重新伸手碰监听族 API,测试 TU 会因"未声明 + 无强符号桩"在
* 编译/链接期直接爆,这是退役语义的编译期绊线(替代退役前的运行时断言)。
*
* 创建日期:2026-10-10
* 创建日期:2026-10-10(2026-11-04 随 :8888 退役收缩)
*/
#ifndef NET_SOCKET_H
@@ -29,41 +27,8 @@
extern "C" {
#endif
/* ===== 以下取自 Drivers/BSP/NET/net_types.h(逐字) ===== */
#define NET_AF_INET 2 /* IPv4 */
#define NET_SOCK_STREAM 1 /* TCP */
#define NET_SOCK_DGRAM 2 /* UDP */
#define NET_INADDR_ANY 0 /* 任意地址 */
#define NET_INADDR_NONE 0xFFFFFFFF /* 无效地址 */
struct net_sockaddr {
uint16_t sa_family; /* 地址族 */
char sa_data[14]; /* 地址数据 */
};
struct net_in_addr {
uint32_t s_addr; /* IP 地址(网络字节序) */
};
struct net_sockaddr_in {
uint16_t sin_family; /* 地址族,必须为 AF_INET */
uint16_t sin_port; /* 端口号(网络字节序) */
struct net_in_addr sin_addr; /* IP 地址(网络字节序) */
char sin_zero[8]; /* 填充字节 */
};
/* ===== 被测代码用到的 Socket API(签名与真实头一致) ===== */
int net_socket(int domain, int type);
int net_bind(int sockfd, const struct net_sockaddr *addr, int addrlen);
int net_listen(int sockfd);
int net_accept(int sockfd, struct net_sockaddr *addr, int *addrlen);
int net_close(int sockfd);
int net_drop_conn(int sockfd);
int net_recv_to(int sockfd, void *buf, int len, uint32_t timeout_ms);
/* 与 Drivers/BSP/NET/net_socket.h 签名一致 */
uint32_t net_get_generation(void);
uint16_t net_htons(uint16_t hostshort);
#ifdef __cplusplus
}

Some files were not shown because too many files have changed in this diff Show More