Files
STM32F4-Base/Drivers/BSP/NET
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
..

Drivers/BSP/NET/ — 网络抽象层(BSD Socket API)

在 CH395F 硬件驱动之上提供 BSD Socket 风格 API,使上层(FTP 服务、时间同步、UI 推流) 以标准 socket 语义编程,无需关心芯片细节。核心是阻塞模型 + 事件驱动 + 周期对账自愈。

文件一览

文件 作用
net_socket.c/h BSD Socket API 实现:net_socket / net_connect / net_send / net_recv / net_close / net_listen / net_accept,含 L3 挂起(pending)与错误码
net_select.c/h select/poll 多路复用(基于芯片中断事件 + 周期轮询)
net_types.h 网络层公共类型定义
net_config.h 网络层编译期配置(缓冲区大小、超时、对账周期等)
lftpd/ 轻量 FTP 服务器(第三方移植,见其子目录)

核心机制

阻塞模型(L3 pending)

  • 一期(RECV)已落地:net_recv 等支持带超时的阻塞(pending 挂起 + tick 唤醒)
  • 二期(ACCEPT + SEND)待做 → docs/待处理内容.md N-4

周期对账自愈(Trap 22 修复)

  • net_reconcile_tick()(200ms)回读芯片状态修正三类失同步: 本层 ESTABLISHED 而芯片已断 → 断开;本层 LISTENING 而芯片已握手 → 补 accept; 本层 LISTENING 而芯片监听消失 → 重建
  • 去抖(连续 2 次)+ 冷却(1s)——单次状态读的重建动作必须去抖, 否则"刚 listen 未生效"瞬态会反复重建直至 relisten give up(三监听口全死)

异常复监听隔离(Trap 23 修复)

  • 异常释放(TIMEOUT)的 socket 复监听前隔离:排空 RX 残渣 + 主动 close + 等 CLOSED
  • 400ms 起、800ms 上限强制放行(上限须 < 重试放弃时限 2000ms)
  • 仅异常路径生效,正常 FIN 路径零改动

错误码(E-03 修复)

  • 按任务隔离:s_net_errno_slots[8](每槽 {任务句柄, err}),替代原全局 s_net_errno
  • net_get_errno() 只读本任务槽位,对外语义不变(成功不清零)

依赖关系

上层(FTP / timeSync / UI 推流)
        ↓ BSD Socket API
    net_socket.c  ←→  net_select.c
        ↓ ch395f_* 接口
    Drivers/BSP/CH395F/

⚠️ 改本模块前必读

  • 就绪屏障位(SYS_EVT_NET_READY 等)等待必须 osFlagsNoClear,不能用默认消费型
  • 每次 CH395F SPI 事务须 ch395f_spi_begin()/end() 包裹
  • 改任何自愈/重建逻辑必须去抖,否则会引发重建风暴
  • 相关陷阱:docs/问题记录/CH395F_Trap_Records.md Trap 21/22/23

相关文档

  • 上层用法:docs/网络/BSD_Socket_API_使用指南.md
  • 内部调用关系:docs/网络/BSD_Socket_API_函数调用关系.md
  • 架构设计:docs/网络/Net层阻塞模型架构设计.md(阻塞等待 / pending 请求模型)
  • 二期设计基线:docs/待处理内容.md §5.1
  • 测试:docs/测试说明/CH395F_Test_Guide.md、docs/测试说明/FTP_Test_Guide.md