当前位置: 首页 > news >正文

LwIP 核心流程总结

主要内容参照9. LwIP一探究竟 — [野火]LwIP应用开发实战指南—基于野火STM32 文档,整理出来自用。

一、网卡接收数据流程

数据从硬件到 LwIP 内核的传递,通过 “中断触发 + 线程通信” 实现,核心是解耦接收与处理

  1. 硬件触发:网卡接收数据后,生成接收中断
  2. 中断响应:中断服务函数释放信号量,通知 “网卡接收线程” 处理数据。
  3. 消息封装:接收线程将数据封装为TCPIP_MSG_INPKT类型消息(含数据包pbuf、网卡netif、处理函数ethernet_input)。
  4. 消息投递:通过tcpip_inpkt()函数,将消息投递到 LwIP 内核邮箱tcpip_mbox
  5. 内核处理tcpip_thread线程从邮箱获取消息,调用ethernet_input()函数:
    • 若为 ARP 包:直接更新 ARP 缓存表,不进入 IP 层;
    • 若为 IP 包:递交给 IP 层进一步处理。

二、内核超时处理

LwIP 通过软件超时链表管理所有超时事件(如 ARP 缓存过期、TCP 重传超时),依赖用户提供的时基。

1. 核心数据结构

结构 / 变量作用
sys_timeo结构体单个超时事件:含超时时间time、回调函数h、函数参数arg、链表指针next
next_timeout超时链表头指针,指向第一个待处理的超时事件。
lwip_cyclic_timers内置周期性超时事件数组(如 TCP 定时器 250ms、ARP 定时器 1000ms)。

2. 关键流程

  • 注册超时事件
    1. 用户调用sys_timeout(msecs, handler, arg),计算绝对超时时间(当前时间 +msecs);
    2. 调用sys_timeout_abs()从内存池申请sys_timeo,按超时时间升序插入链表。
  • 周期性事件维护
    • LwIP 初始化时(sys_timeouts_init()),将lwip_cyclic_timers中事件注册到链表;
    • 事件超时执行回调后,通过sys_timeout_abs()重新注册,实现 “循环触发”。
  • 超时检查与处理
    • 裸机:用户周期性调用sys_check_timeouts(),检查链表头事件是否超时,超时则执行回调并删除。
    • 操作系统tcpip_thread通过tcpip_timeouts_mbox_fetch(),阻塞等待邮箱消息时同步检查超时,超时则调用sys_check_timeouts()

三、tcpip_thread 内核线程

LwIP 内核的 “主线程”,负责接收消息、处理超时、调度核心逻辑

1. 核心逻辑

while (1) {// 1. 阻塞等待邮箱消息,同时处理超时事件TCPIP_MBOX_FETCH(&tcpip_mbox, (void **)&msg); if (msg == NULL) continue;// 2. 按消息类型处理tcpip_thread_handle_msg(msg); 
}

2. 消息处理(tcpip_thread_handle_msg)

根据tcpip_msg的类型,分发到对应处理逻辑:

消息类型处理动作
TCPIP_MSG_API执行用户 API 对应的回调函数(如lwip_netconn_do_bind)。
TCPIP_MSG_INPKT调用ethernet_input(),处理网卡接收的数据包(ARP/IP 包分流)。
TCPIP_MSG_TIMEOUT注册超时事件(调用sys_timeout())。
TCPIP_MSG_UNTIMEOUT删除超时事件(调用sys_untimeout())。
TCPIP_MSG_CALLBACK执行用户注册的回调函数。

四、LwIP 消息机制

用户线程 / 网卡接收线程与tcpip_thread的通信桥梁,核心是tcpip_msg结构体与tcpip_mbox邮箱。

1. 核心消息结构(tcpip_msg)

struct tcpip_msg {enum tcpip_msg_type type; // 消息类型union {struct { tcpip_callback_fn function; void* msg; } api_msg; // API消息struct { struct pbuf *p; struct netif *netif; } inp; // 数据包消息struct { u32_t msecs; sys_timeout_handler h; } tmo; // 超时消息// 其他消息类型...} msg;
};

2. 两类关键消息

消息类型发起方核心作用投递函数
数据包消息网卡接收线程传递网卡接收的数据包到内核tcpip_inpkt()
API 消息用户应用线程传递用户 API 调用(如netconn_bind)到内核netconn_apimsg()

3. 优化配置(LWIP_TCPIP_CORE_LOCKING)

  • 当宏定义LWIP_TCPIP_CORE_LOCKING=1时:
    无需通过邮箱传递 API 消息,用户线程直接加锁调用内核函数(减少线程调度开销),是 LwIP 推荐配置。
  • LWIP_TCPIP_CORE_LOCKING=0时:
    API 消息需通过邮箱投递,用户线程需等待信号量同步(开销较高)。

核心交互关系图

[网卡硬件] → 接收中断 → [接收线程] → 封装数据包消息 → 投递到tcpip_mbox → [tcpip_thread]↓
[用户应用线程] → 封装API消息 → 投递到tcpip_mbox → [tcpip_thread] → 调用内核函数↓
[超时链表] → tcpip_timeouts_mbox_fetch()检查 → 超时则执行回调
http://www.dtcms.com/a/338369.html

相关文章:

  • wishbone总线
  • thinkphp8:一、环境准备
  • c++26新功能—可观测检查点
  • torch.nn.Conv1d详解
  • C++最小生成树
  • 高等数学 8.5 曲面及其方程
  • Python打卡Day45 预训练模型
  • 【加密PMF】psk-pmk-ptk
  • 【168页PPT】IBM五粮液集团数字化转型项目实施方案建议书(附下载方式)
  • 块体不锈钢上的光栅耦合表面等离子体共振的复现
  • 九联科技UMA223-H低功耗蜂窝模组在物联网设备中的应用与价值分析
  • 信号上升时间Tr不为0的信号反射情况
  • 工具集成强化学习:AI数学推理能力的新跃迁
  • Milvus向量数据库安装步骤
  • DRG/DIP支付改革如何通过大数据分析优化病种分组和权重调整?
  • 知识蒸馏 - 各类概率分布
  • CPP异常
  • 公司无公网IP,如何将内网服务,给外面异地连接使用?远程办公可通过什么访问?
  • 内联汇编(Inline Assembly)是什么?
  • redis命令行学习
  • Linux重要目录结构及目录命令
  • Vue3 中的 provide 和 inject 详解:实现跨组件通信
  • 运用4种填充方法补充缺失数据的案例
  • redis的过期键有哪些删除策略
  • Product Hunt 每日热榜 | 2025-08-18
  • 【跨国数仓迁移最佳实践6】MaxCompute SQL语法及函数功能增强,10万条SQL转写顺利迁移
  • 论往返之迴响:时间之织锦与信息之曼舞
  • [激光原理与应用-294]:理论 - 波动光学 - 衍射光学元件(DOE)
  • 如何生成和安全保存私钥?
  • oracle dg duplicate限速