撤回Trap21精确定位轮冻结结论(台架假象:分类器误判+固件读者吞噬数据),N-7暂不实施

This commit is contained in:
2026-09-23 00:54:00 +08:00
parent 563584744d
commit 685a860635
4 changed files with 18 additions and 1 deletions
+1 -1
View File
@@ -13,7 +13,7 @@
| N-2 | **49s 全系统日志静默(defaultTask/NAND syslog 排空停滞)**——串口日志 49s 无行(testTask 10s 周期行/netTask 事件行/[STACK] 行全缺),期间 net 栈照常处理外部连接(FTP banner 92ms)→ 日志管线(defaultTask 排空 → NAND+UART)停滞,队列满后各任务日志行被丢;系统功能不受损 | 2026-09-22 17:23:52~17:24:41(L3 台架 F2 运行中,gen 181) | **A/B 归因:L3 不触碰 defaultTask/syslog 路径 → 既有存储侧现象**。待办:① 复现条件定位(NAND 写/GC 长尾 vs UART TX 卡滞——对照 `CH395F` 无关的 SD2506 侧日志)② 日志队列满的丢弃计数/告警(现静默丢行,排障不可见)③ 与 S8(非阻塞日志)合并评估 | `错误码传播审计.md` E-02 阶段二"台架新发现②";`链路延迟测试说明.md` §6.7 注 |
| N-3 | **L5 队列往返基线(1223/988µs)的 L3 后重验**——L5 测 DONTWAIT 队列全程;L3 对该路径逐位不变、pending tick 无 pending 时为 µs 级指针读 → 机制上无影响,但基线数值属分片时代,严格重锁需跑一轮 Phase 13(需 PC peer,窗口与 N-1 定位可并案) | 2026-09-22(L3 收尾留档) | 低风险:10ms/100ms 阈值余量 >8×;下次 Phase 13 窗口顺带重锁即可 | `链路延迟测试说明.md` §6.4 L5 注¹ |
| N-6 | **Trap 22:快速重连致 CONNECT 中断丢失 → 单连接监听静默死亡(P1,修复待批准)**——轻负载 + 重监听历史 + 断连后 <~1s 重连:芯片握手正常但 MCU 无 standalone accept(状态滞留 LISTENING)→ `net_send` 全失败(-1)→ 断开时 DISCONNECT 落 LISTENING 分支仅告警 → 芯片自动关闭 Socket → 端口永久拒连(不自恢复) | 2026-09-22(Trap 21 二次台架 A 组 run2;出现 1/1,未做 10/10 规模复验) | 修复方案:`handle_disconnect_event` LISTENING 分支回读芯片 socket 状态,非可监听即 `net_relisten_try` 重建(D20 的 LISTENING 分支姊妹情形)+ 可选:重监听后清残留中断位;应用侧规避:单连接 socket 断连后重连 ≥1~2s 退避(lftpd 快速 PASV / 客户端快速重试是生产风险场景)。生产影响:数据通道监听静默死亡 → 后续数据连接全拒,严重度等同端口失效 | `CH395F_Trap_Records.md` Trap 22 |
| N-7 | **Trap 21 生产修复:net 层非阻塞 RX 读强制排空至空(P1,待批准实施)**——致命类 = 部分窗口重通告(排空后缓冲残留):大 Δ(1KB 块读,C/C0 配方)10/10 确定性停摆;小 Δ(64B)相位刀口(一次性落点 10/10 过 vs 5/5 停摆仅数 ms 时移之差)且持续重复必停摆(50/50);排空至空(窗口→满)恒安全(40/40,含 10ms 节拍 E0)、Δ=0 命令(状态读/中断读/poll/TX)恒安全 → **无需时间守卫/冷却**(旧"排空后 RX 暂缓 + 120ms 冷却"设计作废:C0 证明部分排空自身即致命,E0 证明排空至空后 10ms 再排空安全) | 2026-09-22(精确定位轮:E/O/B/F1/S1–S4/C/C0/V1F/O1f 共 11 组台架 110+ 运行 + netcmd 命令序列日志) | 实施要点(2026-09-22 复核细化,完整方案见 `问题记录/CH395F_Trap21_机制图解.md` §5):net 层新增 `net_drain_recv()` 助手,替换 5 处 `min(货架现有, 调用方len)` 读路径——`net_recv_locked:1205`、`net_pending_tick:1514`/`:1536`、`net_pending_settle_close:1618`、`net_recvfrom:2072`:先交付中转筐 → 筐空则 `avail = get_recv_len()` 后**按 avail 全量读空**入筐 → 只交 `min(avail, len)` 给调用方,余量留筐、下次不发芯片命令直接交付(上层筐大小与解析逻辑零改动);中转槽设计(2026-09-22 复核:**一个共用槽即可**,8KB 方案作废):数据通道自带筐 1KB→2KB(`lftpd.c:187`,`len=2048 ⇒ min(avail,len)==avail`,天然读必读空、永不入槽、不参与争用),控制行 512B / UI 64B / 时间同步 16B 共用**一个 2048B 槽**;槽被别的 socket 占用时该读暂缓(WOULDBLOCK / pending 继续等),不发命令即无残余 → 合计 **+3KB**(主 SRAM 余量 47.2KB,占 6.3%),槽数 1→2 仅一行改动;争用暂缓记限频日志。**只改 lftpd 数据筐不足以覆盖**:控制行读、UI 64B、时间同步 16B 为同型雷(且单纯加大控制行缓冲会丢流水线命令;零槽方案需 +6.5KB 并重构控制行读取器)。台架回归:C/C0 与 V1 配方由 10/10 停摆 → 10/10 通过,E 系列保持 40/40;Δ=0 命令(状态读/poll/TX)不受限 | `CH395F_Trap_Records.md` Trap 21;`CH395F_Trap21_机制图解.md`;`Drivers/BSP/NET/net_socket.c`(5 处读路径);`Drivers/BSP/NET/lftpd/lftpd.c` receive_file 块循环 |
| N-7 | **⛔ 已撤回(2026-09-23):前置机理为台架假象(分类器误判 + 固件内读者吞噬对端数据),"读必读空"未被任何有效台架验证 → 本项暂不实施**(原提案:net 层非阻塞 RX 读强制排空至空;撤回依据与本轮证据见 `CH395F_Trap_Records.md` Trap 21 顶部更正块。原"致命类 = 部分窗口重通告(排空后缓冲残留):大 Δ(1KB 块读,C/C0 配方)10/10 确定性停摆;小 Δ(64B)相位刀口(一次性落点 10/10 过 vs 5/5 停摆仅数 ms 时移之差)且持续重复必停摆(50/50);排空至空(窗口→满)恒安全(40/40,含 10ms 节拍 E0)、Δ=0 命令(状态读/中断读/poll/TX)恒安全 → **无需时间守卫/冷却**(旧"排空后 RX 暂缓 + 120ms 冷却"设计作废:C0 证明部分排空自身即致命,E0 证明排空至空后 10ms 再排空安全) | 2026-09-22(精确定位轮:E/O/B/F1/S1–S4/C/C0/V1F/O1f 共 11 组台架 110+ 运行 + netcmd 命令序列日志) | 实施要点(2026-09-22 复核细化,完整方案见 `问题记录/CH395F_Trap21_机制图解.md` §5):net 层新增 `net_drain_recv()` 助手,替换 5 处 `min(货架现有, 调用方len)` 读路径——`net_recv_locked:1205`、`net_pending_tick:1514`/`:1536`、`net_pending_settle_close:1618`、`net_recvfrom:2072`:先交付中转筐 → 筐空则 `avail = get_recv_len()` 后**按 avail 全量读空**入筐 → 只交 `min(avail, len)` 给调用方,余量留筐、下次不发芯片命令直接交付(上层筐大小与解析逻辑零改动);中转槽设计(2026-09-22 复核:**一个共用槽即可**,8KB 方案作废):数据通道自带筐 1KB→2KB(`lftpd.c:187`,`len=2048 ⇒ min(avail,len)==avail`,天然读必读空、永不入槽、不参与争用),控制行 512B / UI 64B / 时间同步 16B 共用**一个 2048B 槽**;槽被别的 socket 占用时该读暂缓(WOULDBLOCK / pending 继续等),不发命令即无残余 → 合计 **+3KB**(主 SRAM 余量 47.2KB,占 6.3%),槽数 1→2 仅一行改动;争用暂缓记限频日志。**只改 lftpd 数据筐不足以覆盖**:控制行读、UI 64B、时间同步 16B 为同型雷(且单纯加大控制行缓冲会丢流水线命令;零槽方案需 +6.5KB 并重构控制行读取器)。台架回归:C/C0 与 V1 配方由 10/10 停摆 → 10/10 通过,E 系列保持 40/40;Δ=0 命令(状态读/poll/TX)不受限 | `CH395F_Trap_Records.md` Trap 21;`CH395F_Trap21_机制图解.md`;`Drivers/BSP/NET/net_socket.c`(5 处读路径);`Drivers/BSP/NET/lftpd/lftpd.c` receive_file 块循环 |
## 存储 / 日志管线
+2
View File
@@ -643,6 +643,8 @@ sequenceDiagram
**通过标准**:4096B 完全匹配。任一失败 → 标记 FAIL
**覆盖原则**:DP-04(2KB 接收缓冲边界 + 单次 DMA 上限) |
> **⛔ 2026-09-23 更正**:下方"复现/对照规则"依据的台架结论**已撤回**(`probe_classify.py` A/C 误判 + 固件内非回显读者吞噬对端数据:探针/Phase 9/11 读走即丢弃 → PC 端短收被误判为"冻结";C0 脚本层实测 1460/1460 全匹配)。**当前无可靠的 TC-NET-604 冻结复现配方**;判读一律用 `MDK-ARM/bench_verdict.py`(脚本层 STEP 为真值并扣除吞噬字节),台架配方不得混用"固件内非回显读者"与固定期望值。
>
> **TC-NET-604 复现/对照规则(2026-09-22 精确定位轮定案:致命类 = 部分窗口重通告(排空后缓冲残留);见 Trap 21)**:
> - **复现(预期 10/10 停摆)**:部分排空构型 = 64×10 + 1460B 填充 + 1024B 部分排空(C/C0 配方,Phase 6-only 构建、零第二命令,10/10 确定性停摆 = 生产 lftpd 块循环的台架复现);旧三因子配方(Phase 6/9/11 组合 + 4096B 超容突发;V1 配方 = Phase 6+11+60ms)10/10 维持;
> - **对照(预期 10/10 全过)**:Phase 6-only 排空至空构建 + `tcp_client` 每轮间隔 ≥15s——排空至空(窗口→满)任意节拍均安全,10/20/40/60ms 全过(E 系列 40/40,含 10ms E0);Δ=0 状态读/TX 任何偏移/密度均安全(B 系列);
@@ -1,5 +1,11 @@
# CH395F Trap 21 机制图解:"搬一半货"为什么会把芯片的嘴封死
> **⚠️ 2026-09-23 更正(重要)**:本文第 2–5 章的机理(部分窗口重通告 = 致命、再武装区间 ≥160ms、相位刀口、C/C0 = 生产复现)**建立在已被证伪的台架判读之上,全部撤回**。复核结论:
> - `probe_classify.py` 的 A/C 模式把**通过的运行**报成 STALL(C0 脚本层 1460/1460 全匹配仍被判停摆);
> - S1–S4/O1/O1f 的短收量**恰等于固件探针吞噬的字节**(探针读走即丢弃 → PC 少收);
> - V1/V1F 的"冻结"= **Phase 11 每 tick 的 64B 读吞掉对端整包**(测试程序不处理收到的数据),E 系列(无此读者)40/40 全过。
> 因此:**本文的"致命性模型/方案设计(读必读空 + 中转槽)"不能作为已证实的机理或已验证的修复**;生产 TC-NET-604 冻结**目前仍无可靠复现与定论**。第 1 章"现场长什么样"可保留(源自现场观察),第 2–5 章请按"未验证设计草案"看待。
> 面向:需要理解/评审本问题的工程与管理人员。逐组台架数据与技术定案见 `CH395F_Trap_Records.md` Trap 21。
> 整理日期:2026-09-22(精确定位轮定案后)。
+9
View File
@@ -539,6 +539,15 @@ NET 层 TCP Client(阶段 7)`net_connect()` 返回 0,但 `net_poll()` 报
## Trap 21:接收缓冲"恰好填满 + 排空"窗口冻结(TC-NET-604)
> **⚠️ 2026-09-23 更正(重要,撤回本轮大部分结论)**:本节 2026-09-22"精确定位轮"中**所有"冻结/WEDGE/停摆"结论均为台架假象,全部撤回**。以脚本层 STEP 行为真值的逐条复核:
> 1. **分类器误判**:C0/C0b(修复前)脚本层为 `STEP B1460 rx=1460/1460 OK` + `K1460+TAIL rx=2100/2100 OK`,且内容逐字节匹配(0x80,0x81,… 与 `pattern(640,1460)` 一致)——**从未冻结**,而 `probe_classify.py` A/C 模式报 `STALL@B1460 | fill part 0/1460`(其"fill part"比对取错 HEX 块、且未扣除固件探针吞噬的字节)。
> 2. **探针吞噬即短收**:S1–S4/O1/O1f 的脚本层短收量**恰等于固件探针吃掉的字节数**(S1:4736−4608 = 128 = 2×64 探针读),即"少回显的正是测试程序自己吞掉的那几个包"——非芯片故障。
> 3. **V1/V1F"唯一真实冻结"同样是假象**:设备侧日志显示 `stage fd=2 avail=64 len=64`,即 **Phase 11 的每 tick 64B 读把对端整包读走后直接丢弃**(该测试分支只判 `n==0`,不处理已收数据),PC 侧下一轮 `STEP R r06 rx=0/64 QUIET`;对照 E 系列(仅 Phase 6、无额外读者)40/40 全过。→ "冻结"= **测试程序自吞数据造成的空洞**,不是芯片 TX 死亡。
> 4. **撤回清单**:下方"致命性模型"整表(部分排空 10/10 致命、持续第二读 50/50、+0/+80/+120/+160ms 全致命、再武装区间 ≥160ms、相位刀口 O1f、C/C0 = 生产复现、keepalive/快重连排除项中的台架依据)**全部作废**;"生产 lftpd STOR 被 C 配方 10/10 复现"不成立。
> 5. **仍然成立的部分**:E 系列(Phase 6-only,排空间隔 10/20/40/60ms,标准 `tcp_client` 序列)40/40 通过(脚本层逐步匹配);"芯片 RX 读是否必须读空"**未被任何有效台架证伪或证实**。
> 6. **现场 TC-NET-604 冻结仍未解释**:需以可信工具重新复现——判读一律用 `MDK-ARM/bench_verdict.py`(脚本层 STEP 为真值,并扣除固件读者吞噬的字节),`probe_classify.py` 仅作参考;台架配方必须避免"固件内非回显读者"(Phase 9/11、探针)与 PC 侧期望值混用。
> 7. 相关代码:本轮 N-7 原型(net 层"读必读空"+ 共用中转槽,+3KB)**未提交**,仅存设计;在机理确认前不落地(见 `docs/待处理内容.md` N-7 撤回标注)。
### 现象
单条 TCP 连接在传输中途**静默单向死亡**:设备侧回显/应答流戛然而止(PC 侧 0 字节),连接不 RST(两侧均保持 ESTABLISHED)、无芯片断开事件;**芯片接收路径仍然健康**(2026-09-22 精确定位轮实证:冻结后继续到达的数据芯片照常接收、MCU 照常排空,命令流节奏完整),**芯片发送路径永久死亡**(已写入的发送数据不出线——SPI 写被芯片接受但线上无任何段;ACK/窗口更新随之停止)→ 对端剩余数据滞留**对端发送缓冲**(窗口视图冻结在 0,对端"重传"实为等窗口的空等,10s 无效)。对端断开重连(新 Socket)后恢复正常。2026-09-22 精确定位轮最小复现:64×10 + 1460B 填充 + **1024B 部分排空**(C/C0 配方,Phase 6-only 构建、零第二命令,10/10);原三因子配方(F1 组合 + 4096B 超容突发)10/10 维持。