lwip基础
LWIP是一个轻量级的TCP/IP协议栈,其全称为Lightweight IP,它专门为小型嵌入式系统设计,具有占用资源少、易于移植、可裁剪性高等特点。
一、源码结构
包含两个仓库:The lwIP TCP/IP stack is maintained in the 'lwip' Git module and contributions (such as platform ports) are in the 'contrib' Git module.
contrib包提供用户LWIP移植文件以及相关的LWIP的demo.它不属于LWIP内核的一部分,它只是起到一个提供移植文件和学习实例的作用。
lwip源码中的src文件夹包含lwIP源码文件,包含5个文件夹:
其中具体的核心源代码文件是core下的文件:
从这里会发现,lwIP 是由一系列的模块组合而成的,这些模块包括:TCP/IP 协议栈 的各种协议、内存管理、数据包管理、网卡管理、网卡接口、基础功能、API 接口模块等,每 一个模块是由几个源文件和一个头文件集合,这些头文件全部放在 include 文件夹下,而源文 件都是放在 core 文件夹下。
lwip-contrib需要关注的就是apps、example和ports文件夹,重点是ports。
二、模块分析
LwIP为用户提供三组API接口:
Netconn API(sequential API): 普通的、顺序的程序提供了使用lwIP栈的方法。依赖操作系统,所有操作都需要协议栈去处理,应用程序与协议栈通信,通过发送消息方式进行,因此这种方式会造成频繁的任务切换,速度相比RAW API慢了许多。在操作系统上推荐使用本API。
Socket API:BSD Socket API 建立在sequential API之上的,封装出的一套BSD Socket API。同样依赖操作系统,效率低,消耗的资源更多。
Raw API(native API / callback): 基于零拷贝发送和接收的事件驱动的API,在没有操作系统的情况下唯一可用的API。操作较复杂但速度最快,效率最高。
2.1 lwip打印调试信息
include/lwipopts.h #define LWIP_DEBUG 0 // #define NETIF_DEBUG LWIP_DBG_ON // #define ETHARP_DEBUG LWIP_DBG_ON // #define TCPIP_DEBUG LWIP_DBG_ON // #define IP_DEBUG LWIP_DBG_ON // #define UDP_DEBUG LWIP_DBG_ON // #define DHCP_DEBUG LWIP_DBG_ON // #define ICMP_DEBUG LWIP_DBG_ON // #define SOCKETS_DEBUG LWIP_DBG_ON // #define ACD_DEBUG LWIP_DBG_ON
2.2 lwip打印状态信息
配置相关宏
include/lwipopts.h /* ---------- Statistics options ---------- */ #define LWIP_STATS 1 #if LWIP_STATS #define LWIP_STATS_DISPLAY 1 #define LINK_STATS 0 #define ETHARP_STATS 0 #define IP_STATS 0 #define ICMP_STATS 0 #define IGMP_STATS 0 #define IPFRAG_STATS 0 #define UDP_STATS 0 #define TCP_STATS 0 #define MEM_STATS 1 #define MEMP_STATS 1 #define PBUF_STATS 0 #define SYS_STATS 0 #endif /* LWIP_STATS */
周期性调用函数打印信息
stats_display();
三、静态IP冲突检测
lwip内只有动态IP冲突检测,而没有静态IP的ACD功能。
+// static ip acd +struct acd acd_static; +static void static_conflict_callback(struct netif *netif, acd_callback_enum_t state) +{ + applog(LOG_WARNING, "static ip conflict detects state:%d", state); + switch (state) { + case ACD_IP_OK: + break; + case ACD_RESTART_CLIENT: + acd_start(netif_default, &acd_static, netif->ip_addr); + break; + case ACD_DECLINE: + //etharp_acd_announce(netif, &acd->ipaddr); + etharp_acd_announce(netif, &netif->ip_addr); + break; + default: + break; + } +} + +void am_static_acd_init(uint8_t* am_ip) +{ + acd_add(netif_default, &acd_static, static_conflict_callback); + acd_start(netif_default, &acd_static, netif_default->ip_addr); +} + +void am_static_acd_deinit(void) +{ + acd_stop(&acd_static); +}
在静态IP启动时初始化即可。
参考:
1. LWIP基础
2. lwip初探
3. lwip【4】 lwIP配置文件opt.h和lwipopts.h初步分析之一
6. LwIP 内存配置