diff --git a/Drivers/BSP/CH395F/ch395f.h b/Drivers/BSP/CH395F/ch395f.h index c4e4732e..4f0977e1 100644 --- a/Drivers/BSP/CH395F/ch395f.h +++ b/Drivers/BSP/CH395F/ch395f.h @@ -143,9 +143,8 @@ extern "C" { * CH395F_SPI_DMA_MAX_PAYLOAD: 单次 DMA 事务最大有效载荷(总缓冲 - 4 字节命令头) * 缓冲按"一条命令读空整个 Socket 接收缓冲(2KB)"定容——排空契约(TRAP-NET-20, * bit3=1 残数据由 MCU 读出)的形态本身就是整缓冲单读。 - * (历史注记:旧注释把定容理由归给"部分读致 recv_len 归零、剩余数据不可见",该机理 - * 2026-10-11 复核**未证实**且与手册 §5.34 相左,已降级为未证实历史观察,结案见 - * `CH395F_Trap_Records.md` 台架纪律;定容不依赖该观察。) + * (旧解释"部分读致 recv_len 归零、剩余数据不可见"未证实且与手册 §5.34 相左, + * 定容不依赖该解释;结案见 `CH395F_Trap_Records.md` 台架纪律。) * 2026-09-22:与 MSS 解耦(此前 = 2×MSS+4,MSS 下调会把 DMA 缓冲缩到装不下整缓冲 * → 整缓冲读会被截断丢弃)。 */ diff --git a/Drivers/BSP/NET/README.md b/Drivers/BSP/NET/README.md index 929a554a..922da455 100644 --- a/Drivers/BSP/NET/README.md +++ b/Drivers/BSP/NET/README.md @@ -7,7 +7,8 @@ | 文件 | 作用 | |---|---| -| `net_socket.c/h` | **BSD Socket API 实现**:`net_socket` / `net_connect` / `net_send` / `net_recv` / `net_close` / `net_listen` / `net_accept`,含 L3 挂起(pending)与错误码 | +| `net_socket.c/h` | **BSD Socket API 实现**:`net_socket` / `net_connect` / `net_send` / `net_recv` / `net_close` / `net_listen` / `net_accept`,含挂起 recv(pending)与错误码 | +| `net_pending.c/h` | **挂起 recv 请求表**(阻塞 recv 挂起模型:登记 / 每轮完成检查 / 取消 / close 结算;真机专属,模拟器走 `net_socket_sim.c`) | | `net_select.c/h` | `select`/`poll` 多路复用(基于芯片中断事件 + 周期轮询) | | `net_types.h` | 网络层公共类型定义 | | `net_config.h` | 网络层编译期配置(缓冲区大小、超时、对账周期等) | @@ -15,7 +16,7 @@ ## 核心机制 -### 阻塞模型(L3 pending) +### 阻塞模型(挂起 recv / pending) - 一期(RECV)已落地:`net_recv` 等支持带超时的阻塞(`pending` 挂起 + tick 唤醒) - 二期(ACCEPT + SEND)待做 → `docs/任务规划/登记簿.md` N-4 diff --git a/Drivers/BSP/NET/lftpd/lftpd_inet.c b/Drivers/BSP/NET/lftpd/lftpd_inet.c index 4492eb2f..ca0f2f03 100644 --- a/Drivers/BSP/NET/lftpd/lftpd_inet.c +++ b/Drivers/BSP/NET/lftpd/lftpd_inet.c @@ -6,16 +6,13 @@ #include /* - * E-02 头阻塞修复 + L3 pending 化(2026-09-22,M3 台架实证): - * netTask 是全部 socket 操作的唯一执行者;lftpd 原先用默认 30s 的**阻塞** - * net_recv 等待对端下一行/下一块数据 → 只要客户端连上却不发完整行,netTask - * 就被长期占用,其余任务(含远端显示)的网络操作整体冻结(实测一次空闲 FTP - * 登录让 LCDMEM 整帧等待 17.7s)。 - * 2026-09-22 先落地分片有界读(5ms 片;实测 100ms 片下受压帧仍达 ~750ms, - * 收到 5ms 后降到 ~10ms 量级,见 m3_data 修复后数据),同日 L3 pending 化 - * 后改为"挂起请求":每次等待 = 一次挂起登记(netTask 零占用,完成按主循环 - * 节拍检查),调用方单次超时 = 剩余总预算(总等待 ≤ LFTPD_TOTAL_BUDGET_MS, - * **总超时语义与旧实现一致**),旧分片协议退役。 + * E-02 头阻塞修复 + recv pending 化(M3 台架实证): + * netTask 是全部 socket 操作的唯一执行者;lftpd 若用**阻塞** net_recv 等待对端 + * 下一行/下一块数据 → 只要客户端连上却不发完整行,netTask 就被长期占用, + * 其余任务(含远端显示)的网络操作整体冻结(实测一次空闲 FTP 登录让 LCDMEM + * 整帧等待 17.7s)。 + * 现形态:每次等待 = 一次挂起登记(netTask 零占用,完成按主循环节拍检查), + * 调用方单次超时 = 剩余总预算(总等待 ≤ LFTPD_TOTAL_BUDGET_MS)。 */ #define LFTPD_TOTAL_BUDGET_MS 30000U @@ -133,8 +130,8 @@ int lftpd_inet_read_line(int socket, char *buffer, size_t buffer_len) int total_read_len = 0; while (total_read_len < (int)buffer_len) { - /* 单次预算 = 剩余总预算(L3 pending:等待期 netTask 零占用,调用方 - * 在自己上下文睡任务通知,旧片间 vTaskDelay(1) 让出退役) */ + /* 单次预算 = 剩余总预算(pending:等待期 netTask 零占用,调用方 + * 在自己上下文睡任务通知) */ TickType_t elapsed = xTaskGetTickCount() - t0; uint32_t rem = (elapsed >= (TickType_t)pdMS_TO_TICKS(LFTPD_TOTAL_BUDGET_MS)) ? 0U : (uint32_t)((TickType_t)LFTPD_TOTAL_BUDGET_MS - elapsed); @@ -215,8 +212,8 @@ int lftpd_inet_write(int socket, const void *buf, int len) int lftpd_inet_read(int socket, void *buf, int len) { - /* L3 pending 读:总预算 30s 不变,等待期 netTask 零占用 - * (空闲数据连接不再冻结全网;旧分片协议随 L3 pending 化退役) */ + /* pending 读:总预算 30s 不变,等待期 netTask 零占用 + * (空闲数据连接不再冻结全网) */ TickType_t t0 = xTaskGetTickCount(); for (;;) { diff --git a/Drivers/BSP/NET/net_listener.c b/Drivers/BSP/NET/net_listener.c index 0e6023ff..bceb1ffa 100644 --- a/Drivers/BSP/NET/net_listener.c +++ b/Drivers/BSP/NET/net_listener.c @@ -33,9 +33,10 @@ #include "net_socket.h" /* net_sock_t / net_get_sock / NET_MAX_SOCKETS / net_set_errno */ #include "net_listener.h" +#include "net_pending.h" /* net_pending_active(挂起 recv 保险查询) */ #include "ch395f.h" #include "test_config.h" /* TEST_LATENCY_PROBE(链路时延探针编译开关) */ -#include "net_latency_test.h" /* L3 探针接口(relisten 恢复计时采样) */ +#include "net_latency_test.h" /* 延迟探针接口(relisten 恢复计时采样) */ #include "main.h" #include "dbg_log.h" @@ -182,7 +183,7 @@ static int net_relisten_locked(int sockfd) { * 其它在用 Socket 的 CONNECT/DISCONNECT/RECV_OK(net_poll 门控焊死); * ③ M1 使沉降成为每次断连热路径后,该搁浅被放大为 FTP 控制/数据通道 * 互杀(E7 实测:lftpd 5s 超时、closed-with-data 救回全部迟到)。 - * 本 Socket 残留全局位交 net_poll 正常读到时 SINT 已为 0,无害了结 */ + * 本 Socket 残留全局位交 net_poll 正常读到时 SINT 已为 0,自然收尾 */ /* 读芯片当前状态(两字节) */ ch395f_get_socket_status((uint8_t)sockfd, st); @@ -289,10 +290,10 @@ static int net_relisten_locked(int sockfd) { * 限定条件:netTask 上下文;由 handle_disconnect_event / handle_timeout_event 调用 * 函数说明:1. 只置事实,不做动作 —— 重建由 net_reconcile_tick(形态③④)/ * net_listener_try 负责 - * 2. 越界 sockfd 静默忽略(与旧直接写 s_relisten_quarantine 行为一致) + * 2. 越界 sockfd 静默忽略 */ void net_listener_settle(int sockfd, net_listener_settle_t level) { - /* 描述符越界:静默忽略(与旧直接写数组行为一致,不设错误码) */ + /* 描述符越界:静默忽略,不设错误码 */ if ((sockfd < 0) || (sockfd >= NET_MAX_SOCKETS)) { return; } @@ -399,7 +400,7 @@ int net_listener_try(int sockfd) { * 返回值:无 * 限定条件:netTask 上下文(由 net_process_messages 每轮调用) * 函数说明:1. 到点重试待办的重监听;成功即报告探针样本 - * 2. 本 fd 有在途挂起 recv 时跳过(net_pending_active,L3 保险: + * 2. 本 fd 有在途挂起 recv 时跳过(net_pending_active,挂起 recv 保险: * 重开 Socket 会摧毁在途连接) * 3. 超过 NET_RELISTEN_DEADLINE_MS 停止 D10 快速重试并留痕 * (监听不永久失效——reconciler 100ms 周期仍按"芯片不在听"认领重建) @@ -429,7 +430,7 @@ void net_listener_retry_tick(void) { continue; } } - /* 本 fd 有在途挂起 recv:重开 Socket 会摧毁在途连接(L3 保险) */ + /* 本 fd 有在途挂起 recv:重开 Socket 会摧毁在途连接(挂起 recv 保险) */ if (net_pending_active(i) != 0U) { continue; } diff --git a/Drivers/BSP/NET/net_listener.h b/Drivers/BSP/NET/net_listener.h index c6a6f849..9d140b90 100644 --- a/Drivers/BSP/NET/net_listener.h +++ b/Drivers/BSP/NET/net_listener.h @@ -49,7 +49,7 @@ typedef enum { * 限定条件:netTask 上下文;由 handle_disconnect_event / handle_timeout_event 调用 * 函数说明:1. 只置事实,不做动作 —— 重建由 net_reconcile_tick(形态③④)/ * net_listener_try 负责 - * 2. 越界 sockfd 静默忽略(不设错误码,与旧直接写数组行为一致) + * 2. 越界 sockfd 静默忽略(不设错误码) */ void net_listener_settle(int sockfd, net_listener_settle_t level); @@ -90,7 +90,7 @@ void net_listener_retry_tick(void); * net_reconcile_tick 单一 100ms tick(判据读驱动状态缓存,《网络自愈架构设计》§4.1)。 * 本模块的 net_listener_try 由 reconciler 形态③④ 与 D10 重试轮询调用。 */ -/* 注:本模块消费的宿主能力 `net_pending_active()` 声明在 net_socket.h - * (它是 net_socket.c 的函数,须与配对头文件同处,见规范 S17 2.2)。 */ +/* 注:本模块消费的宿主能力 `net_pending_active()` 声明在 net_pending.h + * (它是 net_pending.c 的函数,须与配对头文件同处,见规范 S17 2.2)。 */ #endif /* NET_LISTENER_H */ diff --git a/Drivers/BSP/NET/net_pending.c b/Drivers/BSP/NET/net_pending.c new file mode 100644 index 00000000..0ed8a0fb --- /dev/null +++ b/Drivers/BSP/NET/net_pending.c @@ -0,0 +1,416 @@ +/* + * 模块名称:挂起 recv 请求表(阻塞 recv 挂起模型)—— 实现 + * 文件说明:见 net_pending.h;架构与五路语义见 + * docs/网络/Net层阻塞模型架构设计.md + * 依赖(全部单向,无反向 include): + * net_types.h(net_sock_t / NET_ERR_* / NET_SOCK_STATE_*)/ + * net_socket.h(NET_MAX_SOCKETS / net_set_errno / NET_ERR_RETURN_1 / + * net_pending_active 声明)/ net_pending.h(本模块接口)/ + * net_listener.h(net_listener_try)/ ch395f.h(RX 读出)/ main.h(HAL_GetTick) + * 限定条件:本文件真机专属——模拟器走 sim/net_socket_sim.c, + * simulator/CMakeLists.txt 不编译本文件(同 net_listener.c 先例) + * + * 阻塞 recv 挂起模型(E-02 结构演进):阻塞等待 = 挂起请求 + 主循环节拍完成 + * "无数据 + 阻塞等待"不再自旋占用 netTask:登记 pending 后立即返回 + * net_pending_tick(与 D10 重监听重试同节奏,net_process_messages 开头每轮调用) + * 按 ①数据 ②到点(仅显式预算) ③断连 顺序检查完成条件并通知调用方 + * 关闭/网络重建/陈旧重同步走显式 settle/cancel 路径(取消必通知,调用方永不挂死) + * 公开 API 返回契约:>0 字节数 / 0 EOF / -1 错误(错误码经通知值回传) + * 预算归调用方:timeout_ms=0 即无限等待(无默认预算);挂起超时留痕探针为 + * 编译期选项(NET_PENDING_TRIPWIRE,默认 0 = 编译剔除) + */ + +#include + +#include "FreeRTOS.h" +#include "task.h" + +#include "net_types.h" +#include "net_socket.h" +#include "net_pending.h" +#include "net_listener.h" +#include "ch395f.h" +#include "dbg_log.h" +#include "main.h" + +typedef struct { + uint8_t active; /* 1 = 本 fd 有挂起 recv */ + uint8_t infinite; /* 1 = 无限等待(无 deadline;0 预算 = 永等) */ +#if NET_PENDING_TRIPWIRE + uint8_t tripwire_logged; /* 1 = 本轮挂起已留痕(保证只留一条) */ +#endif + void *buf; /* 调用方缓冲(仅指针,须保持有效至完成) */ + int len; /* 缓冲容量 */ + uint32_t deadline; /* 截止时刻(tick)= 登记时刻 + 本次预算(infinite=1 时无意义) */ + uint32_t registered; /* 登记时刻(tick;留痕探针/日志基准) */ + TaskHandle_t caller; /* 调用方任务(完成通知目标) */ +} net_pending_t; + +/* 每 fd 一个挂起(禁止覆盖:覆盖丢失前调用方通知 → 挂死) */ +static net_pending_t s_net_pending[NET_MAX_SOCKETS]; +/* 执行任务(net_init 捕获;防自通知死锁) */ +static TaskHandle_t s_owner_task; + +/* + * 函数功能:捕获执行任务句柄(登记守卫据此拒绝自等待死锁) + * 入口参数:无 + * 出口参数:无 + * 返回值:无 + * 限定条件:执行任务上下文(NET 层 = netTask / 硬件层 = testTask),net_init 顶部 + */ +void net_pending_capture_owner(void) { + s_owner_task = xTaskGetCurrentTaskHandle(); +} + +/* + * 函数功能:通知调用方并清除本 fd 的挂起请求(所有完成/取消路径的公共出口) + * 入口参数:sockfd - Socket 描述符 (0~7) int + * result - 32 位结果原值(>0 字节数 / 0 EOF / 负错误码) int + * 出口参数:无 + * 返回值:无 + * 限定条件:netTask 上下文;sockfd 合法且挂起在位(否则静默返回,防重复通知) + * 函数说明:通知值 = 结果本身(与消息分派同一回传通道,调用方直接按通知值 + * 取结果);失败记入 netTask 自己的 errno 槽位(E-03) + */ +static void net_pending_complete(int sockfd, int result) { + /* 本 fd 挂起请求指针 */ + net_pending_t *p; + + /* 描述符越界:静默返回(防重复通知) */ + if ((sockfd < 0) || (sockfd >= NET_MAX_SOCKETS)) { + return; + } + /* 取挂起请求 */ + p = &s_net_pending[sockfd]; + /* 无在位挂起(已结束/已取消):静默返回 */ + if (p->active == 0U) { + return; + } + /* 失败结果:记入 netTask 自己的错误码槽位(E-03;不再写入跨任务共享全局) */ + if (result < 0) { + (void)net_set_errno(result); + } + /* 覆盖式写入通知值 = 结果本身(32 位原值) */ + xTaskNotify(p->caller, (uint32_t)result, eSetValueWithOverwrite); + /* 清除挂起状态 */ + p->active = 0U; +} + +/* + * 函数功能:登记一个挂起 recv 请求(net_recv_locked 的阻塞无数据路径) + * 入口参数:sockfd - Socket 描述符 (0~7) int + * buf - 调用方接收缓冲(须保持有效至完成) void * + * len - 缓冲容量 int + * to_ms - 本次等待预算(0 = 无限等待) uint32_t + * caller - 调用方任务句柄(完成通知目标) TaskHandle_t + * 出口参数:无 + * 返回值:NET_PENDING_REGISTERED - 登记成功(分派跳过即时通知) + * -1 - 拒绝(同 fd 已有挂起 / 执行任务自身发起) + * 限定条件:netTask 上下文 + * 函数说明:每 fd 至多一个挂起(禁止覆盖——覆盖丢失前调用方通知 = 该任务永久挂死); + * 执行任务自身发起的阻塞等待无他人可完成(tick 跑在执行任务内)→ 自等自 + * 通知 = 死锁,必须拒绝(netTask 上下文调用方须用 DONTWAIT) + */ +int net_pending_register(int sockfd, void *buf, int len, + uint32_t to_ms, TaskHandle_t caller) { + /* 挂起请求指针 */ + net_pending_t *p; + /* 登记时刻(tick) */ + uint32_t now; + + /* 描述符越界 → BADF */ + if ((sockfd < 0) || (sockfd >= NET_MAX_SOCKETS)) { + return NET_ERR_RETURN_1(NET_ERR_BADF); + } + /* 取挂起请求 */ + p = &s_net_pending[sockfd]; + + /* 同 fd 已有挂起:拒绝(覆盖将丢失前通知 = 该任务永久挂死) */ + if (p->active != 0U) { + return NET_ERR_RETURN_1(NET_ERR_BUSY); + } + /* netTask 自身发起:无他人可完成(tick 跑在 netTask 内)→ 拒绝(自等死锁) */ + if ((caller == NULL) || (caller == s_owner_task)) { + return NET_ERR_RETURN_1(NET_ERR_BUSY); + } + + /* 当前 tick(截止/留痕探针基准) */ + now = HAL_GetTick(); + /* 标记挂起在位 */ + p->active = 1U; + /* 预算形态:0 = 无限等待(无 deadline,tick ② 跳过;留痕探针以登记时刻计) */ + p->infinite = (to_ms == 0U) ? 1U : 0U; +#if NET_PENDING_TRIPWIRE + /* 留痕标记清零(每轮挂起只留一条) */ + p->tripwire_logged = 0U; +#endif + /* 调用方接收缓冲(须保持有效至完成) */ + p->buf = buf; + /* 缓冲容量 */ + p->len = len; + /* 截止时刻 = 登记时刻 + 预算(无限等待时不启用,置 0 仅为可观测性) */ + p->deadline = (to_ms == 0U) ? 0U : (now + to_ms); + /* 登记时刻(留痕探针基准) */ + p->registered = now; + /* 完成通知目标 */ + p->caller = caller; + /* 登记成功:分派跳过即时通知 */ + return NET_PENDING_REGISTERED; +} + +/* + * 函数功能:挂起 recv 完成检查(netTask 每轮 net_process_messages 调用一次,非阻塞) + * 入口参数:p_socks - Socket 控制块表首指针(net_socket.c 的 s_net_socks) net_sock_t * + * 出口参数:无 + * 返回值:无 + * 限定条件:netTask 上下文 + * 函数说明:1. 逐 fd 检查完成条件:数据到达 / 到点(仅显式预算)/ 断连 + * 2. 完成即经 net_pending_complete 通知并清除 + * 3. 挂起超时留痕探针(编译期选项 NET_PENDING_TRIPWIRE,默认关):挂起超阈值 + * 只 [ERR] 留痕一次("完成逻辑缺位"探针),绝不强制结束、绝不伪造返回值 + */ +void net_pending_tick(net_sock_t *p_socks) { + /* 当前 tick */ + uint32_t now = HAL_GetTick(); + /* Socket 循环索引 */ + int i; + + for (i = 0; i < NET_MAX_SOCKETS; i++) { + /* 本 fd 挂起请求 */ + net_pending_t *p = &s_net_pending[i]; + /* 本 fd 控制块 */ + net_sock_t *p_sock = &p_socks[i]; + + /* 无挂起请求:跳过 */ + if (p->active == 0U) { + continue; + } + + /* fd 已关闭 */ + if (p_sock->in_use == 0U) { + /* fd 已关闭(正常路径在 close 内先结束;此处兜底,防任何路径漏掉通知) */ + net_pending_complete(i, NET_ERR_CONNRESET); + continue; + } + + /* ① 数据到达(数据优先)——readable 门控:常见无数据路径零额外 SPI 事务 + * (INT# 电平触发链保证缓冲有数据时每轮重读 SINT 重位置位) */ + if ((p_sock->state == NET_SOCK_STATE_ESTABLISHED) || + (p_sock->state == NET_SOCK_STATE_UDP_OPEN)) { + /* 可读标志置位 */ + if (p_sock->readable != 0U) { + /* 查询芯片侧可用字节数 */ + int avail = ch395f_get_recv_len((uint8_t)i); + /* 有数据 */ + if (avail > 0) { + /* 本次读取量 = min(可用, 缓冲容量) */ + int rd = (avail > p->len) ? p->len : avail; + /* 读入调用方缓冲区 */ + ch395f_read_recv_buf((uint8_t)i, (uint8_t *)p->buf, (uint16_t)rd); + /* 累计接收字节统计 */ + p_sock->recv_bytes += (uint32_t)rd; + /* 数据已消费,清可读标志 */ + p_sock->readable = 0U; + /* 结束:以字节数通知 */ + net_pending_complete(i, rd); + continue; + } + /* 虚假标志:缓冲无数据,继续等待 */ + p_sock->readable = 0U; + } + } + + /* ② 到点(仅显式预算登记;无限等待登记无 deadline): + * 超时是调用方策略,net_recv_to 的预算在此兑现,不是伪造。 + * tick 差值按有符号比较,抗回绕) */ + if ((p->infinite == 0U) && ((int32_t)(now - p->deadline) >= 0)) { + /* 结束:超时(错误码由 net_pending_complete 记入本任务槽位) */ + net_pending_complete(i, NET_ERR_TIMEDOUT); + continue; + } + + /* ③ 断连:排空 → 数据或 EOF(0) + 自动重监听。 + * 判据同 net_recv_locked(N-32 P1 不变量 I):`state == CLOSED || + * session_dead`。只判 CLOSED 时,抢先 relisten 后 ①(要求 ESTABLISHED) + * 与 ③(要求 CLOSED) 两头落空 → 挂起的 recv 只能干等 ② deadline 超时 + * (lftpd 阻塞 recv 的"消费者卡死"原型)。无限等待登记没有 ②, + * 漏 ③ = 永久挂死(留痕探针只留痕、不唤醒)—— + * ③ 与显式 cancel 是无限 recv 的全部唤醒责任方,勿动判据。 */ + if ((p_sock->state == NET_SOCK_STATE_CLOSED) || (p_sock->session_dead != 0U)) { + /* 查询残留字节数 */ + int rem = ch395f_get_recv_len((uint8_t)i); + /* 有残留数据:按数据完成 */ + if (rem > 0) { + /* 本次读取量 = min(残留, 缓冲容量) */ + int rd = (rem > p->len) ? p->len : rem; + /* 读入调用方缓冲区 */ + ch395f_read_recv_buf((uint8_t)i, (uint8_t *)p->buf, (uint16_t)rd); + /* 累计接收字节统计 */ + p_sock->recv_bytes += (uint32_t)rd; + /* 数据已消费,清可读标志 */ + p_sock->readable = 0U; + /* 结束:以字节数通知 */ + net_pending_complete(i, rd); + } else { + /* 启用自动重监听:先把监听器重新置回 LISTEN。 + * ⚠ 内层 `state == CLOSED` 门同 net_recv_locked:session_dead + * 但已回 LISTENING 时重建已由别处完成,再 open+listen 会因 + * USE 错误走进关闭分支、关掉正听着的 Socket(U12 同源)。 + * N-32 P2 修正:**保留本处即时重建** —— 它只在有**挂起 recv** + * 时到达(`p->active != 0`),属"消费者在等这条连接结局"的 + * 消费者驱动路径,不是周期性抢先(同 net_recv_locked 的理由)。 */ + if ((p_sock->state == NET_SOCK_STATE_CLOSED) && + (p_sock->auto_relisten != 0U)) { + /* 非阻塞:失败由 D10 重试轮询接管(N-32 §10:入口收敛到 net_listener_try) */ + (void)net_listener_try(i); + } + /* TRAP-NET-18 待办 #3:异常释放(TIMEOUT/RST)不是正常 EOF(对端未发正常 FIN) + * → 按连接重置结束:应用(lftpd STOR)对异常结束回 5xx 而非误报 226; + * 正常 FIN(DISCONNECT)仍回 0(在途 FIN 与正常完成不可区分——协议边界,见 TRAP-NET-18 记录) */ + /* 异常释放:按连接重置结束(回 5xx,不误报 226) */ + if (p_sock->released_abnormal != 0U) { + /* 异常释放(错误码由 net_pending_complete 记入本任务槽位) */ + net_pending_complete(i, NET_ERR_CONNRESET); + } else { + /* 正常 EOF:以 0 结束 */ + net_pending_complete(i, 0); + } + } + continue; + } + + /* 其他状态(CONNECTING/LISTENING/…):保持等待状态迁移——CONNECT→ESTABLISHED + * 是合法迁移,不做状态推断取消,避免误杀正在建链的等待;陈旧 resync 由显式 cancel 处理 */ + + /* ④ 挂起超时留痕探针(编译期选项 NET_PENDING_TRIPWIRE,默认关):挂起超 + * 阈值 = "完成逻辑缺位"探针 → 只留一条 [ERR],**绝不强制结束、绝不伪造 + * TIMEDOUT 返回值**(强制结束会把完成路径缺陷伪装成普通超时,调用方 + * 拿到假结果、缺陷永远潜伏)。判据:无限登记按登记时刻计;显式登记按 + * deadline 计(② 正常不会让它越过阈值,能到这里本身就是完成逻辑缺位)。 */ +#if NET_PENDING_TRIPWIRE + if (p->tripwire_logged == 0U) { + /* 探针基准时刻:无限 = 登记时刻;显式 = 截止时刻 */ + uint32_t base = (p->infinite != 0U) ? p->registered : p->deadline; + if ((int32_t)(now - base) >= (int32_t)NET_RECV_TRIPWIRE_MS) { + /* 留痕(挂起已持续毫秒数,自基准起算) */ + DBG_ERROR("sock%d recv pending %ums (base=%s): completion source missing", + i, (unsigned)((int32_t)now - (int32_t)base), + (p->infinite != 0U) ? "infinite" : "deadline"); + /* 只留痕一次(每轮挂起一条,防日志风暴) */ + p->tripwire_logged = 1U; + } + } +#endif + } +} + +/* + * 函数功能:查询本 fd 是否有在途挂起 recv —— 宿主能力,供 net_listener 用 + * 入口参数:sockfd - Socket 描述符 (0~7) int + * 出口参数:无 + * 返回值:1 - 有挂起;0 - 无(含描述符越界) int + * 限定条件:任意上下文(纯 RAM 读,不发起 RPC) + * 函数说明:1. N-32 §10 模块化:net_listener_retry_tick 用它跳过"重开 Socket + * 会摧毁在途连接"的 fd(挂起 recv 保险,原为直接读 s_net_pending[i].active) + * 2. 声明在 net_pending.h(配对头,规范 S17 2.2) + */ +int net_pending_active(int sockfd) { + /* 描述符越界:视为无挂起 */ + if ((sockfd < 0) || (sockfd >= NET_MAX_SOCKETS)) { + return 0; + } + return (s_net_pending[sockfd].active != 0U) ? 1 : 0; +} + +/* + * 函数功能:清除本 fd 的挂起请求(不通知;用于"新 fd 不得继承"与 close 后的幂等清理) + * 入口参数:sockfd - Socket 描述符 (0~7) int + * 出口参数:无 + * 返回值:无 + * 限定条件:无 + * 函数说明:1. 静默清理不发通知:close 路径先经 settle 通知,本调用仅保证状态归零(幂等) + * 2. 新建 fd 时调用,防复用槽位继承上一条连接的挂起请求 + */ +void net_pending_clear(int sockfd) { + /* 描述符越界:直接返回 */ + if ((sockfd < 0) || (sockfd >= NET_MAX_SOCKETS)) { + return; + } + /* 挂起状态清零(静默,不发通知) */ + s_net_pending[sockfd].active = 0U; +} + +/* + * 函数功能:取消本 fd 的挂起请求并通知调用方(显式路径:陈旧 resync 等) + * 入口参数:sockfd - Socket 描述符 (0~7) int + * err - 通知的错误码(如 NET_ERR_CONNRESET) int + * 出口参数:无 + * 返回值:无(无在位挂起时静默返回) + * 限定条件:netTask 上下文 + * 函数说明:经 net_pending_complete 以指定错误码通知调用方(取消必通知,防挂死) + */ +void net_pending_cancel(int sockfd, int err) { + /* complete 内部校验范围与在位(未在位则静默返回) */ + net_pending_complete(sockfd, err); +} + +/* + * 函数功能:取消全部挂起请求并逐一通知(网络重建路径) + * 入口参数:err - 通知的错误码 int + * 出口参数:无 + * 返回值:无 + * 限定条件:netTask 上下文;须在控制块清零与芯片复位之前调用 + * 函数说明:网络重建(net_stack_bring_up)前调用,保证所有在位调用方均被唤醒 + */ +void net_pending_cancel_all(int err) { + /* 逐 fd 遍历 */ + for (int i = 0; i < NET_MAX_SOCKETS; i++) { + /* 取消并通知(未在位则静默跳过) */ + net_pending_complete(i, err); + } +} + +/* + * 函数功能:关闭前先结束本 fd 的挂起 recv——把结果回传并唤醒调用方(有数据先 + * 送达,无数据则取消),再关闭 Socket(per-fd 串行:先完成、再关闭) + * 入口参数:sockfd - 将被关闭的描述符 (0~7) int + * p_sock - 将被关闭的 Socket 控制块指针(与 sockfd 对应) net_sock_t * + * 出口参数:无 + * 返回值:无(无在位挂起时静默返回) + * 限定条件:netTask 上下文;须在 ch395f_close_socket 之前调用 + * 函数说明:先排空尝试——关闭不丢已到达数据(芯片缓冲在 close 前可读); + * 有数据按字节数通知,否则取消(NET_ERR_CONNRESET) + */ +void net_pending_settle_close(int sockfd, net_sock_t *p_sock) { + /* 通知用结果值(默认为取消) */ + int val; + /* 芯片 RX 可用字节数 */ + int avail; + + /* 描述符越界或无在位挂起:静默返回 */ + if ((sockfd < 0) || (sockfd >= NET_MAX_SOCKETS)) { + return; + } + if (s_net_pending[sockfd].active == 0U) { + return; + } + /* 默认结果 = 取消(CONNRESET) */ + val = NET_ERR_CONNRESET; + /* 查询芯片 RX 可用字节(缓冲内数据在 close 前可读) */ + avail = ch395f_get_recv_len((uint8_t)sockfd); + /* 数据已到达:排空,关闭不丢数据 */ + if (avail > 0) { + /* 本次读取量 = min(可用, 缓冲容量) */ + int rd = (avail > s_net_pending[sockfd].len) ? s_net_pending[sockfd].len : avail; + /* 读入调用方缓冲区 */ + ch395f_read_recv_buf((uint8_t)sockfd, (uint8_t *)s_net_pending[sockfd].buf, (uint16_t)rd); + /* 累计接收字节统计 */ + p_sock->recv_bytes += (uint32_t)rd; + /* 数据已消费,清可读标志 */ + p_sock->readable = 0U; + /* 有数据:以字节数通知 */ + val = rd; + } + /* 结束(必通知) */ + net_pending_complete(sockfd, val); +} diff --git a/Drivers/BSP/NET/net_pending.h b/Drivers/BSP/NET/net_pending.h new file mode 100644 index 00000000..93e822dd --- /dev/null +++ b/Drivers/BSP/NET/net_pending.h @@ -0,0 +1,119 @@ +/* + * 模块名称:挂起 recv 请求表(阻塞 recv 挂起模型) + * 文件说明:阻塞 recv 的"挂起请求"数据结构与生命周期:登记 / 每轮完成检查 / + * 取消(close、网络重建、对账 resync)/ 幂等清理。 + * 架构与五路语义见 docs/网络/Net层阻塞模型架构设计.md + * 依赖:net_types.h(net_sock_t);消费方 = net_socket.c(消息分派 / close / + * 重建 / 对账) + * 限定条件:除 net_pending_active / net_pending_clear(纯 RAM 读)外, + * 全部函数须 netTask 上下文 + */ +#ifndef NET_PENDING_H +#define NET_PENDING_H + +#include +#include "FreeRTOS.h" +#include "task.h" +#include "net_types.h" + +/* 内部哨兵:pending 已登记(消息分派据此跳过即时通知;取值不与字节数空间冲突) */ +#define NET_PENDING_REGISTERED 0x70000000 + +/* 挂起超时留痕探针:排查"调用方挂死唤不醒"时置 1——挂起超 NET_RECV_TRIPWIRE_MS + * 只留一条 [ERR](哪个 fd/多少毫秒/什么基准),绝不强制结束、绝不伪造返回值。 + * 开与关语义完全一致,差别只在留痕;默认 0 = 产品构建零成本。 + * 见 docs/网络/Net层阻塞模型架构设计.md §9 */ +#define NET_PENDING_TRIPWIRE 0 +#if NET_PENDING_TRIPWIRE +#define NET_RECV_TRIPWIRE_MS 60000U /* 挂起超时留痕阈值(ms) */ +#endif + +/* + * 函数功能:捕获执行任务句柄(net_init 顶部调用一次;登记守卫据此拒绝自等待死锁) + * 入口参数:无 + * 出口参数:无 + * 返回值:无 + * 限定条件:执行任务(netTask / 硬件层 = testTask)上下文,创建消息队列前 + */ +void net_pending_capture_owner(void); + +/* + * 函数功能:登记一个挂起 recv 请求(net_recv_locked 的阻塞无数据路径) + * 入口参数:sockfd - Socket 描述符 (0~7) int + * buf - 调用方接收缓冲(须保持有效至完成) void * + * len - 缓冲容量 int + * to_ms - 本次等待预算(0 = 无限等待) uint32_t + * caller - 调用方任务句柄(完成通知目标) TaskHandle_t + * 出口参数:无 + * 返回值:NET_PENDING_REGISTERED - 登记成功(分派跳过即时通知) + * -1 - 拒绝(同 fd 已有挂起 / 执行任务自身发起;错误码经 NET_ERR_RETURN_1) + * 限定条件:netTask 上下文 + * 函数说明:每 fd 至多一个挂起(禁止覆盖——覆盖丢失前调用方通知 = 该任务永久挂死); + * 执行任务自身发起的阻塞等待无他人可完成 → 自等自通知 = 死锁,必须拒绝 + */ +int net_pending_register(int sockfd, void *buf, int len, + uint32_t to_ms, TaskHandle_t caller); + +/* + * 函数功能:挂起 recv 完成检查(netTask 每轮 net_process_messages 调用一次,非阻塞) + * 入口参数:p_socks - Socket 控制块表首指针(net_socket.c 的 s_net_socks) net_sock_t * + * 出口参数:无 + * 返回值:无 + * 限定条件:netTask 上下文 + * 函数说明:逐 fd 按序判定:①数据到达 ②到点(仅显式预算) ③断连(排空→数据或 + * EOF/CONNRESET);命中即经公共出口通知并清槽;另有编译期留痕探针 + * (NET_PENDING_TRIPWIRE,默认关) + */ +void net_pending_tick(net_sock_t *p_socks); + +/* + * 函数功能:清除本 fd 的挂起请求(不通知;"新 fd 不得继承"与 close 后的幂等清理) + * 入口参数:sockfd - Socket 描述符 (0~7) int + * 出口参数:无 + * 返回值:无 + * 限定条件:无 + */ +void net_pending_clear(int sockfd); + +/* + * 函数功能:取消本 fd 的挂起请求并通知调用方(显式路径:对账 resync 等) + * 入口参数:sockfd - Socket 描述符 (0~7) int + * err - 通知的错误码(如 NET_ERR_CONNRESET) int + * 出口参数:无 + * 返回值:无(无在位挂起时静默返回) + * 限定条件:netTask 上下文 + */ +void net_pending_cancel(int sockfd, int err); + +/* + * 函数功能:取消全部挂起请求并逐一通知(网络重建路径) + * 入口参数:err - 通知的错误码 int + * 出口参数:无 + * 返回值:无 + * 限定条件:netTask 上下文;须在控制块清零与芯片复位之前调用 + */ +void net_pending_cancel_all(int err); + +/* + * 函数功能:关闭前先结束本 fd 的挂起 recv——有数据先送达(按字节数),无数据则 + * 取消(CONNRESET),然后调用方才执行 close/拆会话(per-fd 串行) + * 入口参数:sockfd - 将被关闭的描述符 (0~7) int + * p_sock - 将被关闭的 Socket 控制块指针(与 sockfd 对应) net_sock_t * + * 出口参数:无 + * 返回值:无(无在位挂起时静默返回) + * 限定条件:netTask 上下文;须在 ch395f_close_socket 之前调用 + */ +void net_pending_settle_close(int sockfd, net_sock_t *p_sock); + +/* + * 函数功能:查询本 fd 是否有在途挂起 recv —— 宿主能力,供 net_listener 消费 + * 入口参数:sockfd - Socket 描述符 (0~7) int + * 出口参数:无 + * 返回值:1 - 有挂起;0 - 无(含描述符越界) int + * 限定条件:任意上下文(纯 RAM 读,不发起 RPC) + * 函数说明:N-32 §10 模块化:net_listener_retry_tick 用它跳过"重开 Socket + * 会摧毁在途连接"的 fd(挂起 recv 保险) + */ +int net_pending_active(int sockfd); + +#endif /* NET_PENDING_H */ diff --git a/Drivers/BSP/NET/net_socket.c b/Drivers/BSP/NET/net_socket.c index c58aeffc..90d4b99f 100644 --- a/Drivers/BSP/NET/net_socket.c +++ b/Drivers/BSP/NET/net_socket.c @@ -19,9 +19,10 @@ #include "net_socket.h" #include "net_listener.h" +#include "net_pending.h" #include "ch395f.h" #include "test_config.h" /* TEST_LATENCY_PROBE(链路时延探针编译开关) */ -#include "net_latency_test.h" /* L3 探针接口(chunk_wait 采样) */ +#include "net_latency_test.h" /* 延迟探针接口(chunk_wait 采样) */ #include "main.h" /* @@ -104,7 +105,7 @@ static struct { * 函数说明:1. 已存在的槽位(owner 命中)直接复用;空槽(owner == NULL)首次占用 * 2. 快路径**只读不写**:并发读者绝不会看到"owner 已写、err 未写"的中间态 * 3. 槽位与任务不强绑定释放:任务句柄被回收复用时,新任务沿用该槽位的 - * err 初值无碍(语义本就允许残留码,与旧全局变量行为一致) + * err 初值无碍(语义本就允许残留码) */ static uint32_t net_errno_slot(void) { /* 任务句柄(未启动内核/中断上下文时为 NULL) */ @@ -190,41 +191,6 @@ static int net_drop_conn_locked(net_sock_t *p_sock); static int net_accept_locked(int sockfd, struct net_sockaddr *addr, int *addrlen); static int net_connect_locked(int sockfd, const struct net_sockaddr *addr, int addrlen); -/* L3 pending 化(一期,E-02 结构演进):阻塞等待 = 挂起请求 + 主循环节拍完成 - * "无数据 + 阻塞等待"不再自旋占用 netTask:登记 pending 后立即返回 - * net_pending_tick(与 D10 重监听重试同节奏,net_process_messages 开头每轮调用) - * 按 ①数据 ②到点(仅显式预算) ③断连 顺序检查完成条件并通知调用方(语义逐项对齐旧自旋循环) - * 关闭/网络重建/陈旧重同步走显式 settle/cancel 路径(取消必通知,调用方永不挂死) - * 公开 API 返回契约不变:>0 字节数 / 0 EOF / -1 错误(错误码经通知值回传) - * 自愈收敛阶段 1.5:预算归调用方——timeout_ms=0 即无限等待(30s 默认预算已删), - * 原"到点 +1s 强制了结"的看门狗降级为 tripwire(只留痕、绝不伪造返回值) - */ -#define NET_PENDING_REGISTERED 0x70000000 /* 内部哨兵:pending 已登记(分派跳过即时通知;取值不与字节数空间冲突) */ -#define NET_RECV_TRIPWIRE_MS 60000U /* tripwire:挂起超 60s = 完成逻辑缺位探针 → 只 [ERR] 留痕一次,绝不强制了结 */ - -typedef struct { - uint8_t active; /* 1 = 本 fd 有挂起 recv */ - uint8_t infinite; /* 1 = 无限等待(无 deadline,自愈收敛阶段 1.5:0 预算 = 永等) */ - uint8_t tripwire_logged; /* 1 = 本轮挂起已打过 tripwire(保证只留痕一条) */ - void *buf; /* 调用方缓冲(仅指针,须保持有效至完成) */ - int len; /* 缓冲容量 */ - uint32_t deadline; /* 截止时刻(tick)= 登记时刻 + 本次预算(infinite=1 时无意义) */ - uint32_t registered; /* 登记时刻(tick;tripwire/日志基准) */ - TaskHandle_t caller; /* 调用方任务(完成通知目标) */ -} net_pending_t; - -static net_pending_t s_net_pending[NET_MAX_SOCKETS]; /* 每 fd 一个挂起(禁止覆盖:覆盖丢失前调用方通知 → 挂死) */ -static TaskHandle_t s_net_task_handle; /* 执行任务(net_init 捕获;防自通知死锁) */ - -static void net_pending_tick(void); -static void net_pending_complete(int sockfd, int result); -static int net_pending_register(int sockfd, void *buf, int len, - uint32_t to_ms, TaskHandle_t caller); -static void net_pending_clear(int sockfd); -static void net_pending_cancel(int sockfd, int err); -static void net_pending_cancel_all(int err); -static void net_pending_settle_close(net_sock_t *p_sock); - /* * 函数功能:判断 6 字节 MAC 是否全零 * 入口参数:p_mac - MAC 指针(不可为 NULL) const uint8_t * @@ -259,7 +225,7 @@ static bool s_mac_is_zero(const uint8_t *p_mac) { int net_init(const char *ip, const char *mask, const char *gateway, const uint8_t *mac) { ch395f_status_t ret; - /* L3:网络重建前取消全部挂起请求并通知调用方(调用方阻塞等回执, + /* 网络重建前取消全部挂起请求并通知调用方(调用方阻塞等回执, * 取消不通知 = 永久挂死);必须早于控制块清零与芯片复位 */ net_pending_cancel_all(NET_ERR_CONNRESET); @@ -267,7 +233,7 @@ static bool s_mac_is_zero(const uint8_t *p_mac) { memset(s_net_socks, 0, sizeof(s_net_socks)); net_set_errno(NET_OK); s_net_initialized = 0; - s_net_task_handle = xTaskGetCurrentTaskHandle(); /* 执行任务 = net_init 调用者(NET 层 = netTask / 硬件层 = testTask) */ + net_pending_capture_owner(); /* 执行任务 = net_init 调用者(NET 层 = netTask / 硬件层 = testTask) */ /* 检查 CH395F 芯片 */ if (ch395f_check_exist() != CH395F_STATUS_OK) { @@ -649,7 +615,7 @@ int net_poll(void) { * U11 本层 CLOSED(监听型 fd)而芯片在听 → 只重同步,**不发芯片命令** * (重下发因 USE 错误关掉正听着的 Socket,U12 同源事故) * 4. 去抖分级(100ms/轮;E2:LISTEN 可见 100% <=10ms 无长尾):②=1 轮 - * (幽灵甄别挡拆链窗假 ESTABLISHED);③④⑤=2 轮(2026-09-23 实证: + * (幽灵甄别挡拆链窗的旧连接 ESTABLISHED);③④⑤=2 轮(2026-09-23 实证: * 无去抖时监听被反复重建直至放弃);①=4 轮(**勿改小**:F-NET-17 M3 * 可疑电平让位再入,400ms 让位窗=在途投递不可毁的最后租约,E9a 实证) * 5. 动手后冷却 NET_RECONCILE_COOLDOWN_MS 防风暴(U11 被动重同步不占) @@ -727,7 +693,8 @@ static void net_reconcile_tick(void) { } else if (p_sock->state == NET_SOCK_STATE_LISTENING) { if (c.tcp_state == CH395F_TCP_ESTABLISHED) { /* ② 本层 LISTENING 而芯片已完成握手(CONNECT 事件未收到)→ 补做 accept - * N-30(TRAP-NET-20)幽灵态甄别:拆链收尾窗口内芯片假报 ESTABLISHED, + * N-30(TRAP-NET-20)幽灵态甄别:拆链收尾窗口内旧连接未拆净,状态如实 + * 显示 ESTABLISHED(E15:bit3=1 保留现场契约 + TCP 拆链状态机,非谎报), * 回读对端端口 = 上一条连接端口 → 不补 accept(补了会把数据发给 * 已死的旧连接 = 生产 LIST#4 数据被吞的直接成因),等拆净或新 SYN。 * 这是本 tick 唯一的按需 SPI(仅形态②命中时发) */ @@ -825,7 +792,7 @@ static void net_reconcile_tick(void) { /* * 函数功能:netTask 主循环核心 —— 自愈 tick 宿主 + 消息队列分派器。每轮 - * 先跑三个非阻塞自愈 tick(D10 重监听 / L3 挂起 recv / + * 先跑三个非阻塞自愈 tick(D10 重监听 / 挂起 recv / * TRAP-NET-17 状态对账),再非阻塞排空队列按 msg.type 分派到 _locked 实现。 * 入口参数:无 * 出口参数:无 @@ -835,9 +802,9 @@ static void net_reconcile_tick(void) { * 由 net_task.c 在 net_stack_bring_up 之后每次 1ms 循环调用。 * 函数说明:1. 四个自愈 tick 均非阻塞(绝不 osDelay 忙等,netTask 永不冻结),先于消息分派执行 * 2. net_listener_retry_tick(D10):断连后按 30ms(NET_RELISTEN_RETRY_MS) - * 节拍重试 open+listen,2s 总时限到期放弃留痕;本 fd 有在途挂起 recv 时跳过(L3 保险) - * 3. net_pending_tick(L3):按节拍了结挂起 recv(数据/到点[仅显式预算]/断连); - * L3 tripwire(自愈收敛阶段 1.5):挂起超 60s 只 DBG_ERROR 留痕一次,不再强制了结/伪造返回值 + * 节拍重试 open+listen,2s 总时限到期放弃留痕;本 fd 有在途挂起 recv 时跳过(挂起 recv 保险) + * 3. net_pending_tick:按节拍结束挂起 recv(数据/到点[仅显式预算]/断连); + * 挂起超时留痕探针(编译期选项,默认关):挂起超阈值只 DBG_ERROR 留痕一次,绝不强制结束/伪造返回值 * 4. net_reconcile_tick(TRAP-NET-17 + pump 合并,自愈收敛阶段 3):每 100ms 对账 * ①②⑤ + ③④ 重建 + U11 重同步,判据读驱动状态缓存(net_poll 每轮 * 全量刷新,E2 背书);去抖分级(②=1 轮/③④⑤=2 轮/①=4 轮,M3 让位窗) @@ -858,8 +825,8 @@ void net_process_messages(void) { /* 三个非阻塞自愈 tick 置于消息处理之前:断连后即使无应用消息,监听器也能自主恢复 */ /* D10 重监听重试(TRAP-NET-09):沉降后重开芯片监听器 */ net_listener_retry_tick(); - /* L3 挂起 recv 完成检查:数据到达 / 到点 / 断连时通知调用方 */ - net_pending_tick(); + /* 挂起 recv 完成检查:数据到达 / 到点 / 断连时通知调用方 */ + net_pending_tick(s_net_socks); /* TRAP-NET-17 状态对账 + 监听器 pump(自愈收敛阶段 3 合并单一 100ms tick): * 判据读驱动缓存(net_poll 每轮全量刷新),①②⑤ 失同步 + ③④ 重建 + * U11 重同步全部在此(本层唯一周期重建入口,N-32 P2 单一所有者) */ @@ -917,7 +884,7 @@ void net_process_messages(void) { net_set_errno(NET_ERR_BADF); msg.result = -1; } else { - /* 先了结本 fd 挂起 recv(排空或取消,必通知),再关芯片侧 Socket; + /* 先结束本 fd 挂起 recv(排空或取消,必通知),再关芯片侧 Socket; * 单连接模型监听 fd 断开后自动恢复监听,应用不得对它在 EOF 时 close */ msg.result = net_close_locked(p_sock); } @@ -1105,7 +1072,7 @@ int net_socket(int domain, int type) { p_sock->session_dead = 0; /* 新 fd 不得继承上一次的待重试状态(D10) */ net_listener_clear(sockfd); - /* 新 fd 不得继承上一次挂起的 recv 请求(L3) */ + /* 新 fd 不得继承上一次挂起的 recv 请求 */ net_pending_clear(sockfd); /* 返回描述符(控制块已就绪) */ @@ -1334,7 +1301,7 @@ int net_listen_locked(int sockfd) { * 可补回,见 TRAP-NET-08)。 * 全局寄存器交 net_poll 集中读清(AGENTS 模块约定:所有 CH395F 中断经 * net_poll 集中读取并清除);本 Socket 残留的全局位被 net_poll 读到时 - * SINT 已为 0,无害了结。TRAP-NET-12/-18 指定的两级预清落在 + * SINT 已为 0,自然收尾。TRAP-NET-12/-18 指定的两级预清落在 * net_connect_locked / net_close_locked / relisten 隔离段,均为单 Socket, * 本次未动。 */ (void)ch395f_get_sock_int_status((uint8_t)sockfd); @@ -1431,7 +1398,8 @@ int net_listen(int sockfd) { * 永远等不到 → 数据被吞 / 425。固定沉降延时、Socket 轮换、listen 后 close 重试、 * 缓冲重分配均已被实验证伪;唯一有效 = "中断 + 状态轮询"双信源(修复组 15/15 * 全过,机制触发 5 次全部救回)。→ CH395F_Trap_Records.md TRAP-NET-20 - * 幽灵态甄别:拆链窗口内芯片也会直接假报 ESTABLISHED(旧连接未拆净),此时回读 + * 幽灵态甄别:拆链窗口内旧连接未拆净,状态如实为 ESTABLISHED(E15:bit3=1 保留现场 + * 契约,非谎报),此时回读 * 对端端口 = 上一条连接端口;新连接临时端口几乎必然不同 → 端口相同不 accept, * 等旧连接拆净 / 新 SYN 到达(新连接若事件也未收到,后续轮询以新端口命中)。 */ @@ -1549,7 +1517,7 @@ static int net_accept_locked(int sockfd, struct net_sockaddr *addr, int *addrlen /* 当前无连接 → WOULDBLOCK */ return NET_ERR_RETURN_1(NET_ERR_WOULDBLOCK); } - /* drain_pending:落入下方 accept 返回(对端簿记仍在控制块,排空后 EOF 了结) */ + /* drain_pending:落入下方 accept 返回(对端簿记仍在控制块,排空后以 EOF 收尾) */ } /* 填充对端地址(若调用方需要) */ @@ -1720,7 +1688,7 @@ int net_can_read(int sockfd) { if (p_sock == NULL) { return 1; } - /* 连接已非 ESTABLISHED(CLOSED/LISTENING/…):需要一次 recv 了结 EOF/错误 */ + /* 连接已非 ESTABLISHED(CLOSED/LISTENING/…):需要发一次 recv 取回 EOF/错误 */ if (p_sock->state != NET_SOCK_STATE_ESTABLISHED) { return 1; } @@ -2033,8 +2001,8 @@ static int net_send_locked(net_sock_t *p_sock, const void *buf, int len) { p_sock->send_bytes += (uint32_t)chunk; #if defined(TEST_LATENCY_PROBE) - /* L3 探针起点:发送缓冲写入刚完成 - * (样本 = 写缓冲 → SENBUF_FREE 等待,见 链路延迟测试说明 §3 L3) */ + /* 延迟探针起点(chunk_wait):发送缓冲写入刚完成 + * (样本 = 写缓冲 → SENBUF_FREE 等待,见 链路延迟测试说明 §3) */ uint32_t c_l3 = lat_cycles_now(); #endif @@ -2086,12 +2054,12 @@ static int net_send_locked(net_sock_t *p_sock, const void *buf, int len) { * 返回值:实际接收字节数(> 0);0 表示对端关闭;-1 表示出错/非阻塞无数据 int * NET_PENDING_REGISTERED 表示已登记挂起请求(分派据此跳过即时通知) * 限定条件:p_sock 非空;netTask 上下文 - * 函数说明:1. 数据已在(快速路径)→ 立即读出返回,行为与旧实现一致 + * 函数说明:1. 数据已在(快速路径)→ 立即读出返回 * 2. 非阻塞(NET_MSG_DONTWAIT 单次覆盖 **或** socket blocking 属性为 0, * 自愈收敛阶段 1.5 模式属性)无数据立即返回 -1(NET_ERR_WOULDBLOCK) - * 3. 无数据 + 阻塞等待 → 登记挂起请求(L3 pending 化,E-02 结构演进) + * 3. 无数据 + 阻塞等待 → 登记挂起请求(pending 化,E-02 结构演进) * 4. netTask 零占用立即返回;完成条件(数据/到点[仅显式预算]/断连)由 net_pending_tick 按主循环节拍检查 - * 5. 并通知 caller;关闭/网络重建/陈旧重同步由对应路径显式了结(取消必通知) + * 5. 并通知 caller;关闭/网络重建/陈旧重同步由对应路径显式结束(取消必通知) * 6. CLOSED 状态语义(排空 + EOF + 自动重监听)逐项保留在 tick 内 */ static int net_recv_locked(net_sock_t *p_sock, void *buf, int len, int flags, @@ -2165,380 +2133,10 @@ static int net_recv_locked(net_sock_t *p_sock, void *buf, int len, int flags, /* 无数据 + 阻塞等待:登记挂起请求,立即返回(netTask 任何时刻都不被占用)。 * 调用方在自己上下文睡任务通知(LwIP netconn 模型);等待期间 netTask * 继续主循环(事件泵 + 队列),其他消费者零头阻塞。 */ - /* 登记挂起请求(L3):返回值即登记结果 */ + /* 登记挂起请求:返回值即登记结果 */ return net_pending_register(sockfd, buf, len, to_ms, caller); } -/* - * 函数功能:关闭 Socket(内部锁定版本,必须在 netTask 上下文调用) - * 入口参数:p_sock - Socket 控制块指针 net_sock_t * - * 出口参数:无 - * 返回值:0 - 关闭成功 int - * 限定条件:p_sock 非空;netTask 上下文 - * 函数说明:1. 调用 ch395f_close_socket 关闭 CH395F 硬件 Socket - * 2. 清空整个控制块(memset 0),释放该 Socket 资源 - */ - -/* ===== L3 挂起 recv 请求的实现(一期,2026-09-22;自愈收敛阶段 1.5 语义主流化) ===== - * 完成条件按 ①数据 ②到点(仅显式预算) ③断连 顺序检查(逐项对齐旧自旋循环语义) - * ① 数据通道(ESTABLISHED/UDP_OPEN)内 readable 门控 SPI 读——常见无数据路径零额外 SPI 事务 - * (INT# 电平触发链保证缓冲有数据时每轮重读 SINT 重位置位) - * ② 到点(仅当登记时带显式预算 net_recv_to;无限等待登记无 deadline)→ NET_ERR_TIMEDOUT - * ——这是调用方策略的正常兑现,不是伪造 - * ③ CLOSED:先排空(bit3=1 芯片断连后残数据留缓冲待 MCU 读——TRAP-NET-20 排空契约; - * 旧注归"部分读归零"机理、已随复核注降级)→ 有数据按数据完成,否则 EOF(0) + 自动重监听 - * 其他状态(CONNECTING/LISTENING/…)保持等待状态迁移(CONNECT→ESTABLISHED 是合法路径; - * 陈旧 resync 由显式取消处理)——不做状态推断取消,避免误杀正在建链的等待 - * tripwire(自愈收敛阶段 1.5 降级):挂起超 60s = "完成逻辑缺位"探针 → 只 [ERR] 留痕一次, - * **绝不强制了结、绝不伪造 TIMEDOUT 返回值**(唤醒责任在 ①②③ 与显式 cancel 路径) - */ - -/* - * 函数功能:通知调用方并清除本 fd 的挂起请求(所有完成/取消路径的公共出口) - * 入口参数:sockfd - Socket 描述符 (0~7) int - * result - 32 位结果原值(>0 字节数 / 0 EOF / 负错误码) int - * 出口参数:无 - * 返回值:无 - * 限定条件:netTask 上下文;sockfd 合法且挂起在位(否则静默返回,防重复通知) - * 函数说明:通知值 = 结果本身(与消息分派同一回传通道,调用方 net_recv/net_recv_to - * 的映射逻辑不变);失败结果同步 errno 保持 netTask 上下文一致性 - */ -static void net_pending_complete(int sockfd, int result) { - /* 本 fd 挂起请求指针 */ - net_pending_t *p; - - /* 描述符越界:静默返回(防重复通知) */ - if ((sockfd < 0) || (sockfd >= NET_MAX_SOCKETS)) { - return; - } - /* 取挂起请求 */ - p = &s_net_pending[sockfd]; - /* 无在位挂起(已了结/已取消):静默返回 */ - if (p->active == 0U) { - return; - } - /* 失败结果:记入 netTask 自己的错误码槽位(E-03;不再写入跨任务共享全局) */ - if (result < 0) { - (void)net_set_errno(result); - } - /* 覆盖式写入通知值 = 结果本身(32 位原值) */ - xTaskNotify(p->caller, (uint32_t)result, eSetValueWithOverwrite); - /* 清除挂起状态 */ - p->active = 0U; -} - -/* - * 函数功能:登记一个挂起 recv 请求(net_recv_locked 的阻塞无数据路径) - * 入口参数:sockfd - Socket 描述符 (0~7) int - * buf - 调用方接收缓冲(须保持有效至完成) void * - * len - 缓冲容量 int - * to_ms - 本次等待预算(0 = 无限等待,自愈收敛阶段 1.5) uint32_t - * caller - 调用方任务句柄(完成通知目标) TaskHandle_t - * 出口参数:无 - * 返回值:NET_PENDING_REGISTERED - 登记成功(分派跳过即时通知) - * -1 - 拒绝(同 fd 已有挂起 / 执行任务自身发起) - * 限定条件:netTask 上下文 - * 函数说明:每 fd 至多一个挂起(禁止覆盖——覆盖丢失前调用方通知 = 该任务永久挂死); - * 执行任务自身发起的阻塞等待无他人可完成(tick 跑在执行任务内)→ 自等自 - * 通知 = 死锁,必须拒绝(netTask 上下文调用方须用 DONTWAIT) - */ -static int net_pending_register(int sockfd, void *buf, int len, - uint32_t to_ms, TaskHandle_t caller) { - /* 挂起请求指针 */ - net_pending_t *p; - /* 登记时刻(tick) */ - uint32_t now; - - /* 描述符越界 → BADF */ - if ((sockfd < 0) || (sockfd >= NET_MAX_SOCKETS)) { - return NET_ERR_RETURN_1(NET_ERR_BADF); - } - /* 取挂起请求 */ - p = &s_net_pending[sockfd]; - - /* 同 fd 已有挂起:拒绝(覆盖将丢失前通知 = 该任务永久挂死) */ - if (p->active != 0U) { - return NET_ERR_RETURN_1(NET_ERR_BUSY); - } - /* netTask 自身发起:无他人可完成(tick 跑在 netTask 内)→ 拒绝(自等死锁) */ - if ((caller == NULL) || (caller == s_net_task_handle)) { - return NET_ERR_RETURN_1(NET_ERR_BUSY); - } - - /* 当前 tick(截止/tripwire 基准) */ - now = HAL_GetTick(); - /* 标记挂起在位 */ - p->active = 1U; - /* 预算形态:0 = 无限等待(无 deadline,tick ② 跳过;tripwire 以登记时刻计) */ - p->infinite = (to_ms == 0U) ? 1U : 0U; - /* tripwire 留痕标记清零(每轮挂起只留痕一条) */ - p->tripwire_logged = 0U; - /* 调用方接收缓冲(须保持有效至完成) */ - p->buf = buf; - /* 缓冲容量 */ - p->len = len; - /* 截止时刻 = 登记时刻 + 预算(无限等待时不启用,置 0 仅为可观测性) */ - p->deadline = (to_ms == 0U) ? 0U : (now + to_ms); - /* 登记时刻(tripwire 基准) */ - p->registered = now; - /* 完成通知目标 */ - p->caller = caller; - /* 登记成功:分派跳过即时通知 */ - return NET_PENDING_REGISTERED; -} - -/* - * 函数功能:挂起 recv 完成检查(netTask 每轮 net_process_messages 调用一次,非阻塞) - * 入口参数:无 - * 出口参数:无 - * 返回值:无 - * 限定条件:netTask 上下文 - * 函数说明:1. 逐 fd 检查完成条件:数据到达 / 到点(仅显式预算)/ 断连 - * 2. 完成即经 net_pending_complete 通知并清除 - * 3. tripwire(自愈收敛阶段 1.5):挂起超 NET_RECV_TRIPWIRE_MS 只 [ERR] 留痕 - * 一次("完成逻辑缺位"探针),绝不强制了结、绝不伪造返回值 - */ -static void net_pending_tick(void) { - /* 当前 tick */ - uint32_t now = HAL_GetTick(); - /* Socket 循环索引 */ - int i; - - for (i = 0; i < NET_MAX_SOCKETS; i++) { - /* 本 fd 挂起请求 */ - net_pending_t *p = &s_net_pending[i]; - /* 本 fd 控制块 */ - net_sock_t *p_sock = &s_net_socks[i]; - - /* 无挂起请求:跳过 */ - if (p->active == 0U) { - continue; - } - - /* fd 已关闭 */ - if (p_sock->in_use == 0U) { - /* fd 已关闭(正常路径在 close 内先了结;此处兜底,防任何路径漏结) */ - net_pending_complete(i, NET_ERR_CONNRESET); - continue; - } - - /* ① 数据到达(数据优先,与旧自旋一致) */ - if ((p_sock->state == NET_SOCK_STATE_ESTABLISHED) || - (p_sock->state == NET_SOCK_STATE_UDP_OPEN)) { - /* 可读标志置位 */ - if (p_sock->readable != 0U) { - /* 查询芯片侧可用字节数 */ - int avail = ch395f_get_recv_len((uint8_t)i); - /* 有数据 */ - if (avail > 0) { - /* 本次读取量 = min(可用, 缓冲容量) */ - int rd = (avail > p->len) ? p->len : avail; - /* 读入调用方缓冲区 */ - ch395f_read_recv_buf((uint8_t)i, (uint8_t *)p->buf, (uint16_t)rd); - /* 累计接收字节统计 */ - p_sock->recv_bytes += (uint32_t)rd; - /* 数据已消费,清可读标志 */ - p_sock->readable = 0U; - /* 了结:以字节数通知 */ - net_pending_complete(i, rd); - continue; - } - /* 虚假标志:缓冲无数据,继续等待 */ - p_sock->readable = 0U; - } - } - - /* ② 到点(仅显式预算登记;无限等待登记无 deadline——自愈收敛阶段 1.5: - * 超时是调用方策略,net_recv_to 的预算在此兑现,不是伪造。 - * tick 差值按有符号比较,抗回绕) */ - if ((p->infinite == 0U) && ((int32_t)(now - p->deadline) >= 0)) { - /* 了结:超时(错误码由 net_pending_complete 记入本任务槽位) */ - net_pending_complete(i, NET_ERR_TIMEDOUT); - continue; - } - - /* ③ 断连:排空 → 数据或 EOF(0) + 自动重监听。 - * 判据同 net_recv_locked(N-32 P1 不变量 I):`state == CLOSED || - * session_dead`。只判 CLOSED 时,抢先 relisten 后 ①(要求 ESTABLISHED) - * 与 ③(要求 CLOSED) 两头落空 → 挂起的 recv 只能干等 ② deadline 超时 - * (lftpd 阻塞 recv 的"消费者卡死"原型)。自愈收敛阶段 1.5 后该形态更致命: - * 无限等待登记没有 ②,漏 ③ = 永久挂死(只剩 tripwire 留痕)—— - * ③ 与显式 cancel 是无限 recv 的全部唤醒责任方,勿动判据。 */ - if ((p_sock->state == NET_SOCK_STATE_CLOSED) || (p_sock->session_dead != 0U)) { - /* 查询残留字节数 */ - int rem = ch395f_get_recv_len((uint8_t)i); - /* 有残留数据:按数据完成 */ - if (rem > 0) { - /* 本次读取量 = min(残留, 缓冲容量) */ - int rd = (rem > p->len) ? p->len : rem; - /* 读入调用方缓冲区 */ - ch395f_read_recv_buf((uint8_t)i, (uint8_t *)p->buf, (uint16_t)rd); - /* 累计接收字节统计 */ - p_sock->recv_bytes += (uint32_t)rd; - /* 数据已消费,清可读标志 */ - p_sock->readable = 0U; - /* 了结:以字节数通知 */ - net_pending_complete(i, rd); - } else { - /* 启用自动重监听:先把监听器重新置回 LISTEN。 - * ⚠ 内层 `state == CLOSED` 门同 net_recv_locked:session_dead - * 但已回 LISTENING 时重建已由别处完成,再 open+listen 会因 - * USE 错误走进关闭分支、关掉正听着的 Socket(U12 同源)。 - * N-32 P2 修正:**保留本处即时重建** —— 它只在有**挂起 recv** - * 时到达(`p->active != 0`),属"消费者在等这条连接结局"的 - * 消费者驱动路径,不是周期性抢先(同 net_recv_locked 的理由)。 */ - if ((p_sock->state == NET_SOCK_STATE_CLOSED) && - (p_sock->auto_relisten != 0U)) { - /* 非阻塞:失败由 D10 重试轮询接管(N-32 §10:入口收敛到 net_listener_try) */ - (void)net_listener_try(i); - } - /* TRAP-NET-18 待办 #3:异常释放(TIMEOUT/RST)不是正常 EOF(对端未发正常 FIN) - * → 以连接重置了结:应用(lftpd STOR)对异常结束回 5xx 而非误报 226; - * 正常 FIN(DISCONNECT)仍回 0(在途 FIN 与正常完成不可区分——协议边界,见 TRAP-NET-18 记录) */ - /* 异常释放:以连接重置了结(回 5xx,不误报 226) */ - if (p_sock->released_abnormal != 0U) { - /* 异常释放(错误码由 net_pending_complete 记入本任务槽位) */ - net_pending_complete(i, NET_ERR_CONNRESET); - } else { - /* 正常 EOF:以 0 了结 */ - net_pending_complete(i, 0); - } - } - continue; - } - - /* 其他状态:保持等待(见本区块头注释) */ - - /* ④ tripwire(自愈收敛阶段 1.5 降级,原"看门狗强制了结"):挂起超 60s = - * "完成逻辑缺位"探针 → 只 [ERR] 留痕一次,**绝不强制了结、绝不伪造 - * TIMEDOUT 返回值**(旧实现到点 +1s 兜底伪造 TIMEDOUT,掩盖完成路径 - * 缺陷;新语义下无限等待本就无预算,伪造返回值反而违背调用方意图)。 - * 判据:无限登记按登记时刻计;显式登记按 deadline 计(② 正常不会让它 - * 越过 60s,能到这里本身就是完成逻辑缺位)。 */ - if (p->tripwire_logged == 0U) { - /* 探针基准时刻:无限 = 登记时刻;显式 = 截止时刻 */ - uint32_t base = (p->infinite != 0U) ? p->registered : p->deadline; - if ((int32_t)(now - base) >= (int32_t)NET_RECV_TRIPWIRE_MS) { - /* 留痕(挂起已持续毫秒数,自基准起算) */ - DBG_ERROR("sock%d recv pending %ums (base=%s): completion source missing", - i, (unsigned)((int32_t)now - (int32_t)base), - (p->infinite != 0U) ? "infinite" : "deadline"); - /* 只留痕一次(每轮挂起一条,防日志风暴) */ - p->tripwire_logged = 1U; - } - } - } -} - -/* - * 函数功能:查询本 fd 是否有在途挂起 recv(L3 pending)—— 宿主能力,供 net_listener 用 - * 入口参数:sockfd - Socket 描述符 (0~7) int - * 出口参数:无 - * 返回值:1 - 有挂起;0 - 无(含描述符越界) int - * 限定条件:任意上下文(纯 RAM 读,不发起 RPC) - * 函数说明:1. N-32 §10 模块化:net_listener_retry_tick 用它跳过"重开 Socket - * 会摧毁在途连接"的 fd(L3 保险,原为直接读 s_net_pending[i].active) - * 2. 声明在 net_listener.h(本模块提供、监听器模块消费) - */ -int net_pending_active(int sockfd) { - /* 描述符越界:视为无挂起 */ - if ((sockfd < 0) || (sockfd >= NET_MAX_SOCKETS)) { - return 0; - } - return (s_net_pending[sockfd].active != 0U) ? 1 : 0; -} - -/* - * 函数功能:清除本 fd 的挂起请求(不通知;用于"新 fd 不得继承"与 close 后的幂等清理) - * 入口参数:sockfd - Socket 描述符 (0~7) int - * 出口参数:无 - * 返回值:无 - * 限定条件:无 - * 函数说明:1. 静默清理不发通知:close 路径先经 settle 通知,本调用仅保证状态归零(幂等) - * 2. 新建 fd 时调用,防复用槽位继承上一条连接的挂起请求 - */ -static void net_pending_clear(int sockfd) { - /* 描述符越界:直接返回 */ - if ((sockfd < 0) || (sockfd >= NET_MAX_SOCKETS)) { - return; - } - /* 挂起状态清零(静默,不发通知) */ - s_net_pending[sockfd].active = 0U; -} - -/* - * 函数功能:取消本 fd 的挂起请求并通知调用方(显式路径:陈旧 resync 等) - * 入口参数:sockfd - Socket 描述符 (0~7) int - * err - 通知的错误码(如 NET_ERR_CONNRESET) int - * 出口参数:无 - * 返回值:无(无在位挂起时静默返回) - * 限定条件:netTask 上下文 - * 函数说明:经 net_pending_complete 以指定错误码通知调用方(取消必通知,防挂死) - */ -static void net_pending_cancel(int sockfd, int err) { - /* complete 内部校验范围与在位(未在位则静默返回) */ - net_pending_complete(sockfd, err); -} - -/* - * 函数功能:取消全部挂起请求并逐一通知(网络重建路径) - * 入口参数:err - 通知的错误码 int - * 出口参数:无 - * 返回值:无 - * 限定条件:netTask 上下文;须在控制块清零与芯片复位之前调用 - * 函数说明:网络重建(net_stack_bring_up)前调用,保证所有在位调用方均被唤醒 - */ -static void net_pending_cancel_all(int err) { - /* 逐 fd 遍历 */ - for (int i = 0; i < NET_MAX_SOCKETS; i++) { - /* 取消并通知(未在位则静默跳过) */ - net_pending_complete(i, err); - } -} - -/* - * 函数功能:关闭前了结本 fd 的挂起 recv(per-fd 串行:先完成、再关闭) - * 入口参数:p_sock - 将被关闭的 Socket 控制块指针 net_sock_t * - * 出口参数:无 - * 返回值:无(无在位挂起时静默返回) - * 限定条件:netTask 上下文;须在 ch395f_close_socket 之前调用 - * 函数说明:先排空尝试——关闭不丢已到达数据(芯片缓冲在 close 前可读); - * 有数据按字节数通知,否则取消(NET_ERR_CONNRESET) - */ -static void net_pending_settle_close(net_sock_t *p_sock) { - /* 由控制块指针反推描述符 */ - int sockfd = (int)(p_sock - s_net_socks); - /* 通知用结果值(默认为取消) */ - int val; - /* 芯片 RX 可用字节数 */ - int avail; - - /* 无在位挂起:静默返回 */ - if (s_net_pending[sockfd].active == 0U) { - return; - } - /* 默认结果 = 取消(CONNRESET) */ - val = NET_ERR_CONNRESET; - /* 查询芯片 RX 可用字节(缓冲内数据在 close 前可读) */ - avail = ch395f_get_recv_len((uint8_t)sockfd); - /* 数据已到达:排空,关闭不丢数据 */ - if (avail > 0) { - /* 本次读取量 = min(可用, 缓冲容量) */ - int rd = (avail > s_net_pending[sockfd].len) ? s_net_pending[sockfd].len : avail; - /* 读入调用方缓冲区 */ - ch395f_read_recv_buf((uint8_t)sockfd, (uint8_t *)s_net_pending[sockfd].buf, (uint16_t)rd); - /* 累计接收字节统计 */ - p_sock->recv_bytes += (uint32_t)rd; - /* 数据已消费,清可读标志 */ - p_sock->readable = 0U; - /* 有数据:以字节数通知 */ - val = rd; - } - /* 了结(必通知) */ - net_pending_complete(sockfd, val); -} - - /* * 函数功能:关闭 Socket(内部版本,不经过消息队列) * 入口参数:p_sock - 要关闭的 Socket 控制块指针 net_sock_t * @@ -2559,9 +2157,9 @@ static int net_close_locked(net_sock_t *p_sock) { /* 由控制块指针反推描述符 */ int sockfd = (int)(p_sock - s_net_socks); - /* L3:先了结本 fd 的挂起 recv(排空/取消 + 必通知),再关芯片 Socket + /* 先结束本 fd 的挂起 recv(排空/取消 + 必通知),再关芯片 Socket * ——关闭不得让等待中的调用方永久悬挂 */ - net_pending_settle_close(p_sock); + net_pending_settle_close((int)(p_sock - s_net_socks), p_sock); /* 排渣 + 关闭 + 等 CLOSED 一体(见函数头注释 1); * 已 CLOSED 的 fd 只清本 Socket 残留事件(防下一连接误判"刚建立就断开") */ @@ -2579,7 +2177,7 @@ static int net_close_locked(net_sock_t *p_sock) { p_sock->last_peer_port = keep_peer; /* 关闭即取消该 fd 的待重试(D10 重试队列) */ net_listener_clear(sockfd); - /* 关闭即清除该 fd 的挂起状态(L3;幂等) */ + /* 关闭即清除该 fd 的挂起状态(幂等) */ net_pending_clear(sockfd); /* 关闭成功 */ @@ -2602,14 +2200,14 @@ static int net_close_locked(net_sock_t *p_sock) { * (芯片已 CLOSED 直接 open 必成,E4 定案;失败交 D10 重试 + * reconciler 形态④);非 auto_relisten(client fd):收口 CLOSED, * 是否重连由调用方决定 - * 4. 挂起 recv 先了结(settle_close:排空尝试或取消,必通知) + * 4. 挂起 recv 先结束(settle_close:排空尝试或取消,必通知) */ static int net_drop_conn_locked(net_sock_t *p_sock) { /* 由控制块指针反推描述符 */ int sockfd = (int)(p_sock - s_net_socks); - /* L3:先了结本 fd 挂起 recv(排空/取消 + 必通知),再拆芯片会话 */ - net_pending_settle_close(p_sock); + /* 先结束本 fd 挂起 recv(排空/取消 + 必通知),再拆芯片会话 */ + net_pending_settle_close((int)(p_sock - s_net_socks), p_sock); /* 确定性拆除(异常释放 → QUARANTINE 400ms 底,TRAP-NET-18 语义) */ if (net_sock_reset_sync(sockfd, CH395F_RESET_QUARANTINE) != 0) { @@ -3263,7 +2861,7 @@ int net_send_sock(net_sock_t *p_sock, const void *buf, int len) { * -1 - 接收失败 int * 限定条件:必须在 netTask 上下文中调用;p_sock->in_use == 1 * 函数说明:1. 直接操作 Socket 控制块,不经过消息队列。避免 netTask 向自身发送消息造成死锁 - * 2. L3 后:netTask 上下文的阻塞等待会被挂起登记拒绝(自通知死锁) + * 2. pending 化后:netTask 上下文的阻塞等待会被挂起登记拒绝(自通知死锁) * 3. 本函数阻塞用法仅对 DONTWAIT 有效 */ int net_recv_sock(net_sock_t *p_sock, void *buf, int len, int flags) { @@ -3669,9 +3267,8 @@ static void handle_connect_event(net_sock_t *p_sock) { * 限定条件:net_poll() 检测到 DISCONNECT 中断后调用;netTask 上下文 * 函数说明:1. ⚠ FUN_PARA bit3=1(本仓 net_init 置 0x08):DISCONNECT/TIM_OUT 后芯片 * **不**关 Socket、**不清**缓冲(停 0x05/0x00)——残留数据须由本层读出后,再由 - * 本层 ch395f_close_socket 关闭;芯片不代劳(§5.52② / §5.23)。旧注释写"CH395F 在 - * DISCONNECT 后自动关闭 Socket(FUN_PARA 默认)"与实际 0x08 相反,2026-10-12 修正: - * 它会误导维护者跳过显式 close(= U12 的成因之一)。之后需重新 OPEN + LISTEN + * 本层 ch395f_close_socket 关闭;芯片不代劳(§5.52② / §5.23),不得跳过 + * 显式 close(U12 成因之一)。之后需重新 OPEN + LISTEN * 2. 单连接:置 CLOSED,交由 net_recv_locked 排空剩余数据后再关 * 3. 触发 NET_EVENT_DISCONNECTED 回调 */ @@ -3771,7 +3368,7 @@ static void handle_disconnect_event(net_sock_t *p_sock) { net_listener_settle(qfd, NET_LISTENER_SETTLE_GRACEFUL); } } - /* 正常释放(对端 FIN):断连了结回 EOF(0) */ + /* 正常释放(对端 FIN):断连时挂起项以 EOF(0) 结束 */ p_sock->released_abnormal = 0U; /* N-32(P1 不变量 I):置"本会话已结束"电平。须在置 CLOSED **之前**, * 使 session_dead 覆盖"CLOSED 等待 recv 排空"整个窗口——排空期间 @@ -3804,8 +3401,7 @@ static void handle_disconnect_event(net_sock_t *p_sock) { * 返回值:无 * 限定条件:net_poll() 检测到 RECV_OK 中断后调用;netTask 上下文 * 函数说明:1. 仅触发 NET_EVENT_DATA_RECEIVED 回调通知上层 - * 2. 不在此读取 recv_len:单一读取点归 net_recv_locked(省一次 SPI - * 查询;旧"部分读归零"时代的"读取冲突"顾虑已随复核注降级,结构保留) + * 2. 不在此读取 recv_len:单一读取点归 net_recv_locked(省一次 SPI 查询) */ static void handle_recv_event(net_sock_t *p_sock) { /* RECV_OK 中断已触发,直接通知上层。不在此读 recv_len, @@ -3865,8 +3461,8 @@ static void handle_timeout_event(net_sock_t *p_sock) { net_listener_settle(qfd, NET_LISTENER_SETTLE_QUARANTINE); } } - /* TRAP-NET-18 待办 #3:标记异常释放——L3 挂起 recv 排空断连后以 - * NET_ERR_CONNRESET 了结(而非 EOF),应用(lftpd STOR)回报 5xx + /* TRAP-NET-18 待办 #3:标记异常释放——挂起 recv 排空断连后以 + * NET_ERR_CONNRESET 结束(而非 EOF),应用(lftpd STOR)回报 5xx * 而非误报 226(见 net_pending_tick 断连分支) */ p_sock->released_abnormal = 1U; /* N-30(TRAP-NET-20):异常释放同样登记对端端口(幽灵甄别基准) */ diff --git a/Drivers/BSP/NET/net_socket.h b/Drivers/BSP/NET/net_socket.h index 72158406..93677a92 100644 --- a/Drivers/BSP/NET/net_socket.h +++ b/Drivers/BSP/NET/net_socket.h @@ -193,7 +193,7 @@ int net_listener_armed(int sockfd); * 函数功能:查询 Socket 是否"值得发一次 recv"(**纯 RAM 读,不发起 RPC**) * 入口参数:sockfd - Socket 描述符 int * 出口参数:无 - * 返回值:1 - 应发 recv(有数据可读,或连接已非 ESTABLISHED 需了结);0 - 不必发 int + * 返回值:1 - 应发 recv(有数据可读,或连接已非 ESTABLISHED 需发 recv 取回 EOF/错误);0 - 不必发 int * 限定条件:net_init() 已调用;任意任务上下文 * 函数说明:1. ESTABLISHED → 看 readable(net_poll 在 RECV_OK 置位、读空清零) * 2. **非 ESTABLISHED 一律返回 1**:连接已消失时必须让上层真的 recv 一次 @@ -492,18 +492,6 @@ int net_set_errno(int err); * N-32 §10:原定义在 net_socket.c,随 net_set_errno 一并提升到本头文件 */ #define NET_ERR_RETURN_1(err) (net_set_errno(err), -1) -/* - * 函数功能:查询本 fd 是否有在途挂起 recv(L3 pending)—— 供 net_listener.c 消费 - * 入口参数:sockfd - Socket 描述符 (0~7) int - * 出口参数:无 - * 返回值:1 - 有挂起;0 - 无(含描述符越界) int - * 限定条件:任意上下文(纯 RAM 读,不发起 RPC) - * 函数说明:1. N-32 §10 模块化:net_listener_retry_tick 用它跳过"重开 Socket - * 会摧毁在途连接"的 fd(L3 保险,原为直接读 s_net_pending[i].active) - * 2. 定义在 net_socket.c(配对头即本文件) - */ -int net_pending_active(int sockfd); - /* * 函数功能:获取 Socket 本地地址(IP + Port) * 入口参数:sockfd - socket 描述符 diff --git a/Drivers/BSP/NET/net_types.h b/Drivers/BSP/NET/net_types.h index 78adfa2a..82312635 100644 --- a/Drivers/BSP/NET/net_types.h +++ b/Drivers/BSP/NET/net_types.h @@ -188,7 +188,7 @@ typedef struct { uint8_t blocking; /* 释放来源标记(TRAP-NET-18 待办 #3):1 = 异常释放(芯片 TIMEOUT,对端 RST/掉链), - * 0 = 正常释放(芯片 DISCONNECT,对端 FIN)或新连接。L3 挂起 recv 的了结断连 + * 0 = 正常释放(芯片 DISCONNECT,对端 FIN)或新连接。挂起 recv 结束时的断连 * 分支据此决定回 EOF(0) 还是 NET_ERR_CONNRESET:异常结束上报应用(lftpd STOR) * 为错误 → 回 5xx 而非误报 226。由 handle_timeout_event / handle_disconnect_event * 置位,新连接建立时(net_socket / relisten 成功)清零——新连接不得继承上一条 @@ -196,7 +196,8 @@ typedef struct { uint8_t released_abnormal; /* N-30(2026-10-11 裸机芯片台架实证):本 Socket 上一条被释放连接的**对端端口**。 - * 芯片拆链收尾窗口内 Socket 会假报 ESTABLISHED(幽灵态),此时回读的对端端口 + * 芯片拆链收尾窗口内旧连接未拆净,Socket 如实为 ESTABLISHED(幽灵态,E15: + * bit3=1 保留现场契约,非谎报),此时回读的对端端口 * = 旧连接端口;新连接的临时端口几乎必然不同。accept 路径补 accept 与对账② * 均以此甄别幽灵态(见 net_socket.c TRAP-NET-20)。跨 fd 释放保留(幽灵属芯片 * Socket 级,与 fd 复用无关),新连接断开时刷新。 */ diff --git a/MDK-ARM/STM32F407-Demo.uvprojx b/MDK-ARM/STM32F407-Demo.uvprojx index d885e2c1..4d84efbf 100644 --- a/MDK-ARM/STM32F407-Demo.uvprojx +++ b/MDK-ARM/STM32F407-Demo.uvprojx @@ -1603,6 +1603,11 @@ 1 ..\Drivers\BSP\NET\net_listener.c + + net_pending.c + 1 + ..\Drivers\BSP\NET\net_pending.c + net_cfg.c 1 diff --git a/docs/README.md b/docs/README.md index d9cb98da..ce9a63cc 100644 --- a/docs/README.md +++ b/docs/README.md @@ -272,7 +272,7 @@ docs/ | 日期 | 变更 | 说明 | |---|---|---| -| 2026-10-14 | E14"丢中断"复核与归因更正 | 48 轮直读 SINT 矩阵复核历史"丢中断"说法:**芯片侧事件丢失 = 0**("丢失"= drain 读清消费 3/48 + 门控竞态 2/48 + 主机同步 1/48,幽灵态 0/48 未复现);根除性修复 = listen/relisten 路径排事件挪至 LISTEN 命令**之前**(吞新会话 CONNECT 的生产侧自伤窗);全局读收口(全局寄存器唯一读者=`net_poll`,I7 护栏);全库 17 文件约 40 处"丢中断"归因更正为"事件未收到/读清消费竞态",`docs/网络/网络自愈架构设计.md` §5.2 新增 E14 锚点;台架保留复核探针(drain-int/SINT 补读×3/超时归类) | +| 2026-10-14 | E14"丢中断"复核与归因更正 | 48 轮直读 SINT 矩阵复核历史"丢中断"说法:**芯片侧事件丢失 = 0**("丢失"= drain 读清消费 3/48 + 门控竞态 2/48 + 主机同步 1/48,幽灵态 0/48 未复现);根除性修复 = listen/relisten 路径排事件挪至 LISTEN 命令**之前**(吞新会话 CONNECT 的生产侧自伤窗);全局读收口(全局寄存器唯一读者=`net_poll`,I7 护栏);全库 17 文件约 40 处"丢中断"归因更正为"事件未收到/读清消费竞态",`docs/网络/网络自愈架构设计.md` §5.2 新增 E14 锚点;台架保留复核探针(drain-int/SINT 补读×3/超时归类);同日 E15 幽灵态归因复核(官网+手册实锤:0x04+旧端口 = 芯片**如实报告**旧连接拆链进行中——bit3=1 保留现场为自家配置、拆链窗与 §5.17 重传默认值吻合、WCH 官方博客确认断连即重连被拒且官方方案 = 关闭完成后重开,即 settle 等待) | | 2026-10-13 | 网络自愈架构文档瘦身与改名 | 合并文档 `网络/N34-自愈审计.md`(2062 行审计全记录)瘦身为**终版设计描述**(281 行:不变量 I1~I8 / 架构与机制详解 / 参数与 E 锚点速查 / 红线 / 延后项),并经 `rename_ref.py` 改名 [`网络/网络自愈架构设计.md`](网络/网络自愈架构设计.md)(全库 16 文件 30 处引用同步);审计过程(T1~T4、E0~E13)归档 git 历史,考古命令见该文档「引用与归档约定」 | | 2026-10-13 | 网络自愈审计归档 | 原 `docs/网络/N34-自愈审计/` 目录 7 份文档(根因总览 / net 层盘点 / 驱动层审计 / 主流对照 / 汇总裁决 / 实施方案 / 实验方案)**合并为单文档 [`网络/网络自愈架构设计.md`](网络/网络自愈架构设计.md)**,原目录删除;全库引用同步(`docs/` 4 篇 + 驱动/网络代码注释 + 配图生成器与 SVG)。本索引 §5.1 补登记 | | 2026-10-12 | 新增环境与部署 | 新建 `docs/环境与部署/并行任务工作树方案.md`(**多任务并行开发机制规格**:`git worktree` 隔离、目录与共享/独占分配、`task-worktree` / `@task` skill 设计、单写者文档与合并残留审计、台架锁;**已落地并端到端实测**);本索引 §9.2 补登记 | diff --git a/docs/images/Net层阻塞模型.svg b/docs/images/Net层阻塞模型.svg index ca8de14e..205dc5a0 100644 --- a/docs/images/Net层阻塞模型.svg +++ b/docs/images/Net层阻塞模型.svg @@ -48,7 +48,7 @@ 刷新 readable net_pending_tick() -了结挂起 +结束挂起 net_listener_retry_tick() 重试对账 @@ -74,7 +74,7 @@ ⑤ 网络重建(芯片复位) → 取消 + 必须通知(否则调用方永久挂死) -看门狗:到点后 1s 仍未了结 = 完成逻辑缺位 → 强制了结 + DBG_ERROR +挂起超时留痕探针(编译期选项,默认关):挂起超阈值仍未结束 → 只 DBG_ERROR 留痕(不强制结束、不伪造返回值) xTaskNotify 唤醒调用方(结果 = 字节数 / 负错误码) diff --git a/docs/images/引用关系图.dot b/docs/images/引用关系图.dot index 99ad4503..3ad23fac 100644 --- a/docs/images/引用关系图.dot +++ b/docs/images/引用关系图.dot @@ -77,6 +77,8 @@ digraph refgraph_full { "Drivers/BSP/NET/net_config.h" [fillcolor="#dbeafe", color="#1d4ed8"]; "Drivers/BSP/NET/net_listener.c" [fillcolor="#dbeafe", color="#1d4ed8"]; "Drivers/BSP/NET/net_listener.h" [fillcolor="#dbeafe", color="#1d4ed8"]; + "Drivers/BSP/NET/net_pending.c" [fillcolor="#dbeafe", color="#1d4ed8"]; + "Drivers/BSP/NET/net_pending.h" [fillcolor="#dbeafe", color="#1d4ed8"]; "Drivers/BSP/NET/net_select.c" [fillcolor="#dbeafe", color="#1d4ed8"]; "Drivers/BSP/NET/net_select.h" [fillcolor="#dbeafe", color="#1d4ed8"]; "Drivers/BSP/NET/net_socket.c" [fillcolor="#dbeafe", color="#1d4ed8"]; @@ -505,6 +507,20 @@ digraph refgraph_full { "Drivers/BSP/NET/net_listener.c" -> "test/board/test_config.h" [color="#2563eb", penwidth=1.0]; "Drivers/BSP/NET/net_listener.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; "Drivers/BSP/NET/net_listener.h" -> "Drivers/BSP/NET/net_types.h" [color="#2563eb", penwidth=1.0]; + "Drivers/BSP/NET/net_pending.c" -> "Drivers/BSP/CH395F/ch395f.h" [color="#2563eb", penwidth=1.0]; + "Drivers/BSP/NET/net_pending.c" -> "Drivers/BSP/NET/net_listener.h" [color="#2563eb", penwidth=1.0]; + "Drivers/BSP/NET/net_pending.c" -> "Drivers/BSP/NET/net_pending.h" [color="#2563eb", penwidth=1.0]; + "Drivers/BSP/NET/net_pending.c" -> "Drivers/BSP/NET/net_socket.h" [color="#2563eb", penwidth=1.0]; + "Drivers/BSP/NET/net_pending.c" -> "Drivers/BSP/NET/net_types.h" [color="#2563eb", penwidth=1.0]; + "Drivers/BSP/NET/net_pending.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0]; + "Drivers/BSP/NET/net_pending.c" -> "Inc/main.h" [color="#2563eb", penwidth=1.0]; + "Drivers/BSP/NET/net_pending.c" -> "Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h" [color="#94a3b8", penwidth=0.7]; + "Drivers/BSP/NET/net_pending.c" -> "Middlewares/Third_Party/FreeRTOS/Source/include/task.h" [color="#94a3b8", penwidth=0.7]; + "Drivers/BSP/NET/net_pending.c" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; + "Drivers/BSP/NET/net_pending.h" -> "Drivers/BSP/NET/net_types.h" [color="#2563eb", penwidth=1.0]; + "Drivers/BSP/NET/net_pending.h" -> "Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h" [color="#94a3b8", penwidth=0.7]; + "Drivers/BSP/NET/net_pending.h" -> "Middlewares/Third_Party/FreeRTOS/Source/include/task.h" [color="#94a3b8", penwidth=0.7]; + "Drivers/BSP/NET/net_pending.h" -> "外部/系统头文件" [color="#f59e0b", penwidth=0.6, style=dashed]; "Drivers/BSP/NET/net_select.c" -> "Drivers/BSP/CH395F/ch395f.h" [color="#2563eb", penwidth=1.0]; "Drivers/BSP/NET/net_select.c" -> "Drivers/BSP/NET/net_select.h" [color="#2563eb", penwidth=1.0]; "Drivers/BSP/NET/net_select.c" -> "Drivers/BSP/NET/net_socket.h" [color="#2563eb", penwidth=1.0]; @@ -517,6 +533,7 @@ digraph refgraph_full { "Drivers/BSP/NET/net_select.h" -> "Drivers/BSP/NET/net_types.h" [color="#2563eb", penwidth=1.0]; "Drivers/BSP/NET/net_socket.c" -> "Drivers/BSP/CH395F/ch395f.h" [color="#2563eb", penwidth=1.0]; "Drivers/BSP/NET/net_socket.c" -> "Drivers/BSP/NET/net_listener.h" [color="#2563eb", penwidth=1.0]; + "Drivers/BSP/NET/net_socket.c" -> "Drivers/BSP/NET/net_pending.h" [color="#2563eb", penwidth=1.0]; "Drivers/BSP/NET/net_socket.c" -> "Drivers/BSP/NET/net_socket.h" [color="#2563eb", penwidth=1.0]; "Drivers/BSP/NET/net_socket.c" -> "Drivers/BSP/dbg_log.h" [color="#2563eb", penwidth=1.0]; "Drivers/BSP/NET/net_socket.c" -> "Inc/main.h" [color="#2563eb", penwidth=1.0]; diff --git a/docs/images/引用关系图.json b/docs/images/引用关系图.json index 552d1cc9..db64afda 100644 --- a/docs/images/引用关系图.json +++ b/docs/images/引用关系图.json @@ -341,6 +341,14 @@ "path": "Drivers/BSP/NET/net_listener.h", "class": "fp" }, + { + "path": "Drivers/BSP/NET/net_pending.c", + "class": "fp" + }, + { + "path": "Drivers/BSP/NET/net_pending.h", + "class": "fp" + }, { "path": "Drivers/BSP/NET/net_select.c", "class": "fp" @@ -7619,6 +7627,90 @@ "kind": "fp-fp", "include": "net_types.h" }, + { + "from": "Drivers/BSP/NET/net_pending.c", + "to": "外部/系统头文件", + "kind": "fp-ext", + "include": "stddef.h" + }, + { + "from": "Drivers/BSP/NET/net_pending.c", + "to": "Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h", + "kind": "fp-tp", + "include": "FreeRTOS.h" + }, + { + "from": "Drivers/BSP/NET/net_pending.c", + "to": "Middlewares/Third_Party/FreeRTOS/Source/include/task.h", + "kind": "fp-tp", + "include": "task.h" + }, + { + "from": "Drivers/BSP/NET/net_pending.c", + "to": "Drivers/BSP/NET/net_types.h", + "kind": "fp-fp", + "include": "net_types.h" + }, + { + "from": "Drivers/BSP/NET/net_pending.c", + "to": "Drivers/BSP/NET/net_socket.h", + "kind": "fp-fp", + "include": "net_socket.h" + }, + { + "from": "Drivers/BSP/NET/net_pending.c", + "to": "Drivers/BSP/NET/net_pending.h", + "kind": "fp-fp", + "include": "net_pending.h" + }, + { + "from": "Drivers/BSP/NET/net_pending.c", + "to": "Drivers/BSP/NET/net_listener.h", + "kind": "fp-fp", + "include": "net_listener.h" + }, + { + "from": "Drivers/BSP/NET/net_pending.c", + "to": "Drivers/BSP/CH395F/ch395f.h", + "kind": "fp-fp", + "include": "ch395f.h" + }, + { + "from": "Drivers/BSP/NET/net_pending.c", + "to": "Drivers/BSP/dbg_log.h", + "kind": "fp-fp", + "include": "dbg_log.h" + }, + { + "from": "Drivers/BSP/NET/net_pending.c", + "to": "Inc/main.h", + "kind": "fp-fp", + "include": "main.h" + }, + { + "from": "Drivers/BSP/NET/net_pending.h", + "to": "外部/系统头文件", + "kind": "fp-ext", + "include": "stdint.h" + }, + { + "from": "Drivers/BSP/NET/net_pending.h", + "to": "Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h", + "kind": "fp-tp", + "include": "FreeRTOS.h" + }, + { + "from": "Drivers/BSP/NET/net_pending.h", + "to": "Middlewares/Third_Party/FreeRTOS/Source/include/task.h", + "kind": "fp-tp", + "include": "task.h" + }, + { + "from": "Drivers/BSP/NET/net_pending.h", + "to": "Drivers/BSP/NET/net_types.h", + "kind": "fp-fp", + "include": "net_types.h" + }, { "from": "Drivers/BSP/NET/net_select.c", "to": "外部/系统头文件", @@ -7733,6 +7825,12 @@ "kind": "fp-fp", "include": "net_listener.h" }, + { + "from": "Drivers/BSP/NET/net_socket.c", + "to": "Drivers/BSP/NET/net_pending.h", + "kind": "fp-fp", + "include": "net_pending.h" + }, { "from": "Drivers/BSP/NET/net_socket.c", "to": "Drivers/BSP/CH395F/ch395f.h", @@ -41763,6 +41861,12 @@ "stdbool.h", "string.h" ], + "Drivers/BSP/NET/net_pending.c": [ + "stddef.h" + ], + "Drivers/BSP/NET/net_pending.h": [ + "stdint.h" + ], "Drivers/BSP/NET/net_select.c": [ "stdio.h", "string.h" @@ -43501,11 +43605,11 @@ ] }, "stats": { - "files_indexed": 1491, - "includes_parsed": 5939, - "resolved": 4792, - "unresolved": 1147, - "nodes_fp": 211, + "files_indexed": 1493, + "includes_parsed": 5954, + "resolved": 4805, + "unresolved": 1149, + "nodes_fp": 213, "nodes_tp": 1266, "ext_names": 351 }, diff --git a/docs/images/引用关系图.svg b/docs/images/引用关系图.svg index 9a29a04a..fafb3cda 100644 --- a/docs/images/引用关系图.svg +++ b/docs/images/引用关系图.svg @@ -4,5561 +4,5663 @@ - - + + refgraph_full - -STM32F4-Base 项目文件引用关系图(项目代码视图) + +STM32F4-Base 项目文件引用关系图(项目代码视图) App/algo/adc_health.c - -App/algo/adc_health.c + +App/algo/adc_health.c App/algo/adc_health.h - -App/algo/adc_health.h + +App/algo/adc_health.h App/algo/adc_health.c->App/algo/adc_health.h - - + + - + 外部/系统头文件 - -外部/系统头文件 + +外部/系统头文件 App/algo/adc_health.h->外部/系统头文件 - - + + App/algo/adc_input.c - -App/algo/adc_input.c + +App/algo/adc_input.c App/algo/adc_input.h - -App/algo/adc_input.h + +App/algo/adc_input.h App/algo/adc_input.c->App/algo/adc_input.h - - + + - + Drivers/BSP/TPAFE5160/tpafe5160.h - -Drivers/BSP/TPAFE5160/tpafe5160.h + +Drivers/BSP/TPAFE5160/tpafe5160.h App/algo/adc_input.c->Drivers/BSP/TPAFE5160/tpafe5160.h - - + + - + Inc/adc.h - -Inc/adc.h + +Inc/adc.h App/algo/adc_input.c->Inc/adc.h - - + + App/algo/adc_input.c->外部/系统头文件 - - + + App/algo/adc_input.h->外部/系统头文件 - - + + App/algo/freq.c - -App/algo/freq.c + +App/algo/freq.c App/algo/freq.h - -App/algo/freq.h + +App/algo/freq.h App/algo/freq.c->App/algo/freq.h - - + + App/algo/phasor.h - -App/algo/phasor.h + +App/algo/phasor.h App/algo/freq.c->App/algo/phasor.h - - + + App/algo/freq.c->外部/系统头文件 - - + + App/algo/freq.h->外部/系统头文件 - - + + App/algo/phasor.c - -App/algo/phasor.c + +App/algo/phasor.c App/algo/phasor.c->App/algo/phasor.h - - + + App/algo/sample_ring.h - -App/algo/sample_ring.h + +App/algo/sample_ring.h App/algo/phasor.c->App/algo/sample_ring.h - - + + App/algo/phasor.c->外部/系统头文件 - - + + App/algo/phasor.h->App/algo/adc_input.h - - + + App/algo/phasor.h->外部/系统头文件 - - + + App/algo/prot_elm.c - -App/algo/prot_elm.c + +App/algo/prot_elm.c App/algo/prot_elm.c->App/algo/freq.h - - + + App/algo/prot_elm.c->App/algo/phasor.h - - + + App/algo/prot_elm.h - -App/algo/prot_elm.h + +App/algo/prot_elm.h App/algo/prot_elm.c->App/algo/prot_elm.h - - + + App/algo/prot_set.h - -App/algo/prot_set.h + +App/algo/prot_set.h App/algo/prot_elm.c->App/algo/prot_set.h - - + + App/algo/prot_elm.c->外部/系统头文件 - - + + App/algo/prot_elm.h->外部/系统头文件 - - + + App/algo/prot_set.c - -App/algo/prot_set.c + +App/algo/prot_set.c App/algo/prot_set.c->App/algo/prot_set.h - - + + App/algo/prot_set.c->外部/系统头文件 - - + + App/algo/prot_set.h->外部/系统头文件 - - + + App/algo/sample_ring.c - -App/algo/sample_ring.c + +App/algo/sample_ring.c App/algo/sample_ring.c->App/algo/sample_ring.h - - + + App/algo/sample_ring.c->外部/系统头文件 - - + + App/algo/sample_ring.h->App/algo/adc_input.h - - + + App/algo/sample_ring.h->外部/系统头文件 - - + + App/app/app_cfg.h - -App/app/app_cfg.h + +App/app/app_cfg.h App/app/app_main.c - -App/app/app_main.c + +App/app/app_main.c App/app/app_main.c->App/algo/adc_input.h - - + + App/app/app_main.c->App/algo/freq.h - - + + App/app/app_main.c->App/algo/phasor.h - - + + App/app/app_main.c->App/algo/prot_elm.h - - + + App/app/app_main.c->App/algo/prot_set.h - - + + App/app/app_main.c->App/app/app_cfg.h - - + + App/app/app_main.h - -App/app/app_main.h + +App/app/app_main.h App/app/app_main.c->App/app/app_main.h - - + + App/log/sys_log.h - -App/log/sys_log.h + +App/log/sys_log.h App/app/app_main.c->App/log/sys_log.h - - + + App/util/sys_clock.h - -App/util/sys_clock.h + +App/util/sys_clock.h App/app/app_main.c->App/util/sys_clock.h - - + + App/util/task_watchdog.h - -App/util/task_watchdog.h + +App/util/task_watchdog.h App/app/app_main.c->App/util/task_watchdog.h - - + + Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h - -Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h + +Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h App/app/app_main.c->Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h - - + + - + Drivers/BSP/RS485/rs485.h - -Drivers/BSP/RS485/rs485.h + +Drivers/BSP/RS485/rs485.h App/app/app_main.c->Drivers/BSP/RS485/rs485.h - - + + - + Drivers/BSP/SD2506/sd2506.h - -Drivers/BSP/SD2506/sd2506.h + +Drivers/BSP/SD2506/sd2506.h App/app/app_main.c->Drivers/BSP/SD2506/sd2506.h - - + + App/app/app_main.c->Drivers/BSP/TPAFE5160/tpafe5160.h - - + + - + Drivers/BSP/dbg_log.h - -Drivers/BSP/dbg_log.h + +Drivers/BSP/dbg_log.h App/app/app_main.c->Drivers/BSP/dbg_log.h - - + + - + Inc/main.h - -Inc/main.h + +Inc/main.h App/app/app_main.c->Inc/main.h - - + + - + Inc/stm32f4xx_it.h - -Inc/stm32f4xx_it.h + +Inc/stm32f4xx_it.h App/app/app_main.c->Inc/stm32f4xx_it.h - - + + - + Inc/tim.h - -Inc/tim.h + +Inc/tim.h App/app/app_main.c->Inc/tim.h - - + + - + Inc/usart.h - -Inc/usart.h + +Inc/usart.h App/app/app_main.c->Inc/usart.h - - + + - + test/board/test_config.h - -test/board/test_config.h + +test/board/test_config.h App/app/app_main.c->test/board/test_config.h - - + + App/app/app_main.h->外部/系统头文件 - - + + App/app/sys_events.h - -App/app/sys_events.h + +App/app/sys_events.h - + Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h - -Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h + +Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h App/app/sys_events.h->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h - - + + App/cfg/cfg_file.c - -App/cfg/cfg_file.c + +App/cfg/cfg_file.c App/cfg/cfg_file.h - -App/cfg/cfg_file.h + +App/cfg/cfg_file.h App/cfg/cfg_file.c->App/cfg/cfg_file.h - - + + App/cfg/cfg_file_store.h - -App/cfg/cfg_file_store.h + +App/cfg/cfg_file_store.h App/cfg/cfg_file.c->App/cfg/cfg_file_store.h - - + + App/cfg/cfg_file.c->App/log/sys_log.h - - + + App/cfg/cfg_file.c->Drivers/BSP/dbg_log.h - - + + App/cfg/cfg_file.c->外部/系统头文件 - - + + App/cfg/cfg_file.h->外部/系统头文件 - - + + App/cfg/cfg_file_store.h->外部/系统头文件 - - + + App/cfg/cfg_file_store_mcu.c - -App/cfg/cfg_file_store_mcu.c + +App/cfg/cfg_file_store_mcu.c App/cfg/cfg_file_store_mcu.c->App/cfg/cfg_file_store.h - - + + App/fs/vol_lock.h - -App/fs/vol_lock.h + +App/fs/vol_lock.h App/cfg/cfg_file_store_mcu.c->App/fs/vol_lock.h - - + + - + Lib/FatFs/ff.h - -Lib/FatFs/ff.h + +Lib/FatFs/ff.h App/cfg/cfg_file_store_mcu.c->Lib/FatFs/ff.h - - + + - + Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - -Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h + +Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h App/cfg/cfg_file_store_mcu.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + App/cfg/cfg_file_store_mcu.c->外部/系统头文件 - - + + App/cfg/prot_set_store.c - -App/cfg/prot_set_store.c + +App/cfg/prot_set_store.c App/cfg/prot_set_store.c->App/algo/prot_set.h - - + + App/cfg/prot_set_store.c->App/cfg/cfg_file_store.h - - + + App/cfg/prot_set_store.h - -App/cfg/prot_set_store.h + +App/cfg/prot_set_store.h App/cfg/prot_set_store.c->App/cfg/prot_set_store.h - - + + App/cfg/prot_set_store.c->Drivers/BSP/dbg_log.h - - + + App/cfg/prot_set_store.c->外部/系统头文件 - - + + App/fs/vol_lock.c - -App/fs/vol_lock.c + +App/fs/vol_lock.c App/fs/vol_lock.c->App/fs/vol_lock.h - - + + - + Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - -Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h + +Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h App/fs/vol_lock.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + App/fs/vol_lock.h->外部/系统头文件 - - + + App/log/console_log.c - -App/log/console_log.c + +App/log/console_log.c App/log/console_log.c->App/app/sys_events.h - - + + App/log/console_log.h - -App/log/console_log.h + +App/log/console_log.h App/log/console_log.c->App/log/console_log.h - - + + App/log/console_log.c->Inc/usart.h - - + + App/log/console_log.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + App/log/console_log.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + - + Middlewares/Third_Party/FreeRTOS/Source/include/task.h - -Middlewares/Third_Party/FreeRTOS/Source/include/task.h + +Middlewares/Third_Party/FreeRTOS/Source/include/task.h App/log/console_log.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - + + App/log/console_log.c->外部/系统头文件 - - + + App/log/console_log.h->外部/系统头文件 - - + + App/log/soe_rec.c - -App/log/soe_rec.c + +App/log/soe_rec.c App/log/soe_rec.h - -App/log/soe_rec.h + +App/log/soe_rec.h App/log/soe_rec.c->App/log/soe_rec.h - - + + App/log/soe_rec.c->外部/系统头文件 - - + + App/log/soe_rec.h->外部/系统头文件 - - + + App/log/soe_store.c - -App/log/soe_store.c + +App/log/soe_store.c App/log/soe_store.c->App/fs/vol_lock.h - - + + App/log/soe_store.c->App/log/soe_rec.h - - + + App/log/soe_store.h - -App/log/soe_store.h + +App/log/soe_store.h App/log/soe_store.c->App/log/soe_store.h - - + + App/log/soe_store.c->App/util/sys_clock.h - - + + App/log/soe_store.c->Drivers/BSP/dbg_log.h - - + + App/log/soe_store.c->Lib/FatFs/ff.h - - + + App/log/soe_store.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + App/log/soe_store.c->外部/系统头文件 - - + + App/log/soe_store.h->App/log/soe_rec.h - - + + App/log/soe_store.h->外部/系统头文件 - - + + App/log/sys_log.h->外部/系统头文件 - - + + App/log/sys_log_mcu.c - -App/log/sys_log_mcu.c + +App/log/sys_log_mcu.c App/log/sys_log_mcu.c->App/fs/vol_lock.h - - + + App/log/sys_log_mcu.c->App/log/soe_store.h - - + + App/log/sys_log_mcu.c->App/log/sys_log.h - - + + App/log/sys_log_mcu.c->App/util/sys_clock.h - - + + App/log/sys_log_mcu.c->Drivers/BSP/dbg_log.h - - + + App/log/sys_log_mcu.c->Lib/FatFs/ff.h - - + + App/log/sys_log_mcu.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + App/log/sys_log_mcu.c->外部/系统头文件 - - + + App/protocol/iec104/iec104_asdu.c - -App/protocol/iec104/iec104_asdu.c + +App/protocol/iec104/iec104_asdu.c App/protocol/iec104/iec104_asdu.h - -App/protocol/iec104/iec104_asdu.h + +App/protocol/iec104/iec104_asdu.h App/protocol/iec104/iec104_asdu.c->App/protocol/iec104/iec104_asdu.h - - + + App/protocol/iec104/iec104_asdu.c->外部/系统头文件 - - + + App/protocol/iec104/iec104_asdu.h->外部/系统头文件 - - + + App/protocol/iec104/iec104_link.c - -App/protocol/iec104/iec104_link.c + +App/protocol/iec104/iec104_link.c App/protocol/iec104/iec104_link.c->App/protocol/iec104/iec104_asdu.h - - + + App/protocol/iec104/iec104_link.h - -App/protocol/iec104/iec104_link.h + +App/protocol/iec104/iec104_link.h App/protocol/iec104/iec104_link.c->App/protocol/iec104/iec104_link.h - - + + App/protocol/iec104/iec104_link.c->外部/系统头文件 - - + + App/protocol/iec104/iec104_pts.h - -App/protocol/iec104/iec104_pts.h + +App/protocol/iec104/iec104_pts.h App/protocol/iec104/iec104_link.h->App/protocol/iec104/iec104_pts.h - - + + App/protocol/iec104/iec104_link.h->外部/系统头文件 - - + + App/protocol/iec104/iec104_pts.c - -App/protocol/iec104/iec104_pts.c + +App/protocol/iec104/iec104_pts.c App/protocol/iec104/iec104_pts.c->App/algo/adc_input.h - - + + App/protocol/iec104/iec104_pts.c->App/algo/phasor.h - - + + App/protocol/iec104/iec104_pts.c->App/algo/prot_elm.h - - + + App/protocol/iec104/iec104_pts.c->App/algo/prot_set.h - - + + App/protocol/iec104/iec104_pts.c->App/protocol/iec104/iec104_asdu.h - - + + App/protocol/iec104/iec104_pts.c->App/protocol/iec104/iec104_pts.h - - + + App/protocol/iec104/iec104_pts.c->外部/系统头文件 - - + + App/protocol/iec104/iec104_pts.h->外部/系统头文件 - - + + App/sync/time_sync.c - -App/sync/time_sync.c + +App/sync/time_sync.c App/sync/time_sync.c->App/app/sys_events.h - - + + App/sync/time_sync.h - -App/sync/time_sync.h + +App/sync/time_sync.h App/sync/time_sync.c->App/sync/time_sync.h - - + + App/sync/time_sync.c->App/util/sys_clock.h - - + + App/sync/time_sync.c->App/util/task_watchdog.h - - + + - + Drivers/BSP/NET/net_socket.h - -Drivers/BSP/NET/net_socket.h + +Drivers/BSP/NET/net_socket.h App/sync/time_sync.c->Drivers/BSP/NET/net_socket.h - - + + App/sync/time_sync.c->Drivers/BSP/dbg_log.h - - + + App/sync/time_sync.c->外部/系统头文件 - - + + App/sync/time_sync.h->外部/系统头文件 - - + + App/task/adc_task.c - -App/task/adc_task.c + +App/task/adc_task.c App/task/adc_task.c->App/algo/adc_health.h - - + + App/task/adc_task.c->App/algo/adc_input.h - - + + App/task/adc_task.c->App/algo/freq.h - - + + App/task/adc_task.c->App/algo/phasor.h - - + + App/task/adc_task.c->App/algo/sample_ring.h - - + + App/task/adc_task.c->App/log/console_log.h - - + + App/task/adc_task.c->App/log/sys_log.h - - + + App/task/adc_task.h - -App/task/adc_task.h + +App/task/adc_task.h App/task/adc_task.c->App/task/adc_task.h - - + + App/util/task_prof.h - -App/util/task_prof.h + +App/util/task_prof.h App/task/adc_task.c->App/util/task_prof.h - - + + App/task/adc_task.c->App/util/task_watchdog.h - - + + App/task/adc_task.c->Drivers/BSP/TPAFE5160/tpafe5160.h - - + + App/task/adc_task.c->Drivers/BSP/dbg_log.h - - + + App/task/adc_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + App/task/default_task.c - -App/task/default_task.c + +App/task/default_task.c App/task/default_task.c->App/app/sys_events.h - - + + App/task/default_task.c->App/cfg/cfg_file.h - - + + App/task/default_task.c->App/cfg/prot_set_store.h - - + + App/task/default_task.c->App/fs/vol_lock.h - - + + App/task/default_task.c->App/log/sys_log.h - - + + App/task/default_task.h - -App/task/default_task.h + +App/task/default_task.h App/task/default_task.c->App/task/default_task.h - - + + App/task/default_task.c->App/util/task_prof.h - - + + App/task/default_task.c->App/util/task_watchdog.h - - + + Drivers/BSP/GD5F2GQ5UE/nand_ftl.h - -Drivers/BSP/GD5F2GQ5UE/nand_ftl.h + +Drivers/BSP/GD5F2GQ5UE/nand_ftl.h App/task/default_task.c->Drivers/BSP/GD5F2GQ5UE/nand_ftl.h - - + + - + Drivers/BSP/NETCFG/net_cfg.h - -Drivers/BSP/NETCFG/net_cfg.h + +Drivers/BSP/NETCFG/net_cfg.h App/task/default_task.c->Drivers/BSP/NETCFG/net_cfg.h - - + + App/task/default_task.c->Drivers/BSP/dbg_log.h - - + + App/task/default_task.c->Inc/main.h - - + + App/task/default_task.c->Lib/FatFs/ff.h - - + + App/task/default_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + App/task/default_task.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + App/task/default_task.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - + + App/task/default_task.c->test/board/test_config.h - - + + App/task/iec104_serv.c - -App/task/iec104_serv.c + +App/task/iec104_serv.c App/task/iec104_serv.c->App/algo/prot_set.h - - + + App/task/iec104_serv.c->App/app/sys_events.h - - + + App/task/iec104_serv.c->App/protocol/iec104/iec104_link.h - - + + App/task/iec104_serv.c->App/protocol/iec104/iec104_pts.h - - + + App/task/iec104_serv.h - -App/task/iec104_serv.h + +App/task/iec104_serv.h App/task/iec104_serv.c->App/task/iec104_serv.h - - + + App/task/iec104_serv.c->App/util/sys_clock.h - - + + App/task/iec104_serv.c->App/util/task_watchdog.h - - + + App/task/iec104_serv.c->Drivers/BSP/NET/net_socket.h - - + + App/task/iec104_serv.c->Drivers/BSP/dbg_log.h - - + + App/task/iec104_serv.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h - - + + App/task/iec104_serv.c->外部/系统头文件 - - + + App/task/net_task.c - -App/task/net_task.c + +App/task/net_task.c App/task/net_task.c->App/app/sys_events.h - - + + App/task/net_task.c->App/log/sys_log.h - - + + App/task/net_task.h - -App/task/net_task.h + +App/task/net_task.h App/task/net_task.c->App/task/net_task.h - - + + App/task/net_task.c->App/util/task_prof.h - - + + App/task/net_task.c->App/util/task_watchdog.h - - + + Drivers/BSP/CH395F/ch395f.h - -Drivers/BSP/CH395F/ch395f.h + +Drivers/BSP/CH395F/ch395f.h App/task/net_task.c->Drivers/BSP/CH395F/ch395f.h - - + + - + Drivers/BSP/NET/net_select.h - -Drivers/BSP/NET/net_select.h + +Drivers/BSP/NET/net_select.h App/task/net_task.c->Drivers/BSP/NET/net_select.h - - + + App/task/net_task.c->Drivers/BSP/NET/net_socket.h - - + + App/task/net_task.c->Drivers/BSP/NETCFG/net_cfg.h - - + + App/task/net_task.c->Drivers/BSP/dbg_log.h - - + + App/task/net_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + App/task/net_task.c->test/board/test_config.h - - + + App/task/net_task.c->外部/系统头文件 - - + + App/task/protect_task.c - -App/task/protect_task.c + +App/task/protect_task.c App/task/protect_task.c->App/algo/adc_health.h - - + + App/task/protect_task.c->App/algo/prot_elm.h - - + + App/task/protect_task.c->App/algo/prot_set.h - - + + App/task/protect_task.c->App/log/console_log.h - - + + App/task/protect_task.c->App/log/soe_store.h - - + + App/task/protect_task.h - -App/task/protect_task.h + +App/task/protect_task.h App/task/protect_task.c->App/task/protect_task.h - - + + App/task/protect_task.c->App/util/task_watchdog.h - - + + App/task/protect_task.c->Drivers/BSP/dbg_log.h - - + + App/task/protect_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h - - + + App/task/rs485_task.c - -App/task/rs485_task.c + +App/task/rs485_task.c App/task/rs485_task.h - -App/task/rs485_task.h + +App/task/rs485_task.h App/task/rs485_task.c->App/task/rs485_task.h - - + + App/task/rs485_task.c->Drivers/BSP/RS485/rs485.h - - + + App/task/rs485_task.c->Drivers/BSP/dbg_log.h - - + + App/task/rs485_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + App/task/ui_task.c - -App/task/ui_task.c + +App/task/ui_task.c App/task/ui_task.c->App/app/sys_events.h - - + + App/task/ui_task.h - -App/task/ui_task.h + +App/task/ui_task.h App/task/ui_task.c->App/task/ui_task.h - - + + App/task/ui_task.c->App/util/sys_clock.h - - + + App/task/ui_task.c->App/util/task_prof.h - - + + App/task/ui_task.c->App/util/task_watchdog.h - - + + - + Drivers/BSP/UI/ui_menu.h - -Drivers/BSP/UI/ui_menu.h + +Drivers/BSP/UI/ui_menu.h App/task/ui_task.c->Drivers/BSP/UI/ui_menu.h - - + + - + Drivers/BSP/UI/ui_net_sink.h - -Drivers/BSP/UI/ui_net_sink.h + +Drivers/BSP/UI/ui_net_sink.h App/task/ui_task.c->Drivers/BSP/UI/ui_net_sink.h - - + + - + Drivers/BSP/UI/ui_port.h - -Drivers/BSP/UI/ui_port.h + +Drivers/BSP/UI/ui_port.h App/task/ui_task.c->Drivers/BSP/UI/ui_port.h - - + + - + Drivers/BSP/UI/ui_standby.h - -Drivers/BSP/UI/ui_standby.h + +Drivers/BSP/UI/ui_standby.h App/task/ui_task.c->Drivers/BSP/UI/ui_standby.h - - + + App/task/ui_task.c->Drivers/BSP/dbg_log.h - - + + App/task/ui_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + test/board/net_latency_test.h - -test/board/net_latency_test.h + +test/board/net_latency_test.h App/task/ui_task.c->test/board/net_latency_test.h - - + + App/task/ui_task.c->test/board/test_config.h - - + + App/task/ui_task.c->外部/系统头文件 - - + + App/util/sha256.c - -App/util/sha256.c + +App/util/sha256.c App/util/sha256.h - -App/util/sha256.h + +App/util/sha256.h App/util/sha256.c->App/util/sha256.h - - + + App/util/sha256.c->外部/系统头文件 - - + + App/util/sha256.h->外部/系统头文件 - - + + App/util/sys_clock.c - -App/util/sys_clock.c + +App/util/sys_clock.c App/util/sys_clock.c->App/util/sys_clock.h - - + + App/util/sys_clock.c->Drivers/BSP/dbg_log.h - - + + App/util/sys_clock.c->Inc/main.h - - + + App/util/sys_clock.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + App/util/sys_clock.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - + + App/util/sys_clock.c->外部/系统头文件 - - + + App/util/sys_clock.h->Drivers/BSP/SD2506/sd2506.h - - + + App/util/sys_clock.h->外部/系统头文件 - - + + App/util/task_prof.c - -App/util/task_prof.c + +App/util/task_prof.c App/util/task_prof.c->App/log/console_log.h - - + + App/util/task_prof.c->App/util/task_prof.h - - + + App/util/task_prof.c->Inc/main.h - - + + App/util/task_prof.c->外部/系统头文件 - - + + App/util/task_prof.h->外部/系统头文件 - - + + App/util/task_watchdog.c - -App/util/task_watchdog.c + +App/util/task_watchdog.c App/util/task_watchdog.c->App/log/console_log.h - - + + App/util/task_watchdog.c->App/log/sys_log.h - - + + App/util/task_watchdog.c->App/util/task_watchdog.h - - + + Drivers/BSP/NET/lftpd/lftpd.h - -Drivers/BSP/NET/lftpd/lftpd.h + +Drivers/BSP/NET/lftpd/lftpd.h App/util/task_watchdog.c->Drivers/BSP/NET/lftpd/lftpd.h - - + + App/util/task_watchdog.c->Drivers/BSP/dbg_log.h - - + + - + Inc/iwdg.h - -Inc/iwdg.h + +Inc/iwdg.h App/util/task_watchdog.c->Inc/iwdg.h - - + + App/util/task_watchdog.c->Inc/main.h - - + + App/util/task_watchdog.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + App/util/task_watchdog.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - + + App/util/task_watchdog.c->外部/系统头文件 - - + + App/util/task_watchdog.h->外部/系统头文件 - - + + Drivers/BSP/CH395F/ch395f.c - -Drivers/BSP/CH395F/ch395f.c + +Drivers/BSP/CH395F/ch395f.c Drivers/BSP/CH395F/ch395f.c->Drivers/BSP/CH395F/ch395f.h - - + + Drivers/BSP/CH395F/ch395f.c->Drivers/BSP/dbg_log.h - - + + - + Inc/spi.h - -Inc/spi.h + +Inc/spi.h Drivers/BSP/CH395F/ch395f.c->Inc/spi.h - - + + Drivers/BSP/CH395F/ch395f.c->Inc/usart.h - - + + Drivers/BSP/CH395F/ch395f.c->外部/系统头文件 - - + + Drivers/BSP/CH395F/ch395f.h->Inc/main.h - - + + Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c - -Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c + +Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c->Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h - - + + Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c->Drivers/BSP/dbg_log.h - - + + Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c->外部/系统头文件 - - + + Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h->Inc/main.h - - + + Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h->外部/系统头文件 - - + + Drivers/BSP/GD5F2GQ5UE/nand_ftl.c - -Drivers/BSP/GD5F2GQ5UE/nand_ftl.c + +Drivers/BSP/GD5F2GQ5UE/nand_ftl.c Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h - - + + Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Drivers/BSP/dbg_log.h - - + + - + Lib/FatFs/diskio.h - -Lib/FatFs/diskio.h + +Lib/FatFs/diskio.h Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Lib/FatFs/diskio.h - - + + Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Lib/FatFs/ff.h - - + + - + Lib/dhara/map.h - -Lib/dhara/map.h + +Lib/dhara/map.h Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Lib/dhara/map.h - - + + - + Lib/dhara/nand.h - -Lib/dhara/nand.h + +Lib/dhara/nand.h Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->Lib/dhara/nand.h - - + + Drivers/BSP/GD5F2GQ5UE/nand_ftl.c->外部/系统头文件 - - + + Drivers/BSP/GD5F2GQ5UE/nand_ftl.h->外部/系统头文件 - - + + Drivers/BSP/NET/lftpd/lftpd_auth.c - -Drivers/BSP/NET/lftpd/lftpd_auth.c + +Drivers/BSP/NET/lftpd/lftpd_auth.c Drivers/BSP/NET/net_config.h - -Drivers/BSP/NET/net_config.h + +Drivers/BSP/NET/net_config.h Drivers/BSP/NET/net_listener.c - -Drivers/BSP/NET/net_listener.c + +Drivers/BSP/NET/net_listener.c Drivers/BSP/NET/net_listener.c->Drivers/BSP/CH395F/ch395f.h - - + + Drivers/BSP/NET/net_listener.h - -Drivers/BSP/NET/net_listener.h + +Drivers/BSP/NET/net_listener.h Drivers/BSP/NET/net_listener.c->Drivers/BSP/NET/net_listener.h - - + + Drivers/BSP/NET/net_listener.c->Drivers/BSP/NET/net_socket.h - - + + Drivers/BSP/NET/net_listener.c->Drivers/BSP/dbg_log.h - - + + Drivers/BSP/NET/net_listener.c->Inc/main.h - - + + Drivers/BSP/NET/net_listener.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + Drivers/BSP/NET/net_listener.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + Drivers/BSP/NET/net_listener.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - + + Drivers/BSP/NET/net_listener.c->test/board/net_latency_test.h - - + + Drivers/BSP/NET/net_listener.c->test/board/test_config.h - - + + Drivers/BSP/NET/net_listener.c->外部/系统头文件 - - + + - + Drivers/BSP/NET/net_types.h - -Drivers/BSP/NET/net_types.h + +Drivers/BSP/NET/net_types.h Drivers/BSP/NET/net_listener.h->Drivers/BSP/NET/net_types.h - - + + + + + +Drivers/BSP/NET/net_pending.c + +Drivers/BSP/NET/net_pending.c + + + +Drivers/BSP/NET/net_pending.c->Drivers/BSP/CH395F/ch395f.h + + + + + +Drivers/BSP/NET/net_pending.c->Drivers/BSP/NET/net_listener.h + + + + + +Drivers/BSP/NET/net_pending.h + +Drivers/BSP/NET/net_pending.h + + + +Drivers/BSP/NET/net_pending.c->Drivers/BSP/NET/net_pending.h + + + + + +Drivers/BSP/NET/net_pending.c->Drivers/BSP/NET/net_socket.h + + + + + +Drivers/BSP/NET/net_pending.c->Drivers/BSP/NET/net_types.h + + + + + +Drivers/BSP/NET/net_pending.c->Drivers/BSP/dbg_log.h + + + + + +Drivers/BSP/NET/net_pending.c->Inc/main.h + + + + + +Drivers/BSP/NET/net_pending.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h + + + + + +Drivers/BSP/NET/net_pending.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h + + + + + +Drivers/BSP/NET/net_pending.c->外部/系统头文件 + + + + + +Drivers/BSP/NET/net_pending.h->Drivers/BSP/NET/net_types.h + + + + + +Drivers/BSP/NET/net_pending.h->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h + + + + + +Drivers/BSP/NET/net_pending.h->Middlewares/Third_Party/FreeRTOS/Source/include/task.h + + + + + +Drivers/BSP/NET/net_pending.h->外部/系统头文件 + + - + Drivers/BSP/NET/net_select.c - -Drivers/BSP/NET/net_select.c + +Drivers/BSP/NET/net_select.c - + Drivers/BSP/NET/net_select.c->Drivers/BSP/CH395F/ch395f.h - - + + - + Drivers/BSP/NET/net_select.c->Drivers/BSP/NET/net_select.h - - + + - + Drivers/BSP/NET/net_select.c->Drivers/BSP/NET/net_socket.h - - + + - + Drivers/BSP/NET/net_select.c->Inc/main.h - - + + - + Drivers/BSP/NET/net_select.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + Drivers/BSP/NET/net_select.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + - + Drivers/BSP/NET/net_select.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - + + - + Drivers/BSP/NET/net_select.c->外部/系统头文件 - - + + - + Drivers/BSP/NET/net_select.h->Drivers/BSP/NET/net_config.h - - + + - + Drivers/BSP/NET/net_select.h->Drivers/BSP/NET/net_types.h - - + + - + Drivers/BSP/NET/net_socket.c - -Drivers/BSP/NET/net_socket.c + +Drivers/BSP/NET/net_socket.c - + Drivers/BSP/NET/net_socket.c->Drivers/BSP/CH395F/ch395f.h - - + + - + Drivers/BSP/NET/net_socket.c->Drivers/BSP/NET/net_listener.h - - + + + + + +Drivers/BSP/NET/net_socket.c->Drivers/BSP/NET/net_pending.h + + - + Drivers/BSP/NET/net_socket.c->Drivers/BSP/NET/net_socket.h - - + + - + Drivers/BSP/NET/net_socket.c->Drivers/BSP/dbg_log.h - - + + - + Drivers/BSP/NET/net_socket.c->Inc/main.h - - + + - + Drivers/BSP/NET/net_socket.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + Drivers/BSP/NET/net_socket.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + - + Drivers/BSP/NET/net_socket.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - + + - + Drivers/BSP/NET/net_socket.c->test/board/net_latency_test.h - - + + - + Drivers/BSP/NET/net_socket.c->test/board/test_config.h - - + + - + Drivers/BSP/NET/net_socket.c->外部/系统头文件 - - + + - + Drivers/BSP/NET/net_socket.h->Drivers/BSP/NET/net_types.h - - + + - + Drivers/BSP/NET/net_socket.h->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + - + Drivers/BSP/NET/net_socket.h->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - + + - + Drivers/BSP/NET/net_types.h->Drivers/BSP/NET/net_config.h - - + + - + Drivers/BSP/NET/net_types.h->外部/系统头文件 - - + + - + Drivers/BSP/NETCFG/ftp_cfg.c - -Drivers/BSP/NETCFG/ftp_cfg.c + +Drivers/BSP/NETCFG/ftp_cfg.c - + Drivers/BSP/NETCFG/ftp_cfg.c->App/cfg/cfg_file.h - - + + - + Drivers/BSP/NETCFG/ftp_cfg.h - -Drivers/BSP/NETCFG/ftp_cfg.h + +Drivers/BSP/NETCFG/ftp_cfg.h - + Drivers/BSP/NETCFG/ftp_cfg.c->Drivers/BSP/NETCFG/ftp_cfg.h - - + + - + Drivers/BSP/NETCFG/ftp_cfg.c->外部/系统头文件 - - + + - + Drivers/BSP/NETCFG/ftp_cfg.h->外部/系统头文件 - - + + - + Drivers/BSP/NETCFG/net_cfg.c - -Drivers/BSP/NETCFG/net_cfg.c + +Drivers/BSP/NETCFG/net_cfg.c - + Drivers/BSP/NETCFG/net_cfg.c->App/cfg/cfg_file.h - - + + - + Drivers/BSP/NETCFG/net_cfg.c->Drivers/BSP/NETCFG/ftp_cfg.h - - + + - + Drivers/BSP/NETCFG/net_cfg.c->Drivers/BSP/NETCFG/net_cfg.h - - + + - + Drivers/BSP/NETCFG/net_cfg.c->Drivers/BSP/dbg_log.h - - + + - + Drivers/BSP/NETCFG/net_cfg.c->外部/系统头文件 - - + + - + Drivers/BSP/NETCFG/net_cfg.h->外部/系统头文件 - - + + - + Drivers/BSP/RS485/rs485.c - -Drivers/BSP/RS485/rs485.c + +Drivers/BSP/RS485/rs485.c - + Drivers/BSP/RS485/rs485.c->Drivers/BSP/RS485/rs485.h - - + + - + Drivers/BSP/RS485/rs485.h->Inc/main.h - - + + - + Drivers/BSP/SD2506/sd2506.c - -Drivers/BSP/SD2506/sd2506.c + +Drivers/BSP/SD2506/sd2506.c - + Drivers/BSP/SD2506/sd2506.c->Drivers/BSP/SD2506/sd2506.h - - + + - + Drivers/BSP/SD2506/sd2506.c->Drivers/BSP/dbg_log.h - - + + - + Inc/i2c.h - -Inc/i2c.h + +Inc/i2c.h - + Drivers/BSP/SD2506/sd2506.c->Inc/i2c.h - - + + - + Drivers/BSP/SD2506/sd2506.c->外部/系统头文件 - - + + - + Drivers/BSP/SD2506/sd2506.h->Inc/main.h - - + + - + Drivers/BSP/TPAFE5160/tpafe5160.c - -Drivers/BSP/TPAFE5160/tpafe5160.c + +Drivers/BSP/TPAFE5160/tpafe5160.c - + Drivers/BSP/TPAFE5160/tpafe5160.c->Drivers/BSP/TPAFE5160/tpafe5160.h - - + + - + Drivers/BSP/TPAFE5160/tpafe5160.c->Drivers/BSP/dbg_log.h - - + + - + Drivers/BSP/TPAFE5160/tpafe5160.c->Inc/main.h - - + + - + Drivers/BSP/TPAFE5160/tpafe5160.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + - + Drivers/BSP/TPAFE5160/tpafe5160.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - + + - + Drivers/BSP/TPAFE5160/tpafe5160.c->外部/系统头文件 - - + + - + Drivers/BSP/TPAFE5160/tpafe5160.h->Inc/main.h - - + + - + Drivers/BSP/UI/ui_content_page.c - -Drivers/BSP/UI/ui_content_page.c + +Drivers/BSP/UI/ui_content_page.c - + Drivers/BSP/UI/ui_content_page.h - -Drivers/BSP/UI/ui_content_page.h + +Drivers/BSP/UI/ui_content_page.h - + Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_content_page.h - - + + - + Drivers/BSP/UI/ui_deco.h - -Drivers/BSP/UI/ui_deco.h + +Drivers/BSP/UI/ui_deco.h - + Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_deco.h - - + + - + Drivers/BSP/UI/ui_menu_view.h - -Drivers/BSP/UI/ui_menu_view.h + +Drivers/BSP/UI/ui_menu_view.h - + Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_menu_view.h - - + + - + Drivers/BSP/UI/ui_page_ac.h - -Drivers/BSP/UI/ui_page_ac.h + +Drivers/BSP/UI/ui_page_ac.h - + Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_ac.h - - + + - + Drivers/BSP/UI/ui_page_dc.h - -Drivers/BSP/UI/ui_page_dc.h + +Drivers/BSP/UI/ui_page_dc.h - + Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_dc.h - - + + - + Drivers/BSP/UI/ui_page_device_info.h - -Drivers/BSP/UI/ui_page_device_info.h + +Drivers/BSP/UI/ui_page_device_info.h - + Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_device_info.h - - + + - + Drivers/BSP/UI/ui_page_net_cfg.h - -Drivers/BSP/UI/ui_page_net_cfg.h + +Drivers/BSP/UI/ui_page_net_cfg.h - + Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_net_cfg.h - - + + - + Drivers/BSP/UI/ui_page_password.h - -Drivers/BSP/UI/ui_page_password.h + +Drivers/BSP/UI/ui_page_password.h - + Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_password.h - - + + - + Drivers/BSP/UI/ui_page_runlog.h - -Drivers/BSP/UI/ui_page_runlog.h + +Drivers/BSP/UI/ui_page_runlog.h - + Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_runlog.h - - + + - + Drivers/BSP/UI/ui_page_selftest.h - -Drivers/BSP/UI/ui_page_selftest.h + +Drivers/BSP/UI/ui_page_selftest.h - + Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_page_selftest.h - - + + - + Drivers/BSP/UI/ui_pwd_def.h - -Drivers/BSP/UI/ui_pwd_def.h + +Drivers/BSP/UI/ui_pwd_def.h - + Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_pwd_def.h - - + + - + Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/UI/ui_standby.h - - + + - + Drivers/BSP/UI/ui_content_page.c->Drivers/BSP/dbg_log.h - - + + - + Lib/lvgl/lvgl.h - -Lib/lvgl/lvgl.h + +Lib/lvgl/lvgl.h - + Drivers/BSP/UI/ui_content_page.c->Lib/lvgl/lvgl.h - - + + - + Drivers/BSP/UI/ui_content_page.c->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_content_page.h->Lib/lvgl/lvgl.h - - + + - + Drivers/BSP/UI/ui_content_page.h->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_deco.c - -Drivers/BSP/UI/ui_deco.c + +Drivers/BSP/UI/ui_deco.c - + Drivers/BSP/UI/ui_deco.c->Drivers/BSP/UI/ui_deco.h - - + + - + Drivers/BSP/UI/ui_deco.c->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_deco.h->Lib/lvgl/lvgl.h - - + + - + Drivers/BSP/UI/ui_font_cn_12.c - -Drivers/BSP/UI/ui_font_cn_12.c + +Drivers/BSP/UI/ui_font_cn_12.c - + Drivers/BSP/UI/ui_font_cn_12.c->Lib/lvgl/lvgl.h - - + + - + Drivers/BSP/UI/ui_menu.c - -Drivers/BSP/UI/ui_menu.c + +Drivers/BSP/UI/ui_menu.c - + Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_content_page.h - - + + - + Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_menu.h - - + + - + Drivers/BSP/UI/ui_menu_tab.h - -Drivers/BSP/UI/ui_menu_tab.h + +Drivers/BSP/UI/ui_menu_tab.h - + Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_menu_tab.h - - + + - + Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_menu_view.h - - + + - + Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_page_password.h - - + + - + Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_pwd_def.h - - + + - + Drivers/BSP/UI/ui_menu.c->Drivers/BSP/UI/ui_standby.h - - + + - + Drivers/BSP/UI/ui_menu.c->Drivers/BSP/dbg_log.h - - + + - + Drivers/BSP/UI/ui_menu.c->Lib/lvgl/lvgl.h - - + + - + Drivers/BSP/UI/ui_menu.c->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_menu_tab.c - -Drivers/BSP/UI/ui_menu_tab.c + +Drivers/BSP/UI/ui_menu_tab.c - + Drivers/BSP/UI/ui_menu_tab.c->Drivers/BSP/UI/ui_menu_tab.h - - + + - + Drivers/BSP/UI/ui_menu_tab.h->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_menu_view.c - -Drivers/BSP/UI/ui_menu_view.c + +Drivers/BSP/UI/ui_menu_view.c - + Drivers/BSP/UI/ui_menu_view.c->Drivers/BSP/UI/ui_deco.h - - + + - + Drivers/BSP/UI/ui_menu_view.c->Drivers/BSP/UI/ui_menu_tab.h - - + + - + Drivers/BSP/UI/ui_menu_view.c->Drivers/BSP/UI/ui_menu_view.h - - + + - + Drivers/BSP/UI/ui_menu_view.c->Drivers/BSP/dbg_log.h - - + + - + Drivers/BSP/UI/ui_menu_view.c->Lib/lvgl/lvgl.h - - + + - + Drivers/BSP/UI/ui_menu_view.c->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_menu_view.h->Lib/lvgl/lvgl.h - - + + - + Drivers/BSP/UI/ui_menu_view.h->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_net_sink.c - -Drivers/BSP/UI/ui_net_sink.c + +Drivers/BSP/UI/ui_net_sink.c - + Drivers/BSP/UI/ui_net_sink.c->Drivers/BSP/NET/net_socket.h - - + + - + Drivers/BSP/UI/ui_net_sink.c->Drivers/BSP/NET/net_types.h - - + + - + Drivers/BSP/UI/ui_net_sink.c->Drivers/BSP/UI/ui_net_sink.h - - + + - + Drivers/BSP/UI/ui_net_sink_backend.h - -Drivers/BSP/UI/ui_net_sink_backend.h + +Drivers/BSP/UI/ui_net_sink_backend.h - + Drivers/BSP/UI/ui_net_sink.c->Drivers/BSP/UI/ui_net_sink_backend.h - - + + - + Drivers/BSP/UI/ui_net_sink.c->Drivers/BSP/dbg_log.h - - + + - + Drivers/BSP/UI/ui_net_sink.c->test/board/net_latency_test.h - - + + - + Drivers/BSP/UI/ui_net_sink.c->test/board/test_config.h - - + + - + Drivers/BSP/UI/ui_net_sink.c->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_net_sink.h->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_net_sink_backend.h->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_net_sink_backend_mcu.c - -Drivers/BSP/UI/ui_net_sink_backend_mcu.c + +Drivers/BSP/UI/ui_net_sink_backend_mcu.c - + Drivers/BSP/UI/ui_net_sink_backend_mcu.c->Drivers/BSP/UI/ui_net_sink_backend.h - - + + - + Drivers/BSP/UI/ui_net_sink_backend_mcu.c->Drivers/BSP/UI/ui_port.h - - + + - + Drivers/BSP/UI/ui_net_sink_backend_mcu.c->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_page_ac.c - -Drivers/BSP/UI/ui_page_ac.c + +Drivers/BSP/UI/ui_page_ac.c - + Drivers/BSP/UI/ui_page_ac.c->Drivers/BSP/UI/ui_page_ac.h - - + + - + Drivers/BSP/UI/ui_page_ac.h->Drivers/BSP/UI/ui_content_page.h - - + + - + Drivers/BSP/UI/ui_page_dc.c - -Drivers/BSP/UI/ui_page_dc.c + +Drivers/BSP/UI/ui_page_dc.c - + Drivers/BSP/UI/ui_page_dc.c->Drivers/BSP/UI/ui_page_dc.h - - + + - + Drivers/BSP/UI/ui_page_dc.h->Drivers/BSP/UI/ui_content_page.h - - + + - + Drivers/BSP/UI/ui_page_device_info.c - -Drivers/BSP/UI/ui_page_device_info.c + +Drivers/BSP/UI/ui_page_device_info.c - + Drivers/BSP/UI/ui_page_device_info.c->Drivers/BSP/UI/ui_page_device_info.h - - + + - + Drivers/BSP/UI/ui_page_device_info.h->Drivers/BSP/UI/ui_content_page.h - - + + - + Drivers/BSP/UI/ui_page_net_cfg.c - -Drivers/BSP/UI/ui_page_net_cfg.c + +Drivers/BSP/UI/ui_page_net_cfg.c - + Drivers/BSP/UI/ui_page_net_cfg.c->Drivers/BSP/NETCFG/net_cfg.h - - + + - + Drivers/BSP/UI/ui_page_net_cfg.c->Drivers/BSP/UI/ui_page_net_cfg.h - - + + - + Drivers/BSP/UI/ui_page_net_cfg.c->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_page_net_cfg.h->Drivers/BSP/UI/ui_content_page.h - - + + - + Drivers/BSP/UI/ui_page_password.c - -Drivers/BSP/UI/ui_page_password.c + +Drivers/BSP/UI/ui_page_password.c - + Drivers/BSP/UI/ui_page_password.c->Drivers/BSP/UI/ui_page_password.h - - + + - + Drivers/BSP/UI/ui_page_password.c->Drivers/BSP/UI/ui_pwd_def.h - - + + - + Drivers/BSP/UI/ui_page_password.c->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_page_password.h->Drivers/BSP/UI/ui_content_page.h - - + + - + Drivers/BSP/UI/ui_page_runlog.c - -Drivers/BSP/UI/ui_page_runlog.c + +Drivers/BSP/UI/ui_page_runlog.c - + Drivers/BSP/UI/ui_page_runlog.c->App/log/sys_log.h - - + + - + Drivers/BSP/UI/ui_page_runlog.c->Drivers/BSP/UI/ui_page_runlog.h - - + + - + Drivers/BSP/UI/ui_page_runlog.c->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_page_runlog.h->Drivers/BSP/UI/ui_content_page.h - - + + - + Drivers/BSP/UI/ui_page_selftest.c - -Drivers/BSP/UI/ui_page_selftest.c + +Drivers/BSP/UI/ui_page_selftest.c - + Drivers/BSP/UI/ui_page_selftest.c->App/log/sys_log.h - - + + - + Drivers/BSP/UI/ui_page_selftest.c->Drivers/BSP/UI/ui_page_selftest.h - - + + - + Drivers/BSP/UI/ui_page_selftest.c->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_page_selftest.h->Drivers/BSP/UI/ui_content_page.h - - + + - + Drivers/BSP/UI/ui_port.c - -Drivers/BSP/UI/ui_port.c + +Drivers/BSP/UI/ui_port.c - + Drivers/BSP/UI/ui_port.c->Drivers/BSP/UI/ui_port.h - - + + - + Drivers/BSP/UI/ui_port.c->Drivers/BSP/dbg_log.h - - + + - + Drivers/BSP/UI/ui_port.c->Lib/lvgl/lvgl.h - - + + - + Drivers/BSP/UI/ui_port.c->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_port.h->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_pwd_def.h->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_standby.c - -Drivers/BSP/UI/ui_standby.c + +Drivers/BSP/UI/ui_standby.c - + Drivers/BSP/UI/ui_standby.c->Drivers/BSP/UI/ui_menu_view.h - - + + - + Drivers/BSP/UI/ui_standby.c->Drivers/BSP/UI/ui_standby.h - - + + - + Drivers/BSP/UI/ui_standby.c->Drivers/BSP/dbg_log.h - - + + - + Drivers/BSP/UI/ui_standby.c->Lib/lvgl/lvgl.h - - + + - + Drivers/BSP/UI/ui_standby.c->外部/系统头文件 - - + + - + Drivers/BSP/UI/ui_standby.h->外部/系统头文件 - - + + - + Drivers/BSP/dbg_cfg.h - -Drivers/BSP/dbg_cfg.h + +Drivers/BSP/dbg_cfg.h - + Drivers/BSP/dbg_log.h->App/log/console_log.h - - + + - + Drivers/BSP/dbg_log.h->App/util/sys_clock.h - - + + - + Drivers/BSP/dbg_log.h->Drivers/BSP/dbg_cfg.h - - + + - + Drivers/BSP/dbg_log.h->外部/系统头文件 - - + + - + Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h - -Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h + +Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h - + Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h - + Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h - + Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h - + Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h - + Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h - + Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h - + Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h - + Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h - + Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h - + Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h - + Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h - + Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h - + Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h - + Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h - -Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h + +Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h - + Inc/FreeRTOSConfig.h - -Inc/FreeRTOSConfig.h + +Inc/FreeRTOSConfig.h - + Inc/FreeRTOSConfig.h->外部/系统头文件 - - + + - + Inc/adc.h->Inc/main.h - - + + - + Inc/dma.h - -Inc/dma.h + +Inc/dma.h - + Inc/dma.h->Inc/main.h - - + + - + Inc/gpio.h - -Inc/gpio.h + +Inc/gpio.h - + Inc/gpio.h->Inc/main.h - - + + - + Inc/i2c.h->Inc/main.h - - + + - + Inc/iwdg.h->Inc/main.h - - + + - + Inc/main.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h - - + + - + Inc/spi.h->Inc/main.h - - + + - + Inc/stm32f4xx_hal_conf.h - -Inc/stm32f4xx_hal_conf.h + +Inc/stm32f4xx_hal_conf.h - + Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_adc.h - - + + - + Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_cortex.h - - + + - + Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_dma.h - - + + - + Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_exti.h - - + + - + Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash.h - - + + - + Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_gpio.h - - + + - + Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h - - + + - + Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_iwdg.h - - + + - + Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_pwr.h - - + + - + Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_rcc.h - - + + - + Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_spi.h - - + + - + Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h - - + + - + Inc/stm32f4xx_hal_conf.h->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_uart.h - - + + - + Inc/stm32f4xx_hal_conf.h->外部/系统头文件 - - + + - + Inc/tim.h->Inc/main.h - - + + - + Inc/usart.h->Inc/main.h - - + + - + Src/adc.c - -Src/adc.c + +Src/adc.c - + Src/adc.c->Inc/adc.h - - + + - + Src/dma.c - -Src/dma.c + +Src/dma.c - + Src/dma.c->Inc/dma.h - - + + - + Src/freertos.c - -Src/freertos.c + +Src/freertos.c - + Src/freertos.c->App/app/sys_events.h - - + + - + Src/freertos.c->App/sync/time_sync.h - - + + - + Src/freertos.c->App/task/adc_task.h - - + + - + Src/freertos.c->App/task/default_task.h - - + + - + Src/freertos.c->App/task/iec104_serv.h - - + + - + Src/freertos.c->App/task/net_task.h - - + + - + Src/freertos.c->App/task/protect_task.h - - + + - + Src/freertos.c->App/util/task_watchdog.h - - + + - + Src/freertos.c->Drivers/BSP/CH395F/ch395f.h - - + + - + Src/freertos.c->Drivers/BSP/NET/lftpd/lftpd.h - - + + - + Src/freertos.c->Drivers/BSP/NET/net_socket.h - - + + - + Src/freertos.c->Drivers/BSP/dbg_log.h - - + + - + Src/freertos.c->Inc/main.h - - + + - + Src/freertos.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + Src/freertos.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + - + Src/freertos.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - + + - + test/board/ch395f_test.h - -test/board/ch395f_test.h + +test/board/ch395f_test.h - + Src/freertos.c->test/board/ch395f_test.h - - + + - + test/board/ch395f_test_task.h - -test/board/ch395f_test_task.h + +test/board/ch395f_test_task.h - + Src/freertos.c->test/board/ch395f_test_task.h - - + + - + Src/freertos.c->test/board/test_config.h - - + + - + Src/freertos.c->外部/系统头文件 - - + + - + Src/gpio.c - -Src/gpio.c + +Src/gpio.c - + Src/gpio.c->Inc/gpio.h - - + + - + Src/i2c.c - -Src/i2c.c + +Src/i2c.c - + Src/i2c.c->Inc/i2c.h - - + + - + Src/iwdg.c - -Src/iwdg.c + +Src/iwdg.c - + Src/iwdg.c->Inc/iwdg.h - - + + - + Src/main.c - -Src/main.c + +Src/main.c - + Src/main.c->App/app/app_main.h - - + + - + Src/main.c->App/task/adc_task.h - - + + - + Src/main.c->App/util/sys_clock.h - - + + - + Src/main.c->App/util/task_watchdog.h - - + + - + Src/main.c->Drivers/BSP/CH395F/ch395f.h - - + + - + Src/main.c->Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h - - + + - + Src/main.c->Drivers/BSP/NET/net_select.h - - + + - + Src/main.c->Drivers/BSP/NET/net_socket.h - - + + - + Src/main.c->Drivers/BSP/RS485/rs485.h - - + + - + Src/main.c->Drivers/BSP/SD2506/sd2506.h - - + + - + Src/main.c->Drivers/BSP/TPAFE5160/tpafe5160.h - - + + - + Src/main.c->Drivers/BSP/dbg_log.h - - + + - + Src/main.c->Inc/adc.h - - + + - + Src/main.c->Inc/dma.h - - + + - + Src/main.c->Inc/gpio.h - - + + - + Src/main.c->Inc/i2c.h - - + + - + Src/main.c->Inc/iwdg.h - - + + - + Src/main.c->Inc/main.h - - + + - + Src/main.c->Inc/spi.h - - + + - + Src/main.c->Inc/tim.h - - + + - + Src/main.c->Inc/usart.h - - + + - + Src/main.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + Src/main.c->外部/系统头文件 - - + + - + Src/spi.c - -Src/spi.c + +Src/spi.c - + Src/spi.c->Inc/spi.h - - + + - + Src/stm32f4xx_hal_msp.c - -Src/stm32f4xx_hal_msp.c + +Src/stm32f4xx_hal_msp.c - + Src/stm32f4xx_hal_msp.c->Inc/main.h - - + + - + Src/stm32f4xx_hal_timebase_tim.c - -Src/stm32f4xx_hal_timebase_tim.c + +Src/stm32f4xx_hal_timebase_tim.c - + Src/stm32f4xx_hal_timebase_tim.c->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h - - + + - + Src/stm32f4xx_hal_timebase_tim.c->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_tim.h - - + + - + Src/stm32f4xx_it.c - -Src/stm32f4xx_it.c + +Src/stm32f4xx_it.c - + Src/stm32f4xx_it.c->Inc/main.h - - + + - + Src/stm32f4xx_it.c->Inc/stm32f4xx_it.h - - + + - + Src/stm32f4xx_it.c->Inc/usart.h - - + + - + Src/system_stm32f4xx.c - -Src/system_stm32f4xx.c + +Src/system_stm32f4xx.c - + Src/system_stm32f4xx.c->Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h - - + + - + Src/tim.c - -Src/tim.c + +Src/tim.c - + Src/tim.c->Inc/tim.h - - + + - + Src/usart.c - -Src/usart.c + +Src/usart.c - + Src/usart.c->Inc/usart.h - - + + - + simulator/SDL2/SDL2-2.32.10/include/SDL.h - -simulator/SDL2/SDL2-2.32.10/include/SDL.h + +simulator/SDL2/SDL2-2.32.10/include/SDL.h - + simulator/dbg_log.h - -simulator/dbg_log.h + +simulator/dbg_log.h - + simulator/dbg_log.h->外部/系统头文件 - - + + - + simulator/lv_conf.h - -simulator/lv_conf.h + +simulator/lv_conf.h - + simulator/main.c - -simulator/main.c + +simulator/main.c - + simulator/main.c->App/cfg/cfg_file.h - - + + - + simulator/main.c->App/cfg/cfg_file_store.h - - + + - + simulator/main.c->App/log/sys_log.h - - + + - + simulator/main.c->Drivers/BSP/NETCFG/net_cfg.h - - + + - + simulator/main.c->Drivers/BSP/UI/ui_menu.h - - + + - + simulator/main.c->Drivers/BSP/UI/ui_net_sink.h - - + + - + simulator/main.c->Drivers/BSP/UI/ui_standby.h - - + + - + simulator/main.c->Lib/lvgl/lvgl.h - - + + - + simulator/main.c->simulator/SDL2/SDL2-2.32.10/include/SDL.h - - + + - + simulator/sim/sim_port.h - -simulator/sim/sim_port.h + +simulator/sim/sim_port.h - + simulator/main.c->simulator/sim/sim_port.h - - + + - + simulator/main.c->外部/系统头文件 - - + + - + simulator/sim/cfg_file_store_sim.c - -simulator/sim/cfg_file_store_sim.c + +simulator/sim/cfg_file_store_sim.c - + simulator/sim/cfg_file_store_sim.c->App/cfg/cfg_file_store.h - - + + - + simulator/sim/cfg_file_store_sim.c->外部/系统头文件 - - + + - + simulator/sim/net_socket_sim.c - -simulator/sim/net_socket_sim.c + +simulator/sim/net_socket_sim.c - + simulator/sim/net_socket_sim.c->Drivers/BSP/NET/net_socket.h - - + + - + simulator/sim/net_socket_sim.c->外部/系统头文件 - - + + - + simulator/sim/sim_latency_stub.c - -simulator/sim/sim_latency_stub.c + +simulator/sim/sim_latency_stub.c - + simulator/sim/sim_latency_stub.c->test/board/net_latency_test.h - - + + - + simulator/sim/sim_port.c - -simulator/sim/sim_port.c + +simulator/sim/sim_port.c - + simulator/sim/sim_port.c->Lib/lvgl/lvgl.h - - + + - + simulator/sim/sim_port.c->simulator/SDL2/SDL2-2.32.10/include/SDL.h - - + + - + simulator/sim/sim_port.c->simulator/sim/sim_port.h - - + + - + simulator/sim/sim_port.h->外部/系统头文件 - - + + - + simulator/sim/sim_syslog.c - -simulator/sim/sim_syslog.c + +simulator/sim/sim_syslog.c - + simulator/sim/sim_syslog.c->App/log/sys_log.h - - + + - + simulator/sim/sim_syslog.c->外部/系统头文件 - - + + - + simulator/sim/ui_net_sink_backend_sim.c - -simulator/sim/ui_net_sink_backend_sim.c + +simulator/sim/ui_net_sink_backend_sim.c - + simulator/sim/ui_net_sink_backend_sim.c->Drivers/BSP/UI/ui_net_sink_backend.h - - + + - + simulator/sim/ui_net_sink_backend_sim.c->Drivers/BSP/UI/ui_port.h - - + + - + simulator/sim/ui_net_sink_backend_sim.c->Lib/lvgl/lvgl.h - - + + - + simulator/sim/ui_net_sink_backend_sim.c->simulator/sim/sim_port.h - - + + - + test/board/ch395f_reuse_bench.c - -test/board/ch395f_reuse_bench.c + +test/board/ch395f_reuse_bench.c - + test/board/ch395f_reuse_bench.c->Drivers/BSP/CH395F/ch395f.h - - + + - + test/board/ch395f_reuse_bench.c->Drivers/BSP/dbg_log.h - - + + - + test/board/ch395f_reuse_bench.c->Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h - - + + - + test/board/ch395f_reuse_bench.c->Inc/main.h - - + + - + test/board/ch395f_reuse_bench.h - -test/board/ch395f_reuse_bench.h + +test/board/ch395f_reuse_bench.h - + test/board/ch395f_reuse_bench.c->test/board/ch395f_reuse_bench.h - - + + - + test/board/test_common.h - -test/board/test_common.h + +test/board/test_common.h - + test/board/ch395f_test.h->test/board/test_common.h - - + + - + test/board/ch395f_test.h->外部/系统头文件 - - + + - + test/board/ch395f_test_task.c - -test/board/ch395f_test_task.c + +test/board/ch395f_test_task.c - + test/board/ch395f_test_task.c->App/app/sys_events.h - - + + - + test/board/ch395f_test_task.c->App/task/net_task.h - - + + - + test/board/ch395f_test_task.c->Drivers/BSP/CH395F/ch395f.h - - + + - + test/board/ch395f_test_task.c->Drivers/BSP/NET/net_socket.h - - + + - + test/board/ch395f_test_task.c->Drivers/BSP/dbg_log.h - - + + - + test/board/ch395f_test_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + test/board/ch395f_test_task.c->test/board/ch395f_test.h - - + + - + test/board/ch395f_test_task.c->test/board/ch395f_test_task.h - - + + - + test/board/gd5f_test.h - -test/board/gd5f_test.h + +test/board/gd5f_test.h - + test/board/ch395f_test_task.c->test/board/gd5f_test.h - - + + - + test/board/ch395f_test_task.c->test/board/net_latency_test.h - - + + - + test/board/net_test_task.h - -test/board/net_test_task.h + +test/board/net_test_task.h - + test/board/ch395f_test_task.c->test/board/net_test_task.h - - + + - + test/board/sd2506_test.h - -test/board/sd2506_test.h + +test/board/sd2506_test.h - + test/board/ch395f_test_task.c->test/board/sd2506_test.h - - + + - + test/board/storage_test.h - -test/board/storage_test.h + +test/board/storage_test.h - + test/board/ch395f_test_task.c->test/board/storage_test.h - - + + - + test/board/ch395f_test_task.c->test/board/test_config.h - - + + - + test/board/ch395f_test_task.c->外部/系统头文件 - - + + - + test/board/gd5f_test.h->Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h - - + + - + test/board/gd5f_test.h->test/board/test_common.h - - + + - + test/board/gd5f_test.h->外部/系统头文件 - - + + - + test/board/gd5f_test_task.c - -test/board/gd5f_test_task.c + +test/board/gd5f_test_task.c - + test/board/gd5f_test_task.c->Drivers/BSP/GD5F2GQ5UE/nand_ftl.h - - + + - + test/board/gd5f_test_task.c->Drivers/BSP/dbg_log.h - - + + - + test/board/gd5f_test_task.c->Lib/FatFs/ff.h - - + + - + test/board/gd5f_test_task.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + - + test/board/gd5f_test_task.c->test/board/gd5f_test.h - - + + - + test/board/gd5f_test_task.c->test/board/test_config.h - - + + - + test/board/gd5f_test_task.c->外部/系统头文件 - - + + - + test/board/net_latency_test.c - -test/board/net_latency_test.c + +test/board/net_latency_test.c - + test/board/net_latency_test.c->Drivers/BSP/CH395F/ch395f.h - - + + - + test/board/net_latency_test.c->Drivers/BSP/NET/net_socket.h - - + + - + test/board/net_latency_test.c->Drivers/BSP/dbg_log.h - - + + - + test/board/net_latency_test.c->Inc/main.h - - + + - + test/board/net_latency_test.c->test/board/ch395f_test.h - - + + - + test/board/net_latency_test.c->test/board/net_latency_test.h - - + + - + test/board/net_latency_test.c->test/board/test_config.h - - + + - + test/board/net_latency_test.c->外部/系统头文件 - - + + - + test/board/net_latency_test.h->外部/系统头文件 - - + + - + test/board/net_test_task.c - -test/board/net_test_task.c + +test/board/net_test_task.c - + test/board/net_test_task.c->Drivers/BSP/NET/net_select.h - - + + - + test/board/net_test_task.c->Drivers/BSP/NET/net_socket.h - - + + - + test/board/net_test_task.c->Drivers/BSP/NET/net_types.h - - + + - + test/board/net_test_task.c->Drivers/BSP/dbg_log.h - - + + - + test/board/net_test_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + test/board/net_test_task.c->test/board/ch395f_test.h - - + + - + test/board/net_test_task.c->test/board/ch395f_test_task.h - - + + - + test/board/net_test_task.c->test/board/net_latency_test.h - - + + - + test/board/net_test_task.c->test/board/net_test_task.h - - + + - + test/board/net_test_task.c->外部/系统头文件 - - + + - + test/board/sd2506_test.h->test/board/test_common.h - - + + - + test/board/sd2506_test.h->外部/系统头文件 - - + + - + test/board/sd2506_test_task.c - -test/board/sd2506_test_task.c + +test/board/sd2506_test_task.c - + test/board/sd2506_test_task.c->Drivers/BSP/SD2506/sd2506.h - - + + - + test/board/sd2506_test_task.c->Drivers/BSP/dbg_log.h - - + + - + test/board/sd2506_test_task.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + test/board/sd2506_test_task.c->test/board/sd2506_test.h - - + + - + test/board/sd2506_test_task.c->test/board/test_config.h - - + + - + test/board/sd2506_test_task.c->外部/系统头文件 - - + + - + test/board/storage_test.h->test/board/test_common.h - - + + - + test/board/storage_test.h->外部/系统头文件 - - + + - + test/board/storage_test_task.c - -test/board/storage_test_task.c + +test/board/storage_test_task.c - + test/board/storage_test_task.c->Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h - - + + - + test/board/storage_test_task.c->Drivers/BSP/GD5F2GQ5UE/nand_ftl.h - - + + - + test/board/storage_test_task.c->Drivers/BSP/dbg_log.h - - + + - + test/board/storage_test_task.c->Inc/main.h - - + + - + test/board/storage_test_task.c->Lib/FatFs/diskio.h - - + + - + test/board/storage_test_task.c->Lib/FatFs/ff.h - - + + - + test/board/storage_test_task.c->test/board/storage_test.h - - + + - + test/board/storage_test_task.c->test/board/test_config.h - - + + - + test/board/storage_test_task.c->外部/系统头文件 - - + + - + test/board/test_common.h->外部/系统头文件 - - + + - + test/board/test_config.c - -test/board/test_config.c + +test/board/test_config.c - + test/board/test_config.c->Drivers/BSP/dbg_log.h - - + + - + test/board/test_config.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + test/board/test_config.c->test/board/ch395f_test_task.h - - + + - + test/board/test_config.c->test/board/gd5f_test.h - - + + - + test/board/test_config.c->test/board/sd2506_test.h - - + + - + test/board/test_config.c->test/board/storage_test.h - - + + - + test/board/test_config.c->test/board/test_config.h - - + + - + test/board/test_config.h->test/board/ch395f_test.h - - + + - + test/board/test_config.h->test/board/gd5f_test.h - - + + - + test/board/test_config.h->test/board/sd2506_test.h - - + + - + test/board/test_config.h->test/board/storage_test.h - - + + - + test/board/test_config.h->外部/系统头文件 - - + + - + test/host/adc_health/adc_health_test.c - -test/host/adc_health/adc_health_test.c + +test/host/adc_health/adc_health_test.c - + test/host/adc_health/adc_health_test.c->App/algo/adc_health.c - - + + - + test/host/adc_health/adc_health_test.c->外部/系统头文件 - - + + - + test/host/adc_input/adc_input_test.c - -test/host/adc_input/adc_input_test.c + +test/host/adc_input/adc_input_test.c - + test/host/adc_input/adc_input_test.c->App/algo/adc_input.c - - + + - + test/host/adc_input/adc_input_test.c->App/algo/adc_input.h - - + + - + test/host/adc_input/adc_input_test.c->Drivers/BSP/TPAFE5160/tpafe5160.h - - + + - + test/host/adc_input/adc_input_test.c->Inc/adc.h - - + + - + test/host/adc_input/adc_input_test.c->外部/系统头文件 - - + + - + test/host/adc_input/stub/adc.h - -test/host/adc_input/stub/adc.h + +test/host/adc_input/stub/adc.h - + test/host/adc_input/stub/adc.h->外部/系统头文件 - - + + - + test/host/adc_input/stub/tpafe5160.h - -test/host/adc_input/stub/tpafe5160.h + +test/host/adc_input/stub/tpafe5160.h - + test/host/adc_input/stub/tpafe5160.h->外部/系统头文件 - - + + - + test/host/cfg_file/cfg_file_test.c - -test/host/cfg_file/cfg_file_test.c + +test/host/cfg_file/cfg_file_test.c - + test/host/cfg_file/cfg_file_test.c->App/cfg/cfg_file.c - - + + - + test/host/cfg_file/cfg_file_test.c->App/cfg/cfg_file_store.h - - + + - + test/host/cfg_file/cfg_file_test.c->App/log/sys_log.h - - + + - + test/host/cfg_file/cfg_file_test.c->Drivers/BSP/dbg_log.h - - + + - + test/host/cfg_file/cfg_file_test.c->外部/系统头文件 - - + + - + test/host/cfg_file/stub/dbg_log.h - -test/host/cfg_file/stub/dbg_log.h + +test/host/cfg_file/stub/dbg_log.h - + test/host/cfg_file/stub/dbg_log.h->外部/系统头文件 - - + + - + test/host/freq/freq_test.c - -test/host/freq/freq_test.c + +test/host/freq/freq_test.c - + test/host/freq/freq_test.c->App/algo/freq.c - - + + - + test/host/freq/freq_test.c->App/algo/phasor.c - - + + - + test/host/freq/freq_test.c->App/algo/sample_ring.c - - + + - + test/host/freq/freq_test.c->外部/系统头文件 - - + + - + test/host/ftp_auth/ftp_auth_test.c - -test/host/ftp_auth/ftp_auth_test.c + +test/host/ftp_auth/ftp_auth_test.c - + test/host/ftp_auth/ftp_auth_test.c->App/util/sha256.c - - + + - + test/host/ftp_auth/ftp_auth_test.c->Drivers/BSP/NET/lftpd/lftpd_auth.c - - + + - + test/host/ftp_auth/ftp_auth_test.c->外部/系统头文件 - - + + - + test/host/iec104/iec104_test.c - -test/host/iec104/iec104_test.c + +test/host/iec104/iec104_test.c - + test/host/iec104/iec104_test.c->App/algo/freq.c - - + + - + test/host/iec104/iec104_test.c->App/algo/phasor.c - - + + - + test/host/iec104/iec104_test.c->App/algo/prot_elm.c - - + + - + test/host/iec104/iec104_test.c->App/algo/prot_set.c - - + + - + test/host/iec104/iec104_test.c->App/algo/sample_ring.c - - + + - + test/host/iec104/iec104_test.c->App/protocol/iec104/iec104_asdu.c - - + + - + test/host/iec104/iec104_test.c->App/protocol/iec104/iec104_link.c - - + + - + test/host/iec104/iec104_test.c->App/protocol/iec104/iec104_pts.c - - + + - + test/host/iec104/iec104_test.c->外部/系统头文件 - - + + - + test/host/phasor/phasor_test.c - -test/host/phasor/phasor_test.c + +test/host/phasor/phasor_test.c - + test/host/phasor/phasor_test.c->App/algo/phasor.c - - + + - + test/host/phasor/phasor_test.c->App/algo/sample_ring.c - - + + - + test/host/phasor/phasor_test.c->外部/系统头文件 - - + + - + test/host/prot_elm/prot_elm_test.c - -test/host/prot_elm/prot_elm_test.c + +test/host/prot_elm/prot_elm_test.c - + test/host/prot_elm/prot_elm_test.c->App/algo/freq.c - - + + - + test/host/prot_elm/prot_elm_test.c->App/algo/phasor.c - - + + - + test/host/prot_elm/prot_elm_test.c->App/algo/prot_elm.c - - + + - + test/host/prot_elm/prot_elm_test.c->App/algo/prot_set.c - - + + - + test/host/prot_elm/prot_elm_test.c->App/algo/sample_ring.c - - + + - + test/host/prot_elm/prot_elm_test.c->外部/系统头文件 - - + + - + test/host/prot_set/prot_set_test.c - -test/host/prot_set/prot_set_test.c + +test/host/prot_set/prot_set_test.c - + test/host/prot_set/prot_set_test.c->App/algo/prot_set.c - - + + - + test/host/prot_set/prot_set_test.c->外部/系统头文件 - - + + - + test/host/sha256/sha256_test.c - -test/host/sha256/sha256_test.c + +test/host/sha256/sha256_test.c - + test/host/sha256/sha256_test.c->App/util/sha256.c - - + + - + test/host/sha256/sha256_test.c->外部/系统头文件 - - + + - + test/host/soe/soe_test.c - -test/host/soe/soe_test.c + +test/host/soe/soe_test.c - + test/host/soe/soe_test.c->App/log/soe_rec.c - - + + - + test/host/soe/soe_test.c->App/protocol/iec104/iec104_asdu.c - - + + - + test/host/soe/soe_test.c->外部/系统头文件 - - + + - + test/host/sys_clock/stub/FreeRTOS.h - -test/host/sys_clock/stub/FreeRTOS.h + +test/host/sys_clock/stub/FreeRTOS.h - + test/host/sys_clock/stub/FreeRTOS.h->外部/系统头文件 - - + + - + test/host/sys_clock/stub/dbg_log.h - -test/host/sys_clock/stub/dbg_log.h + +test/host/sys_clock/stub/dbg_log.h - + test/host/sys_clock/stub/dbg_log.h->外部/系统头文件 - - + + - + test/host/sys_clock/stub/main.h - -test/host/sys_clock/stub/main.h + +test/host/sys_clock/stub/main.h - + test/host/sys_clock/stub/main.h->外部/系统头文件 - - + + - + test/host/sys_clock/stub/task.h - -test/host/sys_clock/stub/task.h + +test/host/sys_clock/stub/task.h - + test/host/sys_clock/stub/task.h->test/host/sys_clock/stub/FreeRTOS.h - - + + - + test/host/sys_clock/sys_clock_test.c - -test/host/sys_clock/sys_clock_test.c + +test/host/sys_clock/sys_clock_test.c - + test/host/sys_clock/sys_clock_test.c->App/util/sys_clock.c - - + + - + test/host/sys_clock/sys_clock_test.c->App/util/sys_clock.h - - + + - + test/host/sys_clock/sys_clock_test.c->Drivers/BSP/SD2506/sd2506.h - - + + - + test/host/sys_clock/sys_clock_test.c->Drivers/BSP/dbg_log.h - - + + - + test/host/sys_clock/sys_clock_test.c->Inc/main.h - - + + - + test/host/sys_clock/sys_clock_test.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + - + test/host/sys_clock/sys_clock_test.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - + + - + test/host/sys_clock/sys_clock_test.c->外部/系统头文件 - - + + - + test/host/time_sync/stub/FreeRTOS.h - -test/host/time_sync/stub/FreeRTOS.h + +test/host/time_sync/stub/FreeRTOS.h - + test/host/time_sync/stub/FreeRTOS.h->外部/系统头文件 - - + + - + test/host/time_sync/stub/cmsis_os2.h - -test/host/time_sync/stub/cmsis_os2.h + +test/host/time_sync/stub/cmsis_os2.h - + test/host/time_sync/stub/cmsis_os2.h->外部/系统头文件 - - + + - + test/host/time_sync/stub/dbg_log.h - -test/host/time_sync/stub/dbg_log.h + +test/host/time_sync/stub/dbg_log.h - + test/host/time_sync/stub/dbg_log.h->外部/系统头文件 - - + + - + test/host/time_sync/stub/net_socket.h - -test/host/time_sync/stub/net_socket.h + +test/host/time_sync/stub/net_socket.h - + test/host/time_sync/stub/net_socket.h->test/host/time_sync/stub/FreeRTOS.h - - + + - + test/host/time_sync/stub/task.h - -test/host/time_sync/stub/task.h + +test/host/time_sync/stub/task.h - + test/host/time_sync/stub/net_socket.h->test/host/time_sync/stub/task.h - - + + - + test/host/time_sync/stub/net_socket.h->外部/系统头文件 - - + + - + test/host/time_sync/stub/sys_clock.h - -test/host/time_sync/stub/sys_clock.h + +test/host/time_sync/stub/sys_clock.h - + test/host/time_sync/stub/sys_clock.h->外部/系统头文件 - - + + - + test/host/time_sync/stub/sys_events.h - -test/host/time_sync/stub/sys_events.h + +test/host/time_sync/stub/sys_events.h - + test/host/time_sync/stub/sys_events.h->test/host/time_sync/stub/cmsis_os2.h - - + + - + test/host/time_sync/stub/task.h->test/host/time_sync/stub/FreeRTOS.h - - + + - + test/host/time_sync/time_sync_test.c - -test/host/time_sync/time_sync_test.c + +test/host/time_sync/time_sync_test.c - + test/host/time_sync/time_sync_test.c->App/app/sys_events.h - - + + - + test/host/time_sync/time_sync_test.c->App/sync/time_sync.c - - + + - + test/host/time_sync/time_sync_test.c->App/util/sys_clock.h - - + + - + test/host/time_sync/time_sync_test.c->App/util/task_watchdog.h - - + + - + test/host/time_sync/time_sync_test.c->Drivers/BSP/NET/net_socket.h - - + + - + test/host/time_sync/time_sync_test.c->Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h - - + + - + test/host/time_sync/time_sync_test.c->Middlewares/Third_Party/FreeRTOS/Source/include/task.h - - + + - + test/host/time_sync/time_sync_test.c->外部/系统头文件 - - + + - + test/host/vol_lock/stub/cmsis_os.h - -test/host/vol_lock/stub/cmsis_os.h + +test/host/vol_lock/stub/cmsis_os.h - + test/host/vol_lock/stub/cmsis_os.h->外部/系统头文件 - - + + - + test/host/vol_lock/vol_lock_test.c - -test/host/vol_lock/vol_lock_test.c + +test/host/vol_lock/vol_lock_test.c - + test/host/vol_lock/vol_lock_test.c->App/fs/vol_lock.c - - + + - + test/host/vol_lock/vol_lock_test.c->Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os.h - - + + - + test/host/vol_lock/vol_lock_test.c->外部/系统头文件 - - + + - + test/host/watchdog/stub/dbg_log.h - -test/host/watchdog/stub/dbg_log.h + +test/host/watchdog/stub/dbg_log.h - + test/host/watchdog/stub/dbg_log.h->外部/系统头文件 - - + + - + test/host/watchdog/stub/iwdg.h - -test/host/watchdog/stub/iwdg.h + +test/host/watchdog/stub/iwdg.h - + test/host/watchdog/stub/iwdg.h->外部/系统头文件 - - + + - + test/host/watchdog/stub/main.h - -test/host/watchdog/stub/main.h + +test/host/watchdog/stub/main.h - + test/host/watchdog/stub/main.h->外部/系统头文件 - - + + - + test/host/watchdog/watchdog_test.c - -test/host/watchdog/watchdog_test.c + +test/host/watchdog/watchdog_test.c - + test/host/watchdog/watchdog_test.c->App/util/task_watchdog.c - - + + - + test/host/watchdog/watchdog_test.c->Drivers/BSP/dbg_log.h - - + + - + test/host/watchdog/watchdog_test.c->Inc/iwdg.h - - + + - + test/host/watchdog/watchdog_test.c->Inc/main.h - - + + - + test/host/watchdog/watchdog_test.c->外部/系统头文件 - - + + diff --git a/docs/images/引用关系图_模块.dot b/docs/images/引用关系图_模块.dot index b11b4a95..09f776ab 100644 --- a/docs/images/引用关系图_模块.dot +++ b/docs/images/引用关系图_模块.dot @@ -82,12 +82,12 @@ digraph refgraph_module { "BSP/GD5F2GQ5UE" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×1"]; "BSP/GD5F2GQ5UE" -> "dhara" [color="#2563eb", penwidth=1.2, label="×2"]; "BSP/GD5F2GQ5UE" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×4"]; - "BSP/NET" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×2"]; - "BSP/NET" -> "BSP/CH395F" [color="#2563eb", penwidth=1.2, label="×3"]; - "BSP/NET" -> "FreeRTOS" [color="#2563eb", penwidth=1.2, label="×11"]; - "BSP/NET" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×3"]; + "BSP/NET" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×3"]; + "BSP/NET" -> "BSP/CH395F" [color="#2563eb", penwidth=1.2, label="×4"]; + "BSP/NET" -> "FreeRTOS" [color="#2563eb", penwidth=1.2, label="×15"]; + "BSP/NET" -> "Src/Inc (CubeMX)" [color="#2563eb", penwidth=1.2, label="×4"]; "BSP/NET" -> "test" [color="#2563eb", penwidth=1.2, label="×4"]; - "BSP/NET" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×4"]; + "BSP/NET" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×6"]; "BSP/NETCFG" -> "App" [color="#2563eb", penwidth=1.2, label="×2"]; "BSP/NETCFG" -> "BSP(公共)" [color="#2563eb", penwidth=1.2, label="×1"]; "BSP/NETCFG" -> "外部/系统头文件" [color="#94a3b8", penwidth=0.7, label="×4"]; diff --git a/docs/images/引用关系图_模块.svg b/docs/images/引用关系图_模块.svg index fb4dc9bb..a8fce85b 100644 --- a/docs/images/引用关系图_模块.svg +++ b/docs/images/引用关系图_模块.svg @@ -513,28 +513,28 @@ BSP/NET->BSP(公共) -×2 +×3 BSP/NET->BSP/CH395F -×3 +×4 BSP/NET->FreeRTOS -×11 +×15 BSP/NET->Src/Inc (CubeMX) -×3 +×4 @@ -548,7 +548,7 @@ BSP/NET->外部/系统头文件 -×4 +×6 diff --git a/docs/任务规划/基线与待确认.md b/docs/任务规划/基线与待确认.md index e92eca5a..19387487 100644 --- a/docs/任务规划/基线与待确认.md +++ b/docs/任务规划/基线与待确认.md @@ -17,7 +17,7 @@ > 本节仅保留**二期仍要用的设计基线**。 **一期已验证的机制骨架**(二期沿用,勿重新发明):独立静态 pending 表 + `net_pending_tick` -主循环节拍了结(五路:数据/到点/断连/同 fd 串行/重建取消必通知)+ 登记守卫(每 fd 至多一个、 +主循环按节拍结束挂起(五路:数据/到点/断连/同 fd 串行/重建取消必通知)+ 登记守卫(每 fd 至多一个、 不覆盖、拒绝 netTask 自等待)+ 1s 看门狗强结算。 **二期扩展点**: diff --git a/docs/内存管理/RAM使用分析与优化方案.md b/docs/内存管理/RAM使用分析与优化方案.md index 7e27a4fa..5da3b59c 100644 --- a/docs/内存管理/RAM使用分析与优化方案.md +++ b/docs/内存管理/RAM使用分析与优化方案.md @@ -36,10 +36,10 @@ | 区域 | 用量 | 容量 | 占比 | |---|---|---|---| -| ER_IROM1 | 230,208 B (224.81 KB) | 1,048,576 B (1024 KB) | 22.0% | +| ER_IROM1 | 230,048 B (224.66 KB) | 1,048,576 B (1024 KB) | 21.9% | | RW_IRAM1 | 97,912 B (95.62 KB) | 131,072 B (128 KB) | 74.7% | | RW_CCM | 57,376 B (56.03 KB) | 65,280 B (64 KB) | 87.9% | -| **Flash (ROM 合计)** | **231,312 B (225.9 KB)** | 1,048,576 B (1024 KB) | **22.1%** | +| **Flash (ROM 合计)** | **231,152 B (225.7 KB)** | 1,048,576 B (1024 KB) | **22.0%** | 各区的容量与常量来源: diff --git a/docs/内存管理/RAM预算台账.md b/docs/内存管理/RAM预算台账.md index 234c1196..baf1ca5a 100644 --- a/docs/内存管理/RAM预算台账.md +++ b/docs/内存管理/RAM预算台账.md @@ -15,7 +15,7 @@ | 区域 | 用量 | 容量 | 占比 | 门禁(≤92%) | |---|---|---|---|---| -| ER_IROM1 (Flash) | 230,208 B | 1,048,576 B | 22.0% | 参考 | +| ER_IROM1 (Flash) | 230,048 B | 1,048,576 B | 21.9% | 参考 | | RW_CCM | 57,376 B | 65,280 B | 87.9% | PASS | | UNINIT_CCM | 48 B | 256 B | 18.8% | 参考 | | RW_IRAM1 | 97,912 B | 131,072 B | 74.7% | PASS | diff --git a/docs/子系统设计/网络Socket监听生命周期设计说明.md b/docs/子系统设计/网络Socket监听生命周期设计说明.md index f4c7b3b7..d4c6f015 100644 --- a/docs/子系统设计/网络Socket监听生命周期设计说明.md +++ b/docs/子系统设计/网络Socket监听生命周期设计说明.md @@ -241,7 +241,7 @@ P2 之后,对账④保留但只作事件面未收到的补漏(TRAP-NET-17 | 服务 | 认为的连接结束信号 | net 层实际给什么 | 监听重建者 | 是否留无人重建组合 | |---|---|---|---|---| -| `lftpd` 控制 :21 | `read_line!=0`(EOF→-1,`lftpd_inet.c:154-156`) | 阻塞 pending 保证 CLOSED 必了结(FIN→0 / 异常→CONNRESET,`net_socket.c:2457-2462`) | net 层(`:2449-2451`),应用**永不** close 控制 fd(`lftpd.c:746-750`) | 无(契约一致,是正面样板) | +| `lftpd` 控制 :21 | `read_line!=0`(EOF→-1,`lftpd_inet.c:154-156`) | 阻塞 pending 保证 CLOSED 时挂起 recv 必被结束(FIN→0 / 异常→CONNRESET,`net_socket.c:2457-2462`) | net 层(`:2449-2451`),应用**永不** close 控制 fd(`lftpd.c:746-750`) | 无(契约一致,是正面样板) | | `time_sync` :8888 | EOF/30 s 预算/错误,随后**无条件** `net_close(conn==ls)`(`time_sync.c:182`) | 同上 | 应用自己每会话全量重建(`:224`) | 不留孤儿,但违反「EOF 不得 close 监听 fd」→ close→重建沉降窗(TRAP-NET-09)+ 最坏 ~10 s 端口下线 | | `ui_net_sink` :7003 | `net_recv` 返 0 或真错误;重建条件 `net_get_sock(g_listen)==NULL`(`:557`/`:566`) | 该 0 只在 recv 时刻 `state==CLOSED` 才给 | 名义 net 层,实际自身条件在 MCU **恒假**(fd 不释放) | **有**(B10 与"消费者卡死"都出自这里) | | 模拟器后端 | `recv` 0 恒可得、fd 分离(`net_socket_sim.c:293-336`) | Winsock 原生 | 无需 | 无——且对上述全部失效模式**零覆盖** | diff --git a/docs/网络/BSD_Socket_API_使用指南.md b/docs/网络/BSD_Socket_API_使用指南.md index 88e5b147..4ce888a1 100644 --- a/docs/网络/BSD_Socket_API_使用指南.md +++ b/docs/网络/BSD_Socket_API_使用指南.md @@ -1012,7 +1012,7 @@ int net_drop_conn(int sockfd); 应用**放弃会话**(对时 30s 预算耗尽、协议超时)时主动拆掉当前 TCP 会话并**保留监听**——单连接模型下挂起但 TCP 仍活的客户端会永久占住监听(PC 内核自动 ACK keepalive,芯片僵尸判不死,定案见 `docs/网络/网络自愈架构设计.md` §5.2 E13),而应用又不得 `net_close` 监听 fd(毁监听);本 API 补上"拆连接不拆监听"的应用侧形态。 -- **netTask 侧**:先了结本 fd 挂起 recv(排空/取消 + 必通知),再 `sock_reset` QUARANTINE(FIN + 排渣 + 排空事件 + 等 byte0=00H,TRAP-NET-18 异常释放语义,400ms 底);本层收口 CLOSED;`auto_relisten` fd 随即 `net_listener_try` 即时重监听(失败交 D10 重试 + reconciler 形态④) +- **netTask 侧**:先结束本 fd 挂起 recv(排空/取消 + 必通知),再 `sock_reset` QUARANTINE(FIN + 排渣 + 排空事件 + 等 byte0=00H,TRAP-NET-18 异常释放语义,400ms 底);本层收口 CLOSED;`auto_relisten` fd 随即 `net_listener_try` 即时重监听(失败交 D10 重试 + reconciler 形态④) - **幂等**:无活动会话(非 ESTABLISHED/CONNECTING)直接返 0,不动监听 - **EOF 路径不要调**:EOF 时 net 层 `auto_relisten` 已接管(§12.4),无需也不应再拆 - 经消息队列委托 netTask(同其它 `net_*` API,非 netTask 上下文调用);等待期 netTask 有界占用 ~400-600ms @@ -1057,7 +1057,7 @@ void net_process_messages(void); 处理其他任务投递的请求(send/recv/connect/accept/close/drop_conn)。每次调用先跑 3 个**非阻塞** tick,再取队列消息(0 超时出队): 1. **D10 重监听重试**(`net_listener_retry_tick`):断连后监听器恢复的到点重试(30ms 间隔 / 2s 时限,§3.6) -2. **L3 挂起 recv 完成检查**(`net_pending_tick`):按 ①数据 ②到点(仅显式预算) ③断连 检查每个挂起请求并通知调用方;④ tripwire:挂起超 60s 只 `[ERR]` 留痕一次,不强制了结(自愈收敛阶段 1.5) +2. **L3 挂起 recv 完成检查**(`net_pending_tick`):按 ①数据 ②到点(仅显式预算) ③断连 检查每个挂起请求并通知调用方;④ 挂起超时留痕探针(编译期选项,默认关):挂起超阈值只 `[ERR]` 留痕一次,不强制结束 3. **TRAP-NET-17 芯片/本层对账 + 监听重建(合一 `net_reconcile_tick`)**:100ms 周期,判据读驱动状态缓存(`ch395f_sock_state_cached`),修正**五类**失同步(①②③④⑤)+ U11 被动重同步——原 200ms 对账与 100ms 监听器 pump 已合并为单一 tick,**唯一重建入口**=形态③④(§3.6) > `net_msg_t.timeout_ms`:L3 显式预算(`net_recv_to()`),0=**无限等待**(自愈收敛阶段 1.5 删除 `NET_RECV_TIMEOUT_MS` 30s 默认预算——超时归调用方)。消息类型 7 种(send/recv/close/connect/listen/accept/drop_conn)——自愈类消息 `NET_MSG_RESYNC_LISTEN` / `NET_MSG_RELISTEN` 已随 API 退役删除(自愈收敛阶段1)。 diff --git a/docs/网络/BSD_Socket_API_函数调用关系.md b/docs/网络/BSD_Socket_API_函数调用关系.md index 9521adf6..1bf673df 100644 --- a/docs/网络/BSD_Socket_API_函数调用关系.md +++ b/docs/网络/BSD_Socket_API_函数调用关系.md @@ -3,10 +3,13 @@ > **定位**:本文档是 `docs/网络/BSD_Socket_API_使用指南.md`(下称"使用指南")的**内部视图**伴读文档。 > 使用指南回答"**上层该怎么调**"(公开语义 / 示例 / 常见问题);本文回答"**内部函数各自做什么、互相怎么调用、为什么这么设计**"(调用关系 / 设计意图 / 踩坑)。 > -> **范围**:MCU 端 `Drivers/BSP/NET/net_socket.c`(约 3670 行)+ 其拆出的 -> `Drivers/BSP/NET/net_listener.c`(约 550 行,**监听生命周期**,N-32 §10 模块化)。 +> **范围**:MCU 端 `Drivers/BSP/NET/net_socket.c`(约 3660 行)+ 其拆出的 +> `Drivers/BSP/NET/net_listener.c`(约 550 行,**监听生命周期**,N-32 §10 模块化)+ +> `Drivers/BSP/NET/net_pending.c`(约 390 行,**挂起 recv 请求表**,2026-10-14 拆出)。 > 模拟器端后端 `simulator/sim/net_socket_sim.c`(Winsock)是另一套实现,见 `docs/网络/BSD_Socket_API_使用指南.md` §2.3;`net_select.c` 不在此展开,见 `docs/网络/BSD_Socket_API_使用指南.md` §7 / §10.5。 -> `net_listener.c` **只被 `net_socket.c` include**(内部头,不进公开 `net_socket.h`),模拟器零依赖、不编译;其设计依据见 `docs/子系统设计/网络Socket监听生命周期设计说明.md` §10。 +> `net_listener.c` / `net_pending.c` 真机专属(模拟器不编译);设计依据分别见 +> `docs/子系统设计/网络Socket监听生命周期设计说明.md` §10 与 +> `docs/网络/Net层阻塞模型架构设计.md`。 > > **交叉引用约定**:机制标 Trap 号 → `docs/问题记录/CH395F_Trap_Records.md`;用法语义引用使用指南 §;关键参数值与 `net_config.h` / `net_socket.c` 内宏一致。 @@ -57,7 +60,7 @@ flowchart TB LS["netSendLocked
分块 ≤1KB + sendReady 门控"] LR["netRecvLocked
快路径 / DONTWAIT / 登记挂起"] LA["netAcceptLocked
先 netPoll + 状态判定"] - LC["netCloseLocked
了结挂起 + cmd_done 快路径 / sock_reset(GRACEFUL)"] + LC["netCloseLocked
结束挂起 + cmd_done 快路径 / sock_reset(GRACEFUL)"] DC["netDropConnLocked
拆会话保监听:sock_reset(QUARANTINE) + 即时重监听"] RLS["netListenerTry → netRelistenLocked
单次尝试 + TRAP-NET-18 排渣隔离"] end @@ -99,7 +102,7 @@ flowchart TB 2. `net_process_messages()` 开头的 **3 个 tick 是网络层自愈主干**:没有任何应用消息时,重试 / 挂起完成 / 状态对账 + 监听重建照常运转——"断连后即使没人发消息,监听器也能自己活过来"靠的就是它们。 3. 事件处理器**只由 `net_poll` 驱动**,例外是 `net_reconcile_tick`(分级去抖 + 1s 冷却)可再入 `handle_disconnect_event` / `handle_connect_event`——对账是事件未收到的自愈通道(TRAP-NET-17)。**注意职责边界(N-32 P2,自愈收敛阶段 3 合并后)**:对账与事件处理器**只置事实**(置 CLOSED / 登记沉降),**重建监听的动作统一由 `net_reconcile_tick` 形态③④ 做**(本层唯一重建入口)——"谁先看到 DISCONNECT 就谁重建"的竞争在结构上消失。 4. 回调 `event_cb` 在 **netTask 上下文**执行:回调内不得阻塞、不得发网络操作。 -5. **模块归属**:`T1`(D10 重试)/ `RLS` 的 `net_listener_try` / `ST`(settle)在 `net_listener.c`(真机专属、模拟器不编译);其余 tick(含合并后的 `T3` reconciler)与 `_locked` 在 `net_socket.c`。 +5. **模块归属**:`T1`(D10 重试)/ `RLS` 的 `net_listener_try` / `ST`(settle)在 `net_listener.c`(真机专属、模拟器不编译);挂起 recv 完成检查(`net_pending_tick`)与挂起表在 `net_pending.c`(真机专属);其余 tick(含合并后的 `T3` reconciler)与 `_locked` 在 `net_socket.c`。 --- @@ -133,7 +136,7 @@ flowchart TB | `net_recv` | `NET_MSG_RECV`(timeout=0→**无限等待**,自愈收敛阶段 1.5 删 30s 默认) | `net_recv_locked` | `net_poll` + `get_recv_len` / `read_recv_buf` | >0 / 0(EOF) / -1(errno = WOULDBLOCK / CONNRESET;阻塞形态无 TIMEDOUT 一档) | 快路径:数据已在 → 立即读出返回(允许部分读);无数据 + 阻塞(`blocking` 属性=1 且未 DONTWAIT)→ **登记挂起后立即返回**(L3,netTask 零占用),唤醒源=数据/EOF/close/网络重建;DONTWAIT / `blocking=0` + CLOSED/session_dead → EOF + 触发重监听;⚠ IWDG 受监控任务禁用无限形态(`net_socket.h` 文档契约) | | `net_recv_nb` | `NET_MSG_RECV`(flags=DONTWAIT) | `net_recv_locked` | 同上 | >0 / 0 / -1(WOULDBLOCK 等) | 原 `NET_MSG_DONTWAIT` 路径转正的具名入口(自愈收敛阶段 1.5);不改变 `blocking` 属性;受 IWDG 监控 / 有周期职责任务的推荐默认(ui_net_sink / iec104_serv 已迁) | | `net_recv_to` | `NET_MSG_RECV`(timeout>0) | `net_recv_locked` | 同上 | >0 / 0 / -1 / **-2(本片超时无数据)** | E-02 头阻塞修复配套 + **显式预算**入口(自愈收敛阶段 1.5,等价 Python settimeout,无隐藏默认值):调用方把长等待切成有界片(如剩余预算),**总超时语义不变、单次占用有界**;`timeout_ms=0` 直接拒(0 = 无限等待,与本接口"有界"存在理由相反);超时**只凭 -2 判定、不得依赖 errno**(`s_net_errno` 是跨任务共享全局量,随时被别的任务覆盖) | -| `net_close` | `NET_MSG_CLOSE` | `net_close_locked` | `ch395f_cmd_done(CLOSE)` 快路径(芯片已 CLOSED → 只清本 Socket 残留事件)/ `net_sock_reset_sync(GRACEFUL)` 确定性排渣(自愈收敛阶段 3) | 0 / -1 | **先**了结本 fd 挂起 recv(排空/取消 + 必通知,关不得让等待者悬挂);排空只碰本 Socket SINT,**不再读清全局中断寄存器**(F-NET-7:全局唯一读者 = `net_poll`);原"close + 500ms 盲等排空循环"已换 sock_reset(内置 LISTEN 态二段 CLOSE 补发,E2 补充发现);控制块整体清零(`last_peer_port` 幽灵基准跨 fd 保留,N-30) | +| `net_close` | `NET_MSG_CLOSE` | `net_close_locked` | `ch395f_cmd_done(CLOSE)` 快路径(芯片已 CLOSED → 只清本 Socket 残留事件)/ `net_sock_reset_sync(GRACEFUL)` 确定性排渣(自愈收敛阶段 3) | 0 / -1 | **先**结束本 fd 挂起 recv(排空/取消 + 必通知,关不得让等待者悬挂);排空只碰本 Socket SINT,**不再读清全局中断寄存器**(F-NET-7:全局唯一读者 = `net_poll`);原"close + 500ms 盲等排空循环"已换 sock_reset(内置 LISTEN 态二段 CLOSE 补发,E2 补充发现);控制块整体清零(`last_peer_port` 幽灵基准跨 fd 保留,N-30) | | `net_drop_conn` | `NET_MSG_DROP_CONN`(自愈收敛阶段 3 新增) | `net_drop_conn_locked` | `net_pending_settle_close` + `net_sock_reset_sync(QUARANTINE)` +(auto_relisten)`net_listener_try` | 0(含幂等)/ -1 | **拆会话保监听**(E-02 收口):应用放弃会话(对时 30s 预算耗尽 / 协议超时)而单连接监听被挂起对端永久占住时的应用侧出口;EOF 路径**不得**调(`auto_relisten` 已接管);非 ESTABLISHED/CONNECTING 直接返 0 不动监听;本层收口 CLOSED 不清 fd(保留 local_port/auto_relisten),监听型 fd 即时重监听、失败交 D10 + reconciler 形态④ | | ~~`net_relisten`~~ | ~~`NET_MSG_RELISTEN`~~ | **自愈收敛阶段1 已删除**(消息类型同删) | — | — | 原"无条件芯片侧重建"与 pump/D10 完全重叠,且对健康监听器是 footgun(open→USE→close 自毁 ~1s);生产零调用。历史实现见 `net_socket.c` git 历史 | | ~~`net_resync_listen`~~ | ~~`NET_MSG_RESYNC_LISTEN`~~ | **自愈收敛阶段1 已删除**(语义并入对账⑤) | — | — | D14 静默回收(芯片自行回监听、不发 DISCONNECT)现由 `net_reconcile_tick` 判据⑤自动认领:本层 ESTABLISHED 且芯片 0x05/0x01 → 只修本层(state→LISTENING + 转登 `last_peer_port` + 清 `lost_conn_seen` + 取消挂起 recv),**不发芯片命令**(纪律原样保留,run8 实证 170s 拒绝);去抖/冷却沿用对账框架 | @@ -161,9 +164,9 @@ flowchart TB | 函数 | 设计作用 | 主要调用 | 意图 / 注意 | |---|---|---|---| | `net_pending_register` | 登记挂起(`net_recv_locked` 的"无数据 + 阻塞"路径) | 写 `s_net_pending[fd]` | 每 fd 至多一个:**覆盖会丢失前调用方通知 = 永久挂死**;执行任务自身(netTask)发起的等待直接拒绝(自等自通知 = 死锁,netTask 内须用 DONTWAIT) | -| `net_pending_tick` | 完成检查(`net_process_messages` 每轮调用,非阻塞) | ① `get_recv_len` + `read_recv_buf` ② 到点(仅显式预算) ③ `get_recv_len` 排空 + `net_listener_try` ④ `net_pending_complete` | 按 **①数据 ②到点(仅 `net_recv_to` 显式预算;无限登记无 deadline)③断连** 顺序检查(逐项对齐旧自旋语义);CONNECTING/LISTENING 等状态**保持等待**(CONNECT→ESTABLISHED 是合法迁移,不做状态推断取消,防误杀正在建链的等待);**tripwire**(自愈收敛阶段 1.5,原看门狗降级):挂起超 60s = 完成逻辑缺位 → 只 `[ERR]` 留痕一次,**绝不强制了结、绝不伪造 TIMEDOUT**——③ 与显式 cancel 是无限 recv 的全部唤醒责任方 | +| `net_pending_tick` | 完成检查(`net_process_messages` 每轮调用,非阻塞) | ① `get_recv_len` + `read_recv_buf` ② 到点(仅显式预算) ③ `get_recv_len` 排空 + `net_listener_try` ④ `net_pending_complete` | 按 **①数据 ②到点(仅 `net_recv_to` 显式预算;无限登记无 deadline)③断连** 顺序检查(逐项对齐旧自旋语义);CONNECTING/LISTENING 等状态**保持等待**(CONNECT→ESTABLISHED 是合法迁移,不做状态推断取消,防误杀正在建链的等待);**挂起超时留痕探针**(编译期选项 `NET_PENDING_TRIPWIRE`,默认关):挂起超阈值 = 完成逻辑缺位 → 只 `[ERR]` 留痕一次,**绝不强制结束、绝不伪造 TIMEDOUT**——③ 与显式 cancel 是无限 recv 的全部唤醒责任方 | | `net_pending_complete` | 所有完成/取消路径的公共出口 | `xTaskNotify(caller, result)` + 清 active | 通知值 = 结果原值(>0 字节 / 0 EOF / 负错误码,与消息分派同一回传通道);失败结果同步 `s_net_errno`(netTask 上下文一致性);无在位挂起时静默返回(防重复通知) | -| `net_pending_settle_close` | close 前**了结**本 fd 挂起 | `get_recv_len` + `read_recv_buf` + `net_pending_complete` | 关闭不得丢已到达数据(芯片缓冲 close 前可读):有数据 → 按字节数通知;无数据 → 取消(CONNRESET);先于 `ch395f_close_socket` 执行 | +| `net_pending_settle_close` | close 前**结束**本 fd 挂起 | `get_recv_len` + `read_recv_buf` + `net_pending_complete` | 关闭不得丢已到达数据(芯片缓冲 close 前可读):有数据 → 按字节数通知;无数据 → 取消(CONNRESET);先于 `ch395f_close_socket` 执行 | | `net_pending_cancel` / `cancel_all` | 显式取消(**必通知**) | `net_pending_complete` | 取消路径:陈旧 resync(单 fd)/ 网络重建(全部,`net_init` 开头,早于控制块清零)——"取消不通知 = 调用方永久挂死" | | `net_pending_clear` | 清除**不通知** | 清 `active` | 仅用于"新 fd 不得继承"(`net_socket`)与 close 后幂等清理(`net_close_locked`)——这两处前驱通知已由 settle 路径发出 | @@ -374,7 +377,7 @@ sequenceDiagram | 5 | **基于状态读的重建动作必须去抖 + 冷却**:分级门槛 ②=1 轮 / ③④⑤=2 轮 / ①=4 轮(100ms/轮)+ 冷却 1s | 2026-09-23:无去抖 → 监听反复重建直至 `relisten give up`,三服务口全死 | | 6 | **异常释放(TIMEOUT)后复监听前必须隔离**:排空 RX 残渣 + 等 CLOSED/TCP_CLOSED;隔离上限 < 重试放弃时限 | TRAP-NET-18:~2KB 残渣被下条连接当自己的数据 → 首笔上传截断 2048B 并误报 226 成功;上限=2s 时隔离耗尽重试预算 → 监听被弃 | | 7 | **RECV 电平触发中断每轮只处理一批** | TRAP-NET-08:连续循环 → 主循环饿死 | -| 8 | **close 前先了结挂起 recv + 排空残留 DISCONNECT** | TRAP-NET-12:锁存的陈旧 DISCONNECT 秒断下一连接 | +| 8 | **close 前先结束挂起 recv + 排空残留 DISCONNECT** | TRAP-NET-12:锁存的陈旧 DISCONNECT 秒断下一连接 | | 9 | **两段式等待防丢失通知**:零等待拾取 + 阻塞;清除掩码全 1;以 pdTRUE 判定 | run3~11:丢失通知 → 挂死 / 结果错位;0 结果误判"无通知" → 永久挂死 | | 10 | **网络重建先取消并通知全部挂起,再复位芯片** | 取消不通知 = 调用方永久挂死 | | 11 | **监听重建只有一个所有者**(`net_reconcile_tick` 形态③④,自愈收敛阶段 3 合并后;原 `net_listener_pump` 已删);其它位置**只置事实**(置 CLOSED / 登记沉降),不做重建动作 | N-32 P2 / B10:多所有者导致"谁先看到 DISCONNECT 就谁重建"的竞争与重建风暴 | diff --git a/docs/网络/Net层阻塞模型架构设计.md b/docs/网络/Net层阻塞模型架构设计.md index bf1dd0ac..77510422 100644 --- a/docs/网络/Net层阻塞模型架构设计.md +++ b/docs/网络/Net层阻塞模型架构设计.md @@ -1,6 +1,6 @@ # Net 层阻塞模型架构设计 -> **模块名称**:Net 层(`net_socket.c` / netTask)阻塞等待模型 +> **模块名称**:Net 层挂起 recv 模型(`net_pending.c` / netTask 主循环节拍) > **文档定位**:**现状架构设计说明**——描述本层**当前如何组织等待与完成**、为什么这样设计、 > 边界条件与已验证的性能特征。**不是历史记录**:历史演进、门禁实测记录与修订日志 > 一律不保留在文档内(需要时查 git 历史)。 @@ -44,8 +44,8 @@ netTask 是**全部 socket 操作的唯一执行者**——CH395F 的 SPI 总线 | 区域 | 内容 | |---|---| | **左栏 · 调用方任务** | `net_recv` → 判"数据已在?" → **是**走快速路径;**否**(`timeout > 0`)登记 pending 后在自己上下文睡任务通知 | -| **中栏 · netTask 主循环** | ~1ms 节拍:`net_poll`(刷新 readable + 全量刷新驱动状态缓存)→ 3 个非阻塞 tick(`net_listener_retry_tick` D10 → `net_pending_tick` 了结挂起 → `net_reconcile_tick` TRAP-NET-17 对账 + 监听重建唯一入口)→ 排空消息队列 | -| **下带 · 五路判定** | 每轮对每个挂起 fd 按序判定:数据到达 / 到点(仅显式预算)/ EOF / 同 fd 后续操作 / 网络重建;tripwire 60s 只留痕 | +| **中栏 · netTask 主循环** | ~1ms 节拍:`net_poll`(刷新 readable + 全量刷新驱动状态缓存)→ 3 个非阻塞 tick(`net_listener_retry_tick` D10 → `net_pending_tick` 结束挂起 → `net_reconcile_tick` TRAP-NET-17 对账 + 监听重建唯一入口)→ 排空消息队列 | +| **下带 · 五路判定** | 每轮对每个挂起 fd 按序判定:数据到达 / 到点(仅显式预算)/ EOF / 同 fd 后续操作 / 网络重建;挂起超时留痕探针(编译期选项,默认关,见 §9)只留痕 | | **回环** | 判定完成经 `xTaskNotify` 唤醒调用方(结果 = 字节数 / 负错误码) | **关键性质**: @@ -70,7 +70,7 @@ netTask 是**全部 socket 操作的唯一执行者**——CH395F 的 SPI 总线 | 项 | 设计 | |---|---| | 存储 | **独立静态数组** `s_net_pending[NET_MAX_SOCKETS]`(不置于 `net_sock_t` 内) | -| 字段 | `active` / `infinite` / `tripwire_logged` / `buf` / `len` / `deadline` / `registered` / `caller`(`infinite`:0 预算 = 无限等待;`tripwire_logged`:tripwire 只留痕一次) | +| 字段 | `active` / `infinite` / `buf` / `len` / `deadline` / `registered` / `caller`(`infinite`:0 预算 = 无限等待;留痕开启时另有 `tripwire_logged`:保证只留痕一次) | | 容量 | 每 fd **至多一个**挂起请求 | | 占用 | ≈24B/fd × 8 fd = **192B**(+4B 任务句柄),实测 SRAM +200B | @@ -89,28 +89,63 @@ socket 生命周期解耦,与 `net_listener_retry_tick` 的重试表同构。 --- -## 4. 完成与取消语义(五路) +## 4. 挂起的 recv 会被什么结束(5 种触发条件) -`net_pending_tick()` 在主循环每轮运行,对每个挂起 fd 按序判定: +挂起 recv 被结束的方式只有 5 种,下文简称**五路**——①②③ 由 `net_pending_tick()` +每轮对每个挂起 fd 按序判定,④⑤ 由显式操作触发: | # | 条件 | 动作 | 设计要点 | |---|---|---|---| | 1 | **数据到达** | SPI 读出 + 通知(结果 = 字节数) | 由 `net_poll` 维护的 `readable` 门控,**零额外 SPI**;仅 ESTABLISHED / UDP_OPEN 态可读;spurious readable 需清除 | | 2 | **到点** `now >= deadline`(仅显式预算登记;无限等待登记无 deadline) | 通知 `NET_ERR_TIMEDOUT`(对外 -2 映射保持) | 状态无关;用有符号回绕安全差值,防 tick 回绕;这是 `net_recv_to` 调用方策略的正常兑现,不是伪造 | | 3 | **CLOSED**(EOF/DISCONNECT) | 排空:有数据则读出;否则按 0(EOF) 完成 + `auto_relisten` + 通知 | CLOSE 先行完成挂起 = `net_close` 的 settle 钩子(排空→数据否则 CONNRESET) | -| 4 | **同 fd 后续操作** | 先结算挂起,再执行新操作 | per-fd 串行——冻结面从"全网"缩到"本 fd" | +| 4 | **同 fd 后续操作**:close / drop_conn / 对账 resync(芯片静默回收) | 先结束挂起 recv(排空 → 有数据按字节数完成;否则取消 CONNRESET),再执行新操作 | per-fd 串行:pending 模型唯一留下的次序面就在本 fd 内,其他 fd 不受影响。同 fd 第二个 recv 被登记守卫拒绝(BUSY);send 无需结算(收发不冲突,SPI 由 netTask 串行) | | 5 | **网络重建**(`net_stack_bring_up`,芯片复位) | **取消 + 必须通知** | `net_init` 顶部 `net_pending_cancel_all(CONNRESET)`,先于芯片复位;**取消不通知 = 调用方永久挂死** | **状态推断的克制**:CONNECTING / LISTENING 等中间态**保持等待**,**不做**状态推断式取消—— CONNECT → ESTABLISHED 是合法迁移,推断取消会误杀正在建链的等待。 -### 4.1 tripwire +### 4.1 一次阻塞 recv 从调用到返回的全过程 -挂起超 60s(`NET_RECV_TRIPWIRE_MS`)= "完成逻辑缺位"探针 → **只 `DBG_ERROR` 留痕一次, -绝不强制了结、绝不伪造 TIMEDOUT 返回值**——强制了结会掩盖完成路径缺陷,伪造返回值 -违背调用方意图。 -定位:留痕成本极低的开发期探针;唤醒责任在 ①数据 ②到点(仅显式预算)③断连 与 -显式 cancel 路径(close / 网络重建 / 陈旧重同步),见 §4 五路。 +一句话链:**登记(μs 级)→ 调用方自己睡 → 每轮判定(只读标志与到期时间)→ 公共出口(通知+清槽)→ 两段式等待取结果**。以 `net_recv(sockfd, buf, len)` 阻塞路径为例: + +```mermaid +flowchart TD + A["调用方任务:net_recv(sockfd, buf, len)"] --> B["消息入队,随后在
自己上下文睡(两段式等待)"] + B -.-> C + + subgraph NT["netTask —— 唯一执行者(~1ms 节拍)"] + C{"数据已在?
readable / recv_len > 0"} + C -- "是(常见)" --> D["直接读出"] + C -- "否 + 阻塞模式" --> E["登记挂起请求(μs 级)
守卫:每 fd 至多一个、拒绝 netTask 自等待"] + E --> F["随即返回,去处理下一条消息
—— 等待不占用执行者"] + F --> G["每轮检查每个挂起 fd"] + G -- "未命中 → 等下一轮" --> G + G -- "数据到达" --> H1["SPI 读出"] + G -- "到点(仅显式预算)" --> H2["结果 = TIMEDOUT"] + G -- "断连(CLOSED / session_dead)" --> H3["排空:有残留 → 读出
无残留 → EOF(0) / 异常 CONNRESET"] + H1 --> I + H2 --> I + H3 --> I + end + + D --> I + I["通知调用方(同一回传通道):通知值 = 结果原值
挂起路径经公共出口 net_pending_complete:清槽、防重复通知"] + I --> J["调用方醒来取结果
0 = EOF 也是有效通知(以 pdTRUE 判定)"] + + K["取消路径:close / drop_conn / 网络重建"] -. "先结束挂起、再动芯片" .-> I +``` + +1. **入队**(调用方任务):`net_recv` 把请求打包进消息入 `netMsgQueue`,随后进入两段式等待(步骤 6)。netTask 不被占用。 +2. **快速路径判定**(netTask,`net_recv_locked`):数据已在(`readable` / recv_len>0)→ 直接读出、经通知值回传字节数——不产生挂起,常见路径到此为止。 +3. **登记**(netTask):无数据且阻塞模式 → `net_pending_register` 过两条守卫(§3.2:每 fd 至多一个不覆盖;拒绝 netTask 自等待)→ 记 `buf`/`len`/`caller` 与预算(`net_recv_to` → `deadline`;无限等待 → `infinite=1` 无 deadline)→ 返回"已登记"哨兵,netTask 立即处理下一条消息。 +4. **每轮判定**(netTask,`net_pending_tick`):对每个挂起 fd 按序 ①数据 → ②到点 → ③断连(判据见上表;③ 的判据是 `state==CLOSED || session_dead`,漏 ③ = 无限 recv 永久挂死,勿动)。命中任一条件进入公共出口;挂起超时留痕探针只留痕不完成(编译期选项,默认关,见 §9)。 +5. **公共完成出口**(`net_pending_complete`,所有完成/取消路径的唯一出口):`xTaskNotify` 覆盖式写入**通知值 = 结果原值**(>0 字节数 / 0 EOF / 负错误码)→ 清 `active`;无在位挂起则静默返回(防重复通知)。失败结果同步记入 netTask 自己的 errno 槽位(按任务槽位,非跨任务共享全局)。 +6. **唤醒与取结果**(调用方任务):所有 `net_*` API 的回执共用同一条任务通知通道,**两段式等待**防"入队→等待入口"间隙内通知丢失——先零等待拾取(清除掩码全 1;以 pdTRUE/pdFALSE 判定已落地,不能判值≠0——合法的 0 结果=EOF 也是有效通知),未拾取到再阻塞等待。通知值 32 位整体作为结果,不切分位域(大单次收发不被截断)。 +7. **取消路径**(五路中的 ④⑤,共同规则"**先结束挂起、再动芯片**"): + - **同 fd 后续操作**(close / drop_conn):`net_pending_settle_close` 先结算——芯片 RX 有数据(bit3=1 契约:断连后残数据留缓冲待 MCU 读)→ 按字节数完成;无数据 → 取消(CONNRESET)——然后才执行 close/拆会话。对账发现芯片静默回收(resync)时走 `net_pending_cancel`(连接已被芯片收走,无排空窗口,直接取消必通知)。 + - **网络重建**:`net_init` 顶部 `net_pending_cancel_all(CONNRESET)`,先于芯片复位;取消必通知,否则调用方永久挂死。 +8. **buf 生命周期**:挂起期间 `buf` 指针须保持有效至调用返回(挂起表按指针写入,§5)。 --- @@ -144,8 +179,8 @@ CONNECT → ESTABLISHED 是合法迁移,推断取消会误杀正在建链的 | **SEND 路径未覆盖** | 发送仍为分块阻塞(1s/chunk stall) | 该期间队列仍被冻结;二期 pending 化解决 | | **ACCEPT 路径未覆盖** | accept 仍用轮询计时 | 需 pending 化(二期) | | **超时精度** | 随主循环节拍(~1ms),被长操作占用时顺延 | 一期文档化、不修;二期 SEND 化后该顺延面**收窄** | -| **tripwire 未接自检** | 只 `DBG_ERROR` 留痕(不再强制了结),未写 selftest | 二期补齐 | -| **模拟器不可建模** | `net_socket_sim.c` 单线程 Winsock 无法复现**挂起模型内部机制**(外部语义已由包装层按 blocking 属性/预算模拟) | 挂起表/tick/通知路径在模拟器上零覆盖,只能硬件验证;**监听生命周期 `net_listener.c` 亦为真机专属**(内部头只被 `net_socket.c` include,CMakeLists 不编译) | +| **挂起超时留痕探针** | 编译期选项 `NET_PENDING_TRIPWIRE` 默认关(排查挂死时开);未接自检 selftest | 二期补齐自检 | +| **模拟器不可建模** | `net_socket_sim.c` 单线程 Winsock 无法复现**挂起模型内部机制**(外部语义已由包装层按 blocking 属性/预算模拟) | 挂起表/tick/通知路径在模拟器上零覆盖,只能硬件验证;挂起模型实现独立在 `net_pending.c`(真机专属,CMakeLists 不编译;**监听生命周期 `net_listener.c` 同此**) | **二期扩展设计**(ACCEPT / SEND 的挂起化、门禁清单、改动量)见 `docs/任务规划/基线与待确认.md` §2.1。 @@ -154,10 +189,27 @@ CONNECT → ESTABLISHED 是合法迁移,推断取消会误杀正在建链的 ## 8. 设计铁律(为什么是这样) -1. **执行者永不在等待中自旋**——等待必须在调用方上下文完成,netTask 只负责"登记"与"了结"。 +1. **执行者永不在等待中自旋**——等待必须在调用方上下文完成,netTask 只负责"登记"与"结束"。 2. **取消必通知**——任何取消路径(close / 重建 / 陈旧重同步)都必须唤醒调用方, 否则是永久挂死而非错误返回。 3. **挂起状态与 socket 表解耦**——`net_sock_t` 会被整块 memset,跨时间状态不能寄居其中。 4. **不做状态推断式取消**——中间态(CONNECTING/LISTENING)合法迁移存在, 推断取消会误杀正常建链等待。 5. **数据到达不引入额外 SPI**——判据复用主循环既有 `net_poll` 维护的 `readable` 标志。 + +--- + +## 9. 排查辅助:挂起超时留痕探针(编译期选项,默认关) + +五路判定 + 显式 cancel 是挂起 recv 的**全部唤醒责任**(§4)。一个挂起请求若超过阈值 +(60s,`NET_RECV_TRIPWIRE_MS`)还没被任何一路结束,只有一种解释:**完成路径漏了它** +(代码缺陷)——而不是"数据还没到":无限等待本来就是调用方的合法策略,不该被强行打断。 + +探针的处理:`net_pending_tick` 对这样的 fd **只打一条 `[ERR]` 日志**(每 fd 一次, +防刷屏),然后让它继续等——**绝不强制结束、绝不伪造 TIMEDOUT 返回值**。为什么不用 +"强制超时"兜底:强制结束会把"唤醒路径有 bug"这个**缺陷**伪装成一次**普通超时**—— +调用方拿到假结果,缺陷永远潜伏(旧实现正是"到点 +1s 伪造 TIMEDOUT",已废除)。 + +开关:`NET_PENDING_TRIPWIRE`(`net_socket.c`,默认 0 = 编译剔除、产品零成本)—— +排查"调用方挂死唤不醒"时置 1 重烧。**开与关语义完全一致**:探针只留痕,不参与完成。 +代码里该机制名为 tripwire(绊线:挂住 = 踩到缺陷 wiring)。 diff --git a/docs/网络/网络自愈架构设计.md b/docs/网络/网络自愈架构设计.md index c9349ab7..9a98b2f3 100644 --- a/docs/网络/网络自愈架构设计.md +++ b/docs/网络/网络自愈架构设计.md @@ -2,7 +2,7 @@ > **定位**:本文是 CH395F 网络自愈架构的**现状权威描述**——设计结构、原理、关键参数及其实证锚点。 > 文中「收敛阶段 0~3」指 2026-10 自愈架构的分阶段实施(过程已归档,见 §9)。 -> 架构审计过程(T1~T4 三路审计与 39 条编号发现、E0~E14 实验方法与原始记录、分阶段实施清单) +> 架构审计过程(T1~T4 三路审计与 39 条编号发现、E0~E15 实验方法与原始记录、分阶段实施清单) > 已完成使命并删除——过程全文在 git 历史(`git show 1a35b36^:docs/网络/N34-自愈审计/`,目录合并前 > 7 份文档)。实证结论已沉淀进:`docs/问题记录/CH395F_Trap_Records.md`(TRAP-NET-01~21 与 B 系列)、 > `docs/子系统设计/网络Socket监听生命周期设计说明.md`(D1~D10 与模块化边界)、`docs/芯片手册/CH395F.md`。 @@ -15,12 +15,8 @@ 1. **芯片永不自动回 LISTEN**——单连接复用模型(监听与数据通道复用同一 Socket), "监听常驻"只能是软件承诺(I4)。 -2. **事件面不是可靠唯一信源**——旧"芯片丢中断"说法已被 E14 复核**推翻**(2026-10-14, - 48 轮直读 SINT 矩阵:芯片侧事件丢失 = 0,SINT 锁存可靠)。历史"丢失"全部是 - **读清消费竞态**(台架 post-listen drain 吞掉即时到达的 CONNECT,drain-int 探针 - 现场抓获 3/48;生产 B3 类游离全局读已清除)+ **门控观察伪象**(2/48,SINT 30ms 内 - 即捕获)。但结论不变:事件可被其它合法读者消费,且状态面存在事件覆盖不了的幽灵 - (E7b)→ 正确性必须靠回读芯片事实 + 有界超时兜底(I3)。 +2. **事件面不是可靠唯一信源**——事件可被其它合法读者消费,且状态面存在事件覆盖不了的幽灵 + (E7b;E15:幽灵 = 芯片如实报告旧连接拆链进行中,非谎报)→ 正确性必须靠回读芯片事实 + 有界超时兜底(I3)。 3. **close 有沉降窗、RX 残渣有害**——带非空 RX 关闭会拆链停滞、吞下一会话 SYN 且自持 (E4 变体 C 0/20);沉降窗不定长(TRAP-NET-09/-20)→ 复用前清理必须内联进事务(I5)。 @@ -62,7 +58,7 @@ reconciler 保留分级去抖,因为形态①要让位 M3 窗、形态②要 | tick | 节奏 | 职责 | |---|---|---| | `net_poll` | 主循环每轮(≈1ms) | INT# 引脚 → 全局事件汇聚(唯一读者)→ SINT 分派 → **驱动缓存全量刷新** → 链路位喂驱动 → 步进 `ch395f_sock_reset_poll` | -| `net_process_messages` | 每轮 | RPC 消息处理;开头每轮 `net_pending_tick`(挂起 recv 了结)+ `net_listener_retry_tick`(D10) | +| `net_process_messages` | 每轮 | RPC 消息处理;开头每轮 `net_pending_tick`(挂起 recv 结束)+ `net_listener_retry_tick`(D10) | | `net_reconcile_tick` | 100ms | 唯一周期对账 + 重建(§4.1) | ### 3.3 状态模型(会话投影) @@ -161,14 +157,17 @@ reconciler 保留分级去抖,因为形态①要让位 M3 窗、形态②要 socket 属性);`net_recv_to()` = 显式预算便捷入口(`timeout_ms=0` 仍拒 INVAL)。 - 唤醒源 = 数据 / EOF / close / 网络重建 CONNRESET;会话死亡兜底 = 形态①(≈400ms)。 - **L3 pending recv**:阻塞 recv 不独占 netTask(挂起登记 + 主循环节拍完成); - **tripwire**:挂起超 60s 只 `[ERR]` 留痕一次(完成逻辑缺位探针),不伪造 TIMEDOUT。 + **挂起超时留痕探针**(编译期开关 `NET_PENDING_TRIPWIRE`,默认关):挂起超阈值只 + `[ERR]` 留痕一次(完成逻辑缺位),不伪造 TIMEDOUT。 +- **术语**:"结束挂起 recv" = `net_pending_complete` 把结果(字节数 / EOF(0) / 错误码) + 回传给调用任务并唤醒它,挂起槽随之释放(旧称"了结",2026-10-14 更名)。 - **文档契约**(嵌入式特有):IWDG `required_mask` 内任务**禁止无限阻塞 recv**—— 必须 `net_select` 超时或 `net_recv_to` 显式预算。 - 上层 32 轮盲收(`ui_net_sink` / `iec104_serv`)保留现状(E6 裁决,§4.8)。 ### 4.6 `net_drop_conn`——应用主动拆会话保监听(E-02 收口) -- 语义:`net_pending_settle_close` 先了结挂起 recv → `net_sock_reset_sync(QUARANTINE)` +- 语义:`net_pending_settle_close` 先结束挂起 recv(回传结果 + 唤醒调用方)→ `net_sock_reset_sync(QUARANTINE)` → 本层收口 CLOSED(不清 fd)→ `auto_relisten` 即时 `net_listener_try` (失败交 D10 + 形态④)。 - **幂等**(非 ESTABLISHED/CONNECTING 直接返 0);**EOF 路径不得调** @@ -233,6 +232,7 @@ reconciler 保留分级去抖,因为形态①要让位 M3 窗、形态②要 | E6 | U15 命中=0(~4h 常态 + 压测;用户裁决提前收线) | §4.8 观察项 | | E-02 | `drop_conn` 时序定案:配合对端 TIME_WAIT ~150ms→形态④;不配合 FIN_WAIT_2 长尾 | §4.6 | | E14 | "丢中断"复核(2026-10-14,48 轮直读 SINT):芯片侧事件丢失 = 0;"丢失"全部 = drain 读清消费(3/48,drain-int 现场抓获)+ 门控竞态(2/48)+ 主机同步(1/48);幽灵态本轮 0/48 未复现 | §1 事实 2 改写;TRAP-NET-17/-20 归因更正(机制保留不变);生产 listen/relisten 排事件挪至 LISTEN 命令**前**(根除自伤窗) | +| E15 | 幽灵态归因复核(2026-10-14,官方出处):0x04+旧端口 = 芯片**如实报告**旧连接拆链进行中——① bit3 `SOCKET_CLOSE=1` 为我方设置(版本门控,§5.52②:DISCONNECT/TIM_OUT 后芯片按设计不动状态与缓冲);② 拆链走 RFC 9293 §3.3.2 状态机:主动关闭 FIN_WAIT_1→FIN_WAIT_2→TIME_WAIT(2MSL 驻留;TIME_WAIT 协议目的=防旧连接迟到报文伤新连接——"断连即重连被拒"的协议根源),芯片自动走完(手册 §5.22);§5.17 默认重传 12 次、实测耗尽 ≥3s,与拆链窗实测 >2s 同量级;③ WCH 官方博客确认"断连后立即重连被拒、需程序侧特殊处理" | TRAP-NET-20"谎报"→"如实报告";settle 等待 = 官方方案;幽灵甄别 = 强制放行路径的护栏;I3 就此加强 | ## 6. 红线(明确不做的事) diff --git a/docs/问题记录/CH395F_Trap_Records.md b/docs/问题记录/CH395F_Trap_Records.md index 2dc50d98..78f6c14c 100644 --- a/docs/问题记录/CH395F_Trap_Records.md +++ b/docs/问题记录/CH395F_Trap_Records.md @@ -124,7 +124,8 @@ CH395F 以太网驱动与 NET 层的实证陷阱:现象、定案根因、修 - **状态**:✅(回归 4 轮 11/11;全局寄存器读即清见第六章 B3) - **现象**:同一会话内**第 2 次及以后**的数据连接(LIST/STOR/RETR)两类失败,概率随上一条数据连接的负载与间隔变化:① **吞数据**——新连接建立成功、服务端 `net_send` 返回成功,客户端 20s 收不到任何字节;② **425**——新连接被接受后 ~10-20ms 出现 DISCONNECT(`chip tcp=0x00`),accept 失败。 - **定案实验(裸机芯片台架,剥离 OS/net/FTP)**:`test/board/ch395f_reuse_bench.c` 内核启动前直接调 `ch395f_*` 受控矩阵 + 主机侧 `test/host/ch395f_reuse_host.py`。**剥离后 bug 依旧复现** → 纯芯片操作时序问题。关键现场:`post-listen st=0x05/0x04`(listen 成功但 TCP 态停在旧连接 ESTABLISHED=幽灵态)、`unexpected int=0x10`(只等来旧连接滞后 DISCONNECT)、`no CONNECT within 10s`(芯片状态已 0x04 但事件始终未到等待环——E14 复核:事件已被 drain 读清消费,非芯片丢失)。 -- **芯片级规律**:CH395F 拆链收尾窗口**变长且不可观测**(状态显示 CLOSED 持续 1s+ 也不代表拆完,实测可 >2s 且时长不定)。窗口内重新 `open+listen` 三种形态:① 握手完成但 **CONNECT 事件未收到**(E14 复核:事件被台架 post-listen drain 或读清竞态吞掉,非芯片侧丢失)→ 吞数据;② 状态直接假报 0x04 幽灵态(回读对端端口=旧连接端口);③ 旧连接滞后 DISCONNECT 打到新监听 → relisten 毁掉新连接 → 425。 +- **芯片级规律**:CH395F 拆链收尾窗口**变长且不可观测**(状态显示 CLOSED 持续 1s+ 也不代表拆完,实测可 >2s 且时长不定)。窗口内重新 `open+listen` 三种形态:① 握手完成但 **CONNECT 事件未收到**(E14 复核:事件被台架 post-listen drain 或读清竞态吞掉,非芯片侧丢失)→ 吞数据;② 状态显示 0x04 幽灵态——旧连接拆链进行中,状态如实如此(E15 见下条;回读对端端口=旧连接端口);③ 旧连接滞后 DISCONNECT 打到新监听 → relisten 毁掉新连接 → 425。 +- **归因更正(E15,2026-10-14,官方出处)**:旧"芯片谎报 0x04"措辞推翻——芯片**如实报告旧连接拆链进行中**:① `FUN_PARA` bit3 `SOCKET_CLOSE=1` 为我方设置(`net_init` 版本门控 ≥0x46;§5.52②/§5.23:DISCONNECT/TIM_OUT 后芯片**按设计不动 Socket 状态与缓冲**,等 MCU 关闭——"保留现场"是自家配置的文档化行为);② 拆链走 TCP/IP 协议状态机(RFC 9293 §3.3.2 图 5;芯片状态码表见手册 §5.22,明言"其他状态芯片会自动处理并更新"):主动关闭 FIN_WAIT_1→FIN_WAIT_2→TIME_WAIT(对端同时关经 CLOSING、同时关闭直达),TIME_WAIT 驻留 2MSL 才落 CLOSED——这就是拆链窗;TIME_WAIT 的协议目的即"防旧连接迟到报文影响新连接"(RFC 9293 §3.3.2),正是"断连即重连被拒"的协议层根源。重传默认 12 次(§5.17),实测重传耗尽 ≥3s(`test/board/ch395f_test_task.c` 超时分类实测)——与拆链窗实测 >2s 同量级;③ WCH 官方博客(《【WCH以太网接口系列芯片---CH395】CH395 TCP Server模式下客户端重连设置》,cnblogs sw111/18451802)明言"客户端主动断连并立即重新发起连接请求,此时 CH395 会拒绝该连接请求,因此需要程序中做一些特殊处理",官方方案 = 关闭完成后再 open+listen——即我们的 settle/quarantine 等待;幽灵甄别是"强制放行"路径的护栏(防把拆链中的连接当新连接 accept)。状态面从来是真——I3 就此加强。 - **已证伪的修复**(受控实验全部无效,列出防重踩):close 后固定沉降 100~3000ms / Socket 轮换(跨 socket 毒化)/ listen 后 close+重试 / 缓冲重分配 / close 前 TX 排空延时 / 禁用对账 tick(对账不是元凶)。 - **定案一:双信源原则——中断只是快路径,状态寄存器才是真相**: 1. **accept 路径内联探针**(`net_lost_connect_probe`,`net_accept_locked` 每 100ms 挂探针):芯片已 ESTABLISHED 而 CONNECT 事件未到 → 连续 2 轮去抖后补 accept; @@ -187,7 +188,7 @@ CH395F 以太网驱动与 NET 层的实证陷阱:现象、定案根因、修 - **修复(三阶段,`net_socket.c` + `lftpd.c`)**: 1. **异常释放(TIMEOUT/RST)隔离**:`handle_timeout_event` 置 per-fd 隔离标记;`net_relisten_locked` 隔离期内持续排空芯片 RX(`net_drain_chip_rx()`)+ 主动 close + 排空该 socket 中断 + 等 `CLOSED/TCP_CLOSED`,满 `NET_RELISTEN_QUARANTINE_MS`(400ms) 才 open+listen;上限 `NET_RELISTEN_SETTLE_MS`(800ms) 强制放行——**必须小于** `NET_RELISTEN_DEADLINE_MS`(2000ms):取 2000ms 会耗尽重试预算 → give up → **监听器死亡**; 2. **正常释放(FIN)沉降**:`handle_disconnect_event` 登记(仅 `recv_bytes != 0` 时——纯连接即关与只发不收免沉降保复连时序),relisten 前最短等 `NET_RELISTEN_GRACEFUL_MS`(**100ms**,实测悬崖:0/30ms 无效、100ms 稳定通过);日志区分 `relisten settle`/`relisten quarantine`; - 3. **应用侧硬化**:`net_sock_t.released_abnormal` 标记(TIMEOUT 置 1/DISCONNECT 置 0,新 fd 与新监听清零——新连接不得继承上一条的释放原因);`net_pending_tick` 断连了结按标记以 `NET_ERR_CONNRESET` 或 EOF(0) 回传;`lftpd receive_file` 错误路径 **unlink 截断文件** + STOR 回 **450**。 + 3. **应用侧硬化**:`net_sock_t.released_abnormal` 标记(TIMEOUT 置 1/DISCONNECT 置 0,新 fd 与新监听清零——新连接不得继承上一条的释放原因);`net_pending_tick` 断连结束时按标记以 `NET_ERR_CONNRESET` 或 EOF(0) 回传;`lftpd receive_file` 错误路径 **unlink 截断文件** + STOR 回 **450**。 - **协议边界(不可判定,留痕)**:FTP STOR 无长度声明,"在途 FIN 关闭"与"正常完成"**逐字节不可区分** → 优雅中止仍回 226;仅 RST/掉链(芯片 TIMEOUT)可识别 → 450。FIN 边界由客户端长度校验(SIZE/RETR 往返)兜底。 - **回归基线**:`--check-abort` RST **5/5**(450)+ FIN **5/5**(226 边界不变);followup 全过;正常往返 freeze SHA-256 全 MATCH;`:7003` sink 复用 RST×4/FIN×4 全过;`:8888` 真实收包写 RTC 成功。 - **与 TC-NET-604 的关系**:本条是独立、已可信复现并已修复的真实缺陷;TC-NET-604 已结案为非缺陷(判读教训见第六章台架纪律)。现场"上传失败/文件不完整/像卡死"类报告优先用本条判据复核。 diff --git a/scripts/check_registration.py b/scripts/check_registration.py index 7cc20344..651d1ca0 100644 --- a/scripts/check_registration.py +++ b/scripts/check_registration.py @@ -117,6 +117,7 @@ SIM_EXEMPT = [ ("Drivers/BSP/NET/net_select.c", "MCU socket 选择层"), ("Drivers/BSP/NET/net_socket.c", "MCU socket 后端,模拟器另有 net_socket_sim.c"), ("Drivers/BSP/NET/net_listener.c", "MCU 监听器生命周期(依赖 ch395f_* SPI 驱动与 net_socket.c 静态状态),模拟器无对应(Winsock 后端无孤儿态/重监听概念)"), + ("Drivers/BSP/NET/net_pending.c", "MCU 挂起 recv 模型(依赖 ch395f_* SPI 读出与 FreeRTOS 通知),模拟器另有 net_socket_sim.c 按外部语义模拟"), ("Drivers/BSP/RS485/rs485.c", "MCU RS-485 驱动"), ("Drivers/BSP/SD2506/sd2506.c", "MCU RTC 驱动"), ("Drivers/BSP/TPAFE5160/tpafe5160.c", "MCU 计量芯片驱动"), diff --git a/scripts/ram_baseline.tsv b/scripts/ram_baseline.tsv index dcd4dc35..9cefea4d 100644 --- a/scripts/ram_baseline.tsv +++ b/scripts/ram_baseline.tsv @@ -1,4 +1,4 @@ date code ro rw zi er_irom1 er_pct iram1 iram1_pct ccm ccm_pct top_rwzi 2026-10-12 209492 18332 1104 154184 227824 21.7 97864 74.7 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=40960;lftpd.o=7884;ui_net_sink.o=6766;ui_port.o=6420;nand_ftl.o=6216;console_log.o=4120;ch395f.o=4106;default_task.o=2736;sys_log_mcu.o=1924 2026-10-13 211456 18760 1104 154232 230216 22.0 97912 74.7 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=40960;lftpd.o=7884;ui_net_sink.o=6766;ui_port.o=6420;nand_ftl.o=6216;ch395f.o=4162;console_log.o=4120;default_task.o=2736;sys_log_mcu.o=1924 -2026-10-14 211448 18760 1104 154232 230208 22.0 97912 74.7 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=40960;lftpd.o=7884;ui_net_sink.o=6766;ui_port.o=6420;nand_ftl.o=6216;ch395f.o=4162;console_log.o=4120;default_task.o=2736;sys_log_mcu.o=1924 +2026-10-14 211324 18680 1104 154232 230004 21.9 97912 74.7 57376 87.9 heap_4.o=57376;lv_mem_core_builtin.o=40960;lftpd.o=7884;ui_net_sink.o=6766;ui_port.o=6420;nand_ftl.o=6216;ch395f.o=4162;console_log.o=4120;default_task.o=2736;sys_log_mcu.o=1924 diff --git a/tools/arch_diagram/gen_net_pending_svg.py b/tools/arch_diagram/gen_net_pending_svg.py index a9fd381d..f27215b8 100644 --- a/tools/arch_diagram/gen_net_pending_svg.py +++ b/tools/arch_diagram/gen_net_pending_svg.py @@ -74,7 +74,7 @@ FAST_PATH = ("立即 SPI 读出", LOOP_STEPS = [ ("net_poll()", "刷新 readable", C_CHIP), - ("net_pending_tick()", "了结挂起", C_TICK), + ("net_pending_tick()", "结束挂起", C_TICK), ("net_listener_retry_tick()", "重试对账", C_ACTOR), ("排空消息队列", "服务所有消费者", "#64748b"), ] @@ -87,7 +87,7 @@ PHASES = [ ("⑤", "网络重建(芯片复位)", "取消 + 必须通知(否则调用方永久挂死)", C_CANCEL), ] -WATCHDOG = "看门狗:到点后 1s 仍未了结 = 完成逻辑缺位 → 强制了结 + DBG_ERROR" +WATCHDOG = "挂起超时留痕探针(编译期选项,默认关):挂起超阈值仍未结束 → 只 DBG_ERROR 留痕(不强制结束、不伪造返回值)" FOOT = ("关键性质:挂起期间 netTask 零额外占用(判据复用主循环既有 net_poll 的 readable," "不引入额外 SPI 事务);公开 API 不变,既有调用方 / 测试 / 模拟器零改动。")