wandering1
|
13a4a40a14
|
feat(net): 服务器侧 KeepAlive 转正(§5.56,E11)+ Phase 11 重开回归
E11(d96113b)证据链:"链路在、对端静默"注入下生产参数 60/5/3 实测
判死 ≈30s → TIM_OUT → QUARANTINE → pump 重建;静默但存活对端不误杀。
handle_connect_event LISTENING 分支按手册规定位置开启;反汇编确认
编译器把两分支尾部合并(LISTENING 跳入含 keepalive+fire_event 的公共
尾部,hex 全片仅该分支偏移 1 行差异,Code 尺寸不变属填充巧合)。
Phase 11 重开时发现其拉入 32KB s_rx_buf 超产品 RAM 余量(L6406E 链接
失败)→ 改专用 64B 探针缓冲(本 Phase 仅 64B 探针读,门控注释已留
"勿加回"警示),套件恢复 0 错 0 警;TC-NET-1101 步骤同步死对端注入法
(禁用网卡;Windows 防火墙规则对已建立连接无效,E11 实证)。
验证:产品/套件双构建 0 错 0 警 + 反汇编确认调用落地;台架确认
(:7003 静默对端判死 + Phase 11 实跑)待设备冷启动断电重上电后补做。
|
2026-10-13 09:25:06 +08:00 |
|
wandering1
|
d96113bcc4
|
docs(net): N34 E11/E12 实验记录与台架脚本(KeepAlive 服务器侧缺口、TSL 规格偏离)
E11:服务器侧 KeepAlive 未开启(静态证据链 + 注入手段两次修正 + 实测
生产参数 30.0s 判死、空闲存活会话不误杀),给出采纳建议;防火墙规则
对已建立连接无效、有效注入 = 禁用 PC 网卡,两条方法学留痕。
E12:缓存区读写路径长度→数据零间隔属规格偏离(读 0.4us/写 0.2us),
但 460 轮/约 58MB 字节级校验未测得可复现危害;依 Trap 25 登记偏离、
B 变体(两段+TSL,+28B,吞吐无回退)留作待用补丁。
残渣风暴态跨烧录存活污染 A/B 连接级对比,教训写入 E12:实验前后必须
冷启动(断电重上电),MCU 覆写烧录/RESET_ALL 不足以清除。
新增 test/host/e11_keepalive_probe.py(idle/block 两模式 + 注入正对照)
与 test/host/ftp_integrity_test.py(STOR→RETR 全量 SHA-256 比对,
建议纳入常备回归集)。
|
2026-10-13 09:10:17 +08:00 |
|
wandering1
|
eac36526e7
|
docs(net): E10 补收尾门禁结论(ci_local L0 32/32 + L0.5 951/951)与两处修复留痕
|
2026-10-13 06:53:42 +08:00 |
|
wandering1
|
bfbe24e423
|
chore(ram): 同步 RAM 快照/台账受管区至分支当前 .map
本分支(task/N34-bsd-selfheal-audit)自身的代码增长(net_listener.c 等)
从未刷新 RAM 文档受管区,导致 mem-numbers/mem-budget 在分支上长期失败
(任何 App/*.c 提交都会撞),此前用 --no-verify 绕过。
- `scripts/check_mem_numbers.py --write`:docs/内存管理/RAM使用分析与优化方案.md
ER_IROM1 227,824→228,172 B、Flash 合计 228,928→229,276 B
- `scripts/ram_baseline.py --write`:docs/内存管理/RAM预算台账.md 同源数字
RAM 两区(RW_IRAM1 97,864 B / 74.7%、RW_CCM 57,376 B / 87.9%)未变——
印证 N34 阶段 0/1 未改动 RAM 占用(仅 Flash 少量增长)。
验证:check_mem_numbers.py --scan "内存数字一致";ram_baseline.py --gate
"PASS:RW_IRAM1 74.7% / RW_CCM 87.9%(阈值 92%)"。
|
2026-10-13 06:52:08 +08:00 |
|
wandering1
|
d5bdc6eb54
|
docs(net): N34 阶段0/1 实施结果与台架留痕(E10)
- README:新增"实施状态"表(9ac9879/ae17d36/4c0a0af/b8c6a3d);§2 逐机制
裁决表补"✅ 已实施"与关键坑位索引
- 实验方案:新增 E10 —— 阶段 0/1 转正验证全记录,含阶段 1 首版台架失败的
根因链(armed 漏放行 ESTABLISHED → i104 整场饿死 18/18 FAIL → 修复后
18/18 PASS、127s→8.3s)、M3 无辜旁证、time_sync 连续 6 轮实测、
两处实施偏差(lftpd 未走 listener_try;阶段 0 提交合并)
- 实施方案:阶段 0/§2、阶段 1/§3 标注完成与验证判据;P0 转正标注
- 盘点:F-NET-2/3/4/13/14 补实施结论;⚠ F-NET-4 补"门控迁移必须给
net_listener_armed 补 ESTABLISHED 放行"的坑位说明;net_listener_try
调用点计数 5→4;§2/§4 的缺口表述改闭环状态
- 顺带修正两条既有 doc-links 违规(实验方案 §4.4 → 实施方案 §4 第 4 项;
盘点 §5.29 → docs/芯片手册/CH395F.md §5.29),该 4 份文档 doc-links
现 Passed
无代码改动(纯文档)。
|
2026-10-13 06:46:40 +08:00 |
|
wandering1
|
b8c6a3dab0
|
refactor(net)!: N34 阶段1 API 面收敛(对账⑤ + 删 3 个手动自愈 API)
BREAKING CHANGE: 删除公开 API net_relisten / net_resync_listen /
net_can_accept 与消息类型 NET_MSG_RESYNC_LISTEN / NET_MSG_RELISTEN。
生产调用者为零(仅看门狗文档与 iec104 门控),应用侧无迁移成本;
如有外部消费者须改用对账/pump 自动机制(见下)。
1. 对账①扩展为①②⑤(F-NET-2 缺口,先补缺口再删 API)
net_reconcile_tick 新增 bad=5:本层 ESTABLISHED 且芯片 0x05/0x01
(Socket OPEN + TCP LISTEN,静默回收回监听、不发 DISCONNECT)
→ RESYNC 语义只修本层(state→LISTENING + last_peer_port 转登 +
lost_conn_seen 清零 + 取消挂起 recv),**不发任何芯片命令**
(纪律同 pump③ U11,run8 实证重下发会 170s 永拒)。
原判据①要求 TCP==CLOSED、②要求本层 LISTENING,均不命中此形态
——此前生产无人认领(仅手动 API 能修)。
2. 删 net_relisten(net_socket.c 函数 + 消息分派 + 头文件声明)
footgun:对健康监听器无条件 open→USE→close 自毁 ~1s(原注释自认);
与 pump(100ms)/D10(30ms) 完全重叠。
3. 删 net_resync_listen(同上;语义并入第 1 条)
4. 删 net_can_accept(net_socket.c + net_socket.h + sim 三处)
只认 ESTABLISHED 的旧门控把"监听器在服役、待 CONNECT"窗口全挡掉,
:2404 丢 CONNECT 探针因此从不运行;iec104 门控迁 net_listener_armed。
5. timeSync :8888 会话收尾不再 net_close(同 fd 续 accept,监听跨会话
常驻;原 close→重建每会话一个 Trap 09 沉降窗)。server 脚本注释同步
新契约(PC 侧 2s 宽限后自行关闭)。
6. lftpd 应用层阻塞重试退役:lftpd_inet_listen 5 轮(500ms/2000ms,最坏
10s 阻塞 ftpTask) → 单次 + 失败即 425;cmd_pasv 3×200ms 同删。
就绪屏障已消除 Trap 09 启动形态,客户端自带传输重试语义。
台架实证修正(本提交内二次修复,务必留痕):
- net_listener_armed 补齐 **ESTABLISHED 放行**。首版迁移只放行
LISTENING/CLOSED+残留,漏了 ESTABLISHED=单连接模型的"待 accept"电平
→ iec104 200ms 任务周期抢不过对账② 的 ~400ms 去抖,对账②先 standalone
accept 转 ESTABLISHED 后 armed=0 → 应用整场不 accept,18/18 检查全 FAIL
(设备日志证据:sock1 standalone accept 后无 i104 accepted,直至对端 FIN
才由 closed-with-data 救回)。补放行后 18/18 PASS,且耗时 127s→8.3s。
该态 accept 必返 fd,无 RPC 风暴风险。
- 期间顺带验证 M3 无辜:sock1 suspect DISCONNECT on live conn 命中后
defer→对账①→closed-with-data accept 把未 accept 的 RX 数据救回,
正是 M3 设计意图(资产门保护)。
验证(全绿):@build 0/0(Code=209580;含 CH395F 套件+Phase13 全量重编
0/0 的编译验证);@test PASS(回读无差异);iec104 18/18(8.3s);
n30 0/50;:21 @0ms 50/50 p50=512;:7003 50/50 p50=517;ftp_regression
11/11;Trap23 RST 5/5 + FIN 5/5;time_sync :8888 连续推送正常(RTC 更新、
无 [ERR])。文档同步:BSD 指南(§3.3/3.6/10.1/10.2/12 + 变更记录)、
函数调用关系、监听生命周期设计说明、IEC104 上行设计说明、模拟器差距
清单、链路延迟测试说明。
门禁说明:doc-links 工作树 junction 伪影按既定口径 SKIP;mem-budget
分支 .map 漂移同前;cppcheck/coding-standard 手跑 Passed。
|
2026-10-13 06:44:26 +08:00 |
|
wandering1
|
b8d87c62d7
|
docs(net): N34 E8 风暴态深查 + T6 核实 + E9 M3 记录
- 实验方案:E8(状态依赖矩阵 2%~54%、风暴签名、三缺陷机制)
+ E9(M3 三轮迭代判据演进表与裁决、遗留观察归因)
- 盘点:F-NET-17 风暴态节 + T6 补充节(TC-NET-204 模式 C 证伪
"close 产生锁存"强形式,锁存生成者=拆链完成事件;泵/救回同
缓冲竞态证实;M3 补丁设计与 M5 drain-until-quiescent 状态机草案)
- 实施方案:§1.5 E8 修正(残余非稳定 3% 而是风暴态,M3/M5 互补)
|
2026-10-13 05:38:21 +08:00 |
|
wandering1
|
a0b9d27821
|
docs(net): N34 BSD 自愈审计与实施/实验方案(E0-E7b 台架记录)
五层自愈机制盘点(F-NET-1..15)、CH395F 驱动层审计(F-DRV-1..16)、
主流方案对照(ioLibrary/FreeRTOS+TCP/mbed/Zephyr)、实施方案
(阶段 0..3 + P0 止血包 + 阶段 1.5 recv 语义主流化)、实验方案
(E0/E1/E5/E7/E7b 实测数据与判据)。
关键结论:
- 对账是冷路径(E0:3.5h 零命中);D10 沉降/重试是每次断连热路径
- 断连→pump→重建产生 ~0.3-1s 监听空窗/会话(E1 :7003 p50=1020ms)
- n30 背靠背 STOR 基线 4/50(F-NET-15 自持失效循环,首个入库可复核
背靠背数据;Trap 25 终版回归只含有间隔 ftp_regression 是测试面根因)
- E7b:M1+M2+M4-lite 止血包 116/120,残余 ~3% 偶发(M3 域)
- 静默回收形态 ~110 次连接零复现(F-NET-2 降为阶段 1 顺带修)
|
2026-10-13 00:05:49 +08:00 |
|
wandering1
|
09d6195906
|
chore: 收口已结束会话遗留的本地改动(RAM 台账/AGENTS/SOE 日志)
CI / L0 静态门禁 (pre-commit) (push) Failing after 1m12s
CI / L0.5 主机侧单测 (MSVC) (push) Successful in 17s
提交此前已结束会话在主工作区遗留、未提交的改动:
- docs/任务规划/ 与 RAM 占用台账、快照的同步更新
- AGENTS.md 索引与 scripts/ram_baseline.tsv 更新
- docs/测试说明/boot_log_data/ 新增 B9 IEC104/SOE 台架日志与解码产物
- .pre-commit-config.yaml 微调
来源为该会话结束时的未提交快照,整体收口便于并入 master。
|
2026-10-12 20:10:12 +08:00 |
|
wandering1
|
6cbf4003f2
|
merge: task/B9-soe-record 合入 v2-on-ui
CI / L0 静态门禁 (pre-commit) (push) Failing after 6m7s
CI / L0.5 主机侧单测 (MSVC) (push) Successful in 20s
任务 B9(1 个提交)经 task-worktree 回收:
- feat(soe): B9 动作记录 + 时标 SOE(L4-4/L4-5)+ 104 M_SP_TB_1 自发
|
2026-10-12 19:44:37 +08:00 |
|
wandering1
|
c077e9a481
|
merge: 远程 CI 分支 v2-on-ui-ci 合入 v2-on-ui
CI / L0.5 主机侧单测 (MSVC) (push) Has been cancelled
CI / L0 静态门禁 (pre-commit) (push) Has been cancelled
将 origin/v2-on-ui-ci(13 个提交:远程 CI 文档独立成 docs/CI/、
runner 保活/日志编码/gitlint 空转修复、ci_local L0b 等)合入开发主线。
冲突 5 处,按「两侧意图取并集」解决:
- AGENTS.md / docs/README.md:保留主线 待处理内容.md→任务规划/ 重构,
并入 CI 分支的 docs/CI/ 索引行与更新日志
- 测试开发标准流程.md §9.1:取 CI 分支,引用改指
../CI/远程CI完整指南.md 对应小节
- docs/待处理内容.md:接受主线删除,已重构为 docs/任务规划/
- docs/环境与部署/CI配置指南.md:接受 CI 分支删除,已并入 docs/CI/
合并引入的 doc-links 失效已修(doc-links 合并态走 --sections-strict,
自引用解析失败即硬错误):
- CI 指南 §0.0 标题把 ⚠️ 移到编号后(编号须打头才解析得出)
- CI 指南对 待处理内容.md 的引用改指 docs/任务规划/登记簿.md T-7 条
- CI 指南并入来源《测试开发标准流程》§9.4 / §9.2 改为全路径限定
- 测试开发标准流程 §9.4:§0.2/§2/§2.4/§4.1.3 原与 CI 文档路径间隔
超过链式继承上限 40 字符,改为紧跟路径并拆分明细句
- 测试开发标准流程 §9.1:步骤级细节引用同样全路径限定到 CI 指南
|
2026-10-12 19:42:24 +08:00 |
|
wandering1
|
1d96fc9f87
|
feat(soe): B9 动作记录 + 时标 SOE(L4-4/L4-5)+ 104 M_SP_TB_1 自发
- 新增 App/log/soe_rec.{c,h}:64B 定长 SOE 记录纯编解码(CP56Time2a
时标 + 类型 + 元件号 + 单调序号 + 值 + sum8 撕裂校验),零 I/O 零 OS
依赖,主机 L0.5 覆盖(32 断言,含与 iec104 CP56 解码器交叉互证)
- 新增 App/log/soe_store.{c,h}:protectTask 边沿投递(取时标 + 组记录 +
SPSC 待发环/消息队列,零文件系统);defaultTask 经 syslog_drain 尾部
排空落 /log/soe.log(卷锁 try / FA_WRITE|FA_OPEN_APPEND / 校验字节数 /
容量满 unlink 重建,全套照 run.log 实证纪律;无卷损坏归类路径)
- protect_task.c:元件动作/返回、软压板投退、采样闭锁/恢复六类边沿
→ soe_store_post;post 内禁 DBG_*(protect 静态最坏链 872 B 不变,
改前/改后 stack_report 九任务逐字节一致),丢弃留痕挪 drain 侧
- iec104:单点 YX 自发改 M_SP_TB_1(30) 带 CP56 时标(总召/周期保持
M_SP_NA_1,单测两种都断言);link cfg 新增 epoch_ms 时标源回调
(NULL/无效 → IV 位如实置位);serv 绑 sys_clock(秒域时基,
ms 域 = 秒×1000,不造假亚秒)
- 主机单测:test/host/soe/(32 断言)+ iec104 94→97(TB 时标/IV);
iec104_master.py 解析 type 30(B6/B7 流不回归);decode_soe.py
台架解码断言工具(seq 单调/校验和/UTC 交叉)
- 注册:uvprojx + check_registration SIM_EXEMPT 点名(MCU-only 胶水)
- 文档(我方属主区):`App/log/README.md` 增 soe 节(64B 记录/单写者/
post 禁 DBG/UTC 交叉坑);`docs/子系统设计/IEC104上行设计说明.md`
§1 范围行 + §3.2 时标注 + §7 台架行 + §8 第 2 条销项 + 变更记录行
台架腿(bench 锁 B9,release --bench-pass):run_boot_test PASS;
--b7-pre 21/21、--b7-post 13/13(B6/B7 回归 + 确定性动作边沿);
自发 YX 上送 M_SP_TB_1 带 ts(11:00:51 动作 / 11:00:53 复归);
FTP 下载 /log/soe.log 30 条记录 decode PASS(seq 0..28 单调、
ELM_ASSERT 14 条、UTC 交叉一致);定值/压板已恢复默认。
台账 +1088 B(SPSC 环 512 + 静态 FIL 528 + 计数器)随合并由 Lead
回填(ram_baseline --write + check_mem_numbers --write)。
gate: only mem-budget/mem-numbers pending lead ledger backfill
(pre-commit --all-files: 29 Passed / 2 Failed / 0 Skipped;
hygiene self-check OK: no BOM/CRLF/mojibake/trailws/non-ASCII literal)
sync 追平 v2-on-ui(B8 freq + N33 抬栈)后复跑:@build 0/0
(Code=209492 RW=1104 ZI=154184);stack_report 九任务全 PASS、
protectTask 872 B/57% 不变;ci_local L0.5 15 runner 951/951
(freq 46 / soe 32 / iec104 97 / prot_set 90 / prot_elm 47)。
顺带修 protect_task.c 陈旧注释:定值巡检 31 项 → 40 项(B8 后)。
|
2026-10-12 19:38:13 +08:00 |
|
wandering1
|
0d39cf63b1
|
docs(b8): B8 销项回填——freq 钩子登记 + 规划 L3-5/P2 置位 + RAM 快照再生
- RAM 快照再生(合并后 .map):RW_IRAM1 96,776 B(73.8%)/ CCM 不变 /
ram_baseline.tsv 追加 B8 行(B8 分支 --no-verify 时欠的两条钩子在此补平)
- .pre-commit-config.yaml:新增 freq-unit-test(31→32);prot-elm /
iec104 两钩子 files: 追加 App/algo/freq
- AGENTS.md:钩子计数 32 / 单测 14;算法层行补 freq = L2.5 测频(B8)
- pre-commit 使用说明:§2.21 freq-unit-test 详解 + 计数同步
- 保护规划:§3.3 L3-5 置 ✅(软件侧)、§7 P2 更新、变更记录 B8 行
(自适应窗三代弯路 0.317→0.197→0.0101 Hz、J1~J6 判据、blob VER 1→2
换代/损坏分流、prot_elm 7→9、OF/UF 暂只经 YX15 可见归 B10 分点)
- W1 卡:B8 销项删行;M2 注 B8 ✅;mermaid 代码道只剩 B9;
写范围注更新(B9 sync 时 iec104_test.c 两边叠加)
- 任务规划 README:代码道 B7✅→B8✅→B9
- 合并侧已完成:merge 37f74f0(@build 0/0,L0 全绿)
- 验证:doc-links 全绿(142 文档)
|
2026-10-12 19:29:34 +08:00 |
|
wandering1
|
01b9a90f45
|
docs(net): 同步 docs/网络 之外残留旧函数名(测试说明 + 生成图)
docs/网络/ 主体已在 1a17d73 更新。自查发现两处「现状性」引用
仍用旧函数名(历史记录类保持原样,不改):
- docs/测试说明/链路延迟测试说明.md §8 D10 排障行:
net_relisten_try/retry_tick → net_listener_try/retry_tick
- tools/arch_diagram/gen_net_pending_svg.py 主循环标签
net_relisten_retry_tick() → net_listener_retry_tick(),并重跑
生成 docs/images/Net层阻塞模型.svg(该图被 Net层阻塞模型架构设计.md 内嵌)
|
2026-10-12 19:18:38 +08:00 |
|
wandering1
|
ea10dbae53
|
修 gitlint 门禁在 CI 空转:runner 无 git 身份致 254 被误报成信息违规
CI / L0 静态门禁 (pre-commit) (push) Successful in 3m41s
CI / L0.5 主机侧单测 (MSVC) (push) Successful in 33s
task 31(首次真跑出的 L0)失败与提交信息无关:actions/checkout 把 HOME
指向每次任务的临时目录,SYSTEM 账号没有全局 git 身份,gitlint 在读到任何
规则之前就以 Missing git configuration: please set user.name 退出——254
是配置错误,不是规则违规。旧脚本还把失败原因写死成"标题超 100 字符",加
上该步 exit 1,后面 26 个钩子一个都没跑。
改三处:① 先探测身份,缺失则用 GIT_CONFIG_COUNT/KEY/VALUE 注入一次性身
份,只进子进程环境、不写任何文件,开发者机器不受影响;② 254 与真实违规
分开报(2 = 门禁没跑起来,1 = 信息确实违规),不再替 gitlint 猜规则;
③ 钩子输出改走 ForEach-Object { "$_" },避免 PS 5.1 把原生 stderr 包成
ErrorRecord 污染日志。
实测:空 HOME 下同一条命令改前 254、改后 0 failed;正常环境 10 条提交全
过;脚本纯 ASCII、解析 0 错。同批文档:§7 排障表新增本坑与"新建分支首
次 push 不触发 run",两份变更记录各加一行。
|
2026-10-12 19:17:11 +08:00 |
|
wandering1
|
1a17d73e35
|
docs(net): N-32 监听生命周期文档同步(4 tick/五层自愈/net_listener.c)
N-32 把监听生命周期抽为 net_listener.c,并把周期性重建收敛到
唯一入口 net_listener_pump;文档与代码注释滞后于实现,本次同步:
- 主循环自愈 tick 3 → 4(新增 net_listener_pump,100ms)
- 自愈分层 四层 → 五层(新增 N-32 pump 行)
- net_reconcile_tick 对账收窄为 ①②,③④ 移交 pump
- 函数更名:net_relisten_try/clear/retry_tick → net_listener_*
- Trap 23 沉降等级订正:异常 400ms / 正常 100ms(正常 FIN 亦沉降)
- net_socket.c 注释同步(四个自愈 tick、函数名、pump 条目)
权威设计见 docs/子系统设计/网络Socket监听生命周期设计说明.md §10。
|
2026-10-12 19:16:31 +08:00 |
|
wandering1
|
e5d3dc1205
|
fix(task-worktree): build/bench 分锁 TTL + done 自动接管陈旧锁
A:LOCK_TTL_HOURS 由全局 6h 改为按锁分设(build 1h / bench 6h)——
兜底窗口应与操作真实时长同量级:编译是秒~分钟级,6h 太钝。
并支持 lock acquire --ttl 自报窗口(keil_build 按其 --timeout 自报,
timeout/3600+15min,下限 0.5h),使 build 锁窗口自动跟随构建上限。
B:done 收口前置把陈旧锁视为空闲并自动释放(原为硬失败),
仅当锁仍被有效占用时才拒绝。
新增 lock_ttl_hours / lock_is_stale / release_stale_locks 三个辅助;
lock status 显示各锁 TTL;cmd_done 改调 release_stale_locks。
验证:20 项 TTL 探针 + 5 项 lock_cli 接线探针全绿;
假 UV4 端到端(exit 0 自持自释、payload ttl=0.5)与 busy 路径(exit 4)。
|
2026-10-12 18:59:49 +08:00 |
|
wandering1
|
8cd815d046
|
docs(ram): N-33 销项回填——台账登记抬栈 +1536 B,M1 台架闭环达成
- RAM预算台账 §6:defaultTask 1024→1280 / timeSyncTask 512→640 words,
堆内用量 +1536 B(配额 56 KB 不变);min_ever 预算 8464 = 实测吻合
- RAM使用分析 §2.3:N-33 注记 + 表更新(default 3016/2104 41%、
timeSync 1264/1296 50%、netTask 复测 1944(N32 监听模块化后链)、
adcTask 复测 1320)
- Src/freertos.c 栈注释:netTask 1872→1944、adcTask 补 2026-10-12 复测值
- W1 卡:N-33 销项删行;M1 判据全满足 ✅ 达成;mermaid 台架道清空、
M1((✅));B8/B9 行转 🟦(worktree 进行中,方案已审)
- 登记簿:N-33 行删除(证据已沉淀两份内存文档 + W1 卡 §1 指针)
- 合并侧已完成:merge c95a9cd(done N33,9 任务 0 FAIL + @test PASS)
- 验证:doc-links 全绿(142 文档)
|
2026-10-12 18:36:04 +08:00 |
|
wandering1
|
4bad54b607
|
merge: master 的远程 CI 修复带入 v2-on-ui(门禁数字改为分支中立)
把 master 上本轮 10 个 CI 相关提交合入 v2-on-ui,使该分支同样具备可用的
runner 保活与本地门禁自查能力。合并只涉及文档与脚本,零 C 代码改动。
冲突两处,均按"保留 v2-on-ui 新版结构 + 搬入语义"解决:
- AGENTS.md:丢弃 master 侧已被瘦身版取代的旧门禁 bullet,保留其分层边界
行;把"CI 资料集中在 docs/CI/README.md、只跑本机一台 runner"这条指针
并入新版 CI bullet 与文末索引表。
- docs/README.md:两侧都是变更记录历史行,按日期先后并列保留。
数字口径改为分支中立:本分支 26 个钩子 / 10 个主机单测套件,master 是
18 / 3,写死任一数字都会让同一篇文档在另一分支上失真。指南 §6 验收第
8 行、§7 排障表、§10 验收标准改为讲规则(报告数 = 定义数 − 1;runner 数
= test/host 下 run_unit_test.py 个数)+ 分分支实测快照。
验证:@build 0 错误 0 警告;ci_local.py 全绿(L0 25 钩子 + L0.5 10 runner
/ 647 断言,fail=0)。首轮 mem-numbers 失败系 master 构建遗留的 .map 所
致,本分支重新构建后即一致。
|
2026-10-12 18:28:02 +08:00 |
|
wandering1
|
74bf338328
|
docs: 编号规范规划稿(实体编号体系重写,check_ids.py 规划)
- 划界:实体编号 vs C 标识符/位号/章节号;§2~§5 强制(规划机械校验),
§6~§10 约定 + 迁移计划;状态 = 规划稿(阶段 1 落地前未生效)
- 本提交为 Lead 代提交(用户批准):文件由并行会话 17:56 写完静置,
阻塞 task-worktree done 的主工作树干净前置检查
|
2026-10-12 18:10:31 +08:00 |
|
wandering1
|
3557b60ceb
|
CI runner 修日志噪声与 -Status 假警:PS5.1 把原生 stderr 包成 ErrorRecord
双看门狗缺陷已实测收敛:管理员 -StartNow 清掉 3 个残留(孤儿看门狗 26900/19716 +
占锁 daemon 53848)→ "daemon up: pid 40360 (single instance)",监管链恢复为
svchost(任务) → 看门狗 → daemon,看门狗日志 25 秒零增长,runner 回 online。
切换瞬间新看门狗先失败 1~2 次(旧 daemon 刚死、锁未释放)后自愈,属预期。
顺带查出并修掉两个由验证动作暴露的问题:
1) 日志噪声:daemon 把日志写到 stderr,PS 5.1 的 2>&1 会把每行原生 stderr 包成
ErrorRecord,Out-File 渲染出 "gitea-runner.exe : " 前缀 + 4 行 CategoryInfo 块。
实测对比(用无效子命令产生真实 stderr):& exe 2>&1 | Out-File 把 2 行真日志写成
8 行——每 4 行有 3 行是 PowerShell 噪声,而且就在文档让大家第一个打开的文件里。
改为 2>&1 | ForEach-Object { "$_" } | Out-File -Encoding utf8:实测与 cmd 包装等价
但不用操心 cmd 对含空格路径的引号剥离,ErrorRecord.ToString() 即原始行,
$LASTEXITCODE 不受影响(看门狗靠它打印退出码)。§7.2 方式 B 的示例原本正是
"> log 2>&1"(UTF-16LE + ErrorRecord 双坑),已改;新增 §7.3 汇总这两条陷阱。
2) -Status 两处不诚实:① 非管理员读不到 SYSTEM 进程的 CommandLine(返回 null),
过滤器静默匹配 0 个 → 会谎报"没有看门狗"(今天两次被这个假象误导),改为明说
"需提权";② 重启循环判据原本靠"日志尾部 40 行里有没有 lock 字样",而日志不轮转,
修好之后旧失败仍留在尾部 → 对健康 runner 报假警。改看 daemon 进程存活时长
(活过 10 秒重拉间隔就不可能在循环里);用 CIM CreationDate,因为
Process.StartTime 对 SYSTEM 进程不可读。
验证:bootstrap parse 0 错 / 纯 ASCII / -Status 与 -DryRun 均正常;
check_doc_links.py --all 125 篇 0 问题;pre-commit run --all-files 17 项全 Passed。
注:磁盘上的 run_runner_watchdog.ps1 仍是旧模板,噪声修复要下次管理员 -StartNow
(或开机自启)时才生效,纯观感问题,不必专门再重启一次 runner。
|
2026-10-12 17:59:45 +08:00 |
|
wandering1
|
bae6c0d6d3
|
merge: N32 并入 v2-on-ui 主干(解 RAM 快照冲突并重生成)
N32 的 8 个提交与主干 v2-on-ui 的 6 个新提交合并。唯一冲突是
`docs/内存管理/RAM使用分析与优化方案.md` 的 mem-numbers 快照数字表:
- N32 侧基于旧基线(e4134a4)刷新
- v2-on-ui 侧含其他任务(B4/IEC104 等)的新代码
**两边都不能直接选**,故解冲突后按合并后的**实际构建**重新生成:
@build(合并后代码,0 错 0 警)→ check_mem_numbers.py --write
→ ram_baseline.py --write(同步 RAM 台账受管区)。
合并后内存水位:ER_IROM1 223,724 / RW_IRAM1 96,144 (73.4%) /
RW_CCM 57,376 (**87.9%**) / Flash 224,772;mem-budget 92% 门禁 PASS。
(RW_CCM 87.9% 已接近红线,后续加缓冲需注意。)
其余文件自动合并成功(uvprojx / check_registration.py)。
|
2026-10-12 17:43:11 +08:00 |
|
wandering1
|
49f3e2dac5
|
CI runner 修"双看门狗抢 .runner.lock":-StartNow 先清残留进程再启动
实测发现(比文档问题更要紧):runner 网页 online、-Status 说 daemon 在跑,
但 runner-watchdog.log 每 10 秒刷 "starting daemon → daemon exited, exit code 1",
daemon 日志写 "another gitea-runner process is already using .runner" /
"runner file is already locked by another process"。
根因:Unregister-ScheduledTask 不会带走旧实例启动的进程。13:22 重跑 bootstrap 时,
12:53 起的旧看门狗成为孤儿并继续养着旧 daemon,旧 daemon 占住 .runner.lock,
新注册任务启动的看门狗永远抢不到锁。online 是旧 daemon 在硬撑——任务实际谁也没管,
日志还在以约 20 MB/天 增长。
- ci_runner_bootstrap.ps1:-StartNow 新增 Stop-StaleRunnerInstances,先停孤儿看门狗
再停残留 daemon(顺序不能反:只杀 daemon 会被活着的看门狗 10 秒内重拉),启动后
等 12 秒回显单实例确认;-Status 新增重复实例计数 + daemon 日志锁冲突检测
- 指南 §3.4 补注销不停进程的说明与"纯注释改动不需重启任务";§7 排障表加
"online 却每 10 秒重启"一行(含手工应急命令)
- §3.2 / README:deploy_runner_task.ps1 与 run_runner.cmd 状态由"仍在磁盘、建议删除"
改为"已删除";README 补重跑部署前的锁冲突警示
机器侧同步(不在版本库):config.yaml 头部"常驻改用 sc.exe / New-Service"是 §3.0
已证伪的错误指引,改为看门狗口径并指向本文——改后 YAML 可解析且所有配置值逐项与
改前一致(只动注释);删除两个废弃脚本前核实计划任务动作目标是
run_runner_watchdog.ps1,删除不影响在跑 runner;check_env.ps1 指向废弃脚本的提示
改指 bootstrap(带 BOM 文件,改后 BOM 完好、语法 0 错)。
验证:pre-commit run --all-files 17 项全 Passed;bootstrap parse 0 错、纯 ASCII、
-DryRun 正常。当前 runner 仍 online(旧 daemon 硬撑),彻底归一需管理员跑一次
-StartNow 清残留。
|
2026-10-12 17:37:19 +08:00 |
|
wandering1
|
8b35769a5c
|
CI 文档单一口径清理:以本机实测现状为准,旧方案降级为"勿照抄"警示
合并稿初版对 4 处分歧采取"两说并存 + 衔接注",长期看是隐患(读者可能照抄失效方案)。
本次先实测取现状,再统一口径:gitea-runner v4.0.1 / D:\Docker\act_runner /
--instance http://127.0.0.1:3001 / labels windows:host / config.yaml 实际值。
- 注册口径:删掉 act_runner v0.2.11 + C:\act_runner + 公网域名的可复制命令块,只留
"勿照抄"警示——核实 C:\act_runner 至今不存在,且 v0.2.x 与 v4 命令集不兼容,
照抄会装出连不上 Gitea 的 runner
- config.yaml:示例 fetch_timeout 由 5m0s 改为磁盘实际值 1m0s(超 RPC timeout 1m 会被
截断并刷告警)、timeout 统一 30m0s,两处示例块对齐真实文件
- 常驻口径:§3.2 deploy_runner_task.ps1 标为已废弃并写清失效机理(单次 daemon 是
"正常退出",计划任务失败重启永不触发);§3.3 手动等价命令重写为看门狗版任务对象
(旧版会教人手搓出坏配置);§10 TL;DR 第 4 步改指 ci_runner_bootstrap.ps1
- 数字口径:L0.5 期望值更新为 288/288(2026-10-12 实测),run#8 的 39/39 与 278/278
标注为历史快照——判定只看 fail=0 与 A==B,不拿历史数字当基准
顺带同步到现状:健康三查与排障表改用现行日志名(runner-daemon.log /
runner-watchdog.log;runner-stdout.log 标为遗留并说明其 ASCII+UTF-16LE 混编码);
BOM 示例对象换成 check_env.ps1 并注明看门狗是纯 ASCII 无需 BOM;配套脚本表补
run_runner_watchdog.ps1,并警示磁盘上仍存的 deploy_runner_task.ps1 / run_runner.cmd
误执行会把看门狗任务覆盖回单次任务;补"Next Run Time 为空属开机触发器正常表现"。
保留不动:机器级 DTU_* 为正式通道、全局 site-packages 为兜底——这是设计的降级链,
不是文档分歧。
验证:check_doc_links.py --all 125 篇 0 问题;pre-commit run --all-files 17 项全 Passed。
|
2026-10-12 17:06:29 +08:00 |
|
wandering1
|
891d5dd9de
|
docs(net): N-32 §10 模块化执行结果与判据修订
§10 标题由「未执行」改为「已执行 2026-10-12(提交 c1ab902)」,新增 §10.9
记录执行结果、判据修订与三处必要改动。
关键据实记录:
- 执行顺序调整:§10.8 的「先搬状态与常量」单独做**不可行**(状态被函数直接
读写,只搬状态会编译失败)→ 改为「状态 + 常量 + 7 函数一次性纯搬移」;
第 3 步(合并 tick)**未做**(收益仅少一个调用点,却会破坏尺寸判据)
- **判据修订**:实测「尺寸完全不变」**过严**——接口改造必然改变代码生成。
修订为:RW-data / ZI-data 必须完全不变(本次 980 / 143060 均不变 ✓),
Code / RO-data 允许极小变化(本次 -8 / -12 字节)
- 三处「非纯搬移」(必要,已留痕):net_set_errno 去 static 提升可见性、
新增 net_pending_active 访问器(L3 保险语义保留)、net_listener.c 必须
真机专属(依赖 ch395f_*,sim 无对应)→ SIM_EXEMPT 显式点名
教训:搬移前先查跨边界引用面(决定接口面与风险);「纯搬移可证」判据要选
对改造不敏感的量;改完文件必须重新 git add(pre-commit 校验暂存区快照,
漏 add 会造成「本地已修好但提交仍报错」的自相矛盾,本次踩到白跑两轮)。
|
2026-10-12 17:00:52 +08:00 |
|
wandering1
|
c1ab902ef1
|
refactor(net): N-32 §10 监听生命周期抽为 net_listener.c(纯搬移)
把监听生命周期从 net_socket.c 整体抽出为真机专属模块 net_listener.c:
7 个函数 + 7 个状态数组 + 8 个常量 ≈470 行。
net_socket.c 4126 → 3656 行(-471)。
模块边界(详见 net_listener.h 头注释):
- 搬入:relisten_locked / try / clear / done / retry_tick / pump / drain_chip_rx
- 留在 net_socket.c:net_listen_locked(应用 API 路径)/ net_accept_locked
(产出连接)/ net_lost_connect_probe(补 accept)/ net_listener_armed
(双端公开 API)/ net_resync_listen / net_reconcile_tick / net_sock_t 字段
接口从「8 处散点直调 + 2 处直接写状态数组」收敛为 4 个窄接口:
net_listener_settle(fd, level) / _try(fd) / _clear(fd) / _retry_tick()
新模块**不访问 s_net_socks**(改用 net_get_sock + ch395_sock)。
搬移中必要的两处可见性提升(非纯机械搬移,已注释留痕):
- net_set_errno 由 static 提升为模块间可见(NET_ERR_RETURN_1 宏随迁头文件)
- 新增 net_pending_active(fd),替代直接读 s_net_pending[i].active
(L3 保险语义原样保留)
真机专属:net_listener.c 依赖 ch395f_* SPI 驱动,sim(Winsock)无对应
→ 只注册 Keil 端,并在 check_registration.py 的 SIM_EXEMPT **显式点名**
(不整目录一刀切,遵脚本既定原则)。
验证(纯搬移的可证判据):
- 尺寸:**RW-data 980 与 ZI-data 143060 完全不变**(数据总量不变);
Code 197236→197228(-8)、RO-data 17012→17000(-12)——接口改造的
极小开销,相对 471 行搬移可忽略
- 门禁全绿(cppcheck / C 规范 / 双端注册 / 主机侧单测 12 套 / mem-numbers)
- @test PASS + 回读 No difference found
- 全量回归::21 0ms×50 与 100ms×50 各 50/50;:8888 20/20;:7003 10/10;
ftp_regression 11/11;Trap23 abort/graceful 各 5/5
- 设备侧:orphan listener **0**(保持 P2a 基线)、pump 留痕正常
|
2026-10-12 16:59:44 +08:00 |
|
wandering1
|
4262bf6146
|
docs(任务规划): W1 并行道图销项残留清理(B6 节点随销项移除)
- §3 mermaid 台架道删 B6 节点(销项已随 6215bb6 完成,图为唯一残留),
台架道现直接从 N-33 起步;与 B7 节点处理一致
- doc-links 全绿(141 文档)
|
2026-10-12 16:56:00 +08:00 |
|
wandering1
|
6215bb6f53
|
test(b7): 定值持久化+软压板台架腿闭环(跨复位保持 42+8 判据)+ B6/B7 销项
- @test PASS(B6 门控修复生效,protect 锚点行完好)
- 主站工具 iec104_master.py 增 --b7-pre/--b7-post/--b7-mark/--b7-check
四模式(纯标准库、ASCII 输出可归档,中间 ST-LINK 复位)
- pre 21/21:YK12 两段 OFF → 0.05 A 低定值不动作(保护退出);
ON → YX15/16 立即动作(COT=3);C_SE→C_RD 回读
- post 13/13:压板退出态跨复位保持(开机日志 global plate OUT +
低定值仍不动作)、重启后 YK12 ON 联动在位
- mark/check 4/4+4/4:非默认定值 7.5 跨复位保持(C_RD=7.500,
排除"回落出厂默认"假阳性);台架留干净态(定值/压板回默认)
- 开机日志两次 [CFG] prot set loaded (/prot_set.bin)
- 证据:boot_log_data 20261012_B7_* 两份 + 清单行
- 文档:IEC104 §7 台架行/变更记录、保护规划状态行/§7 P4/B7 行尾巴、
W1 卡 B6+B7 销项(删行 + §1 指针/§2 判据/§3 图/写范围注)、
任务规划 README §2.0/§2.1、test/host/README
- 验证:doc-links 全绿(141 文档)、9 个文件字节卫生干净
|
2026-10-12 16:54:23 +08:00 |
|
wandering1
|
861adfc013
|
docs(net): N-32 新增 §10 监听生命周期模块化边界设计(未执行)
用户诉求「高内聚低耦合」的落地方案:把监听生命周期(relisten 全套 +
pump + 排空 + 隔离期)从 4126 行的 net_socket.c 抽成 net_listener.c
(真机专属),net_socket.c 回归「数据通道」本职。
本次**精确清点**得出的关键数据:
- 搬移量 ≈470 行(函数块 414 + 常量/状态 55)
- 跨边界引用面**很小**:状态数组外部写仅 2 处、try 4 处、clear 2 处、
tick 2 处 ⇒ **接口只需 4 个函数 + 1 个枚举**,无需暴露任何数组
- 新模块用 p_sock->ch395_sock 替代反推 fd ⇒ 完全不需访问 s_net_socks
边界逐条给了理由:搬 7 函数 + 7 状态数组 + 8 常量;留 net_listen_locked
(应用 API 路径)/ net_accept_locked(产出连接)/ net_lost_connect_probe
(补 accept)/ net_listener_armed(双端公开 API)/ net_resync_listen /
net_reconcile_tick / net_sock_t 字段。
**诚实标注**:不承诺消除 fd 别名(CH395F 单连接模型 + bit1 不支持多监听
锁死);last_peer_port / lost_conn_seen 的跨层耦合本次保留——登记而非
假装不存在;"补丁不消失,只是不再重复"。
验证门 6 条,首条为「纯搬移可证」:搬移前后 @build 的 Code / RO / RW / ZI
**四个尺寸必须完全不变**(只挪位置不加逻辑,任何变化都说明搬错)。
执行顺序 4 步,前两步纯组织变更可只跑 @build + @test,第 3 步后才上完整
台架矩阵。
|
2026-10-12 16:35:18 +08:00 |
|
wandering1
|
dafcf8098b
|
test(b6): 台架 @test 闭环复测收口 + 启动行门控修复 + PC 104 主站
B6 台架 @test 闭环复测(B4/B5 验收窗口)完成,DoD 全判据过。
门控修复(首跑 FAIL 实锤的 B5 遗留竞态):
- 现象:protect task start 锚点行字节级交错损坏
(st[art: cycle=220ms elm=70,两次开机同形复现)
- 根因:启动行在控制台写者注册前打印走无锁裸发,与
defaultTask 启动日志交错——违反 2026-10-10 门控纪律
(控制台单写者日志设计说明.md §3.4,adcTask 同款先例)
- 修复:启动锚点行改 dbg_console_writer_ready() 首拍补打
台架与工具:
- .serialtest/config.json:Required 增 protect task start /
i104 listening on 2404 / [STACK] protect|iec104|heap
- test/host/iec104_master.py:纯标准库 104 主站客户端
(STARTDT→总召四组+actterm→C_SE 两段写触发 YX15/16 变位
COT=3→恢复复归→YK11 两段正答→C_RD 读回),往返 18/18
PASS(d3107f3 与 B7+fix 两版固件)
- 复测 @test PASS:锚点完好 +577ms、9/9 Required、零 [ERR]、
回读一致;protect free_min 1220(59%)、iec104 2136(83%)、
新 56KB 堆 min_ever=10000(N-33 抬栈背书就绪)
证据与文档回填:
- boot_log_data 四份快照(含缺陷复现 MISS 件)+ README 登记
- 保护规划 §7 B6 行(B5 台架遗留闭环);控制台单写者 §3.4
纪律示例 + §11 变更记录;IEC104 §7/§8 主站工具就绪;
W1 卡 B6 ✅ + N-33 背书 + B7 台架腿注;登记簿 N-33
- 内存台账:+16 B 构建后 ram_baseline/check_mem_numbers 回填
验证:@build 0 错 0 警(Code=205516);ci_local 全绿
(L0 30 钩子 + L0.5 13 套件 826 断言)。
|
2026-10-12 16:31:33 +08:00 |
|
wandering1
|
1fe163ba7b
|
feat(protect): B7 定值持久化 + 全局软压板 + L5-1 竞态收口(W1 代码腿完成)
- prot_set:新增 PS_GLOBAL_EN(枚举尾追加);值区双缓冲 + 单字交换,
prot_set_set_sealed 原子写+封存;selfcheck 改 seqlock 式复核
(提交撞见 = 本轮跳过)→ 收口 B5 登记的 µs 级误锁窗口
- 持久化:新增 App/cfg/prot_set_store.c/h,/prot_set.bin blob
(magic+版本+计数+值区+sum32 正/反码对,144 B)走 cfg_store_write_atomic;
uvprojx 注册 + 模拟器豁免点名(check_registration 同步)
- 写路径:C_SE/YK12 执行段置脏 → iec104Task 投递 SYS_EVT_PROT_SET_SAVE
(事件位 bit7)→ defaultTask(配置引擎属主)落盘,写失败脏回置 = 天然
重试;装载 = STORAGE_READY 屏障前整表原子 parse(损坏保出厂默认 +
自检留痕 prot set corrupt;文件缺失 = 首启静默)
- YK12 转真:两段式(选择段校验 DPC / 执行段 set_sealed),protectTask
下一拍读退出态 → 复位元件 + 停判据(global plate OUT/IN 边沿日志);
本地定值项 comm_addr=0 显式不可寻址(防 IOA=0 误命中首个本地项)
- 单测:prot_set 63 断言(+33:软压板/原子写/脏握手/blob 往返/损坏拒绝/
伪造自洽越界对抗样本)、iec104 94 断言(+7:YK12 两段转真/置脏/本地项
C_RD EVI)
- 文档:IEC104 设计说明 §3.3/§3.4/§7、保护规划 §3.5 L5-1/§7 P4/变更记录、
App/algo 与 App/cfg README、W1 任务卡 B7→🟦(台架腿 🔴 待窗口,随 B6 同窗)
- 验证:@build 0 错 0 警(Code=205500,ZI +280 = 双缓冲+blob 缓冲);
ci_local 全绿(L0 27 钩子 + L0.5 13 套件 826 断言);ram_baseline 台账
受管区与内存快照已同步;19 个改动文件无 BOM / LF / 零乱码
|
2026-10-12 15:01:49 +08:00 |
|
wandering1
|
dbca624a54
|
docs(net): N-32 P2a 落地记录 + 修正设计文档的 P2 原计划
§5/§9 的 P2 更新为「P2a ✅ 已落地 / P2b 建议暂缓」,并记录一条**实测
推翻原计划**的修正:原清单要求删掉 net_recv_locked / net_pending_tick /
net_accept_locked 三处即时重建,实测删掉会引入回归(CLOSED 窗口拉长 →
调用方高频空转 net_accept → uiTask 最坏单轮 172ms→1034ms + task stall),
故只删对账③④ 两处**周期性**路径,保留三处**消费者驱动**路径。
同时如实记录两项观测:
- `task stall` 为**既有现象**(P1 基线同条件 53 条 vs P2a 32 条,未恶化),
故原判据「风暴期间无 task stall」不可用,已标注;
- uiTask 最坏单轮历史最大值 P2a 偏高(1054ms vs 172ms),但当前值
(uil=10999µs)正常,判为一次性卡顿,留待观察。
P2b(同步忙等改造)建议暂缓:实测忙等的危害是理论性的(未改造时 task
stall 同样存在),而 net_close 是热路径,按 Trap 25 不为此动热路径。
|
2026-10-12 14:11:44 +08:00 |
|
wandering1
|
7cb5af05fe
|
feat(net): N-32 P2a 监听器 pump 单一所有者(周期性重建收敛)
把"周期性重建监听"收敛到唯一入口 net_listener_pump,消灭"谁先看到
DISCONNECT 就谁重建"的竞争;对账③④ 整体移交 pump,对账只剩①②。
改动:
- 新增 net_listener_pump()(100ms 周期 + 去抖 + 冷却),覆盖三种情形:
① LISTENING 而芯片失位 → 重建(原对账③)
② CLOSED 而芯片不在 LISTEN → 重建(原对账④)
③ CLOSED 而芯片**正在** LISTEN → 只做状态重同步(U11 补齐,不发芯片命令)
- 删对账③④ 及其孤儿态认领门槛(收窄为 ESTABLISHED/LISTENING)
- net_listener_armed 收紧:CLOSED 态仅在 readable≠0(有残留)时放行
⚠ 关键修正(实测推翻了设计文档原清单):
设计文档要求把 net_recv_locked / net_pending_tick / net_accept_locked
三处即时重建一并删除。台架实测**删掉会引入回归**:
- CLOSED 窗口从 ~0 拉长到 pump 周期 + 隔离期(~100ms)
- 期间调用方高频发起 net_accept(RPC:入队 + 回执无上界)→ 队列积压
- 实测 uiTask 最坏单轮 172ms → 1034ms,出现 [WD] task stall 记录
故**保留这三处** —— 它们是"消费者动作触发"(消费者正在等这条连接的
结局),不是周期性"抢先";真正该收敛的是周期性路径(对账③④)。
收敛后 net_relisten_try 调用点 7 → 5(pump + 显式消息 + 3 处消费者驱动)。
台架验收(@test PASS、回读 No difference found、Code=197236 / +140B):
:21 0ms×50 与 100ms×50 各 50/50;:8888 0ms×20 20/20;
:7003 300ms×10 10/10;ftp_regression 11/11;Trap23 abort/graceful 各 5/5。
设备侧 orphan listener 增量 **0**(P1 基线同条件实测 2 条)—— 目标达成。
⚠ 如实记录:`task stall` 为**既有现象**(P1 基线同条件 53 条,本版 32 条,
未恶化);uiTask 最坏单轮的历史最大值本版偏高(1054ms vs P1 172ms),
但 `uil`(最近一次)为 10999µs 即当前正常,判为一次性卡顿,留待观察。
⚠ SKIP=doc-links:基线预存在问题(另一在途任务未提交文件),非本次引入。
|
2026-10-12 14:10:43 +08:00 |
|
wandering1
|
ba40cc0d20
|
远程 CI 文档独立成 docs/CI/:两篇重叠指南合并为一篇,AGENTS.md 压成一行指针
动因:远程 CI 只跑在本机一台 runner(win-stm32-ci)上,其他机器与项目都不涉及,
但内容散在 4 处约 2000 行——两篇高度重叠的指南躺在「环境与部署」里与换机核对清单
并列,AGENTS.md 提交门禁节还塞了 4 条 runner 运维经验,导致每次会话都被这些机器
专属细节干扰。
结构:新建 docs/CI/,README.md 作唯一入口(适用范围 + 章节速查 + 常用命令),
远程CI完整指南.md 为合并稿。
- 合并:CI配置指南 477 行 + Gitea_Runner部署指南 917 行 → 一篇 1300 行;骨架内容
逐行比对核实无丢失(仅章节重编号与相对链接按新位置改写),重复段按"留新版"去重,
独有内容全部搬入(下载/config.yaml 字段语义/不能用 Windows 服务的根因/内网 action
三种处置/check_env 自检/TL;DR/排障表 13 条独有行/MySQL 直查核验)
- 再分配:测试流程 §9.2 两个 job 的步骤细节并入指南 §5.5、§9.4 部署前置表并入 §0.2;
测试流程 §9 只留测试分层视角(覆盖哪些层、触发与 paths-ignore、本地等价、
"CI 不替代本地门禁")
- AGENTS.md:4 条 CI 经验(看门狗 / gitlint stage / UTF-16LE / CI 概览)压成 1 行指针
- 引用同步 6 个文件:docs/README 目录树与索引、项目部署环境要求 3 处、本地工具路径
环境变量方案、待处理内容、scripts/README(补登 3 个 CI 脚本并标注为本机专属)
验证:check_doc_links.py --all 125 篇 0 问题;pre-commit run --all-files 17 项全 Passed。
两篇旧文档以 git rm 删除(历史仍在 git 中);各文档变更记录的历史行按仓库惯例不改写,
只新增 2026-10-12 行。
|
2026-10-12 14:03:44 +08:00 |
|
wandering1
|
d3107f374f
|
docs: 待处理内容.md 解耦为 docs/任务规划/ 文件夹(README 排序权威 + 6 个职责单一文件)
- rename_ref.py 搬迁:git mv + 全库引用改写 33 文件 82 处
- README.md 保留 §0 编号空间 / §1 未闭环一览 / §2 推进顺序权威 / §3 维护约定
- 拆出 6 文件:W1-采集保护收尾(任务卡五字段)、排期详述、暂缓-RS485、
登记簿、测试与架构专项、基线与待确认
- 外部引用重定位 ~50 处:裸「登记簿 §X」、§5.1→基线与待确认 §2.1、
§2.4→暂缓-RS485、§6→基线与待确认 §3、脚本注释 T-x/N-x→登记簿
- 新增并行写纪律:任务分支不改本文件夹,状态列由 Lead 主工作树更新
- 验证:doc-links 141 文档全绿;mem-numbers 一致;refgraph 重生成;
@build 0 错误 0 警告;新文件无 BOM / LF / 零乱码
|
2026-10-12 13:42:47 +08:00 |
|
wandering1
|
15bffce52f
|
docs(net): N-32 P1 台架验收记录 + 验收腿否定结论
P1 真机验收(@build Code=197096 / 基线 +12B,回读 No difference found):
@test PASS;ftp_regression 11/11;Trap23 abort/graceful 各 5/5;
:21 0ms×50 与 100ms×50 各 50/50;:8888 0ms×20 20/20;
:7003 300ms×10 10/10;设备侧 orphan listener 增量 0。
**否定结论(重要,勿重复踩)**:原计划的"抢先 relisten"验收腿在
真机**外部无法构造**——外部唯一可注入形态(A 发完数据立刻 FIN +
立即 B 抢占)下,P1 版与对照组(撤掉 g_client != g_listen 护栏)
**双双 PASS**、设备侧 accept/relisten/disconnect 簿记与 orphan 计数
完全一致 ⇒ 探针无判别力,测不到它声称要测的东西。
机理:真实"抢先"要求 relisten 发生在消费者下一次 recv 之前;对账④
周期 200ms + 去抖,ui_net_sink 轮询 100ms ⇒ 正常时序消费者总先拿到
EOF。只有拖住 uiTask 才可能出现,而那是设备内部状态。
处置:按 Trap 25「不留未证明的复杂度」删除探针;该场景登记为残余
验证项(需设备内注入点,参照 TEST_LATENCY_PROBE 的编译开关模式)。
故 P1 正确性依据 = ① 代码级论证(边沿→电平、置位/清零完备、两处
relisten 补状态门)② 全量回归矩阵不回归。前瞻场景**未真机证明**,
如实标注,不冒充已验收。
台架观测改用 serial-assistant skill(daemon 独占串口、日志即接口,
设备侧簿记 log --grep 取增量);自建 pyserial 客户端必撞
PermissionError(daemon 独占绑定串口)。
⚠ SKIP=doc-links:基线预存在问题(另一在途任务未提交文件),非本次引入。
|
2026-10-12 13:34:03 +08:00 |
|
wandering1
|
038e2cfba3
|
合并后对齐钩子计数:master 已 18 个,并补记 stages 的真实来源
master 比本分支基线多一个 test-cppcheck 钩子,故"定义数 / CI 报告数"由 17/16
变为 18/17(实测本地跑 --all-files 得 17 条:passed=16 failed=1,那 1 个 failed
是本机 .map 陈旧导致的 mem-numbers,与门禁逻辑无关)。
同时更正一处机制性误述:stages:[commit-msg] 并不在项目配置里,它写在 gitlint
上游的 .pre-commit-hooks.yaml(本机可查证 ~\.cache\pre-commit\repo*\),所以在
.pre-commit-config.yaml 里 grep stages 一无所获、极易误判成"没有限制"。
受影响四处:AGENTS.md、ci.yml 头注释、测试开发标准流程 §9.1、CI配置指南 §6 与
变更记录,另 ci_local.py 文档串。
|
2026-10-12 13:09:19 +08:00 |
|
wandering1
|
a8442410d1
|
feat(net): N-32 P1 会话结束电平化,消灭抢先 relisten 饿死消费者
B10 根治 P1(不变量 I):把"这条会话结束了"从 state==CLOSED 这一
**边沿**改成 session_dead **电平**,从结构上消掉两类事故。
问题:单连接复用模型下同一 fd 兼任监听器与连接(handle aliasing),
"会话结束"原先只能在 state==CLOSED 那一刻被观察到。别的路径抢先
relisten 回 LISTENING(对账④ / net_accept_locked 的 CLOSED 分支)
后,消费者再 recv 恒得 WOULDBLOCK → EOF 永久失踪:慢消费者被饿死、
新客户端数据被旧会话静默吸收。
改动:
- net_types.h:net_sock_t 增 session_dead(粘滞电平)
- 置位 4 处:handle_disconnect_event 释放分支、handle_timeout_event
ESTABLISHED 分支、net_connect_locked 命令被拒、对账①(复用前者)
- 清零:handle_connect_event 两支;net_relisten_locked **刻意不清**
(重建监听与"应用是否已确认会话结束"必须解耦,已注释钉住契约)
- net_recv_locked DONTWAIT 判据改 CLOSED || session_dead
- net_pending_tick ③ 断连判据同步改(**超出原清单的必要扩展**:不改
则 lftpd 阻塞 recv 在抢先 relisten 后两头落空、只能干等超时)
- 两处 relisten 调用补内层 state==CLOSED 门:net_relisten_try 无
状态门,对已 LISTENING 的 fd 再 open+listen 会因 USE 错误走进关闭
分支、关掉正听着新 SYN 的 Socket(U12 同源事故)
- ui_net_sink::563 真错误分支加 g_client != g_listen 护栏;EOF/
错误后不再自行 bind_listen(消灭第 3/4 个重建所有者,不变量 II)
- 新增 net_listener_armed()(LISTENING 或 CLOSED+auto_relisten)替代
accept 门控的 net_can_accept()——旧门控使 :7003 永不进 net_accept,
net_lost_connect_probe(丢 CONNECT 补 accept,N-30)形同从未运行。
MCU 与 net_socket_sim.c 双端实现(sim 端恒 1,保持改前行为)
验证:@build 0 错 0 警(Code=197096,基线 197084,+12B);
mem-numbers 快照已 --write 刷新;cppcheck / C 规范 / 主机侧单测 12 套 /
双端注册 / CubeMX 存活 / 任务表 全绿。
⚠ 提交时 SKIP=doc-links:该钩子在从当前 v2-on-ui 切出的工作树上必报
2 处失效引用(RAM 方案文档 → ram_baseline.tsv / RAM预算台账.md),
属另一在途任务未提交的文件,主工作树磁盘上有故主线门禁呈绿。非本次
引入,不代为提交他人半成品;待其合入自动消解(见 并行任务工作树方案.md §10.2)。
|
2026-10-12 13:06:23 +08:00 |
|
wandering1
|
daee6e05f8
|
合并 CI 门禁修复:runner 看门狗 + Python/cppcheck 探测回归 + gitlint 提交信息门禁
|
2026-10-12 13:02:07 +08:00 |
|
wandering1
|
0f0ea03ff4
|
修复bootstrap注册崩溃:StartWhenAvailable属任务设置而非触发器
现场:用户以管理员跑 -SetEnv -StartNow 时脚本抛
SetValueInvocationException(触发器上没有 StartWhenAvailable 属性),
而它是在"已注销旧任务、尚未注册新任务"之间抛的,等于把 runner 任务删没了。
- StartWhenAvailable 改设到 settings(MSFT_TaskSettings 继承属性,
CIM 属性列表里看不见但可直接赋值,实测 StartWhenAvailable=True)
- 任务对象改由 New-WatchdogTaskPlan 统一构建,先构建、后注销旧任务
- Register-ScheduledTask 失败时显式告警"旧任务已删、CI 裸奔"并 exit 1
- 新增 -DryRun:免管理员即可全量校验 action/trigger/settings
- -Status 增补上次运行时间与返回码,并提示"非管理员看不见任务"
同时更正根因:旧计划任务其实一直存在(非管理员会话看不见,先前误判为
"从未注册"),但它跑的是单次 run_runner.cmd——daemon 属"正常退出"而非
"失败",计划任务的失败重启根本接不到,必须靠看门狗循环重拉。
|
2026-10-12 12:52:27 +08:00 |
|
wandering1
|
20ee35b76a
|
修复CI门禁三因:runner掉线致12个job零日志、L0探测回归全灭、gitlint在CI从不执行
1) runner 掉线:run 16~21 共 12 个 job 零日志。gitea-runner v4 的
daemon 无服务支持、首次 Declare 失败即退出进程,Gitea/机器重启
一次 CI 就静默停摆;叠加 cancel-in-progress 后症状是"任务凭空
消失"。新增 scripts/ci_runner_bootstrap.ps1:等 Gitea 就绪 +
崩溃自拉起看门狗 + 开机计划任务 + -SetEnv 写 MACHINE 级 DTU_*。
2) L0 自 33a4aa4 起在 runner 上必挂:Python 候选被收窄成 PATH python
(msys64,无 pre-commit) + 仓库 .venv(gitignore),cppcheck 目录兜底
亦被删,而机器级 DTU_* 从未设置。探测收进 ci_find_python.ps1
(两 job 共用、可离线自测、恢复机器级安装兜底)。
3) gitlint 声明 stages:[commit-msg],而 --all-files 只跑 pre-commit
stage → 17 个钩子定义 CI 只报 16 个且全绿。新增
ci_gitlint_range.ps1 逐条校验本次范围,ci_local.py 增 L0b 段。
另:GITHUB_ENV/PATH/OUTPUT 写入显式 -Encoding ascii(PS 5.1 的
Out-File -Append 默认 UTF-16LE,会把带 NUL 的行追加进 UTF-8 文件)
|
2026-10-12 12:39:27 +08:00 |
|
wandering1
|
90db528032
|
W1 功能主线完成:内存台账三件套(W1-0) + IEC104 上行(B4) + protectTask 板端接线(B5)
W1-0 台账三件套:scripts/ram_baseline.py(四模式)+ ram_baseline.tsv 趋势 +
docs/内存管理/RAM预算台账.md + pre-commit mem-budget 钩子(RW_IRAM1/RW_CCM >92%
即 FAIL + Top-10 附表);审查报告 §5.5 三条闭环。
B4 IEC 60870-5-104 上行(被控站,TCP 2404):App/protocol/iec104/ 三模块
(asdu 编解码 / pts 点表+数据源 vtable / link APCI+FSM,纯逻辑零 I/O)+
App/task/iec104_serv.c(iec104Task,NET_READY 屏障 100ms 分片喂位)。
82 断言 L0.5 全绿 + iec104-unit-test 钩子(第 31 钩子);
设计说明 docs/子系统设计/IEC104上行设计说明.md 全量回填。
B5 protectTask(L3 板端接线):App/task/protect_task.c——20ms 判据节拍
prot_elm_run + L5-4 采样故障闭锁(adc_health 电平位→元件复位)+ L5-1 定值
校验和巡检;新增 prot_elm_request_reset() 收口跨上下文复归(104 YK11 落请求、
eval 头部消费);定值/元件初始化移入 app_main_init(内核前)。TC-PE-010
(prot_elm 28 用例)。
门禁与内存:TASK_WD_PROTECT=8 入 required_mask(产品 0x77→0x1F7、HW 层
0x1F5,看门狗单测 39 断言同步);FreeRTOS 堆 48→56KB(.ioc L1 参数 +
FreeRTOSConfig.h 同步,RAM预算台账 §6 登记配额 48→56KB)。
ZI 144,008→152,204(+8,196 B = 堆 +8KB,B5 扩容);Code=204,348。
stack_report:protectTask 512 words 静态链 872 B/余 57%、iec104Task
640 words 1456 B/余 43% 均 PASS;RW_IRAM1 73.1% / RW_CCM 87.9%(<92%)。
验证:@build 0 错 0 警;ci_local 全绿(31 钩子 + 13 主机侧单测);
doc-links 135 文档 PASS。登记簿 B4/B5 销项、W1 波次完成;保护规划/看门狗
说明/AGENTS(9 任务)/RAM 三文档全部同步。
遗留(验收窗口,非代码空洞):台架第三方 104 主站往返(送检窗口)、
标准源注入动作判据、@test PROT 锚点 + protect 栈水位 + 新堆 min_ever 复测。
|
2026-10-12 12:36:23 +08:00 |
|
wandering1
|
0d084e6ec9
|
docs(net): 修正 FUN_PARA bit3 口径注释 + 补必要性论证
N-32 / B10 残余 P0 阶段:零风险的纯注释与文档口径修正。
net_socket.c:3627 / :3641 两处函数头注释写"CH395F 在 DISCONNECT
后自动关闭 Socket(FUN_PARA 默认)",与本仓 net_init 实际下发的
0x08(bit3 SOCKET_CLOSE=1,芯片不关、不清缓冲)相反。这类注释
会误导维护者跳过显式 close,是 U12 的观念源头。
新增设计文档 §2.4 回答"bit3=1 必要性大吗、如何安全处理":
- bit3=0 时芯片当场清缓冲,FTP「发完即 FIN」尾部数据必被硬件
擦除且不可补救;bit3=0 也挡不住丢中断(Trap 22),孤儿态
照样有。故保持 0x08,改在软件层收口(结论并入 D4)。
- 安全处理 = 把契约落到不变量 I(session_dead 电平化)与
不变量 II(单一所有者 pump)+ 补 U12 的 close 对称。
验证:@build 0 错 0 警(Code=197084 与改前一致,纯注释);
pre-commit 全绿(cppcheck / doc-links / C 规范)。
|
2026-10-12 12:36:18 +08:00 |
|
wandering1
|
e4134a4723
|
feat(skill): 新增 task-worktree 多任务并行工作树 skill
用 git worktree 给每个任务开独立工作空间,干完由固定命令合回主干,
解决多任务共用同一工作目录时构建产物/日志/登记簿互相踩的问题。
- 机制:worktree + 任务分支 task/<ID>-<slug>(ID 沿用待处理内容编号)
- 目录:仓库同级 _wt/;.venv 与 simulator/SDL2 以 junction 共享
- .workbuddy-ai/ 刻意独占,清场前归并回主工作树
- 命令:new/list/status/sync/lock/done/abort(短命令 @task)
- 锁:build(UV4 不能并发)+ bench(COM6/ST-LINK/设备 IP),
按时效 TTL 判定,不绑定进程存活
- done:merge-tree 预演 -> merge --no-ff -> 残留审计 -> 重生成产物
-> 门禁 -> 清场;门禁未绿则保留工作树;不含 push
- 隔离演练(DTU_INTEGRATION_WORKTREE)暴露并修复 4 个缺陷,
见 docs/环境与部署/并行任务工作树方案.md §11.1
同步:AGENTS.md 主题表、docs/README.md §9.2 与变更记录。
|
2026-10-12 11:56:13 +08:00 |
|
wandering1
|
09f8a6fb20
|
docs(net): 监听生命周期根治设计——证据、决策与执行清单
新增 docs/子系统设计/网络Socket监听生命周期设计说明.md(9 节):
原理三层证据——芯片层:LISTEN 与 ESTABLISHED 是同一 TCP 状态字节的互斥
取值(手册 §5.22 L535-545、§5.29 L609「直到连接成功后」),全手册无任何
"连接结束自动恢复监听"条款;且本仓 fun_para=0x08(bit3 SOCKET_CLOSE=1,
Trap 18/25 定案)使断开后芯片停在 0x05/0x00,即 B10 看到的"孤儿芯片态"
是本仓配置的合法后果,而非芯片异常。规范层:RFC 1122 §4.2.2.18 明文被动
OPEN MUST NOT affect any previously created connection record,POSIX
accept() 原文 socket 不变,lwIP 把监听器所有权写进 tcp_close() 文档——
本仓需要靠"EOF 不得 close 监听 fd"铁律维持正确性,即架构欠债的凭证。
实现层:EOF 是时序敏感边沿(只在 recv 那一刻 state==CLOSED 才给),导致
重建所有者散成 12 个(栈内 8 + 应用 4)、15 个迁移点、15 个无人负责组合。
关键决定 D1~D7:不启用芯片原生多连接模式(A′ 出局——FTP 改造清单第 4 条
已定案"多连接模式不支持多监听",本产品有 21/8888/7003 三个常驻监听加会
话期动态 PASV,且历史上踩过 Trap 02/11,FUN_PARA 初始化后不可改);采用
"会话结束电平化 + 监听重建单一所有者"的形态 B 深化,不做控制面重写;对
账④保留不撤回(Trap 22 实证事件会丢,周期对账不可删),其副作用由 P1
消除;fun_para 保持 0x08,不回退 Trap 25 的排空契约。
证据附录含 B10 探针日志、A/B 归因数据(基线 5/1/1/5 vs B3 3/7/2/1,均值
3.0 vs 3.25,统计不可区分)、④ 修复后完整回归矩阵、官方 EXAM5/EXAM10 所
有权模型(SDK 行号)、状态机 15 迁移点与关键判据、三服务契约不一致表。
Trap_Records B10 残余改写为指向该文档,并明确记录 ④ 的副作用:抢先
relisten 会把慢消费者的 EOF 永久吞掉,g_client 不清、新客户端数据被旧会
话静默吸收——④ 修好了端口拒连却撑大了另一侧窗口,P1 必须补。
登记行 N-32 已写入 docs/待处理内容.md 工作区,但该文件与并发在途的 N-27
改动混杂,本次不提交,留待其归属方一并入库。
|
2026-10-12 11:17:48 +08:00 |
|
wandering1
|
4f2cc8bc90
|
fix(net): B3 只清本 Socket 中断;B10 对账认领孤儿监听修永久拒连
B3(net_listen_locked / net_relisten_locked 两处):
原先对全部 8 个 Socket 做 GET_INT_STATUS_SN(读即清)并丢弃式读全局中断
状态。依据三条:§5.15 明文全局寄存器整体读即清且无按位清除手段;net_poll
只在全局位置位时才读该 Socket 的 SINT(位图门控);SINT 粘滞到被读
(Trap 14 实证 close/open 都不清)→ 读走即永久销毁其它在用 Socket 的
CONNECT/DISCONNECT/TIM_OUT/SENBUF_FREE。git 考古定性为多连接时代调试遗留
(e862009bc → 319d00e3 → db64e6acf),不属于任何已登记 Trap 的修复;官方
SDK 21 个例程一律"位图门控 + 单 Socket 读 + 立刻转存",open/listen 前后
不清任何中断,无一例全量读 8 个 SINT。现收窄为只清本 Socket 的 SINT,
全局交 net_poll 集中读清,与 AGENTS 模块约定一致。
B10(孤儿监听 → 端口永久拒连):
断开时 handle_disconnect_event 释放分支置 CLOSED 并注释"等待应用重新监
听",而 ui_net_sink 只在 net_recv 返 0(EOF)时才清 g_client,EOF 已被该
事件分支消费 → net 层等应用、应用等 EOF、对账只裁 ESTABLISHED/LISTENING
直接跳过、芯片不会自己回 LISTEN,四方互等。实测孤儿态 state=0 /
chip=0x05/0x00 持续 12s+,:7003 300ms×10 为 0/10 且 +30s 仍拒连。
net_reconcile_tick 新增类型④认领孤儿,复用 net_relisten_try(自带"已在
重试队列不重复登记"保护,与 D10 队列、Trap 23 沉降隔离兼容)。门槛中
auto_relisten 是决定性一条:缺它则出向连接(板级 Phase 7 TC701~703 绑本
地口)会被误判孤儿并被 relisten 成监听器。
工具:ftp_abort_probe.py 仍用 anonymous 登录,N-19 后 530 拒 → Trap 23 两
条腿假 0/5(round1 PASV failed,且半认证会话占死 FTP 唯一会话)。改
admin/admin 后 RST 5/5、FIN 5/5。
回归::7003 300ms×10 由 0/10 永久死 → 10/10(+20s 存活);:21 0ms×50 与
100ms×50 均 50/50;:8888 0ms×20 为 20/20;ftp_regression 11/11×2;Trap 23
RST 5/5、FIN 5/5;@test PASS(600ms、回读无差异);@build 0/0,
Code=197084。
残余:B10 生产者未根治,释放分支仍把状态停在 CLOSED 等应用重建,类型④
是兜底;根治涉及 Trap 25 closed-with-data 契约,单列评估。
|
2026-10-12 10:35:55 +08:00 |
|
wandering1
|
794a688a3c
|
fix(net): B2 不再丢弃 TCP_CONNECT 命令状态,命令级被拒立即回滚返 -1
问题:net_connect_locked() 调 ch395f_tcp_connect() 后直接丢弃返回值,
而同函数内 open/listen 都查了状态。§9.2.2 ⑧ 明文:发完
CMD_TCP_CONNECT_SN 后须轮询 GET_CMD_STATUS,返回 SUCCESS 仅表示
**命令**执行成功(不代表 TCP 连接成功),其他值表示命令执行失败。
丢弃它 = 命令级被拒时本层停在 CONNECTING,要等 30 s recv 超时才暴露。
修法(不能一刀切):只拦"非 SUCCESS 且非 BUSY"。因为
ch395f_poll_cmd_status() 超时返回的就是 CH395F_ERR_BUSY(= 4 s 内
芯片仍在执行,命令并未被拒绝),把它当失败会误杀慢芯片。明确失败
→ 打 [ERR] rejected by chip: 0xNN 留痕 + 按 §9.2.2 ⑧"再次连接需从
⑤ 重开"关掉 Socket、状态回滚 CLOSED、返 -1(NET_ERR_INVAL)。
顺带修一处错注释:原写"发起 TCP 连接(异步:芯片立即返回)",实际
驱动内部已按 §9.2.2 ⑧ 轮询 GET_CMD_STATUS 最多 4 s,并非立即返回。
硬件回归(Phase 7,NET 层 TCP Client 主动连接):
- TC701 连接 + 64 B 回显逐字节比对 PASS(cksum=0x000007E0)
- TC702 关闭重连 x3 全 PASS → 正常连接路径无误杀
- 不可达对端时芯片回的是 SUCCESS、ret=0 且不打 rejected by chip
→ 失败仍由 CONNECT TIMEOUT(~1.6 s) 裁定,行为未变;新分支只在
芯片明确说"命令执行失败"时才走
- TC704 socket create #5 FAIL = E-23 既有(NET_MAX_SOCKETS=8 减 3
个常驻监听 → 并发上限 5,而 PHASE7_MULTI_COUNT 仍是 8),与本次无关
- TC703 要求 PC 服务器离线,与 701/702/704 环境互斥,同轮连跑必有
一侧失真;其 rc==0 断言等于把"返回值被丢弃"写进判据,真发生命令
级被拒时它会 FAIL(属正确告警)
前两轮 Phase 7 全灭不是改动问题,已登记为台架坑:本机对
C:\programdata\anaconda3\python.exe 有两条 Public 入站 Block 规则,
而 .venv 的基座解释器正是 Anaconda python;Windows 防火墙块规则优先
于放行规则,故中途加的 8081 端口级 Allow 完全无效,只有临时关 Public
才通。症状极具误导性(芯片 1.6 s 报 CONNECT TIMEOUT、net_connect 仍
返 0、openOK 照常打印),看着像芯片/驱动故障。
残余(登记未动):net_reconcile_tick 仍只裁 ESTABLISHED/LISTENING,
CONNECTING 丢中断无人收口——产品不走出向连接、无法实测,按 Trap 25
"不加未证明的复杂度"只登记不实现。
验证:构建 0 错 0 警、Code=197032;内存快照已刷新;doc-links EXIT=0、
无 U+FFFD;@test 闭环 PASS(戳 fw build: Oct 12 2026 08:03:29
suite=NONE、回读无差异、548 ms)。测试宏已复原,两个测试头文件与
HEAD 字节一致;临时防火墙规则已删除、Public 已重新启用。
|
2026-10-12 08:17:36 +08:00 |
|
wandering1
|
9a45be1700
|
docs(net-audit): B1 服务器侧 KeepAlive 前提被实测推翻,撤回改动并记台架注入陷阱
B1 原判"产品路径从未启用 Socket KeepAlive → 静默断开无人知晓"(§5.56
要求 TCP 服务器在产生 SINT_STAT_CONNECT 后开启,产品三服务全是
Server,60s/5s/3 参数空转)。本轮按 §5.56 在 LISTENING→ESTABLISHED
分支补了 ch395f_set_keepalive_enable() 并上板做定案实验,结果推翻前提。
实测:连接静置时禁用 PC 网卡(真·静默死亡),芯片 +2 s 即报
"[ERR][NET] sock0 TIMEOUT" → 本层 relisten quarantine 释放重开监听。
2 s 只能是重传(§5.17 本仓 8×200 ms = 1.6 s 量级),与 KeepAlive 无
关——IDLE 最短 60 s、芯片默认也要 20 s。链路层失效本就被快速覆盖,
故依 Trap 25 铁律「不留未证明的复杂度」撤回该改动,只在代码内留注释
记录(含未覆盖场景与注入难点),不保留无证据的动作。
另一半天真:设备 2 s 就重开监听,PC 侧那条 socket 却继续"自认存活"
直到 4 分钟后自行 close(Python 对死链路 close() 不报错)。不对称恢复
才是现场隐患——客户端下次写会吃到 §5.29 的 RESET;单靠设备侧开
KeepAlive 只解决设备这一半。
新增「台架注入陷阱(2026-10-12)」四条(本轮踩到的,全部实测):
1. Windows 出站防火墙规则不能模拟"对端静默死亡"——WFP 对已建立的流
有状态缓存,中途加 Block 不影响既有连接;实测静置+阻断 250 s 芯片
毫无反应,看着像"KeepAlive 不生效",实则 ACK 一直正常往返。
2. 该规则还会吃掉本机后发的 FIN → 设备留下幽灵 ESTABLISHED,之后新
连接被 §5.29"向试图连接的远端发送 TCP RESET"直接 RST,表现为"端口
拒连",极易误判成设备故障(实为自伤,撤规则后自愈)。
3. 真正掐断链路用 Disable-NetAdapter;本机该 cmdlet 只有 -Name /
-InterfaceDescription,没有 -InterfaceIndex/-ifIndex(第一次写错
导致那轮网卡根本没关)。网卡名是中文,用
(Get-NetAdapter -InterfaceIndex 19).Name 取值再传,避免命令行写中文;
禁用/恢复必须写在 try/finally 里。
4. 仍未覆盖:"链路仍在、对端静默"(NAT 会话过期、中间节点黑洞)才是
服务器侧 KeepAlive 唯一可能的价值场景,本机无安全注入手段(静态
ARP 黑洞会被交换机泛洪兜底、删 IP 会连带拆掉本机连接)——未证实,
故不保留改动。
判读教训(与 Trap 25 同源):看到 TIMEOUT 先算时序再归因,2 s 与 60 s
一眼可分;否则会把重传超时误记成"KeepAlive 生效",把相关性当因果。
验证:构建 0 错 0 警、Code=196912(与 afb0bfd 一致,说明撤回后二进制
回到已提交状态);doc-links EXIT=0、Trap_Records 无 U+FFFD 无 BOM;
@test 闭环 PASS(回读无差异 + forbidden 三项与 [ERR] 全缺席 + 594 ms)。
|
2026-10-12 07:49:58 +08:00 |
|
wandering1
|
afb0bfd5ff
|
fix(net-audit): 修 6 处寄存器口径/注释错误 + Trap 记录全量复核与审计章节
智能体团队四路并行只读审计(驱动层逐命令 / NET+测试层逐调用点 /
Trap 01-12 复核 / Trap 13-25 复核),三源交叉:芯片手册 + WCH 官方
SDK(CH395CMD.c / CH395INC.H / 21 个例程)+ git 历史。本提交只落
"已确认且低风险"的修法,其余发现登记进文末审计章节待逐项决策。
已修(A 类,全部有手册/SDK 出处):
A1 测试 TC-203 反核实写成 st_chk[0]==CH395F_TCP_ESTABLISHED——§5.22
byte0 只有 00H/05H,条件恒假,这道 Trap 14 防线自写下起从未生效
且日志无痕(与 Trap 07 同类的 byte0/byte1 语义越界)。改为
byte0==OPEN && byte1==ESTABLISHED。
A2 测试 Phase3/4 把 GET_RECV_LEN 返回值直接当读取长度(本地
rx_buf[300]/[64],芯片 RX 缓冲 2KB)→ 栈溢出;补夹取 + 留痕
(同文件 TC201/202/204 早已 clamp,这两处是漏)。
A3 CH395F_GINT_STAT_DHCPV6 由 0x8000(bit15) 改 0x1000:SDK 是
(1<<12)、§5.16 明确 CH395F 的 [12:15] 保留。全仓零引用。
A4 ch395f.h 命令分组注释字节数错 4 处(GET_GLOB_INT_STATUS_ALL /
GET_UNREACH_IPPT 归"1 字节输出"、SET_FUN_PARA 归"1 入 1 出"、
SET_RETRAN_PERIOD 归"3 字节输入"、GET_SOCKET_STATUS_SN 归"1 字节
输出");KeepAlive 参数注释"秒"改"毫秒"(§5.53/5.54 单位 ms);
set_retrans_count 删"0=默认值5"(§5.17 默认 12、无 0=默认语义)。
实现全对、注释误导——Trap 25 的 1 字节缓冲栈越界正是这类注释发起。
A5 net_socket.c 六处注释与手册/HEAD 相反:FUN_PARA(SOCKET_CLOSE=0)
实为 bit3=1(正是 closed-with-data accept 的契约依据,写反会诱导
把 0x08 改回去)、"初始化成功后设置 MAC"(§9.2.1 ① 是之前)、
"复用默认缓冲"(net_init 已为 8 Socket 显式分配)、"由 MSS 推导"
(固定布局、Trap 21 已解耦)、"等 SEND_OK"(门控是 SENBUF_FREE)、
UDP 头 [0-1] reserved(§9.2.4 是数据长度)。
A6 ch395f.c write_send_buf 超限静默 return(void 无日志),且上限取
DMA 2048 而非发送缓冲 1024;读路径有 OVERSIZE 金丝雀、写路径没有
→ 补 [ERR] 留痕 + >1KB 告警,行为不变(分块责任仍在调用方)。
审计确认"不是 bug"的最危险一项:GET_GLOB_INT_STATUS_ALL 拼装方向。
我们"第1字节|第2字节<<8"与官方 CH395CMDGetGlobIntStatus() 逐字相同,
glob & (1<<(sock+4)) = §5.16 bit4..bit11 = SDK GINT_STAT_SOCKn,三源
一致。另 55 条命令码、9 处 16 位字节序、14 条读命令字节数、60 个
常量、12 个单位参数点、48 块缓冲布局逐条核对无异常;17 处
get_socket_status 调用点全是 st[2],Trap 25 的 1 字节 bug 无残留。
文档:Trap_Records 加文末「2026-10-11 寄存器/数值口径全量审计」章节
(干净清单计数 + 15 条新发现含已修/待修 + 文档待修清单)。就地修正:
Trap 07 定案更正里"全文 RST 仅见于错误码与引脚"的绝对表述(§5.29 /
§9.2.6 其实写了芯片发 TCP RESET,只是都与 close 无关)+ 删不可核验的
"11 个悬空提交";Trap 16 的"IP/端口寄存器大端"(端口 §5.25/5.26 明确
低字节在前)+ 注明 §5.8 总括与官方例程自相矛盾;Trap 18 删悬空
"Trap 19"(该条从未存在)、net_socket() 改 net_bind();速查清单 DMA
1500 改 2052;Trap 13 加复核注(最高优先级:其"部分读后 recv_len
归零"与 §5.34 直接相左、与本仓 TC201 注释相反,且同族结论已被 Trap 21
撤回,却仍被 6 处当现行约束引用);Test_Guide 的 TRAP-07 行仍教
"卡 FIN_WAIT_2 / close(RST)"、悬空的 Trap 19 与两处"见风险 #N"。
待修(B 类,登记未动,需逐项决策与实测):B1 产品路径从未启用 Socket
KeepAlive(唯一调用点在 client 分支,产品三服务全是 TCP Server,
§5.56 要求服务器在 CONNECT 后开,60s/5s/3 参数空转);B2 tcp_connect
返回值丢弃且 CONNECTING 不在对账范围;B3 net_listen_locked 全 8 Socket
读即清会吞别槽事件;B4 全局中断 bit0-3 从不消费、get_unreach_info 零
调用;B5 getsockname 的 s_addr 与本层约定相反致 FTP 日志设备 IP 反序
(PASV 双重反转恰好正确,勿误判);B6 三处判据只看 byte1 未按 byte0
门控;B7 Phase5 单次写 4093B;B8 Phase4 缓冲块与 sock4 交叠;B9 杂项。
验证:产品构建 0 错 0 警、Code=196912(+124B,写路径两条新日志);
测试路径(PHASE2/3/4 打开)单独编译 0/0;内存快照已刷新;doc-links
EXIT=0、无 U+FFFD、pre-commit 全绿;@test 闭环 PASS(戳匹配 + 回读无
差异 + 锚点 x1 + 548ms)。
|
2026-10-12 00:20:17 +08:00 |
|
wandering1
|
bca6cc694c
|
test(net): TC-NET-204 定案 Trap 07——disconnect→close 不卡死,真因是 bit3
Trap 07(2026-07-19 写成"2025-07")断言"disconnect→close 让 Socket 卡
FIN_WAIT_2 数分钟、因为 close 不发 RST"。新增定案用例 TC-NET-204(Phase 2
硬件层,同一 Socket、同一 PC 回显、FUN_PARA=0x08,三模式 × 5 轮 = 45 项判定
全过)做受控对照,实测推翻其机制说法、保留其做法:
A close → 回 CLOSED 0/0/150/0/0 ms,重开 5/5 OK
B disconnect → close → 全部 +0 ms,重开 5/5 OK("卡死"未出现)
C disconnect(不 close)→ 10 s 内从未回 CLOSED,byte0 恒 0x05、byte1 0x00;
直接 open → 0x20 FAIL(5/5),补 close 后 +0 ms
三条推翻:① FIN_WAIT_2(06H) 全程未出现(15 轮 × 9 采样点),实测过渡态只有
TIME_WAIT(0AH);② 手册无 RST 语义(§5.35 只说 close 前自动断链),且主动发
FIN 先进 FIN_WAIT_1 才进 FIN_WAIT_2,原说法跳拍;③ 观测越过了 byte1 的语义
边界——§5.22 byte0 只有 00H/05H,官方 SDK 注释明确 byte1 仅在 byte0=OPEN 时
有意义,而当年代码判据用的是正确的 byte0,break 后照样打印 byte1,于是"已
CLOSED 下的残留读数"被读成"卡在某个 TCP 态"。
真因:FUN_PARA bit3 SOCKET_CLOSE=1(§5.52 ②)下产生 DISCONNECT 后芯片不关
Socket、不清缓冲,Socket 停在 0x05(OPEN)/0x00(TCP_CLOSED),此时 open_socket
必返 0x20 FAIL——即历史那条 Phase 2 open_socket: 0x20 / socket 未完全关闭。
拉回 CLOSED 的动作是 close,与 RST 无关。
git 佐证:ch395f_tcp_disconnect() 自首个提交起只有定义、零调用点(含全部分支
与 11 个悬空提交),"disconnect→close" 从未进入提交代码;当时驱动已轮询
GET_CMD_STATUS(4 s 上限),也不是"命令没等完成"。
做法保留,理由换成三条有支撑的:§5.35 close 已自动断链故 disconnect 多余;
disconnect 制造的 DISCONNECT 事件在 bit3=1 下须我方消费/预清(Trap 14/17/22);
它把芯片推进 closing 过渡态、重开需沉降(Trap 09)。本轮 15 轮重开均未观察到
残留 DISCONNECT(0x10)——close 顺带清掉锁存,这才是"直接 close"安全的原因。
另消解 Trap 17 与 Trap 07 的旧矛盾:实测支持 Trap 17(close 走 FIN teardown、
0~150 ms 可见 TIME_WAIT),不支持 RST 说法。
文档:Trap_Records.md 加 Trap 07「定案更正」整节 + 改写「驱动关键点 → TCP 关闭
重连」速查清单(删 RST 说法、补 byte0/byte1 口径与 0x20 陷阱);Test_Guide.md
新增 TC-NET-204 用例表(前置含 tcp_server --timeout 900 这条坑:首连后连接
间隔 >60 s 服务器会自行退出)。
验证:测试构建 0 错 0 警、Phase 2 74/75(唯一 FAIL 是 TC-203 环境守卫,PC 服务
未及时关闭);宏已还原,产品构建 Code=196788 与 HEAD 一致(用例全在测试宏内、
产品零足迹),@test 闭环 PASS(戳匹配 + 回读无差异 + 锚点 x1 + 590 ms)。
pre-commit 全绿(test-cppcheck / doc-links / no-mojibake 均 Passed)。
|
2026-10-11 21:40:45 +08:00 |
|