diff --git a/Drivers/BSP/CH395F/ch395f.c b/Drivers/BSP/CH395F/ch395f.c
index b744cd05..f5304b46 100644
--- a/Drivers/BSP/CH395F/ch395f.c
+++ b/Drivers/BSP/CH395F/ch395f.c
@@ -1163,7 +1163,7 @@ void ch395f_read_recv_buf(uint8_t sock, uint8_t *p_data, uint16_t len) {
total = 4U + len;
if (total > CH395F_DMA_BUF_SIZE) {
/* 异常金丝雀:接收读不应超过整个接收缓冲(2KB,recv_len 不可能超过缓冲大小);
- * 触发即调用方参数异常。静默丢弃会把芯片接收窗口锁死在 0(见 Trap 21),
+ * 触发即调用方参数异常。静默丢弃会让数据与错误一起消失(无从诊断),
* 故必须留痕。正常路径不会到达此处。 */
DBG_ERROR("read_recv_buf OVERSIZE: sock %u req %u > max %u, read dropped",
(unsigned)sock, (unsigned)len, (unsigned)(CH395F_DMA_BUF_SIZE - 4U));
diff --git a/Drivers/BSP/CH395F/ch395f.h b/Drivers/BSP/CH395F/ch395f.h
index 0a75dbc2..25e25c50 100644
--- a/Drivers/BSP/CH395F/ch395f.h
+++ b/Drivers/BSP/CH395F/ch395f.h
@@ -114,11 +114,9 @@ extern "C" {
* TCP MSS(CH395F_CMD_SET_TCP_MSS 参数)
* 由 net_init 经 ch395f_set_tcp_mss() 下发(须在 ch395f_init 之前);此处为单一真值源。
* 维持 1024:8 Socket 共享 24KB 缓冲时,单 Socket 接收缓冲 = 2×MSS = 2KB(手册 §9.2.8
- * 满足上限的最大值)。TC-NET-604 台架验证(2026-09-22,详见 Trap 21):芯片接收冻结角
- * (WCH FAQ:"收不到数据且 TCP 窗口不更新")不受 MSS 裕量影响——降 512 反而更差
- * (新连接 4096B 突发即确定性停摆,剩 64B 未达);MSS=1024 时新连接 4096B 正常,
- * 仅"同连接前序突发 + 新突发 + 任务负载"模式触发。MSS 裕量假设被证伪,恢复 1024
- * (每次满缓冲周期段数少 = 触发概率低)。MSS 只影响芯片分包与窗口动态,
+ * 满足上限的最大值)。MSS=512 裕量方案未采纳;当年支撑该决策的台架判据不可信,
+ * 已随 TC-NET-604 结案为非缺陷一并撤回(2026-09-23,见 Trap 21)——维持 1024 的
+ * 现有理由 = 手册允许的最大值、满缓冲周期段数少。MSS 只影响芯片分包与窗口动态,
* 与下方缓冲块布局解耦。
*/
#define CH395F_TCP_MSS 1024U
@@ -127,10 +125,10 @@ extern "C" {
#define CH395F_RAM_BLOCK_SIZE 512U
/* 单 Socket 缓冲块数:固定布局(2026-09-22 与 MSS 解耦;此前由 MSS 推导,改 MSS 会
* 连带静默缩小布局):接收 4 块=2KB、发送 2 块=1KB,8 Socket × 6 块 = 48 块恰好用满。
- * 布局满足手册 §9.2.8:接收 2KB = 2×MSS(1024)(建议下沿,零裕量——用满 48 块的代价,
- * 其携带的窗口冻结角见 Trap 21)/ ≥ MSS(必须)/ ≤ 6×MSS(建议);
- * 发送 1KB = MSS(WCH FAQ 要求"发送缓冲 > MSS",此处取等值——台架实测芯片在
- * 缓冲边界可正常成包,验证记录见 Trap 21)。 */
+ * 布局满足手册 §9.2.8:接收 2KB = 2×MSS(1024)(建议下沿,零裕量——用满 48 块的代价)/
+ * ≥ MSS(必须)/ ≤ 6×MSS(建议);
+ * 发送 1KB = MSS(WCH FAQ 要求"发送缓冲 > MSS",此处取等值——生产实测(FTP 大文件
+ * 上传/下载 + UI 推流)在缓冲边界可正常成包)。 */
#define CH395F_RECV_BLOCKS 4U
#define CH395F_SEND_BLOCKS 2U
/* 单 Socket 硬件收发缓冲字节数(= 块数 × 块大小)。写入发送 FIFO 的单次长度严禁超过此值,
@@ -145,7 +143,7 @@ extern "C" {
* 导致剩余数据不可见),故总缓冲 = 接收缓冲大小 + 4(4 为命令头开销),
* 有效载荷 = 接收缓冲大小(2KB)。
* 2026-09-22:与 MSS 解耦(此前 = 2×MSS+4,MSS 下调会把 DMA 缓冲缩到装不下整缓冲
- * → 整缓冲读被截断丢弃 → 窗口锁死,见 Trap 21)。
+ * → 整缓冲读会被截断丢弃)。
*/
#define CH395F_SPI_DMA_BUF_SIZE (CH395F_RECV_BUF_SIZE_BYTES + 4U)
#define CH395F_SPI_DMA_MAX_PAYLOAD (CH395F_SPI_DMA_BUF_SIZE - 4U)
diff --git a/Drivers/BSP/NET/net_socket.c b/Drivers/BSP/NET/net_socket.c
index 4ef27543..7ceb232e 100644
--- a/Drivers/BSP/NET/net_socket.c
+++ b/Drivers/BSP/NET/net_socket.c
@@ -168,11 +168,11 @@ static bool s_mac_is_zero(const uint8_t *p_mac) {
* bit3=1: DISCONNECT/TIMEOUT 时不自动清空缓冲区,由软件排空数据后手动关闭 */
ch395f_set_fun_para(0x09);
- /* 设置 TCP MSS(2026-09-22 TC-NET-604:试 512 裕量方案被台架证伪,恢复 1024,见 Trap 21)
+ /* 设置 TCP MSS(维持 1024;512 裕量方案未采纳,当年支撑该决策的台架判据不可信、
+ * 已随 TC-NET-604 结案为非缺陷一并撤回(2026-09-23,见 Trap 21))
* 手册(§5.45):CH395F 内部缓冲共 48 块 × 512B = 24KB。下方为 8 个 Socket 各分配 6 块
* (接收 4 块=2KB + 发送 2 块=1KB),块布局固定(与 MSS 解耦,ch395f.h)。
- * MSS=1024 为满足布局的最大值(接收=2×MSS);MSS 裕量不能消除芯片窗口冻结角
- * (512 方案反使新连接突发也停摆),真值源为 ch395f.h 的 CH395F_TCP_MSS。 */
+ * MSS=1024 为满足布局的最大值(接收=2×MSS);真值源为 ch395f.h 的 CH395F_TCP_MSS。 */
ch395f_set_tcp_mss(CH395F_TCP_MSS);
/* 设置 TCP 重传参数(必须在 INIT_CH395 之前调用;P0-a:周期 500→200ms。
@@ -279,7 +279,7 @@ void net_generation_inc(void) {
* 4. RECV 中断为电平触发,每次 net_poll() 只处理一批中断,避免主循环饿死
*/
#if defined(NET_BENCH_CMD_LOG)
-/* Bench:芯片命令序列日志(2026-09-22 Trap 21 精确定位;netTask 上下文)。
+/* Bench:芯片命令序列日志(2026-09-22 排障台架工具,默认关;netTask 上下文)。
* 每个真实 SPI 命令点一行:tag=命令类别(P=poll全局中断 R=recv S=send C=close
* A=accept L=listen N=connect U=relisten M=其他),fd=socket,t=FreeRTOS tick,
* d=距上一条命令的 tick 间隔,x=结果/中断状态。台架专用,实验后回退。 */
diff --git a/docs/待处理内容.md b/docs/待处理内容.md
index 6da0f590..062561d9 100644
--- a/docs/待处理内容.md
+++ b/docs/待处理内容.md
@@ -9,11 +9,10 @@
| # | 事项 | 发现 | 证据与现状 | 出处 |
|---|---|---|---|---|
-| N-1 | **TC-NET-604:芯片"缓冲恰好填满 + 排空"后 RX 窗口冻结(根因已确认,代码侧已闭环)**——同连接前序突发(64B×10+1460B)后 4096B 突发:前 2KB 正常回显,其余永不被芯片确认/交付,停摆 10s、无 RST、缓冲全程空、窗口不更新;断开重连后恢复正常(台架 10/10 复现,F1 组合) | 2026-09-22 17:00/17:03(L3 台架 F1 组合) | **根因 = CH395F 片内 TCP 状态机角(WCH 官方 FAQ 留档的已知局限,W5500 同类),非我方代码缺陷**:① 驱动"超限读静默丢弃"排除(DMA 缓冲 2052B 可容整缓冲,失败运行 0 次丢弃事件)② L3 排除(A/B 逐字节同现)③ "RX>2×MSS" 裕量假设**证伪**——MSS=512 实验原序列 10/10 仍停摆,且新连接 4096B 确定性停摆恒剩 64B(已回退,维持 MSS=1024:新连接 4096B 31ms 正常)。复现探针(本地未跟踪工件,MDK-ARM/ 下):完整序列 = `test/ch395f_socket_test.py tcp_client --ip 192.168.1.100 --port 8080 --count 10`(F1 组合构建);独立 4096B = `MDK-ARM/probe_4096.py`。代码侧闭环(已提交):缓冲块布局与 MSS 解耦 + 超限读 OVERSIZE 金丝雀 + 注释留痕。**2026-09-22 精确定位轮定案(11 组台架 110+ 运行 + netcmd 命令序列日志)**:真致命类 = **部分窗口重通告(排空后缓冲残留)**——大 Δ 部分排空(1KB 块读,C/C0 配方)10/10 确定性停摆(零第二命令也致命);小 Δ(64B)部分读呈相位刀口(一次性落点 10/10 过 vs 5/5 停摆仅数 ms 时移之差)且持续重复必停摆(S1–S4/V1/V1F 50/50);排空至空(窗口→满)与 Δ=0 状态读/TX 恒安全(40/40+,含 10ms 节拍 E0)→ 本条停摆**存在 MCU 侧修复路径**(N-7 = 非阻塞 RX 读强制排空至空,无需时间守卫);数据预算缩短保留为兜底方案(N-7 落地后本决策项紧迫性下降)。同台架副产品见 N-6。**残留决策项**:冻结不自恢复(唯一恢复 = 断连 + 客户端重试,重连路径台架已验证);lftpd 数据通道停摆预算现为 30s/读(`LFTPD_TOTAL_BUDGET_MS`,与控制行共用)——是否将数据通道单独缩短至 10–15s 以压缩停摆暴露(代价:慢速健康传输亦被中断;机器客户端不受影响)待用户决策 | `CH395F_Trap_Records.md` Trap 21;`错误码传播审计.md` E-02;`链路延迟测试说明.md` §6.3 |
+| N-1 | **✅ 已结案(2026-09-23):TC-NET-604"接收缓冲填满后 RX 窗口冻结"判定为非缺陷**——原报告(阶段 8:前序突发后 4096B 突发仅前 2KB 回显、其余无回显)在当前固件**不可复现**:真实生产路径(产品固件 + 真 lftpd FTP 上传,判据 = FTP 协议结果 + **上传后 RETR 回读 SHA-256**)**227 轮全过**(8KB/64KB/256KB/1MB,含零间隔快速重连与 100 轮浸泡),并发生产 UI 流 600 帧 CRC 全过,设备侧无 FAIL/ERROR/WARN。原台架"停摆"系**测试程序自吞数据**(Phase 9/11 的 64B 读、固件探针读走不回显;短收量恰等于被吞字节数)+ **判读工具误判**(`probe_classify.py` A/C 把通过运行报成 STALL,C0 脚本层实测 1460/1460 全匹配)——详见 `CH395F_Trap_Records.md` Trap 21"教训"节。**原残留决策项(数据通道预算缩短)随之关闭** | 2026-08-26 发现 / 2026-09-23 结案 | 结案依据与台架纪律见 Trap 21;真实路径工具 `MDK-ARM/ftp_freeze_probe.py`(上传+回读哈希)、判读 `MDK-ARM/bench_verdict.py`;同类真实缺陷见 Trap 23(已修复) | `CH395F_Trap_Records.md` Trap 21;`CH395F_Test_Guide.md` TC-NET-604 |
| 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-3 | **L5 队列往返基线(1223/988µs)的 L3 后重验**——L5 测 DONTWAIT 队列全程;L3 对该路径逐位不变、pending tick 无 pending 时为 µs 级指针读 → 机制上无影响,但基线数值属分片时代,严格重锁需跑一轮 Phase 13(需 PC peer) | 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 | **⛔ 已撤回(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 块循环 |
| N-8 | **✅ 已修复(2026-09-23 当日闭环):Trap 23 上传中止后首笔复连上传被静默截断(≤2048B)并误报成功**——修复前可信复现 15/15(RST 10/10 + 优雅 FIN 5/5);修复后 RST **10/10**、FIN **5/5** 全通过,正常路径回归 30/30 + 20/20(SHA-256 全匹配)。**真因**:中止时对端仍有在途数据 → 芯片 TIMEOUT 后才把在途段落进 RX 缓冲(约 2048B 残渣)→ 立即复监听时残渣被下一条连接当作自己的数据读走(新上传只"收"2048B 就判结束并回 226)。**修复**:异常释放(TIMEOUT)的 socket 复监听前隔离(持续排空 RX 残渣 + 主动 close + 等 CLOSED/TCP_CLOSED),400ms 起、800ms 上限强制放行(上限须 < 重试放弃时限 2000ms,否则监听被放弃,已实测修正);`net_drain_chip_rx()` 分块读空、零新增静态缓冲;仅异常路径生效,正常 FIN 路径零改动。详见 Trap 23"修复实施与验证"——生产路径 FTP STOR 中途断开(RST 或 FIN 均可)后,紧跟的第一笔复连上传被截断到 ≤2048B(芯片单 socket RX 缓冲)且回报 226 成功 → 客户端认为上传成功 = 静默数据损坏;第二笔起恢复正常 | 2026-09-23(可信复现 + 当日修复闭环;`MDK-ARM/ftp_abort_probe.py` 自动判定) | 已实施:`net_socket.c` 新增 `s_relisten_quarantine[]`(`handle_timeout_event` 置位)+ `net_drain_chip_rx()` + `net_relisten_locked` 隔离门(`NET_RELISTEN_QUARANTINE_MS`=400 / `NET_RELISTEN_SETTLE_MS`=800 < `NET_RELISTEN_DEADLINE_MS`=2000) | `CH395F_Trap_Records.md` Trap 23;`Drivers/BSP/NET/net_socket.c`(`net_relisten_locked` / `handle_timeout_event` / `net_drain_chip_rx`) |
## 存储 / 日志管线
diff --git a/docs/测试说明/CH395F_Test_Guide.md b/docs/测试说明/CH395F_Test_Guide.md
index 605450fa..dc777c49 100644
--- a/docs/测试说明/CH395F_Test_Guide.md
+++ b/docs/测试说明/CH395F_Test_Guide.md
@@ -643,16 +643,10 @@ sequenceDiagram
**通过标准**:4096B 完全匹配。任一失败 → 标记 FAIL
**覆盖原则**:DP-04(2KB 接收缓冲边界 + 单次 DMA 上限) |
-> **✅ 2026-09-23 首选复现方法(可信)**:走**真实生产路径**——产品固件 + 真 lftpd FTP 上传,判据 = FTP 协议结果 + **上传后 RETR 下载比对 SHA-256** + 卡住时用**控制通道 NOOP** 探测存活;工具 `MDK-ARM/ftp_freeze_probe.py`(`--size/--rounds/--gap`)。首轮结果:177 轮全过(8KB~1MB,含零间隔快速重连与 100 轮浸泡),并发 UI 流 600 帧 CRC 全过 → 当前固件未复现。**探针类配方(Phase 9/11、固件内 64B 探针)禁止再用于冻结判定**(其短收 = 固件读者吞掉对端数据)。
->
-> **⛔ 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 系列);
-> - **Phase 6-only 构建禁止无间隔连跑**:<~1s 重连间隔会触发 Trap 22 失同步(自 run2 起:无 standalone accept、`send -1`、其后全部 connection refused)——快速重连场景须用带第二 RX 路径的构建或留 15s 间隔;
-> - **MSS/块配额改动前**:先跑复现序列(基线 = 10/10 停摆,为芯片侧已知角,改动后不得恶化/不得出现新停摆模式)+ 新连接独立 4096B 对照(必须过,MSS=512 实验在此失败被回退)+ Phase 6-only 15s 对照(必须过)。
-> - **注意**:停摆主因已定案为 **部分窗口重通告**(部分排空致缓冲残留——大 Δ 确定性致命、小 Δ 相位刀口/持续重复必停摆),与命令条数/窗口时长无关——存在 MCU 侧修复方案(`docs/待处理内容.md` N-7 = 非阻塞 RX 读强制排空至空,无需时间守卫,未实施);N-7 落地前勿以"芯片侧不可修"为由调整几何参数。
+> **2026-09-23 结案**:TC-NET-604 的"缓冲满回显"路径**判定为非缺陷**——真实生产路径(产品固件 + 真 lftpd FTP 上传,判据 = FTP 协议结果 + **上传后 RETR 回读 SHA-256**)实测 **227 轮全过**(8KB~1MB,含零间隔快速重连与 100 轮浸泡),并发生产 UI 流(`:7003`)600 帧 CRC 全过;原台架"停摆"系**测试程序自吞数据 + 判读工具误判**(详见 `CH395F_Trap_Records.md` Trap 21"教训"节)。
+> - **本用例判据(不变)**:PC 发 4096B → 固件分次取空并回显 → **PC 侧内容完全匹配**即 PASS;上传/中止类真实缺陷见 **Trap 23**(回归工具 `MDK-ARM/ftp_abort_probe.py`)。
+> - **台架纪律**:判读一律用 `MDK-ARM/bench_verdict.py`(脚本层 STEP 行为真值,并扣除固件读者吞噬的字节);`probe_classify.py` 的 A/C 判定**不可信**;**禁止**把"固件内非回显读者"(Phase 9/11、固件探针)与固定期望值混用在同一配方里。
+> - **Phase 6-only 构建禁止无间隔连跑**:<~1s 重连间隔会触发 Trap 22 失同步(自 run2 起:无 standalone accept、`send -1`、其后全部 connection refused)——快速重连场景须留 ≥15s 间隔;带 Phase 9/11 的构建会被其读者吞数据,不能当对照。
### TC-NET-605: 断开重连
diff --git a/docs/测试说明/链路延迟测试说明.md b/docs/测试说明/链路延迟测试说明.md
index e42f4494..33d809ff 100644
--- a/docs/测试说明/链路延迟测试说明.md
+++ b/docs/测试说明/链路延迟测试说明.md
@@ -318,8 +318,9 @@ DTU-RemoteLCD 客户端;输出每帧 `req2first / total / recv 批次到达时
## 6. 实测基线(2026-09-22 台架,已重锁)
-> 2026-09-22 TC-NET-604 闭环注记:该轮代码变更(缓冲块布局与 MSS 解耦 + 超限读 OVERSIZE 金丝雀,见 Trap 21)
+> 2026-09-22 注记:该轮代码变更(缓冲块布局与 MSS 解耦 + 超限读 OVERSIZE 金丝雀,见 Trap 21)
> 不改变任何芯片行为参数(MSS=1024、块布局 4/2、DMA 缓冲 2052B 均不变)→ 本节全部基线继续有效,无需重锁。
+> (2026-09-23 补:Trap 21 的"RX 冻结"结论已结案为非缺陷,该轮代码变更按防御性/可观测性改进保留。)
### 6.1 M1 段(Phase 12,SPI 层)
@@ -702,8 +703,7 @@ sock4 auto-relisten ok / relisten retry ok ← 监听器随后自行恢复
6. **S4** 发送块配额与 MSS:48 块按实际使用的 3 个 socket 重新分配(各 16 块),MSS → 1460
(3209B 从 4 段降到 1~2 段);**约束**:单次写长度必须 ≤ 发送缓冲(Trap 20 铁律),
改分配策略需同步 `net_bind` 重复分配路径,改前先读 `CH395F_Trap_Records.md`,改后跑 Phase 8 吞吐用例;
- **另(Trap 21)**:MSS 是芯片 RX 冻结角的敏感变量(MSS=512 实验使新连接 4096B 突发也停摆,已证伪回退)——
- 任何 MSS/块配额变更必须先跑 TC-NET-604 复现序列(`test/ch395f_socket_test.py tcp_client` 全序列)+ 独立 4096B 对照,全 PASS 方可采用;
+ **另**:MSS/块配额变更**必须**跑可信用例(`test/ch395f_socket_test.py tcp_client` 全序列 + 新连接独立 4096B 对照),判据 = **客户端侧内容完全匹配**(勿用带固件内读者的台架配方,其短收是读者吞数据不是故障);
7. **S5** 去掉一次 3200B 拷贝(`g_tx` 直接承接位图,省 ~3.2KB 常驻 RAM;改前跑 `scripts/ram_report.py`);
8. **S7** uiTask:`ui_net_sink_poll()` 前置到 `ui_port_step` 前 + while 排空(省按键一整拍);
9. **S8** 日志改非阻塞(`fputc` → 环形缓冲 + TX 中断/DMA;处理溢出丢弃与 HardFault 冲刷);
diff --git a/docs/问题记录/CH395F_Trap21_机制图解.md b/docs/问题记录/CH395F_Trap21_机制图解.md
deleted file mode 100644
index baa3e0f7..00000000
--- a/docs/问题记录/CH395F_Trap21_机制图解.md
+++ /dev/null
@@ -1,185 +0,0 @@
-# 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(精确定位轮定案后)。
-
-## 0. 一句话
-
-CH395F 每个 socket 有一个 2KB 收货货架;**MCU 每次取货必须一次取空**。只要"取一半、留一半",芯片的 TCP 引擎就可能走进死角、**永久封死它的发送嘴**——它还能收货(RX 正常),但再也发不出一个字节(回显、ACK、窗口更新全停),连接却不 RST。对端看到的就是"静默死亡"。
-
-## 1. 现场长什么样
-
-- **PC 侧**:传输到一半,设备回显/应答戛然而止(0 字节),但 TCP 连接**没断**——PC 还能发数据,设备侧也照收。
-- **PC 的 TCP**:窗口停在 0 不动,剩余数据卡在 **PC 自己的发送缓冲**里(不是"重传失败",是在**等一个永远不会更新的窗口**),等 10 秒、100 秒都一样。
-- **设备侧**:MCU 一点异常都没有——SPI 命令照发、节奏 10ms 不变、芯片照收数据、连接 ESTABLISHED、无 FAIL/ERROR。
-- **唯一恢复方式**:对端断开重连(新连接 = 新 socket = 干净状态)。
-
-这是最难查的那类故障:**所有软件指标都健康,功能已经死了**。
-
-## 2. 芯片里到底发生了什么(比喻版)
-
-### 2.1 货架 + 告示牌
-
-- 每个 socket 有 **2KB 收货货架**(RX 缓冲)。
-- 货架旁挂**告示牌**:TCP 窗口 = 货架剩余空位(手册 L1281)。
-- 对端是守规矩的快递员:**告示牌写多少空位,他就塞多少货**。所以只要 MCU 不及时搬,货架必然被塞满(2048/2048,窗口 = 0)——这是"结构性必达",躲不开。
-- MCU 是搬运工:定期 `net_recv` 把货搬进屋。
-
-### 2.2 "搬空"与"搬一半" = 芯片的一次对账
-
-搬运工每搬走一批货,芯片都要做一次**对账**(重算空位 → 改写告示牌 → 更新 TCP 序号,即"窗口重通告 / 再武装"):
-
-```mermaid
-flowchart TD
- A["对端把 2KB 货架塞满
窗口 = 0"] --> B["MCU 发起取货
READ_RECV_BUF"]
- B --> C{"取完后货架上还有货吗?"}
- C -->|"没有(取空)
告示牌 → 2048"| D["芯片对账一次到位
✅ 正常循环
40/40 全过,含 10ms 快取"]
- C -->|"有残余 N 字节
告示牌 → 部分值(非 0 非满)"| E["芯片对账被打断
❌ 发送引擎永久锁死"]
- E --> F["SPI 写回显仍返回成功
但线上 0 字节
ACK / 窗口更新全停"]
- F --> G["对端窗口永远停在 0
剩余数据卡在对端发送缓冲
连接仍 ESTABLISHED(无 RST)"]
-```
-
-| 搬运方式 | 告示牌变化 | 芯片状态 | 台架结果 |
-|---|---|---|---|
-| **搬空**(货架 0,告示牌 2048) | 一次到位 | 对账干净结束 | ✅ 任意节拍安全(10/20/40/60ms,40/40) |
-| **搬一半**(留 436,告示牌 588→1612 这种"半吊子"数字) | 改到"部分值" | 对账被打断,引擎走进死角 | ❌ 可能永久封嘴(大 Δ 必然,小 Δ 看落点) |
-
-**关键:芯片怕的不是"货架满",也不是"搬得慢",而是"取货取一半、在货架上留下残余"这个动作本身。**
-
-### 2.3 嘴被封死,耳朵还灵(单向死亡)
-
-- **发送引擎彻底锁死**:MCU 通过 SPI 把回显写进芯片发送缓冲,芯片回答"收到了"(SPI 写成功、字节数正确),**但线上一个包都不发**;ACK、窗口更新一并停止。
-- **接收引擎完全正常**:继续收、继续被 MCU 搬空(命令序列日志实证:冻结之后到达的数据,芯片照收、MCU 照搬,10ms 命令节奏完整)。
-- 连接双方都认为"连接还在"(无 RST)→ 对端只能看到"对方不说话了"。
-
-### 2.4 为什么 64B 是"刀尖",1KB 是"必死"
-
-芯片的对账动作有几个内部小阶段(子相位),像齿轮咬合的缝隙:
-
-- **小 Δ(一次只搬 64B)**:告示牌只改一点点,落点撞上缝隙就出事、错开就没事——这就是**相位刀口**:
- - 同一套"满排空 + 一次性 64B 部分读"配置:**非日志构建 10/10 全过**;
- - 只打开命令日志、netTask 时序挪了几毫秒 → **5/5 全部封嘴**。
- - 但**反复搬**(每 10ms / 60ms 搬一次 64B)→ 几十上百次总有撞上 → **50/50 必死**(6 套构建、5 种节拍)。
-- **大 Δ(一次搬 1KB,= 生产 lftpd 块读)**:告示牌大幅改写,缝隙躲不开 → **10/10 确定性封嘴**;而且**哪怕 10ms 后立刻把剩下的 436B 也搬空,也救不回来**(C0 对照实测)——伤害在"取一半"那一瞬间就已造成。
-
-### 2.5 为什么"只读状态"没事
-
-只问"还有多少货"(空读长度)、只读中断标志(poll)、只往发送缓冲写回显(TX)——**货架一个字节没动,告示牌不用改**:
-
-- 台架:Δ=0 状态读(0.4 秒内连读约 40 次)+ 每 tick 的 poll + 每次排空后的 TX,**全部 40/40 干净**。
-
-所以修复方案里这些**不需要拦**——拦了只会白增延迟。
-
-## 3. 台架证据一览
-
-| 行为 | 结果 |
-|---|---|
-| 每次搬空,10/20/40/60ms 节拍(任意 Δ:64B/1460B/2048B) | ✅ 40/40 |
-| Δ=0 状态读 / poll / TX | ✅ 40/40+ |
-| 满排空 + **一次性** 64B 部分读(非日志构建) | ✅ 10/10(相位运气) |
-| 同上 + 命令日志(时序挪几毫秒) | ❌ 5/5 封嘴 |
-| 满排空 + **每 tick** 64B 部分读(10/90/130/170/60ms,6 套构建) | ❌ 50/50 封嘴 |
-| **部分排空(1460 里搬 1024、留 436),零第二命令** | ❌ **10/10 封嘴** |
-| 部分排空 + 一次性 64B 再读 | ❌ 10/10 封嘴 |
-| 快速重连链(20 连接、0.6s 间隔) | ✅ 20/20("重连预置"假说证伪) |
-
-再武装脆弱区间实测**下界 ≥160ms**(+0/+80/+120/+160ms 偏移位均致命),且相位敏感 → 不存在"可移植的单值时间窗"。
-
-## 4. 为什么生产一定会踩:代码里的"正常写法"
-
-问题在于:**"我筐多大就读多少"是 socket 编程的标准写法**,而 CH395F 恰恰惩罚这个写法。net 层有 **5 处**同型读路径(每一处单独看都写得完全正确):
-
-| 位置 | 谁在用 | 一次要多少 | 说明 |
-|---|---|---|---|
-| `net_recv_locked`(net_socket.c:1203-1209) | 非阻塞 / 有数据即返的读 | 调用方 `len` | **主触发**:`read_len = min(货架现有, len)` |
-| `net_pending_tick` ① 数据到达(1512-1518) | pending(阻塞)读完成 | 调用方 `len` | 同型 |
-| `net_pending_tick` ③ 断连排空(1534-1540) | 断连前最后一次排空 | 调用方 `len` | 同型 |
-| `net_pending_settle_close`(1615-1618) | close 前排空 | 调用方 `len` | 同型 |
-| `net_recvfrom`(2047-2073,UDP) | UDP 读 | 调用方 `len` | 同型 |
-
-而调用方给的筐,天生就小:
-
-| 调用方 | 筐 | 场景与风险 |
-|---|---|---|
-| `lftpd.c:187` `receive_file`(数据通道 STOR) | **1024B** | 每 1KB 一次 → 大 Δ 部分排空 = **10/10 必死**(生产停摆本体) |
-| `lftpd_inet.c:130` 控制行读 | `buffer_len-1`(行缓冲) | 客户端流水线发命令时留残余 |
-| `ui_net_sink.c:40` UI 帧 | **64B** | UI 帧大于 64B 就留残余 |
-| `time_sync.c:96` 时间包 | **16B**(栈上) | 多包/重传时留残余 |
-
-**结论:只修 lftpd 那一处不够**——控制行、UI、时间同步都是同一颗雷,且以后新写的读取方会再踩一次。这就是"必须在 net 层做成结构性不可能"的理由。
-
-## 5. 解决方案
-
-### 5.1 核心规则
-
-**MCU 每一次从芯片货架取货,都必须一次取空。** 上层要小口吃,就让 net 层先把货整批取进"中转筐",再一勺一勺喂给它。
-
-### 5.2 落点:5 处 `min()` 收敛成一个助手
-
-net 层新增 `net_drain_recv(sockfd, buf, len)`,替换第 4 节表中的 5 处:
-
-1. **共用中转槽**里若有本 socket 的余量 → **直接交付**(不发芯片命令);
-2. 槽空闲 → `avail = ch395f_get_recv_len(fd)`(Δ=0,安全);
-3. **按 `avail` 全量读空**进槽(`read_len == avail`,恒排空至空);
-4. 拷 `min(avail, len)` 给调用方,**余量留在槽里**(登记 owner fd / 偏移 / 长度),下次直接交付;
-5. 槽被**别的** socket 占用 → **暂缓本次读**(不发芯片命令),DONTWAIT 返 WOULDBLOCK、pending 保持等待。
-
-驱动层无需改动(一次 SPI 事务本来就能搬满 2KB)。
-
-### 5.3 中转筐设计:**一个共用槽就够**(+3KB,不是 8KB)
-
-**可以共用。** 共用的安全性不靠"没人同时用",而靠一条铁律:**槽被占用时,别的 socket 就不发芯片命令**(DONTWAIT 返 WOULDBLOCK、pending 继续等)——不发命令 = 不产生残余 = 不会封嘴。**共用只影响等待时间,不影响安全。**
-
-但要共用,必须先让**热路径自己不占槽**:
-
-| 读方 | 筐 | 处理 |
-|---|---|---|
-| lftpd 数据通道(STOR,唯一大流量) | 1024B → **2048B(+1KB,`lftpd.c:187`)** | 货架最多 2048B,`len=2048` ⇒ `min(avail,len) == avail` ⇒ **天然读必读空**,永不入槽、永不参与争用 |
-| lftpd 控制行读(`read_buffer[512]`) | 512B | 共用槽(客户端流水线发命令时才留残余) |
-| UI sink(`RM_RX_BUF=64`) | 64B | 共用槽(帧大于 64B 时) |
-| 时间同步(栈上 16B) | 16B | 共用槽 |
-
-- **为什么热路径不能共用**:它的循环是 `net_recv → f_write(NAND) → net_recv`,而 NAND 写入有长尾(GC/擦除;本仓库已记录过百毫秒级停顿)。若它占着共用槽去写盘,**其他 socket 全部读不了**(FTP 控制通道哑掉、UI 卡顿)→ 所以给它自带 2KB 筐,直接退出争用。
-- **冷读方的占槽时间**:读 → 解析 →(必要时)发应答,全是 CPU 短动作(控制行 = 解析 + `net_send`,TX 命令不碰货架;UI = 逐字节喂解析器 + 失效重绘,真正渲染由 LVGL 后续处理;时间同步 = 解析 8B),毫秒级;而这几个通道的预算都是 30s 级,完全容忍。
-- **RAM 账**:共用槽 2048B + 数据通道加筐 1024B = **+3KB**(主 SRAM 余量 47.2KB,占 6.3%)。若现场显示确有争用,把槽数 1 → 2(+2KB)即可,是一行改动。
-- **可观测性**:因槽被占而暂缓时记一次限频日志(如 `stage busy fd=N`),别让"变慢"成为新的黑盒。
-- 上层**零改动**(除 lftpd 数据筐 1024→2048):调用方筐大小与每次拿到的字节数范围都不变 → 解析逻辑不受影响。
-
-**被否决的"零槽方案"**(所有调用方自带 2KB 筐、完全不设槽):账上要 **+6.5KB**(数据 +1KB、控制行 512→2048 需 +1.5KB、UI +2KB、时间同步 +2KB),而且控制行读必须重构成"带余量的行读取器"(`lftpd_inet_read_line` 一旦找到 `\r\n` 就返回,多读进来的流水线命令会被丢弃),要改 4 个子系统且没有强制手段——比 +3KB 的共用槽更贵、更脆。
-
-### 5.4 被否决的方案(及原因)
-
-| 方案 | 为什么不选 |
-|---|---|
-| 各调用方把筐加大到 2KB、一次读 2KB | ① 5 个调用方都要改,且控制行读会**丢流水线命令**(找到 `\r\n` 就返回,多读进来的后半段被丢弃);② 没有强制手段,未来新调用方会再踩;③ UI / 时间同步加筐纯属浪费 |
-| 让驱动把残余留在 SPI DMA 缓冲里 | DMA 缓冲被**每一次 SPI 事务复用**(poll、TX、别的 socket),残余会被静默覆盖 → 更隐蔽的数据损坏 |
-| 读了不交付(把残余丢掉) | 文件传输直接损坏,不可接受 |
-
-### 5.5 明确**不需要**的东西
-
-- ❌ 不需要"排空后暂缓 RX 命令 + 120ms 冷却"(旧 N-7 方案作废):只要"读必读空",压根不存在残余窗口;C0 证明部分排空**自身**即致命(冷却救不了第一条命令),E0 证明排空至空后 10ms 再排空也安全(冷却纯属多余)。
-- ❌ 不需要拦状态读 / poll / TX(实测安全),保住 10ms 级低延迟。
-
-### 5.6 回归判据(改完必须过)
-
-1. **C/C0 配方**(64×10 + 1460B 填充 + 1024B 部分排空):修复前 10/10 封嘴 → 修复后 **10/10 通过**;
-2. **V1 配方**(Phase 6+11 + 60ms 节拍):修复前 10/10 封嘴 → 修复后 **10/10 通过**;
-3. **E 系列**(排空至空,10/20/40/60ms):保持 **40/40 通过**;
-4. 产品态 FTP 大文件上传(>2KB)浸泡:不再出现"回显中断但连接不断"。
-
-## 6. 给非工程读者的一句话交底
-
-芯片里有一条怪规矩:**取货必须一次取空**。取一半,它就可能把嘴封死——还能收货,但再也不说话,而连接显示一切正常。我们的上传程序按标准写法"一次取 1KB",正好踩上。修法同样直白:**每次取货都取空,先放进自己的中转筐,再慢慢喂给程序**;实测这样 10ms 一次快取也平安无事。
-
-## 7. 相关文件
-
-- 定案与逐组台架数据:`docs/问题记录/CH395F_Trap_Records.md` Trap 21
-- 修复条目(待批准实施):`docs/待处理内容.md` N-7
-- 复现/对照规则:`docs/测试说明/CH395F_Test_Guide.md` TC-NET-604
-- 涉及代码:`Drivers/BSP/NET/net_socket.c`(5 处读路径)、`Drivers/BSP/NET/lftpd/lftpd.c`、`Drivers/BSP/NET/lftpd/lftpd_inet.c`、`Drivers/BSP/UI/ui_net_sink.c`、`App/time_sync.c`、`Drivers/BSP/CH395F/ch395f.c`(`read_recv_buf` OVERSIZE 金丝雀)
diff --git a/docs/问题记录/CH395F_Trap_Records.md b/docs/问题记录/CH395F_Trap_Records.md
index da4b8b21..75b4289a 100644
--- a/docs/问题记录/CH395F_Trap_Records.md
+++ b/docs/问题记录/CH395F_Trap_Records.md
@@ -537,81 +537,28 @@ NET 层 TCP Client(阶段 7)`net_connect()` 返回 0,但 `net_poll()` 报
### 发现时间
阶段 8 大文件传输实现,2026-08-26。
-## Trap 21:接收缓冲"恰好填满 + 排空"窗口冻结(TC-NET-604)
+## Trap 21:接收缓冲"恰好填满 + 排空"窗口冻结(TC-NET-604)—— **结论:非缺陷(2026-09-23 结案)**
-> **⚠️ 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 撤回标注)。
-> 8. **可信复现首轮(2026-09-23)**:改用**真实生产路径**——产品固件(无测试套件、**无任何固件探针**)+ 真 lftpd FTP 上传,判据 = FTP 协议结果 + **上传后 RETR 下载比对 SHA-256**(内容真值)+ 卡住时用**控制通道 NOOP** 区分"数据 socket 卡死 vs 整层卡死"(工具 `MDK-ARM/ftp_freeze_probe.py`,判据天生免疫"固件读者吞数据"假象)。结果:**177 轮全过**(8KB×10、64KB×10/20/100、256KB×5、1MB×2;含零间隔快速重连与 100 轮浸泡),SHA-256 全匹配;并发 UI 流(`:7003`,600 帧)CRC 600/0 全过;设备侧日志无 FAIL/ERROR/WARN(仅每轮数据 socket 正常 `auto-relisten ok`)。→ **当前固件在该组条件下未复现现场冻结**;现场现象是否已被 2026-09-20 起的一系列修复(Trap 09 重监听重试 / L3 pending 化 / D20 / 自动重监听)顺带消除,或需更极端的客户端行为,待进一步验证。
+### 结案结论
+原报告(阶段 8 大文件传输期间:同连接前序突发后 4096B 突发"前 2KB 正常回显、其余静默无回显")**在当前固件上无法复现,判定为非缺陷**。可信判据(产品固件 + 真实 lftpd FTP 上传,成功 = FTP 协议结果 + **上传后 RETR 回读比对 SHA-256**)实测:**227 轮全过**(8KB/64KB/256KB/1MB;含零间隔快速重连与 100 轮浸泡),并发生产 UI 流(`:7003`)600 帧 CRC 全过,设备侧日志无 FAIL/ERROR/WARN。
-### 现象
-单条 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 维持。
+### 为什么原台架会"复现"——**教训,务必先读**
+2026-09-22"精确定位轮"给出的**全部"冻结/停摆/WEDGE"结论均为台架假象,已撤回**:
+1. **测试程序自吞数据**:台架配方里的固件内读者(Phase 9/11 的 64B 读、固件探针读)把对端数据读走后**不回显**——PC 端自然少收,被误当成"设备停摆"。实测短收量**恰等于被吞字节数**(例:`4736−4608 = 128 = 2×64` 探针读);所谓"V1 配方必冻结"就是 Phase 11 吞掉整包(设备日志 `avail=64 len=64`,PC 侧下一轮 `rx=0/64`)。对照组(仅 Phase 6、无额外读者)40/40 全过。
+2. **判读工具误判**:`probe_classify.py` A/C 模式把**通过**的运行报成 `STALL`(C0 的脚本层实测为 `1460/1460` + 尾段 `2100/2100`,且内容逐字节匹配)。
+3. 由此派生的"部分排空致命 / 再武装区间 ≥160ms / 相位刀口 / C 配方复现生产停摆"等结论**全部作废**;MSS=512 实验的"停摆"亦未经可信判据复核。
-> **通俗图解与修复方案**(比喻版机理 + net 层"读必读空"设计 + 代码落点 + RAM 账):见 `CH395F_Trap21_机制图解.md`。
+### 现在怎么做(台架纪律)
+1. 判读一律用 `MDK-ARM/bench_verdict.py`:**以脚本层 STEP 行为真值**,并扣除固件读者吞噬的字节;
+2. 冻结/卡死类问题走**真实生产路径 + 端到端内容校验**:`MDK-ARM/ftp_freeze_probe.py`(FTP 上传 + RETR 回读 SHA-256);卡住时用**控制通道 NOOP** 区分"数据面卡死"与"整层卡死";
+3. **禁止把"固件内非回显读者"与固定期望值混用在同一配方里**——这是本轮最大的教训。
-### 根因
-CH395F 片内 TCP 状态机的角(芯片固件,MCU 侧无法修补)。2026-09-22 精确定位轮(11 组台架、110+ 运行、芯片命令序列级 netcmd 日志)定案:致命变量是 **RX 排空的结束态(排空后缓冲是否残留)**,与命令条数/类型/窗口时长无关(逐组实证见下):
+### 保留的代码变更(与被撤回的机理无关)
+缓冲块布局与 MSS 解耦(`ch395f.h`)、超限读 OVERSIZE 金丝雀(`ch395f.c`)保留:属防御性/可观测性改进,不回退。
-1. **结构性前提**:窗口=剩余空间(手册 L1281)→ 守规矩的对端永远把窗口灌满 → 每个稳态轮次缓冲**恰好填满**(2048/2048,窗口=0)是结构性必达状态,无法通过几何裕量规避。
-2. **冻结机制(实证签名)**:MCU 的 RX 数据读命令使芯片 RX 缓冲**残留非空**(窗口重通告到部分值——既非 0 也非满)时,芯片 TCP 再武装状态机被破坏:**芯片发送路径永久死亡**(已写入发送缓冲的数据永不出线——SPI 写被接受但线上无段,ACK/窗口更新随之停止),**接收路径与 MCU 侧 SPI 交互完全健康**(命令序列日志:冻结后 MCU 命令流节奏完整,继续到达的数据芯片照常接收、MCU 照常排空),连接保持 ESTABLISHED → 单向死亡;对端剩余数据滞留对端发送缓冲(窗口视图冻结在 0)。WCH 在 CH395 系列官方 FAQ 留档了同类现象:"接收缓冲区需要大于 2 倍设置的 MSS 值,否则……若对端设备不会根据 tcp 窗口来分包发送数据时,有可能会造成 CH395 收不到数据且 TCP 窗口不更新现象"(www.cnblogs.com/sw111/p/18750601,2025-03);WIZnet W5500(同类:每 Socket 小型缓冲 + 片内 TCP + 窗口=剩余空间)官方文档同为"缓冲满则挂起连接等待空闲空间"模型,zero-window 停摆是该类芯片的经典病理(docs.wiznet.io W5500 TCP Application 文档;Wireshark 论坛 49849 实例)。
-3. **致命性模型(2026-09-22 精确定位轮:11 组台架、110+ 运行、芯片命令序列级 netcmd 日志;逐组实证,非日志/生产时基;Δ = 本次读移走的字节数,"残留" = 排空后缓冲剩余)——取代下方旧"三因子/50–100ms"模型**:
-
- | RX 读模式(构建) | n | 结果 |
- |---|---|---|
- | 排空至空(窗口→满),10/20/40/60ms 节拍,任意 Δ(64/1460/2048B;E 系列) | 40/40 | **全过**(含 10ms 节拍 E0:满→空→满 正常循环,排空后 10ms 再排空安全) |
- | Δ=0 纯状态读(GET_RECV_LEN 空读 / SINT 中断读 / poll 每 tick)与 TX 命令(E 系列 / B 系列 0.4s 静置 ~40 次状态读) | 40/40+ | **全过**(任何偏移/密度) |
- | 满(零窗)排空 + 一次性 64B 部分读 @~50ms(v3 O1,10ms 栅格) | 10/10 | 过(相位刀口,见下) |
- | 同上 + netcmd 命令日志(netTask 时移数 ms,O1f) | 5/5 | **全冻结**(一次性落点相位翻转) |
- | 满排空 + 每 tick 64B 部分读(持续 Δ=64):10ms(S1) / 90ms(S2,+80ms) / 130ms(S3,+120ms) / 170ms(S4,+160ms) / 60ms(V1、V1F) | 50/50(6 构建) | **全冻结**(每事件相位风险累积) |
- | **部分排空(1460 中排 1024、留 436 残留)、零第二命令(C0)** | **10/10** | **全冻结(第一条命令即致命)** |
- | 部分排空 + 一次性 64B 部分读(C) | 10/10 | 全冻结 |
- | 快速重连链(20 连接、0.6s 间隔、窗口内状态读 + canary;F1 链) | 20/20 | 全过("快重连预置"假说证伪) |
-
- → **部分窗口重通告(排空后缓冲残留)= 致命类**:小 Δ(64B)呈**相位刀口**——残留态持续 ~10ms 多为安全(v3 O1 10/10)、~20ms 多为致命(O1f 5/5)、45–60ms 多为致命(V1/V1F 10/10):芯片再武装内部子相位周期性,且对构建/时基对齐敏感(O1f:命令日志引入数 ms 时移即 10/10 过 → 5/5 冻);大 Δ(1KB 级 = 生产 lftpd 块读)为**确定性致命**(C0:残留态 10ms 后即被下一次排空清掉仍 10/10 冻结);小 Δ 持续重复 = 数百事件累积 → 必然(S1–S4/V1/V1F 50/50)。**排空至空(窗口→满)恒安全**(40/40,含 10ms 节拍)——芯片设计的正常循环;Δ=0 命令(状态读/中断读/TX)恒安全(B/E 系列)。
- - **再武装区间(实测下界)**:满排空后的"第二条 RX 数据读"在 +0/+80/+120/+160ms 偏移位均致命(S1–S4 各 10/10)→ 脆弱区间 **≥160ms**,内部致命子相位周期性、相位敏感 → **不存在可移植的单值窗口**;旧"~50–100ms"为两点外推(V1 45ms 致命 / E 95ms 安全),上界被 S3/S4(120/160ms 仍致命)证伪。
- - **生产触发(实证复现)**:lftpd 数据通道 STOR 块循环 = 每 1KB 一条 `net_recv(1024)`(部分排空、留 ~1KB 残留、间隔 15–70ms)= C/C0 模式 → **10/10 确定性冻结**(C 系列 = 生产停摆的台架复现,无需任何其他因子);RETR(下载,设备为发送方)不经芯片 RX 排空路径,不受本机制影响。
- - 历史条目(前轮台架,与新模型自洽):MSS=512 时新连接 4096B 突发(8×512 段)确定性停摆恒剩 64B = 高段密度下部分读事件密集;单轮 ≤2KB 无溢出突发在任何几何/命令结构下正常(排空即至空)。
-
-4. **(历史记录:2026-09-22 二次台架"三因子/第二条 RX 命令"模型——已被上方致命性模型取代,保留作过程记录)**
- - **三因子模型(MSS=1024 基线;主因已定案)**:① 同连接前序突发(芯片 RX 状态预置;高段密度可等效替代,见 MSS=512 条)+ ② 后续突发超缓冲容量(4096B > 2KB,需 ≥2 个填周期)+ ③ **填周期内第二条 RX 命令**(排空之后同一 socket 的任何额外 SPI 命令——纯状态读 GET_RECV_LEN 即足够)——**三者齐备才触发,缺一不触发**:
-
- | 变体 | 与 Phase 6-only(单 RX 命令路径)的差异 | 结果 |
- |---|---|---|
- | Phase 6/9/11(每周期多路 RX 命令) | Phase 9/11 各加一路 RX 命令/周期 | **10/10 停摆**(4096B 步:前 2048B 回显正常,余停) |
- | Phase 6-only + 排空间隔 10/20/40/60ms(E 系列) | **只拉长排空间隔,不加第二条命令** | **40/40 全过**(每档 10/10,含满态持续 60ms+) |
- | Phase 6 + 11 + 60ms 间隔(V1,最小扰动) | 每周期加一条 GET_RECV_LEN 状态读(落点 ≈ 排空后 45ms) | **10/10 停摆**(4096B 步,落点与经典模式一致) |
- | 多路 RX 命令、无前序突发 | 新连接独立 4096B | 过(31ms;probe_mss 对照——前序突发因子缺失) |
-
- - **主因(历史记录:二次台架时的"第二条 RX 命令"定案——已由上方致命性模型精化:真致命类 = 排空后缓冲残留的部分窗口重通告,"第二条命令"是其在当时构建中的表面形态)**:冻结与缓冲"满"的持续时长**无关**——排空间隔拉到 60ms、缓冲满态持续 60ms+,单命令路径仍 40/40 干净("满了滞后不舀"假设被证伪,此条仍然成立)。旧结论"排空后 ~50–100ms 内到达的第二条 socket 命令"为两点外推(V1 落点 45ms → 10/10 卡死;E 系列落点 ≈95ms → 10/10 干净),上界被精确定位轮 S3/S4(+120/+160ms 仍致命)证伪;一次性第二条命令的生死取决于落点相位(v3 O1 10/10 过 / O1f 5/5 冻,同一构型仅时移数 ms)。
- - MSS=512:新连接 4096B 突发(8×512 段,4 段装不进 2KB 缓冲)**确定性停摆**,恒剩 64B 未达(4032/4096,2/2 同值)——段密度维度:满周期内段数越多,突发内自我预置越快,越易触发(该实验在多 RX 命令构建上执行,与主因模型自洽)。
- - 单轮无溢出突发(≤2KB,如 1460B)在任何几何/命令结构下均正常。
-5. **排除项**:① 驱动层"超限读静默丢弃"排除——SPI DMA 缓冲 = 2×MSS+4 = 2052B(载荷 2048 = 整个接收缓冲),整缓冲读单事务完成,失败运行中丢弃事件 0 次(Trap 13 所记 1500B DMA 缓冲为 8-Socket 改造前旧值,改造后扩至 2052B);② L3 pending 化排除(切片构建 A/B 行为逐字节一致);③ "RX > 2×MSS"裕量假设排除——MSS 1024→512 实验(2KB=4×MSS、1KB 裕量)既未消除原复现序列的停摆(10/10),又新增新连接停摆 → 已回退 1024;④ "快速重连残留预置"假说排除——受控 20 连接 0.6s 间隔链 20/20 干净(v2 轮 1/9 单例未复现,按孤立事件处理);⑤ keepalive 命令排除——S1 纯探针构建(无 keepalive)10/10 冻结,V1F(带 keepalive)10/10 = 与部分读机制一致,keepalive 既非触发也非保护。
-
-### 解决(2026-09-22;精确定位轮定案更新:MCU 侧修复 = 非阻塞 RX 读强制排空至空)
-1. **MSS 维持 1024**(布局允许最大值;实测 1024 下新连接 4096B 正常、每满周期段数少 = 预置积累最慢)。MSS=512 裕量方案被证伪并回退。
-2. **缓冲块布局与 MSS 解耦**(`ch395f.h`):`CH395F_RECV_BLOCKS=4` / `CH395F_SEND_BLOCKS=2` 固定(此前由 MSS 推导,改 MSS 会连带缩小布局);`CH395F_SPI_DMA_BUF_SIZE = 接收缓冲 + 4`(此前 2×MSS+4,改 MSS 会缩到装不下整缓冲)。
-3. **超限读金丝雀**(`ch395f_read_recv_buf`):正常路径不可能发起超过接收缓冲(2KB)的读;守卫命中即留痕 `read_recv_buf OVERSIZE`(原为静默 return,会把窗口锁死在 0 且无从诊断)。
-4. **MCU 侧修复(2026-09-22 精确定位轮定案 → N-7,待批准实施)**:致命类 = 部分窗口重通告(排空后缓冲残留)→ net 层**强制一切非阻塞(DONTWAIT)RX 读排空至空**:RX 读上限强制为接收缓冲全量(2048B)——"只读一部分"经安全 API 不可表达;应用按自身块粒度消化排空结果(lftpd `receive_file` 块循环 `net_recv(1024)` → `net_recv(2048)`,仍按 1KB 块处理,接收缓冲需 ≥2KB)。依据:排空至空任意节拍均安全(E 系列 40/40,含 10ms E0)→ **无需时间守卫/冷却**(旧"第二命令暂缓 + 120ms 冷却"设计作废:C0 证明部分排空自身即致命(零第二命令也 10/10 冻结),E0 证明排空至空后 10ms 再来一次排空也安全——时间守卫既不足又多余);Δ=0 命令(状态读/中断读/poll/TX)豁免(实测安全,不过度阻塞)。残留约束:阻塞/pending 读若以部分结果落地且未即刻排空至空,仍属致命类(pending 完成点同样强制全量,或应用同 tick 内排空)——N-7 实施时处理。
-5. **兜底缓解(决策项,未实施)**:冻结不自恢复(对端重传 10s 无效;芯片无限期保持连接)。唯一恢复 = 断开受影响连接(释放芯片 per-socket 状态)+ 对端重试(新连接成功率高;台架实测停摆后重连回显正常)。现 lftpd 数据路径预算 `LFTPD_TOTAL_BUDGET_MS=30000`(每次读 30s)即实际停摆超时——若将**数据通道**预算单独缩短(10–15s,与控制行预算分离),可把停摆暴露时间从 30s 压缩到客户端重试路径;代价 = 慢速但健康的传输也会被中断(机器客户端不受影响,人工客户端受影响)→ 已列 `docs/待处理内容.md` N-1 待决策(N-7 落地后本项紧迫性下降,保留为兜底)。
-
-### 注意事项
-- 复现模式(2026-09-22 精确定位轮更新):**部分排空(读后缓冲残留)= 唯一实证致命模式**——最小台架复现 = 64×10 + 1460B 填充 + 1024B 部分排空(C/C0 配方,Phase 6-only 构建,零第二命令,10/10 冻结);旧"三因子"配方(F1 组合 + 4096B 超容突发)10/10 维持,其中 Phase 9/11 每 tick 64B 读、V1 每周期状态读后的 64B 读、生产块循环 1KB 读均为"部分读"模式的不同剂量形态。生产主要风险场景 = **lftpd 数据通道 STOR(上传)**:块循环每 1KB 一条 `net_recv`(大 Δ 部分排空,间隔 15–70ms)= C 配方 10/10;RETR(下载,设备为发送方)不经芯片 RX 排空路径,不受本机制影响;N-7(排空至空强制)落地后 STOR 块循环转为 E 系列模式(40/40 安全)。
-- 与 Trap 22 的鉴别(两者都可在断连/重监听后出现):本条 = RX 路径冻结(有 standalone accept、前段回显正常、其后 RECV_OK 永不再来、无 send 失败);Trap 22 = 连接状态失同步(缺 standalone accept + `send -1` + `WARNING: listen` + 监听死亡)。
-- 冻结对 MCU 是静默的:无 RST、无芯片断开事件、无 send 失败;精确定位轮命令序列日志修正旧表述——MCU 侧 RX 路径照常工作(冻结后到达的数据可正常排空,命令流节奏完整),**死的是芯片 TX 路径**(已写入的发送段永不出线);MCU 无直接信号,只能靠应用层数据预算(lftpd 30s / 客户端自身超时)或对端视角(收不到回显/ACK)发现。
-- E-02 审计"STOR 方向缓冲满 + 重传耗尽 → 必断"的预警方向成立(STOR 方向 = 致命),机制修正为本条 RX 冻结(非 RST 拆连)。
-- WCH FAQ"发送缓冲必须大于 MSS"为严格不等式;本设计发送缓冲 = MSS(1KB = 1024)取等值——台架实测芯片在缓冲边界可正常成包(L3/L8 基线在 1KB 分块写入下全部正常),该条按保守表述处理,非运行约束。
-- 本条的冻结是确定性触发模式缺陷(排空结束态 = 缓冲残留的部分窗口重通告;小 Δ 落点另有相位刀口),非低概率随机竞态——发现新停摆模式时先核对"是否存在部分排空(net_recv 上限 < 缓冲现有字节数,读后缓冲非空)",再怀疑 MCU 侧。
-
-### 对应文件
-`Drivers/BSP/CH395F/ch395f.h`(布局解耦 + MSS=1024 维持);`Drivers/BSP/CH395F/ch395f.c`(OVERSIZE 金丝雀);`Drivers/BSP/NET/net_socket.c`(MSS 下发注释;netcmd 芯片命令序列日志——bench 开关 `NET_BENCH_CMD_LOG` 默认关,2026-09-22 精确定位轮工具);`test/ch395f_socket_test.py`(复现:tcp_client 全序列);`MDK-ARM/probe_mss.py`(MSS/芯片 TX 分包探针)+ `probe_{boundary,status,partial,fastrecon}.py`、`probe_classify.py`、`netcmd_extract.py`(精确定位轮台架/离线判读/命令序列提取工具,均本地不提交)。
-
-### 发现时间
-2026-09-22(TC-NET-604;根因确认、MSS=512 证伪与回退、布局解耦同日完成,提交于 wip/v2-pending-recv 分支)。2026-09-22 精确定位轮:11 组台架 110+ 运行(E/O/B/F1/S1–S4/C/C0/V1F/O1f)定案"部分窗口重通告"致命性模型,N-7 设计由"排空后 RX 守卫 + 120ms 冷却"改为"非阻塞 RX 读强制排空至空"(无时间守卫),netcmd 命令序列日志工具入库(默认关)。
+### 相关
+- 真实缺陷见 **Trap 23**(上传中止后首笔复连上传被静默截断,已可信复现并修复);
+- 发现:2026-08-26(阶段 8);结案:2026-09-23。
## Trap 22:重监听后快速重连丢失 CONNECT 中断 → 监听静默死亡
@@ -623,7 +570,7 @@ CH395F 片内 TCP 状态机的角(芯片固件,MCU 侧无法修补)。2026
1. 芯片硬件完成握手但 CONNECT 中断未上报(或 MCU 侧丢失)→ `handle_connect_event` 未执行 → 状态滞留 LISTENING。
2. **实证边界(2×2 台架)**:失同步仅现于"轻负载 + 重监听历史 + 快速重连(~600ms)"组合;重负载(Phase 6/9/11)下断连后 ~500ms 重连仍同步正常(B' 组 20/20 standalone accept、10/10 全连接成功);轻负载 + 15s 重连间隔亦全正常(A' 组 20/20)。即中断丢失窗口 ≈ "close → 重监听 → SYN" 间隔 < ~1s 且 netTask 相对空闲。芯片侧丢中断的具体原因未解(列为后续观察项,不阻塞下述修复)。
3. 后果链确定:状态滞留 LISTENING → `net_send` 被拒(send -1)→ 断开时 DISCONNECT 落 LISTENING 分支(现有代码仅告警)→ 芯片自动关闭 Socket → MCU 不再重开 → 监听死亡。
-4. 与 Trap 21 的关系:**独立失效模式**——Trap 21 = RX 路径冻结(缓冲空、无 RECV_OK、窗口冻结、连接状态正常);本条 = 连接状态失同步(数据可流但发送被拒,且可致监听死亡)。日志签名鉴别:Trap 21 无 standalone accept 缺失、无 send -1;本条三者齐现(缺 standalone accept + `send -1` + `WARNING: listen`)。
+4. 与 Trap 21 的关系:Trap 21(TC-NET-604 "RX 窗口冻结")**已结案为非缺陷**(真实生产路径 227 轮全过;原台架"停摆"系测试程序自吞数据 + 判读工具误判,见 Trap 21);本条(Trap 22)是**独立且仍待修**的失效模式:连接状态失同步(缺 standalone accept + `send -1` + `WARNING: listen`),须与之分开跟踪。
### 修复(方案,未实施 → N-6)
1. `handle_disconnect_event` LISTENING 分支:回读芯片 socket 状态,非可监听状态(即芯片已自动关闭)时执行 `net_relisten_try` 重建(重 OPEN + TCP_LISTEN)——D20 陈旧事件修复的 LISTENING 分支姊妹情形(D20 只处理 ESTABLISHED 分支)。
@@ -657,7 +604,7 @@ CH395F 片内 TCP 状态机的角(芯片固件,MCU 侧无法修补)。2026
### 影响
- **静默数据损坏**:上传被中断后"重试的第一笔"会生成截断文件且客户端收到成功回报(FTP 客户端通常不做长度校验)→ 现场可能表现为"上传的文件损坏/不完整";
- 主风险面 = 生产路径 STOR(上传);RETR(下载)不涉及;
-- 与 TC-NET-604 的关系:本条为**独立、已复现**的真实缺陷;TC-NET-604 的台架"冻结"结论已撤回(见 Trap 21 顶部更正块),现场"卡死/失败"报告应优先用本条的判据(协议结果 + 哈希往返)复核。
+- 与 TC-NET-604 的关系:本条(Trap 23)是**独立、已可信复现并已修复**的真实缺陷;TC-NET-604 已结案为非缺陷(见 Trap 21)。现场"上传失败/文件不完整/像卡死"类报告,应优先用本条的判据复核:**FTP 协议结果 + 上传后 RETR 回读 SHA-256**(+ 卡住时控制通道 NOOP 探活)。
### 复现
```
diff --git a/docs/问题记录/错误码传播审计.md b/docs/问题记录/错误码传播审计.md
index 92cec918..86be7bd4 100644
--- a/docs/问题记录/错误码传播审计.md
+++ b/docs/问题记录/错误码传播审计.md
@@ -167,7 +167,7 @@ E-60"write_enable WRTC2 与手册矛盾"经三方复核(手册表头 D7~D0 顺
- **功能套件(Phase 6/9/11 组合 + Phase 8-RECV 独占组合,分两次构建)**:64B/1460B 回显 11/11、select 回显 11/11、断开重连、KeepAlive 断连 + 自动重监听全 PASS;**Phase 8-RECV 100KB 阻塞接收(pending 主路径)50/50 块(2048B/块)逐块校验 + CRC32 整包一致**(0x9A0E0C8C),收齐后主动 close + auto-relisten 正常
- **产品构建 `@test`**:PASS(Required 全中/Forbidden 零命中);netTask 运行栈峰值 **488B/4096(余量 88%)**、静态最坏链 432B——零占用设计实测落点
- **RAM/Flash 代价(map A/B,同一测试配置)**:SRAM +200B(192B `s_net_pending[8]` + 4B `s_net_task_handle` + 4B 他项)、Flash +608B(code +528/RO +80)——远低于内存预算阈值
- - **台架新发现(与 L3 无关,A/B 归因后转 `docs/待处理内容.md` N-1/N-2)**:① TC-NET-604 前序突发后 4096B 停摆 = CH395F 片内 TCP RX 冻结角(2026-09-22 确认为 WCH 官方 FAQ 留档的已知局限,MSS=512 裕量方案被证伪;根因/闭环见 Trap 21,代码侧已闭环提交,残留数据通道预算决策项在 N-1)② 台架运行中一次 49s 全系统日志静默(net 栈期间照常处理连接 = defaultTask/NAND syslog 排空停滞,既有存储侧现象,L3 无责)
+ - **台架新发现(与 L3 无关,A/B 归因后转 `docs/待处理内容.md` N-1/N-2)**:① TC-NET-604 已结案为**非缺陷**(2026-09-23:真实生产路径 227 轮全过;原台架"停摆"系测试程序自吞数据 + 判读工具误判,见 Trap 21);② 台架运行中一次 49s 全系统日志静默(net 栈期间照常处理连接 = defaultTask/NAND syslog 排空停滞,既有存储侧现象,L3 无责)
#### E-03 全局 `s_net_errno` 跨任务覆写竞态(09-21 修复的残留)
- **位置**:写方 = `net_socket.c:39` 单全局;netTask 侧 `:362/365/375/385/410` + **notify 值构造 `:419-423`**(`s_notified` 分支读同一全局);6 个队列包装器在**调用方上下文** `:660/758/818/1233/1286/1333`(仅失败路径写);6 个直调 API 在**调用方上下文**失败时写(`net_socket :442/449`、`net_bind :482-538`、`net_sendto/net_recvfrom`、`net_getsockname :1953-1964`),**成功不写** → stale 滞留(`:1609` 文档化)。读端:`ui_net_sink.c:460`(uiTask 100Hz,BelowNormal 被抢占窗口最大)、`test/net_test_task.c:230/381`