refactor(NET): 源码注释去阶段化 + 网络两份文档重构 + 不稳根因图更新

- 源码注释:删去自愈收敛阶段
1/1.5/3等 scaffolding 称谓,改为语义引用
  (E-02 收口 / F-NET-2/3/4 / docs/网络/网络自愈架构设计.md §5.2 E13);
  涉及 net_socket/.h、net_events、net_listener、net_pending、net_types、
  net_config、ch395f、time_sync、iec104_serv、ui_net_sink、lftpd、
  simulator/sim/net_socket_sim、board/host 测试与探针
- 文档重构:网络自愈架构设计.md 与 Net层阻塞模型架构设计.md 改为现状口径
  (删历史节与阶段叙事),NET/README.md、docs/README.md 同步
- 工具与配图:gen_net_instability_svg.py 与
  docs/images/网络不稳根因总览.svg 随源码口径一并更新
- 门禁:@build 0 错误 0 警告
This commit is contained in:
2026-10-14 22:05:53 +08:00
parent cea2b51efb
commit d770e36c7c
30 changed files with 574 additions and 682 deletions
+9 -8
View File
@@ -18,18 +18,18 @@
### 阻塞模型(挂起 recv / send / pending)
- 一期(RECV)已落地:`net_recv` 等支持带超时的阻塞(`pending` 挂起 + tick 唤醒)
- 二期(SEND)已落地:`net_send` 快路径有界自旋(`NET_SEND_SPIN_MS` = 2ms),超预算登记
- **recv 挂起(pending)已落地**:`net_recv` 阻塞不占 netTask——登记挂起请求 + 每轮 tick 唤醒
- **send 挂起已落地**:`net_send` 快路径有界自旋(`NET_SEND_SPIN_MS` = 2ms),超预算登记
挂起 send,由 `net_send_pending_tick` 按主循环节拍分块推进;netTask 最坏停滞由 1s 压到 2ms
- 二期(ACCEPT)待做 → `docs/任务规划/登记簿.md` N-4
- **ACCEPT 尚未挂起化**(调用方轮询问题,不是队头阻塞)→ `docs/任务规划/登记簿.md` N-4
- 架构细节:`docs/网络/Net层阻塞模型架构设计.md`
### 周期对账自愈(TRAP-NET-17 修复;自愈收敛阶段 3 合并 pump)
### 周期对账自愈(TRAP-NET-17 修复;对账与监听重建合一)
- `net_reconcile_tick()`(100ms,自愈收敛阶段 3 起判据读**驱动状态缓存**——唯一
- `net_reconcile_tick()`(100ms,判据读**驱动状态缓存**——唯一
刷新点 `net_poll` 每轮全量刷新,E2 实测单次回读 18.1us)修正失同步:
本层 ESTABLISHED 而芯片已断 → 断开;本层 LISTENING 而芯片已握手 → 补 accept;
本层 LISTENING/CLOSED(监听型 fd)而芯片监听消失 → 重建(原 pump③④);
本层 LISTENING/CLOSED(监听型 fd)而芯片监听消失 → 重建(形态③④);
本层 CLOSED 而芯片在听 → 只重同步(U11);芯片静默回收 → RESYNC(⑤)
- **分级去抖(②=1 轮 / ③④⑤=2 轮 / ①=4 轮)+ 冷却(1s)**——监听失位的重建
动作**必须去抖**,否则"刚 listen 未生效"瞬态会反复重建直至
@@ -39,7 +39,8 @@
### 异常复监听隔离(TRAP-NET-18 修复)
- 异常释放(TIMEOUT)的 socket 复监听前隔离:排空 RX 残渣 + 主动 close + 等 CLOSED
- 400ms 起、800ms 上限强制放行(上限须 < 重试放弃时限 2000ms)
- 400ms 起;**800ms 上限只留痕、不强行放行**(芯片未回 CLOSED 时 open 注定吃 USE 错,
真正兜底 = D10 预算到期 + 对账形态④ 重新登记)
- 仅异常路径生效,正常 FIN 路径零改动
### 错误码(E-03 修复)
@@ -69,5 +70,5 @@
- 上层用法:`docs/网络/BSD_Socket_API_使用指南.md`
- 内部调用关系:`docs/网络/BSD_Socket_API_函数调用关系.md`
- 架构设计:`docs/网络/Net层阻塞模型架构设计.md`(阻塞等待 / pending 请求模型)
- 二期设计基线:`docs/任务规划/基线与待确认.md` §2.1
- ACCEPT 挂起化设计基线:`docs/任务规划/基线与待确认.md` §2.1
- 测试:`docs/测试说明/CH395F_Test_Guide.md`、`docs/测试说明/FTP_Test_Guide.md`
+1 -1
View File
@@ -467,7 +467,7 @@ static int cmd_pasv(lftpd_client_t *client, const char *arg)
client->data_socket = -1;
}
/* 自愈收敛阶段1-6:原 3×200ms 应用层重试已删(lftpd_inet_listen 单次化)——
/* 原 3×200ms 应用层重试已删(lftpd_inet_listen 单次化)——
* 失败直接 425,FTP 客户端自带传输重试语义;服务端不再叠阻塞重试 */
int listener_socket = lftpd_inet_listen(0);
if (listener_socket < 0) {
+1 -1
View File
@@ -31,7 +31,7 @@ void lftpd_task_wd_beat(void)
int lftpd_inet_listen(int port)
{
/* 自愈收敛阶段1-6:应用层阻塞重试退役(原 5 轮 500ms/2000ms,最坏 10s 阻塞
/* 应用层阻塞重试退役(原 5 轮 500ms/2000ms,最坏 10s 阻塞
* ftpTask)——TRAP-NET-09 的启动形态已由就绪屏障消除(FTP_READY 等 NET_READY,
* lftpd_start 外层本就有监听失败重建循环);芯片忙窗失败属罕见,PASV 数据
* 监听交给 FTP 客户端自身的重试语义(主流 FTP 服务器 passive listen 失败
+3 -3
View File
@@ -11,10 +11,10 @@
* 实际生效值 60s/5s/3 并在 net_socket.c 引用(原宏为无效遗留值)
* 2026-09-22 新增 NET_RETRANS_COUNT/NET_RETRANS_PERIOD_MS(P0-a:重传周期
* 500→200ms 治 D1 症状),net_socket.c 的字面量 8/500 移入本文件
* 2026-10-13 自愈收敛阶段 1.5:删除 NET_RECV_TIMEOUT_MS(30s 默认预算)——
* 2026-10-13 recv 语义主流化:删除 NET_RECV_TIMEOUT_MS(30s 默认预算)——
* recv 超时改为调用方策略(net_recv 无限阻塞 /
* net_recv_to 显式预算 / net_select 首选),API 不再强加默认值
* 2026-10-14 二期 SEND pending:新增 NET_SEND_SPIN_MS(发送快速路径有界自旋
* 2026-10-14 SEND pending 化:新增 NET_SEND_SPIN_MS(发送快速路径有界自旋
* 预算,超预算转挂起登记)——netTask 发送最坏停滞由
* NET_SEND_TIMEOUT_MS(1s)压到本值,健康路径行为不变
*/
@@ -36,7 +36,7 @@ extern "C" {
/*
* 超时时间配置(毫秒)
* 0 = 无限等待(阻塞模式)
* 注:recv 侧无编译期默认预算(自愈收敛阶段 1.5 删除 NET_RECV_TIMEOUT_MS)——
* 注:recv 侧无编译期默认预算(NET_RECV_TIMEOUT_MS 已删除)——
* 超时是调用方策略:net_recv() 无限阻塞、net_recv_to() 显式预算、
* net_select() 首选机制。
*/
+7 -7
View File
@@ -79,7 +79,7 @@ void net_bench_cmd_log(char tag, int sock, int detail) {
#endif
/* 对账+pump 合并周期(自愈收敛阶段 3:原 200ms 对账 / 100ms pump 合一) */
/* 对账与监听重建合一周期(原 200ms 对账 / 100ms 重建合一) */
#define NET_RECONCILE_PERIOD_MS 100U
/* 同一 socket 两次动手的最小间隔(防抖成风暴) */
#define NET_RECONCILE_COOLDOWN_MS 1000U
@@ -242,7 +242,7 @@ void handle_disconnect_event(net_sock_t *p_sock) {
* 而 TCP 槽 0x00 且本层 ESTABLISHED = 逻辑矛盾(活连接应 0x04):陈旧 DISCONNECT
* (拆链完成滞后锁存,TRAP-NET-12)与"真断开恰被旧拆链覆写槽"在 D20 上不可分辨
* (结构性失明,F-NET-15 Q1)。处置:不吃边沿,置可疑电平返回,交对账①
* (ESTABLISHED + 芯片 TCP==CLOSED)电平去抖再入本函数(自愈收敛阶段 3 合并
* (ESTABLISHED + 芯片 TCP==CLOSED)电平去抖再入本函数(对账与重建合一
* 后=4×100ms,NET_RECON_STABLE_DEATH,让位租约 400ms 不变 + 冷却):
* flag==1 旁路本门 → 正常释放;连接真活则租约内
* 会话正常完成(风暴链掐断,E9a n30 0/50 实证)。
@@ -426,7 +426,7 @@ static void fire_event(net_sock_t *p_sock, net_event_t event) {
* 返回值:无
* 限定条件:netTask 上下文(net_accept_locked 内调用,其开头已 net_poll(),
* 驱动缓存新鲜度有保证)
* 函数说明:1. 自愈收敛阶段 3(F-MS-9):判据改读**驱动状态缓存**(零 SPI;唯一
* 函数说明:1. F-MS-9:判据改读**驱动状态缓存**(零 SPI;唯一
* 刷新点=net_poll),**探针去抖删除**——原去抖防的两类瞬态已
* 结构性消除:"刚 listen 尚未生效"显示 TCP=00 永不命中 ESTABLISHED
* 门(E2:LISTEN 可见 100% <=10ms 无长尾);拆链窗假 ESTABLISHED
@@ -456,7 +456,7 @@ void net_lost_connect_probe(net_sock_t *p_sock) {
p_sock->lost_conn_seen = 0U;
return;
}
/* 自愈收敛阶段 3(F-MS-9):去抖已删(判据读缓存,两类瞬态结构性消除,
/* F-MS-9:去抖已删(判据读缓存,两类瞬态结构性消除,
* 见函数头注释 1);lost_conn_seen 仅作 M3 可疑电平标志用,动手前清零 */
p_sock->lost_conn_seen = 0U;
/* 留痕:事件未收到自愈命中 */
@@ -468,7 +468,7 @@ void net_lost_connect_probe(net_sock_t *p_sock) {
/*
* 函数功能:芯片/本层 socket 状态周期对账(TRAP-NET-17 事件面未收到自愈,E14 复核:非芯片丢事件是被读清消费)+ 监听器 pump(N-32 P2)—— 自愈收敛阶段 3 合并为单一 100ms tick(docs/网络/网络自愈架构设计.md §4.1)
* 函数功能:芯片/本层 socket 状态周期对账(TRAP-NET-17 事件面未收到自愈,E14 复核:非芯片丢事件是被读清消费)+ 监听器重建 —— 合并为单一 100ms tick(docs/网络/网络自愈架构设计.md §4.1)
* 入口参数:无
* 出口参数:无
* 返回值:无
@@ -556,7 +556,7 @@ void net_reconcile_tick(void) {
stable_need = NET_RECON_STABLE_DEATH;
} else if ((c.open != CH395F_SOCKET_CLOSED) &&
(c.tcp_state == CH395F_TCP_LISTEN)) {
/* ⑤(F-NET-2 缺口,自愈收敛阶段1):芯片静默回收——本层 ESTABLISHED
/* ⑤(F-NET-2 缺口):芯片静默回收——本层 ESTABLISHED
* 而芯片已自行把 Socket 收回 LISTEN(0x05/0x01,**不发 DISCONNECT
* 中断**,run8 台架实证)→ RESYNC 语义 */
bad = 5;
@@ -633,7 +633,7 @@ void net_reconcile_tick(void) {
handle_disconnect_event(p_sock);
} else if (bad == 5) {
/* 类型⑤:静默回收 → RESYNC 语义(原 NET_MSG_RESYNC_LISTEN 分派体
* 原样并入,自愈收敛阶段1;纪律同 U11:**不发任何芯片命令**——
* 原样并入;纪律同 U11:**不发任何芯片命令**——
* 重下发 close/重监听会摧毁芯片侧健康监听器 → 端口永拒,
* run8 实证 170s 拒绝) */
DBG_INFO("sock%d reconcile: chip re-listened w/o DISCONNECT (0x%02X/0x%02X) -> resync",
+2 -2
View File
@@ -8,8 +8,8 @@
* 作者:王建锋
* 创建日期:2026-10-12
* 修改记录:
* 2026-10-12 王建锋 从 net_socket.c 整体抽出监听生命周期(N-32 §10 模块化)
* 2026-10-13 王建锋 自愈收敛阶段 3:pump 并入 net_reconcile_tick
* 2026-10-12 王建锋 从 net_socket.c 整体抽出监听生命周期(模块化)
* 2026-10-13 王建锋 监听重建 pump 并入 net_reconcile_tick(单一决策者)
* 2026-10-14 王建锋 单一所有者收口(I2 加强):try 当场动作 + 四处调用点各自带门
* → request 登记意图 + tick 唯一执行;沉降留痕改"只留首末"
* 2026-10-14 王建锋 注释精简(−45%,代码零改动):陷阱详情沉淀进架构设计文档,
+1 -1
View File
@@ -114,7 +114,7 @@ void net_listener_clear(int sockfd);
*/
void net_listener_tick(void);
/* 自愈收敛阶段 3:原 `net_listener_pump`(周期重建决策者)已并入 net_socket.c 的
/* 原 `net_listener_pump`(周期重建决策者)已并入 net_events.c 的
* net_reconcile_tick 单一 100ms tick(判据读驱动状态缓存,《网络自愈架构设计》§4.1)。
* 本模块的 net_listener_tick 是执行者,登记方 = reconciler 形态③④ + 各消费者路径
* (accept / recv EOF / drop_conn / 挂起 recv 断连),全部走 net_listener_request。 */
+2 -2
View File
@@ -151,8 +151,8 @@ int net_pending_active(int sockfd);
* ⚠ **调用方铁律**:`sent < len` 是调用侧必须保证的**前置条件**,不是本函数的
* 兜底。`sent == len` 表示"全部字节已交付芯片、无剩余块可挂起"——此时超预算
* 应**直接返回 sent**,不得调用本函数;本函数会按参数非法拒绝并回 -1,
* 把一次完整发送报成失败(net_send_locked 末块等待 2026-10-14 台架实证,
* 见《Net层阻塞模型架构设计.md》 §9.1)。
* 把一次完整发送报成失败(net_send_locked 末块等待即此情形,
* 见《Net层阻塞模型架构设计.md》 §5.5 末块边界)。
*/
int net_send_pending_register(int sockfd, const void *buf, int len, int sent,
TaskHandle_t caller);
+39 -39
View File
@@ -45,7 +45,7 @@
* 假设=「RX 非空但 readable=0」(RECV_OK 事件未收到的数据面形态)在生产真实
* 发生。置 1 烧实验固件:net_poll 每 32 轮对在用 fd 发一条 GET_RECV_LEN,
* 命中计数 + 低频日志(每小时 ≤1 条防刷屏);跑 24h 常态 + E1 压测。
* 判据:命中 >0 → 阶段 3 项 4(U15 内化)立项;=0(含压测)→ 上层 32 轮
* 判据:命中 >0 → U15(数据面失配)内化立项;=0(含压测)→ 上层 32 轮
* 盲收保留现状、U15 登记观察项。**默认 0 = 产品构建零成本(编译剔除)**。
* E6 已裁决(2026-10-13,《网络自愈架构设计》§5.2 E6):命中=0(含压测)→ 项 4 不立项,维持默认 0。
* ⚠ 必须定义在文件最前部:bring_up 的 armed 日志与 net_poll 探测环两处消费。 */
@@ -240,7 +240,7 @@ static bool s_mac_is_zero(const uint8_t *p_mac) {
/* 复位芯片 */
ch395f_reset();
/* 芯片版本留痕 + 0-6 版本门控(自愈收敛阶段0,§5.52 表):bit3 SOCKET_CLOSE
/* 芯片版本留痕 + 版本门控(CH395F 手册 §5.52 表):bit3 SOCKET_CLOSE
* 需芯片 ≥0x46、TCP_SERVER 需 ≥0x44。本台架芯片实测 ≥0x46(TRAP-NET-20 定案
* SOCKET_CLOSE 实际生效);门控防批次漂移——版本不足则**拒置 bit3**
* (退回芯片自动关断语义)并 [ERR] 留痕,不静默带病运行 */
@@ -414,7 +414,7 @@ int net_poll(void) {
/* 读取全局中断状态(2 字节):读操作本身会清除 CH395F 中断并使其拉高 INT#,
* 若此后仍有新中断,CH395F 会再次拉低 INT#,由下一次 net_poll() 处理 */
int_status = ch395f_get_glob_int_status_all();
/* 自愈收敛阶段 3(F-DRV-13 接线):把全局位喂驱动——bit2 PHY_CHANGE 时驱动
/* F-DRV-13 接线:把全局位喂驱动——bit2 PHY_CHANGE 时驱动
* 重读 PHY 更新 link_up 缓存 + 变化计数,net 层在 reconciler 订阅留痕
* (运行期拔网线不再静默;不自动重配,重配仍走 UI/配置引擎路径) */
ch395f_glob_event_feed(int_status);
@@ -496,7 +496,7 @@ int net_poll(void) {
/* 因此每次 net_poll() 只处理“一批”,剩余数据在后续轮询中读取 */
} while (0);
/* 自愈收敛阶段 3(§5 项 1 基础):每轮全量刷新在用 Socket 的驱动状态缓存
/* 单一事实源(I1):每轮全量刷新在用 Socket 的驱动状态缓存
* (唯一刷新点;E2 实测单次回读 18.1us,在用 5~6 个 ≈100us ≪ 1ms 轮询
* 周期)。reconciler / 探针 / 镜像降级决策点一律读缓存(
* ch395f_sock_state_cached),不再各自发状态 SPI。放在中断处理之后:
@@ -504,7 +504,7 @@ int net_poll(void) {
for (int i = 0; i < NET_MAX_SOCKETS; i++) {
if (s_net_socks[i].in_use != 0U) {
(void)ch395f_get_sock_state((uint8_t)i);
/* 自愈收敛阶段 3(E-02 收口):驱动 sock_reset 状态机在 net_poll 步进
/* E-02 收口:驱动 sock_reset 状态机在 net_poll 步进
* (驱动头注释契约"在 net_poll 或测试循环里周期调用")。IDLE 槽位
* 纯 RAM 判返回 0 无 SPI;仅活跃复位机做短 SPI。作用:同步包装
* (net_sock_reset_sync)600ms 放弃后复位机不搁浅,芯片条件满足
@@ -572,7 +572,7 @@ int net_poll(void) {
* 30ms 节奏 / 2s 预算;门集与"芯片在听就不 open"(U12 防护)都在这一处
* 3. net_pending_tick:按节拍结束挂起 recv(数据/到点[仅显式预算]/断连)
* 4. net_send_pending_tick:按节拍推进挂起 send(断连/推进/写完/无进展超时)
* 5. net_reconcile_tick(TRAP-NET-17 + pump 合并,自愈收敛阶段 3):100ms 对账
* 5. net_reconcile_tick(TRAP-NET-17 事件面自愈 + 监听重建合一):100ms 对账
* ①②⑤ + ③④ 重建 + U11 重同步,判据读驱动状态缓存;去抖分级 + 1s 冷却
* 6. net_msg_t 按值入队 → 结果只能搭任务通知值回传(32 位整体即结果,不做位域压缩)
* 7. RECV / SEND 特例:超预算登记 pending 哨兵 NET_PENDING_REGISTERED(0x70000000),
@@ -593,7 +593,7 @@ void net_process_messages(void) {
net_pending_tick(s_net_socks);
/* 挂起 send 推进与完成检查(SEND pending):断连 / 推进写块 / 写完 / 无进展超时 */
net_send_pending_tick(s_net_socks);
/* TRAP-NET-17 状态对账 + 监听器 pump(自愈收敛阶段 3 合并单一 100ms tick):
/* TRAP-NET-17 状态对账 + 监听重建合一(单一 100ms tick):
* 判据读驱动缓存(net_poll 每轮全量刷新),①②⑤ 失同步 + ③④ 重建 +
* U11 重同步全部在此(本层唯一周期重建入口,N-32 P2 单一所有者) */
net_reconcile_tick();
@@ -690,7 +690,7 @@ void net_process_messages(void) {
break;
}
case NET_MSG_DROP_CONN: {
/* 自愈收敛阶段 3(E-02 收口):应用放弃会话的主动拆除(拆连接、保监听) */
/* E-02 收口:应用放弃会话的主动拆除(拆连接、保监听) */
net_sock_t *p_sock = net_get_sock(msg.sockfd);
if (p_sock == NULL) {
/* 描述符无效 → BADF */
@@ -709,7 +709,7 @@ void net_process_messages(void) {
}
break;
}
/* 自愈收敛阶段1(F-NET-3):NET_MSG_RESYNC_LISTEN / NET_MSG_RELISTEN 两个
/* F-NET-3:NET_MSG_RESYNC_LISTEN / NET_MSG_RELISTEN 两个
* 手动自愈消息已删——RESYNC 语义并入对账⑤(net_reconcile_tick),
* RELISTEN 与 reconciler/D10 完全重叠且对健康监听器是 footgun;
* 生产调用者本就为零(仅 test/board Phase 13,已改由自动机制接管) */
@@ -833,7 +833,7 @@ int net_socket(int domain, int type) {
p_sock->send_ready = 1;
/* 无可读数据 */
p_sock->readable = 0;
/* 自愈收敛阶段 1.5:阻塞模式默认 = 阻塞(BSD/Python 语义;非阻塞用
/* 阻塞模式默认 = 阻塞(BSD/Python 语义;非阻塞用
* net_setblocking(fd, 0) 显式设置)。close 的 memset 会清零本字段,
* 新 fd 必须在此显式置 1(同 released_abnormal 的"不得继承"纪律) */
p_sock->blocking = 1;
@@ -962,7 +962,7 @@ int net_bind(int sockfd, const struct net_sockaddr *addr, int addrlen) {
}
/*
* 函数功能:驱动 sock_reset 原语的有界确定性排渣等待(P2b 收口,自愈收敛阶段 3;
* 函数功能:驱动 sock_reset 原语的有界确定性排渣等待(排渣收口;
* 替代原"close + 盲等 500ms"式忙等)
* 入口参数:sockfd - Socket 描述符 (0~7) int
* mode - CH395F_RESET_GRACEFUL(等 100ms)/ QUARANTINE(等 400ms)
@@ -1038,7 +1038,7 @@ int net_listen_locked(int sockfd) {
ch395f_set_sour_port(sockfd, p_sock->local_port);
/* CH395F 关闭 Socket 后需延时才能重新打开(TRAP-NET-09),故失败重试最多 3 次。
* P2b 收口(自愈收敛阶段 3):原"close + 盲等 500ms"改**确定性排渣**——
* 排渣收口:原"close + 盲等 500ms"改**确定性排渣**——
* sock_reset(读空 RX -> CLOSE -> 排空事件 -> 等 byte0=00H,内置 LISTEN
* 态二段 CLOSE 补发;E4 定案 60 轮实证复位后 open 必成)。GRACEFUL
* 最短等 100ms ≪ 原 500ms 盲等;复位失败/超时仍走下一轮重试,TRAP-NET-09 语义保留 */
@@ -1084,7 +1084,7 @@ int net_listen_locked(int sockfd) {
status = ch395f_tcp_listen(sockfd);
/* LISTEN 失败 → BUSY */
if (status != CH395F_ERR_SUCCESS) {
/* 0-3(自愈收敛阶段0,U12 对称):open 已成而 LISTEN 失败必须 close,
/* U12 对称:open 已成而 LISTEN 失败必须 close,
* 否则芯片 Socket 卡"OPEN 无监听"、后续 open 恒返 USE(同
* net_relisten_locked 对应分支) */
ch395f_close_socket(sockfd);
@@ -1326,7 +1326,7 @@ int net_accept(int sockfd, struct net_sockaddr *addr, int *addrlen) {
return msg.result;
}
/* 自愈收敛阶段1(F-NET-4):net_can_accept 已删除——它只认 ESTABLISHED,作为 accept
/* F-NET-4:net_can_accept 已删除——它只认 ESTABLISHED,作为 accept
* 门控会把"监听器在服役但本轮还没 CONNECT"的窗口全挡掉(:2404 CONNECT 事件补 accept 探针
* 因此从不运行,与已修的 :7003 探针失效同型);唯一生产调用者 iec104 已迁
* net_listener_armed。net_can_read(RECV 门控)不受影响、保留。 */
@@ -1338,11 +1338,11 @@ int net_accept(int sockfd, struct net_sockaddr *addr, int *addrlen) {
* 返回值:1 - 就绪(LISTENING,或 CLOSED + auto_relisten = 断连待重建态);
* 0 - 未就绪(fd 未分配 / 非监听型 / 正处隔离期以外的不就绪态) int
* 限定条件:任意任务上下文;net_init() 已调用
* 函数说明:1. N-32(P1 不变量 II):取代已退役的 net_can_accept()(要求
* ESTABLISHED,自愈收敛阶段1 删除)作为监听 accept 门控。原门控下
* 函数说明:1. 不变量 II(单一重建所有者):取代已退役的 net_can_accept()(只认
* ESTABLISHED,F-NET-4 删除)作为监听 accept 门控。原门控下
* :7003 永不进 net_accept →
* net_lost_connect_probe(CONNECT 事件未收到补 accept)对该端口从不运行
* (设计文档 §2.3 末"探针失效")
* (F-NET-4)
* 2. 为什么放行 LISTENING:探针与"closed-but-readable 接受"(:1338)
* 只在 net_accept_locked 内部发生,门控挡在外面就永远到不了;
* LISTENING 态 accept 由探测补 accept 或返 WOULDBLOCK,均安全
@@ -1364,7 +1364,7 @@ int net_listener_armed(int sockfd) {
/* 连接已到、应用尚未 accept:单连接模型下 CONNECT 处理(net_poll 分派 /
* 探针补 accept / 对账② standalone accept)把监听 fd 转 ESTABLISHED,
* 这就是"待 accept"电平——**必须放行**(原 net_can_accept 唯一放行态;
* 自愈收敛阶段1 i104 台架实证:200ms 任务周期抢不过对账②的 ~400ms 去抖,
* i104 台架实证:200ms 任务周期抢不过对账②的 ~400ms 去抖,
* 对账②先转 ESTABLISHED → 不放行则应用永不 accept、会话整场饿死)。
* 无 RPC 风暴风险:此态下 accept 必返 fd,一次调用即离开本分支 */
if (p_sock->state == NET_SOCK_STATE_ESTABLISHED) {
@@ -1380,7 +1380,7 @@ int net_listener_armed(int sockfd) {
* 仍能拿到该连接。
* ⚠ 无残留时必须返回 0 —— 否则调用方会在整个 CLOSED 窗口内每轮都发起
* net_accept(RPC:入队 + xTaskNotifyWait 回执**无上界**)→ 队列积压 →
* 调用方任务喂不上狗。2026-10-12 P2a 台架实测:删掉即时 relisten 后 CLOSED
* 调用方任务喂不上狗。台架实测:删掉即时登记重建后 CLOSED
* 窗口被拉长到 reconciler 周期 + 隔离期(~100ms),:21 0ms×50 期间出现 48 条
* `[WD] task stall`(mask=0x67/req=0x77,缺 bit4=UI)。
* 重建本身由 net_reconcile_tick 形态③④ 负责,调用方**无需**在此催促。
@@ -1501,7 +1501,7 @@ int net_connect(int sockfd, const struct net_sockaddr *addr, int addrlen) {
* 限定条件:net_init() 已调用;必须在 netTask 上下文中调用
* 函数说明:1. 校验控制块(in_use、TCP 类型、地址参数)并保存对端地址
* 2. 芯片侧 OPEN(失败重试 3 次,每次失败走 sock_reset 确定性排渣,
* 见 TRAP-NET-09 / P2b)+ 配置源/目的端口与目的 IP
* 见 TRAP-NET-09)+ 配置源/目的端口与目的 IP
* 3. 清本 Socket 残留中断状态(丢弃上一条连接遗留的 DISCONNECT)
* 4. 发起 TCP_CONNECT(驱动内已轮询 CMD_STATUS)并置 CONNECTING;
* 命令级被拒立即关 Socket 返 -1,TCP 层成败仍由 CONNECT/TIMEOUT 裁定
@@ -1553,7 +1553,7 @@ static int net_connect_locked(int sockfd, const struct net_sockaddr *addr, int a
ch395f_set_proto_type(sockfd, CH395F_PROTO_TYPE_TCP);
/* CH395F 关闭 Socket 后需延时才能重新打开(TRAP-NET-09),故失败重试最多 3 次。
* P2b 收口(自愈收敛阶段 3):原"close + 盲等 500ms"改**确定性排渣**——
* 排渣收口:原"close + 盲等 500ms"改**确定性排渣**——
* sock_reset(读空 RX -> CLOSE -> 排空事件 -> 等 byte0=00H,内置 LISTEN
* 态二段 CLOSE 补发;E4 定案 60 轮实证复位后 open 必成)。GRACEFUL
* 最短等 100ms ≪ 原 500ms 盲等;复位失败/超时仍走下一轮重试,TRAP-NET-09 语义保留 */
@@ -1574,7 +1574,7 @@ static int net_connect_locked(int sockfd, const struct net_sockaddr *addr, int a
}
/* 清掉本 Socket 可能残留的中断状态,丢弃上一条连接遗留的 DISCONNECT。
* F-NET-7(自愈收敛阶段 3):只清**本 Socket** SINT(驱动护栏原语)——原
* F-NET-7:只清**本 Socket** SINT(驱动护栏原语)——原
* "再读清全局"会焊死其它在用 Socket 的事件位(全局寄存器唯一读者=net_poll) */
(void)ch395f_sock_events((uint8_t)sockfd);
@@ -1670,7 +1670,7 @@ static int net_connect_locked(int sockfd, const struct net_sockaddr *addr, int a
* netTask 最坏停滞由 1s 压到 NET_SEND_SPIN_MS。
* ⚠ 仅**写块前**的等待可挂起:末块写完后 sent == len,此时超预算必须
* 直接返回 sent 而非登记(登记函数按 sent >= len 拒收,会把完整发送
* 报成 -1;2026-10-14 台架实证,详见《Net层阻塞模型架构设计.md》 §9.1)
* 报成 -1;详见《Net层阻塞模型架构设计.md》 §5.5 末块边界)
* 4. 发送中途断连(状态非 ESTABLISHED)→ 立即失败并返回已发字节
* (errno=CONNRESET,不再空等超时)
* 5. 未写完即返回(含挂起完成)均为**短写**:调用方须按 ret != len 判定
@@ -1810,7 +1810,7 @@ static int net_send_locked(net_sock_t *p_sock, const void *buf, int len,
* buf - 接收缓冲区指针 void *
* len - 缓冲区大小 int > 0
* flags - 标志位,NET_MSG_DONTWAIT 表示非阻塞 int
* timeout_ms - 本次等待预算(0 = 无限等待,自愈收敛阶段 1.5 起无默认值)uint32_t
* timeout_ms - 本次等待预算(0 = 无限等待,无默认值)uint32_t
* caller - 调用方任务句柄(挂起请求的完成通知目标) TaskHandle_t
* 出口参数:buf - 填充接收到的数据
* 返回值:实际接收字节数(> 0);0 表示对端关闭;-1 表示出错/非阻塞无数据 int
@@ -1818,7 +1818,7 @@ static int net_send_locked(net_sock_t *p_sock, const void *buf, int len,
* 限定条件:p_sock 非空;netTask 上下文
* 函数说明:1. 数据已在(快速路径)→ 立即读出返回
* 2. 非阻塞(NET_MSG_DONTWAIT 单次覆盖 **或** socket blocking 属性为 0,
* 自愈收敛阶段 1.5 模式属性)无数据立即返回 -1(NET_ERR_WOULDBLOCK)
* 模式属性)无数据立即返回 -1(NET_ERR_WOULDBLOCK)
* 3. 无数据 + 阻塞等待 → 登记挂起请求(pending 化,E-02 结构演进)
* 4. netTask 零占用立即返回;完成条件(数据/到点[仅显式预算]/断连)由 net_pending_tick 按主循环节拍检查
* 5. 并通知 caller;关闭/网络重建/陈旧重同步由对应路径显式结束(取消必通知)
@@ -1835,7 +1835,7 @@ static int net_recv_locked(net_sock_t *p_sock, void *buf, int len, int flags,
}
/* 超时来源:只有调用方显式预算(net_recv_to);0 = 无限等待
* (自愈收敛阶段 1.5:NET_RECV_TIMEOUT_MS 30s 默认预算已删,API 不强加隐藏值) */
* (NET_RECV_TIMEOUT_MS 30s 默认预算已删,API 不强加隐藏值) */
uint32_t to_ms = timeout_ms;
/* 先轮询一次:刷新状态机与可读标志 */
@@ -1859,7 +1859,7 @@ static int net_recv_locked(net_sock_t *p_sock, void *buf, int len, int flags,
}
/* 非阻塞模式:NET_MSG_DONTWAIT 单次覆盖,或 socket 的 blocking 属性为 0
* (net_setblocking(fd, 0),自愈收敛阶段 1.5 模式挂控制块属性) */
* (net_setblocking(fd, 0),模式挂控制块属性) */
if ((flags & NET_MSG_DONTWAIT) || (p_sock->blocking == 0U)) {
/* 非阻塞且当前无数据:若连接已断开则视为 EOF(0) 并自动重监听,
* 否则返回 WOULDBLOCK(-1) 表示暂时无数据 */
@@ -1905,7 +1905,7 @@ static int net_recv_locked(net_sock_t *p_sock, void *buf, int len, int flags,
* 出口参数:无
* 返回值:0 - 关闭成功 int
* 限定条件:必须在 netTask 上下文中调用;p_sock 有效
* 函数说明:1. P2b 收口(自愈收敛阶段 3):原"close + 500ms 盲等排空循环"改
* 函数说明:1. 排渣收口:原"close + 500ms 盲等排空循环"改
* **确定性 sock_reset**(读空 RX -> CLOSE(幂等) -> 排空本 Socket
* 事件(quiescent) -> 等 byte0=00H,内置 LISTEN 态二段 CLOSE 补发
* ——E2 补充发现:一次 CLOSE 只拆监听 byte0 恒 05)
@@ -2077,7 +2077,7 @@ int net_send(int sockfd, const void *buf, int len, int flags) {
/*
* 函数功能:接收数据(线程安全版本,通过消息队列委托给 netTask;
* **默认无限阻塞**——自愈收敛阶段 1.5 语义主流化,30s 默认预算已删)
* **默认无限阻塞**,30s 默认预算已删)
* 入口参数:sockfd - Socket 描述符 int >= 0 && < NET_MAX_SOCKETS
* buf - 接收缓冲区指针 void *
* len - 缓冲区大小 int > 0
@@ -2121,7 +2121,7 @@ int net_recv(int sockfd, void *buf, int len, int flags) {
msg.len = len;
/* 标志:0=按 socket 阻塞属性,NET_MSG_DONTWAIT=单次非阻塞 */
msg.flags = flags;
/* 0 = 无限等待(自愈收敛阶段 1.5:无默认预算;显式预算走 net_recv_to) */
/* 0 = 无限等待(无默认预算;显式预算走 net_recv_to) */
msg.timeout_ms = 0U;
/* 调用方任务句柄(netTask 凭它回传回执) */
msg.caller = xTaskGetCurrentTaskHandle();
@@ -2147,7 +2147,7 @@ int net_recv(int sockfd, void *buf, int len, int flags) {
}
/*
* 函数功能:接收数据(非阻塞具名入口——自愈收敛阶段 1.5 把 NET_MSG_DONTWAIT 路径转正,
* 函数功能:接收数据(非阻塞具名入口——原 NET_MSG_DONTWAIT 路径转正,
* 对齐 BSD recv(MSG_DONTWAIT) / Python recv 非阻塞模式的"名如其义")
* 入口参数:sockfd - Socket 描述符 int >= 0 && < NET_MAX_SOCKETS
* buf - 接收缓冲区指针 void *
@@ -2167,7 +2167,7 @@ int net_recv_nb(int sockfd, void *buf, int len) {
/*
* 函数功能:接收数据(带调用方指定超时的阻塞版,用于分片有界读;
* 自愈收敛阶段 1.5 起为**显式预算**便捷入口,等价 Python settimeout,
* 为**显式预算**便捷入口,等价 Python settimeout,
* 不再有隐藏默认值)
* 入口参数:sockfd - Socket 描述符 int >= 0 && < NET_MAX_SOCKETS
* buf / len - 接收缓冲与容量 void * / int > 0
@@ -2199,7 +2199,7 @@ int net_recv_to(int sockfd, void *buf, int len, uint32_t timeout_ms) {
}
/* ---- 3. 分片长度检查:timeout_ms = 0 在 netTask 侧意味着"**无限等待**"
* (自愈收敛阶段 1.5 删除 30s 默认预算),恰与本接口"有界等待"的存在
* (已删除 30s 默认预算),恰与本接口"有界等待"的存在
* 理由相反,直接拒绝 ---- */
if (timeout_ms == 0U) {
/* 分片长度必须 > 0 */
@@ -2508,7 +2508,7 @@ int net_sendto(int sockfd, const void *buf, int len, int flags,
* 限定条件:Socket 已创建且为 UDP 类型(SOCK_DGRAM);net_init() 已调用;有数据可用
* 函数说明:1. 轮询检查芯片接收缓冲(net_poll + get_recv_len),有数据即返回
* 2. UDP 数据报前 8 字节为报文头(源端口+源 IP),据此填充 src_addr
* 3. 无数据时(自愈收敛阶段 1.5,与 net_recv 同构):DONTWAIT / 非阻塞属性
* 3. 无数据时(与 net_recv 同构):DONTWAIT / 非阻塞属性
* 立即返回 -1(WOULDBLOCK);阻塞模式**无限等待**(30s 默认预算已删;
* 本接口为轮询自旋实现且无生产调用者,受 IWDG 监控的任务勿用无限形态)
*/
@@ -2535,7 +2535,7 @@ int net_recvfrom(int sockfd, void *buf, int len, int flags,
return NET_ERR_RETURN_1(NET_ERR_INVAL);
}
/* 轮询直到:有数据 / 非阻塞(自愈收敛阶段 1.5:阻塞 = 无限等待,无默认预算) */
/* 轮询直到:有数据 / 非阻塞(阻塞 = 无限等待,无默认预算) */
while (1) {
/* 轮询一次:更新状态机与可读标志 */
net_poll();
@@ -2588,13 +2588,13 @@ int net_recvfrom(int sockfd, void *buf, int len, int flags,
}
/* 非阻塞模式:NET_MSG_DONTWAIT 单次覆盖,或 socket blocking 属性为 0
* (自愈收敛阶段 1.5,与 net_recv_locked 同判据):无数据立即返回 */
* (与 net_recv_locked 同判据):无数据立即返回 */
if ((flags & NET_MSG_DONTWAIT) || (p_sock->blocking == 0U)) {
/* 置 WOULDBLOCK */
return NET_ERR_RETURN_1(NET_ERR_WOULDBLOCK);
}
/* 阻塞模式:无数据继续轮询等待(自愈收敛阶段 1.5:无限等待,无默认预算——
/* 阻塞模式:无数据继续轮询等待(无限等待,无默认预算——
* 旧 NET_RECV_TIMEOUT_MS 30s 兜底已删;唤醒源 = 数据,与 net_recv 的
* 差异是本接口为自旋实现,勿在受 IWDG 监控任务中使用无限形态) */
}
@@ -2706,7 +2706,7 @@ int net_set_event_cb(int sockfd, net_event_cb_t cb, void *arg) {
}
/*
* 函数功能:设置 Socket 阻塞/非阻塞**模式属性**(自愈收敛阶段 1.5,模式挂控制块属性,
* 函数功能:设置 Socket 阻塞/非阻塞**模式属性**(模式挂控制块属性,
* 对齐 BSD O_NONBLOCK / Python setblocking)
* 入口参数:sockfd - Socket 描述符 int >= 0 && < NET_MAX_SOCKETS
* on - 1 = 阻塞(net_socket 默认);0 = 非阻塞 int
@@ -2784,7 +2784,7 @@ int net_sock_state(int sockfd) {
return (int)s_net_socks[sockfd].state;
}
/* 自愈收敛阶段1(F-NET-3):手动自愈 API net_resync_listen / net_relisten 已删除——
/* F-NET-3:手动自愈 API net_resync_listen / net_relisten 已删除——
* RESYNC 语义并入对账⑤(net_reconcile_tick 自动认领"芯片静默回收回 LISTEN"形态,
* 200ms×2 去抖 + 1s 冷却沿用);RELISTEN 与 reconciler/D10 完全重叠且对健康监听器是
* footgun(无条件 open→USE→close 自毁 ~1s,原注释自认)。生产调用者本就为零
+14 -14
View File
@@ -37,8 +37,8 @@ typedef enum {
NET_MSG_CONNECT,
NET_MSG_LISTEN,
NET_MSG_ACCEPT,
NET_MSG_DROP_CONN, /* 自愈收敛阶段 3(E-02 收口):主动拆会话、保监听(见 net_drop_conn) */
/* 自愈收敛阶段1(F-NET-2/3):NET_MSG_RESYNC_LISTEN / NET_MSG_RELISTEN 已删——
NET_MSG_DROP_CONN, /* E-02 收口:主动拆会话、保监听(见 net_drop_conn) */
/* F-NET-2/3:NET_MSG_RESYNC_LISTEN / NET_MSG_RELISTEN 已删——
* 静默回收由对账⑤自动认领(net_reconcile_tick),重建由 reconciler
* 形态③④/D10 单一
* 所有者负责;手动自愈 API 面退役(生产调用者本就为零) */
@@ -51,7 +51,7 @@ typedef struct {
int len; /* 数据长度/缓冲区大小 */
int flags; /* 接收标志 */
uint32_t timeout_ms; /* 接收超时(入队方向;0 = 无限等待,无默认预算——
* 自愈收敛阶段 1.5 删除 NET_RECV_TIMEOUT_MS 30s 默认) */
* NET_RECV_TIMEOUT_MS 30s 默认已删除) */
TaskHandle_t caller; /* 调用方任务句柄 */
int result; /* 操作结果 */
/* 连接参数 */
@@ -154,7 +154,7 @@ int net_listen(int sockfd);
*/
int net_accept(int sockfd, struct net_sockaddr *addr, int *addrlen);
/* 自愈收敛阶段1(F-NET-4):net_can_accept 已退役——只认 ESTABLISHED 的旧门控会把
/* F-NET-4:net_can_accept 已退役——只认 ESTABLISHED 的旧门控会把
* "监听器在服役、本轮待 CONNECT"窗口全挡掉(CONNECT 事件补 accept 探针因此从不运行);
* 监听 accept 门控统一用 net_listener_armed(),recv 门控 net_can_read() 保留。 */
@@ -165,18 +165,18 @@ int net_accept(int sockfd, struct net_sockaddr *addr, int *addrlen);
* 返回值:1 - 就绪(ESTABLISHED 待 accept / LISTENING / CLOSED+auto_relisten
* +残留数据);0 - 不就绪 int
* 限定条件:net_init() 已调用;任意任务上下文
* 函数说明:1. N-32(P1 不变量 II,自愈收敛阶段1 补齐 ESTABLISHED 放行):取代已退役的
* 函数说明:1. 不变量 II(单一重建所有者;补齐 ESTABLISHED 放行):取代已退役的
* `net_can_accept()`(只认 ESTABLISHED)作为监听 accept 门控——原门控使
* :7003 永不进 `net_accept()`,
* `net_lost_connect_probe`(CONNECT 事件未收到补 accept,N-30 实证的
* "数据被吞/425"主根因修复)对该端口等于从未运行
* 2. 放行 LISTENING:探针与 "closed-but-readable 接受" 都发生在
* `net_accept_locked` **内部**,门控挡在外面就永远到不了
* 2b. 放行 ESTABLISHED(自愈收敛阶段1 台架修正):单连接模型下 CONNECT 处理
* 2b. 放行 ESTABLISHED(i104 台架实证):单连接模型下 CONNECT 处理
* (net_poll 分派 / 探针补 accept / 对账② standalone accept)把监听 fd
* 转 ESTABLISHED,这正是"待 accept"电平——漏放行则任务周期慢的消费者
* (i104 200ms 抢不过对账② ~400ms 去抖)永不 accept、会话整场饿死
* (2026-10-13 实测全 18 项 FAIL)。此态 accept 必返 fd,无风暴风险
* (实测全 18 项 FAIL)。此态 accept 必返 fd,无风暴风险
* 3. 放行 CLOSED+auto_relisten **且 readable≠0**(有残留数据):
* 保住 N-30 的 "closed-but-readable" 接受;**无残留时必须返回 0**,
* 否则调用方会在整个 CLOSED 窗口内每轮发起 `net_accept`(RPC 无上界)
@@ -242,7 +242,7 @@ int net_connect(int sockfd, const struct net_sockaddr *addr, int addrlen);
int net_send(int sockfd, const void *buf, int len, int flags);
/*
* 函数功能:接收数据(TCP,**默认无限阻塞**——自愈收敛阶段 1.5 语义主流化)
* 函数功能:接收数据(TCP,**默认无限阻塞**)
* 入口参数:sockfd - socket 描述符
* buf - 接收缓冲区
* len - 缓冲区大小
@@ -263,7 +263,7 @@ int net_send(int sockfd, const void *buf, int len, int flags);
int net_recv(int sockfd, void *buf, int len, int flags);
/*
* 函数功能:接收数据(非阻塞具名入口,原 NET_MSG_DONTWAIT 路径转正——自愈收敛阶段 1.5)
* 函数功能:接收数据(非阻塞具名入口,原 NET_MSG_DONTWAIT 路径转正)
* 入口参数:sockfd - socket 描述符
* buf - 接收缓冲区
* len - 缓冲区大小
@@ -277,7 +277,7 @@ int net_recv_nb(int sockfd, void *buf, int len);
/*
* 函数功能:设置 Socket 阻塞/非阻塞**模式属性**(对齐 BSD O_NONBLOCK / Python
* setblocking——自愈收敛阶段 1.5,模式挂 socket 控制块属性)
* setblocking,模式挂 socket 控制块属性)
* 入口参数:sockfd - socket 描述符
* on - 1 = 阻塞(net_socket 默认);0 = 非阻塞
* 返回值:0 成功;-1 失败(描述符无效/未占用)
@@ -298,7 +298,7 @@ int net_setblocking(int sockfd, int on);
* timeout_ms - 单次调用在 netTask 内的最长等待(毫秒,>0)
* 返回值:>0 实际字节数;0 = 对端关闭(EOF);-1 = 真错误(errno 可查);**-2 = 超时无数据**
* 限定条件:非 netTask 上下文;Socket 已连接
* 函数说明:1. **显式预算**便捷入口(等价 Python settimeout,自愈收敛阶段 1.5 起
* 函数说明:1. **显式预算**便捷入口(等价 Python settimeout,
* 不再有隐藏默认值):net_recv 的无限阻塞 + 本接口的显式预算构成
* 超时语义的全部来源;超时首选仍是 net_select
* 2. E-02 修复配套:lftpd 等"等对端下一行/下一块数据"的调用方
@@ -335,7 +335,7 @@ int net_sendto(int sockfd, const void *buf, int len, int flags,
* 返回值:实际接收字节数,失败返回 -1
* 限定条件:socket 已创建,指针非空
* 函数说明:1. 读取 CH395F 接收缓冲区,获取对端地址
* 2. 阻塞语义与 net_recv 同(自愈收敛阶段 1.5):blocking 属性下无数据
* 2. 阻塞语义与 net_recv 同:blocking 属性下无数据
* 无限等待,DONTWAIT / 非阻塞属性立即 NET_ERR_WOULDBLOCK;
* 本接口为轮询自旋实现(历史遗留,UDP 专用),受 IWDG 监控的
* 任务同样禁止对其无限等待
@@ -353,7 +353,7 @@ int net_recvfrom(int sockfd, void *buf, int len, int flags,
int net_close(int sockfd);
/*
* 函数功能:主动拆掉当前 TCP 会话,**保留监听**(自愈收敛阶段 3,E-02 收口)
* 函数功能:主动拆掉当前 TCP 会话,**保留监听**(E-02 收口)
* 入口参数:sockfd - socket 描述符
* 返回值:0 成功(含幂等:无活动会话),-1 失败
* 限定条件:非 netTask 上下文(经消息队列委托,同其它 net_* API)
@@ -409,7 +409,7 @@ int net_get_errno(void);
*/
int net_sock_state(int sockfd);
/* 自愈收敛阶段1(F-NET-3):net_resync_listen / net_relisten 声明已删——
/* F-NET-3:net_resync_listen / net_relisten 声明已删——
* 静默回收形态由对账⑤自动认领(2 轮去抖 + 1s 冷却,纪律"不发芯片命令"
* 原样保留在认领动作内);监听重建由 reconciler 形态③④(100ms 周期)/
* D10(30ms 重试)单一所有者。勿再引入"应用层手动自愈"入口。 */
+3 -4
View File
@@ -48,8 +48,7 @@ extern "C" {
* 接收标志定义
*/
#define NET_MSG_DONTWAIT 0x01 /* 非阻塞模式(单次覆盖 socket 的 blocking 属性;
* 具名入口见 net_recv_nb() / net_setblocking(),
* 自愈收敛阶段 1.5) */
* 具名入口见 net_recv_nb() / net_setblocking()) */
/*
* 网络字节序转换宏
@@ -112,7 +111,7 @@ struct net_sockaddr_in {
/*
* Socket 状态枚举(**本层会话投影**,非芯片状态事实源)
* 自愈收敛阶段 3(镜像降级,docs/网络/网络自愈架构设计.md §3.3):
* 镜像降级(docs/网络/网络自愈架构设计.md §3.3):
* 芯片侧状态唯一事实源=驱动状态缓存(ch395f_sock_state_cached,刷新点=net_poll);
* 本 8 态只表达**本层会话语义**(fd 生命周期/待 accept 电平/门控展示),
* 事件与对账把它与芯片事实对齐。新增"按芯片状态决策"的代码一律读驱动缓存,
@@ -178,7 +177,7 @@ typedef struct {
/* 单连接模式自动重监听:连接断开后由 net 层自动回到 LISTEN(BSD 风格监听常驻) */
uint8_t auto_relisten;
/* 自愈收敛阶段 1.5(2026-10-13):阻塞/非阻塞**模式属性**(对齐 BSD O_NONBLOCK /
/* 阻塞/非阻塞**模式属性**(对齐 BSD O_NONBLOCK /
* Python setblocking 的"模式归使用者"模型)。
* 1 = 阻塞(net_socket() 默认);0 = 非阻塞(net_setblocking(fd, 0))。
* net_recv() 无 NET_MSG_DONTWAIT 时按本属性决定"无数据 → 登记挂起等待"