前言
本系列笔记主要记录学习LWIP时的简单笔记。
方便以后用到可以快速学习了解。
李柱明博客:https://www.cnblogs.com/lizhuming/p/15487034.html
1.1 优缺点
LwIP 具有主要特性:
- 支持 ARP 协议(以太网地址解析协议)。
- 支持 ICMP 协议(控制报文协议),用于网络的调试与维护。
- 支持 IGMP 协议(互联网组管理协议),可以实现多播数据的接收。
- 支持 UDP 协议(用户数据报协议)。
- 支持 TCP 协议(传输控制协议),包括阻塞控制、RTT 估算、快速恢复和快速转发。
- 支持 PPP 协议(点对点通信协议),支持 PPPoE。
- 支持 DNS(域名解析)。
- 支持 DHCP 协议,动态分配 IP 地址。
- 支持 IP 协议,包括 IPv4、IPv6 协议,支持 IP 分片与重装功能,多网络接口下的数据包转发。
- 支持 SNMP 协议(简单网络管理协议)。
- 支持 AUTOIP,自动 IP 地址配置。
- 提供专门的内部回调接口(Raw API),用于提高应用程序性能。
- 提供可选择的 Socket API、NETCONN API (在多线程情况下使用) 。
LwIP 在嵌入式中使用有以下优点:
- 资源开销低,即轻量化。LwIP 内核有自己的内存管理策略和数据包管理策略, 使得内核处理数据包的效率很高。另外,LwIP 高度可剪裁,一切不需要的功能都可以通过宏编译选项去掉。 LwIP 的流畅运行需要 40KB 的代码 ROM 和几十 KB 的 RAM,这让它非常适合用在内存资源受限的嵌入式设备中。
- 支持的协议较为完整。几乎支持 TCP/IP 中所有常见的协议,这在嵌入式设备中早已够用。
- 实现了一些常见的应用程序:DHCP 客户端、DNS 客户端、HTTP 服务器、MQTT 客户端、TFTP 服务器、SNTP 客户端等等。
- 同时提供了三种编程接口:RAW API、NETCONN API(注:NETCONN API 即为 Sequential API)和 Socket API。这三种 API 的执行效率、易用性、可移植性以及时空间的开销各不相同,用户可以根据实际需要,平衡利弊,选择合适的 API 进行网络应用程序的开发。
- 高度可移植。其源代码全部用 C 实现,用户可以很方便地实现跨处理器、跨编译器的移植。 另外,它对内核中会使用到操作系统功能的地方进行了抽象,使用了一套自定义的 API, 用户可以通过自己实现这些 API,从而实现跨操作系统的移植工作。
- 开源、免费,用户可以不用承担任何商业风险地使用它。
- 相比于嵌入式领域其它的 TCP/IP 协议栈,比如 uC-TCP/IP、FreeRTOS-TCP 等, LwIP 的发展历史要更悠久一些,得到了更多的验证和测试。LwIP 被广泛用在嵌入式网络设备中, 国内一些物联网公司推出的物联网操作系统,其 TCP/IP 核心就是 LwIP;物联网知名的 WiFi 模块 ESP8266,其 TCP/IP 固件,使用的就是 LwIP。
缺点:
- 相比于 Linux 和 Windows 系统自带的 TCP/IP 协议栈,LwIP 的功能不算完整和强大。
1.2 文件说明
1.2.1 获取 lwip 源码文件
LwIP 的项目主页:http://savannah.nongnu.org/projects/lwip/
关注其:project homepage 和 download area 这两个点即可:
- project homepage:LwIP 的使用注意、 数据的拷贝、系统初始化流程、多线程中要注意的问题、优化方法、内核模块的分类介绍、 内核数据结构、内核重要全局变量、内核源码文件等。
- download area:下载页面。推荐:http://download-mirror.savannah.gnu.org/releases/lwip/
说明:contrib 包里面装的是移植和应用 LwIP 的一些 demo。
1.2.2 lwip 文件夹说明
1.2.2.1 总目录
下载两个包:lwip-2.1.2.zip(源码包)和 contrib-2.1.0.zip(contrib 包)
1.2.2.2 lwip 包
- doc 是一些应用文档和移植 LwIP 的指南。(有点混乱,不建议参考)
- src 是 LwIP 源码文件。
- test 是测试 LwIP 内核性能的源码,将它们和 LwIP 源码加入到工程中一起编译,调用它们提供的函数,可以获得许多与 LwIP 内核性能有关的指标。
- CHANGELOG 版本升级记录。
- COPYING LwIP 这个开源软件的 license。
- FILES 介绍当前目录下的目录信息。
- README LwIP 的一个简单的介绍。
- UPGRADING 记录了 LwIP 每个大版本的更新,会对用户使用和移植 LwIP 造成的影响。
1.2.2.3 lwip\src 内核源码
- api 文件夹里面装的是 NETCONN API 和 Socket API 相关的源文件,只有在操作系统的环境中,才能被编译。
- apps 文件夹里面装的是应用程序的源文件,包括常见的应用程序,如 httpd、mqtt、tftp、sntp、snmp 等。
- core 文件夹里面是 LwIP 的内核源文件。
- include 文件夹里面是 LwIP 所有模块对应的头文件。
- netif 文件夹里面是与网卡移植有关的文件,这些文件为我们移植网卡提供了模板,我们可以直接使用。
LwIP 内核是由一系列模块组合而成的,这些模块包括:
- TCP/IP 协议栈的各种协议
- 内存管理模块;
- 数据包管理模块;
- 网卡管理模块;
- 网卡接口模块;
- 基础功能类模块;
- API 模块。
每个模块是由相关的几个源文件和头文件组成的,通过头文件对外声明一些函数、宏、数据类型,使得其它模块可以方便地调用此模块的功能。而构成每个模块的头文件都被组织在了 include 目录中,而源文件则根据类型被分散地组织在 api、apps、core、netif 目录中。
部分文件说明:
-
def.c 文件定义了一些基础类函数,比如主机序和网络序的转换、字符串的查找和比较、整数转换成字符串等,这些函数会被 LwIP 内核的很多模块所调用。所以会常看到
#include “def.h”
。 -
init.c 文件对 LwIP 的用户宏配置进行了检查,会将配置错误和不合理的地方,通过编译器的 #error & #warning 功能表示出来。另外,init.c 定义了
lwip_init();
初始化函数,这个函数会依次对 LwIP 的各个模块进行初始化。 -
mem.c 文件实现了动态内存池管理机制,各模块可以灵活地申请和释放内存。
-
memp.c 文件实现了静态内存堆管理机制,各模块可以快速地申请和释放内存。
-
netif.c 文件实现了网卡的操作,比如注册/删除网卡、使能/禁能网卡、设置网卡 IP 地址等等。netif.c 与 include 目录中的 netif.h 文件共同构成了 LwIP 的 netif 模块。
-
pbuf.c 文件实现了 LwIP 对网络数据包的各种操作。网络数据包在 LwIP 内核中以 pbuf 结构体的形式存在,这提高了 LwIP 内核对数据包处理效率,以及提高了数据包在各层之间递交的效率。pbuf 结构体也是我们使用 RAW/Callback API 进行网络应用程序开发的关键。
-
raw.c 文件实现了一个传输层协议的框架,我们可以在它的基础上修改和添加代码,实现自定义的传输层协议,与 UDP/TCP 一样,它可以与 IP 层直接进行交互。这类似 RAW Socket。在实际的应用中,我们常用 UDP 和 TCP 作为传输层协议。但有时,底层网络开发人员会嫌 UDP 的可靠性太差,或者 TCP 虽然可靠性强,但是很耗费时间和内存,他们需要根据实际需求,平衡利弊,定义自己的传输层协议。LwIP 的 raw 模块可以满足这个需求。
-
stat.c 文件实现了 LwIP 内核的统计功能,使用户可以实时地查看 LwIP 内核对网络数据包的处理情况。
-
timeouts.c 定义了 LwIP 内核的超时处理机制。LwIP 内核中多个模块的实现需要借助超时处理机制,包括 ARP 表项的时间统计、IP 分片报文的重装、TCP 的各种定时器、实现各种应用层协议需要的超时处理。
1.2.2.4 lwip 官方说明文档
LwIP 官方说明文档:http://www.nongnu.org/lwip/2_1_x/index.html
陷阱章节-Common pitfalls:
- 里面提到有无操作系统相关注意点:Mainloop Mode(主函数轮询模式)与 OS Mode(操作系统模式)。
1.2.3 contrib 文件夹说明
就是 demo 文件夹。后面开发可参考。
资料
参考: