Files
STM32F4-Base/test/host/net_socket/ns_peers.h
T
super_agent_bot a4b8bee209
CI / 静态门禁 (pre-commit) (push) Has been cancelled
CI / 主机侧单测 (MSVC) (push) Has been cancelled
CI / 静态门禁 (pre-commit) (pull_request) Has been cancelled
CI / 主机侧单测 (MSVC) (pull_request) Has been cancelled
feat(net/udp): UDP 数据面并入 netMsgQueue 串行执行(#73)
前置来自 #57 SNTP 调研:旧 net_sendto / net_recvfrom 由调用方直调
SPI 且无限自旋收包,既违约「netTask 是芯片唯一访问者」,又把 IWDG
预算吃在自旋里。

改造面
- 新增 Drivers/BSP/NET/net_udp.c/.h(真机专属,模拟器不编译):
  bind/set_peer/sendto/recvfrom 四条执行体 + 挂起收包表 + tick;
  net_msg_type_t 加四型,公开 API 一律「入队 → 睡在通知上」。
- 源地址出参不搭 net_msg_t(按值拷贝,AGENTS 禁加回传字段):改住
  net_udp.c 的 per-fd 槽,netTask 就地写回调用方内存,通知值只带
  结果码;每条出口都清槽,泄漏 = 该 fd 永久 BUSY。
- 发送复用 net_send_locked,不写第二份分块逻辑;「会话是否已死」
  收成一条判据 net_send_state_down()(TCP 看 ESTABLISHED、UDP 看
  UDP_OPEN),原先 4 处各写一遍。
- 顺带修掉真缺陷(新条 TRAP-NET-22):旧 sendto 把 DesIP 写成具体
  IP,芯片静默切 UDP Client,而旧 recvfrom 无条件剥 8 字节 → SNTP
  这类 48 B 应答丢载荷前 8 字节并交出垃圾源地址。加 udp_mode(塞进
  原有 padding,sizeof 不变)、bind 恒 SERVER、显式对端 sendto 切
  CLIENT、set_peer(fd, NULL) 轻量回 SERVER,仅 SERVER 且 avail >= 8
  才剥头。
- 截断定案:一次调用交付一个数据报,buf 装不下的尾巴用 64 B 栈上
  scratch 排空(不用 clear_recv_buf——它连后面已到达的包一起丢)。
- 取消点接齐:net_init 重建 cancel_all、net_socket 分配 fd clear、
  net_close settle_close + clear、重 bind 前先结算等包者,
  net_process_messages 第 5 个 tick 位挂 net_udp_tick。
- 收紧两处契约(原实现无生产调用者):UDP 未 bind 一律 -5;
  net_recv / _nb / _to 拒 DGRAM(绕过剥头就是静默吃 8 字节);
  NET_ERR_NOT_IN_NETTASK(-12) 退役为历史常量并写明原因。

验证
- 主机单测 test/host/net_socket 全套 616/616 绿(改造前 470):新
  分片 ns_s7_udp.c 20 组,改写 440 / 555 / 560 组;覆盖率
  net_udp.c 234/236(99.2%)、net_socket.c 956/969(98.7%),
  scripts/test_coverage_baseline.json 随本提交登记新文件。
- 测试抓到 4 个被测码真 bug:自等守卫误用调用侧谓词、芯片长度被读
  两次、槽指针取在 fd 合法性检查之前、重 bind 静默作废等待者。
- Keil ARMCC 0 Error(s) 0 Warning(s);net_udp.o Code 1,358 / ZI 224
  (8 fd × 28 B,其余模块零增长),全仓 RW_IRAM1 72.2%;内存台账
  受管区按门禁提示用 --write / --update 机器回填,未手改数字。
- pre-commit 全量钩子(含 doc-links、coding-standard、mem-budget、
  generated-fresh、bsp-err、registration、nested-comment)全绿。

限度
- 本轮无板子:真机回归 5 条(两端互通、set_peer(NULL) 能否恢复收
  广播、截断排空后下一包完整性、挂起 recv 期间 IWDG 余量、bind 写
  DesIP 与 open 先后的真芯片效果)已写进覆盖率口径「台架必验」。
- scripts/stack_report.py 退出码 1 是 10-26 起挂在账上的 iec104Task
  栈债(margin 1,016 < 1,024,见 docs/代码规范/pre-commit使用说明.md:
  122);本轮只让 net_bind 的 UDP 分支多一层静态帧(1,544 → 1,600),
  netTask margin 1,888 与 timeSyncTask 1,152 不受影响。抬栈要过
  mem-budget 台账,不在本分支自行处理。
- 登记簿销项按仓库约定留给主工作树,本分支不动 docs/任务规划/**。
2026-11-03 18:08:27 +08:00

85 lines
2.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 模块名称:NET 层兄弟模块桩的观测面(net_socket 主机侧单测专用)
* 模块功能:声明 ns_peers.c 的记录结构与复位入口。原型层面的约束(必须与真实头逐字
* 一致)在 ns_peers.c 里由"include 真实头 + 直接实现同名函数"保证:
* 签名漂移 = 本套编译期红。
* ⚠ 仅供 test/host/net_socket/ 使用,不参与 MCU 构建。
* 创建日期:2026-10-24
*/
#ifndef NS_PEERS_H
#define NS_PEERS_H
#include <stdint.h>
#include "FreeRTOS.h"
#include "net_types.h"
typedef struct {
/* —— net_listener —— */
int listener_req_calls;
int last_req_fd;
int last_req_reason;
int listener_clear_calls;
int last_clear_fd;
int listener_tick_calls;
int listener_settle_calls;
int last_settle_fd;
int last_settle_level;
int req_armed[NET_MAX_SOCKETS]; /* 登记未清=1(clear/tick 后归 0) */
int req_reason[NET_MAX_SOCKETS];
/* —— net_pending(recv) —— */
int pending_capture_calls;
int pending_reg_calls;
int pend_register_rc; /* 注入登记结果(默认 NET_PENDING_REGISTERED) */
int last_pend_fd;
uint32_t last_pend_to;
TaskHandle_t last_pend_caller;
int pending_tick_calls;
int pending_clear_calls;
int last_pend_clear_fd;
int pending_cancel_calls;
int pending_cancel_all_calls;
int last_pend_cancel_err;
int pending_settle_calls;
int pending_notified; /* 经由桩真实发出通知的次数(必通知契约) */
int pend_active_now[NET_MAX_SOCKETS];
/* —— net_pending(send) —— */
int send_reg_calls;
int send_register_rc;
int last_snd_fd;
int last_snd_sent;
int last_snd_len;
int send_tick_calls;
int send_clear_calls;
int send_cancel_calls;
int send_cancel_all_calls;
int last_snd_cancel_err;
int send_notified;
/* 会话断开判据被问次数(2026-11-03 起该判据按 type 分流,TCP/UDP 共用一份) */
int state_down_calls;
/* —— net_events —— */
int evt_connect_calls;
int evt_disconnect_calls;
int evt_recv_calls;
int evt_send_calls;
int evt_timeout_calls;
int reconcile_calls;
int lost_probe_calls;
int lost_probe_hit; /* 1=让探针命中(补 accept) */
int last_probe_state;
} ns_peers_obs_t;
extern ns_peers_obs_t g_peers;
void ns_peers_reset(void);
void ns_peers_arm_pending_done(int sockfd, int result);
void ns_peers_arm_send_pending_done(int sockfd, int result);
/* 由 ns_peers.c 调用,把"桩内部完成的通知"接到假内核的通知面上 */
void ns_peers_note_notify(TaskHandle_t to, uint32_t v);
#endif /* NS_PEERS_H */