- LwIP应用开发实战指南:基于STM32
- 刘火良 杨森
- 3270字
- 2023-07-10 16:09:18
2.2 LwIP的文件说明
2.2.1 获取LwIP源码文件
LwIP的代码已经交由Savannah托管,项目主页是http://savannah.nongnu.org/projects/lwip/。这个主页中简单地介绍了一下LwIP,然后给出了许多链接,你可以通过这些链接去挖掘更多关于LwIP的信息。在这里,我们只关注两点,如图2-1中的方框所示。
图2-1 LwIP项目主页截图
单击Project Homepage,会打开一个网页,如图2-2所示。这个网页可以看作LwIP的官方说明文档。我们可以通过这个网页获得关于LwIP的很多信息,包括使用LwIP的注意事项、数据的复制、系统初始化流程、多线程中要注意的问题、优化方法、内核模块的分类介绍、内核数据结构、内核重要全局变量、内核源码文件等。这些内容的专业性比较强,不建议初学时在这方面花费精力,并且里面的很多内容在本书的后续章节中会有所讲解,目前只需要了解即可。
图2-2 LwIP官方说明文档
单击Download Area打开的网页如图2-3所示。通过这个网页,我们可以下载LwIP所有版本的源代码包和contrib包。每单击一个红色字体的资源链接,浏览器就会打开一个ftp连接,帮助你下载想要的文件。但是这个页面提供的下载链接在国内一般无法打开。这个网页最下方的黑字内容推荐我们使用另外一个下载页面:http://download-mirror.savannah.gnu.org/releases/。在这个页面下,用户可以下载到所有在Savannah托管的开源软件,但我们只关心LwIP。利用浏览器的搜索功能,按Ctrl+F快捷键可以快速找到lwip目录。在这里为了便于读者下载,我们直接给出最终的下载链接http://download-mirror.savannah.gnu.org/releases/lwip/。
图2-3 LwIP的资源下载
可能你会问,什么是contrib包,它与源代码包有什么不同?源代码包中装的主要是LwIP内核的源码文件,而contrib包中装的是移植和应用LwIP的一些demo,即应用示例。contrib包不属于LwIP内核的一部分,里面的很多内容来自开源社区,因此对contrib包的版本管理不像内核源码那样严格和规范,但contrib包也是很有参考价值的。LwIP源码面世越久,开源社区对它的贡献就越大,所以越高版本的contrib包,提供的应用示例就越丰富,越有参考价值。在大版本区别不大的情况下,建议下载最新的contrib包。后文中我们会对contrib包中提供的应用示例进行讲解。另外,还有一些后缀为.sig的文件,这些文件是数字签名,忽略即可。
2.2.2 LwIP文件说明
按照2.2.1节的介绍,我们下载两个包:lwip-2.1.2.zip(源码包)和contrib-2.1.0.zip(contrib包)。解压以后会得到两个文件夹,如图2-4所示。
图2-4 下载解压后得到的源码包和contrib包
我们先打开lwip-2.1.2文件夹,如图2-5所示。
图2-5 源码包的目录
该目录的主要内容为:
1)CHANGELOG文件记录了LwIP在版本升级过程中源代码发生的变化。
2)COPYING文件记录了LwIP这个开源软件的license。一个软件开源,不代表你能无限制地使用它,你需要在使用它的过程中遵守一定的规则,这些规则就是license。大家可以用记事本打开此文件看一看它的内容。开源软件的license有很多种,LwIP的属于BSD License。LwIP的开源程度很高,几乎可以无限制地使用它。
3)FILES文件用于介绍当前目录下的目录信息。
4)README文件对LwIP进行了一个简单的介绍。
5)UPGRADING文件记录了LwIP每个大版本的更新,以及会对用户使用和移植LwIP造成的影响。大版本更新指的是类似1.3.x—1.4.x—2.0.x—2.1.x。小版本更新,比如2.0.1—2.0.2—2.0.3,这个过程只进行了一些bug的修复和性能的改善,不会对用户的使用造成影响。用户只要将原有工程的目录中与LwIP相关的旧版本文件替换成新版本文件,重新编译,就能直接使用。
6)doc文件夹中是关于LwIP的一些文档,可以看作应用和移植LwIP的指南,但是这些文档比较零散,不成体系,此处可略过。
7)test文件夹中是测试LwIP内核性能的源码,将它们和LwIP源码加入工程中一起编译,调用它们提供的函数,可以获得许多与LwIP内核性能有关的指标。只有非常专业的人士才会用到这种内核性能测试功能。
8)src文件夹中就是我们最关心的LwIP源码文件,下面详细讲解。
打开src文件夹,如图2-6所示。
图2-6 src目录(LwIP源码文件所在的目录)
● 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目录中。
接下来,我们详细介绍一下core文件夹,如图2-7所示。
图2-7 core目录
这里逐一介绍一下这些源文件的功能。
ipv4文件夹中是与IPv4模块相关的源文件,它们实现了IPv4协议规定的对数据包的各种操作。ipv4文件夹中还包括一些并非属于IP,但会受IP影响的协议源文件,包括DHCP、ARP、ICMP、IGMP。
ipv6文件夹中是与IPv6模块相关的源文件,它们实现了IPv6协议规定的对数据包的各种操作。ipv6文件夹中也包括一些并非属于IP,但会受IP影响的协议源文件,如DHCP、ARP、ICMP、IGMP。
altcp.c、altcp_alloc.c、altcp_tcp.c等文件处于一个抽象层,用于应用层与TCP之间的连接,如TLS等,但此类接口我们并没有过多使用,如果选择使用安全的加密传输,可以配合mbed TLS使用。
def.c文件定义了一些基础类函数,比如主机序和网络序的转换、字符串的查找和比较、整数转换成字符串等,这些函数会被LwIP内核的很多模块所调用。include目录中的def.h文件对外声明了def.c所实现的函数,同时定义了许多宏,能实现一些基础操作,比如取最大值、取最小值、计算数组长度等,这些宏同样也被内核的许多模块调用。我们经常可以看到某个内核的源文件在开始处即有#include "def.h"。
dns.c文件实现了域名解析的功能,有了它,用户就可以在知道服务器域名的情况下,获得该服务器的IP地址。很多时候我们只记得服务器域名而不记得服务器IP地址,例如www.baidu.com就是一个域名,通过DNS功能,我们就可以得到与服务器域名对应的IP地址,这给用户使用带来了很多便利。
inet_chksum.c文件提供了LwIP所需的校验和功能,在IP、UDP、TCP的实现中,需要计算校验和。
init.c文件对LwIP的用户宏配置进行了检查,会将配置错误和不合理的地方通过编译器的#error和#warning功能标出。另外,init.c文件中定义了lwip_init初始化函数,这个函数会依次对LwIP的各个模块进行初始化。
ip.c文件实现了IP相关的函数,但只是封装了ipv4和ipv6文件夹中的函数。
mem.c文件实现了动态内存池管理机制,使得LwIP内核的各个模块可以灵活地申请和释放内存。
memp.c文件实现了静态内存堆管理机制,使得LwIP内核的各个模块可以快速地申请和释放内存。
netif.c文件实现了关于网卡的操作,比如注册/删除网卡、启用/禁用网卡、设置网卡的IP地址等。netif.c与include目录中的netif.h文件共同构成了LwIP的netif模块,它对网卡进行了抽象,使得LwIP内核可以方便地管理多个特性各异的物理网卡。
pbuf.c文件实现了LwIP对网络数据包的各种操作。网络数据包在LwIP内核中以pbuf结构体的形式存在,这提高了LwIP内核对数据包的处理效率,也提高了数据包在各层之间递交的效率。pbuf结构体也是我们使用RAW/Callback API进行网络应用程序开发的关键,第6章中会详细讲解。
raw.c文件实现了一个传输层协议的框架,我们可以在该文件的基础上修改和添加代码,实现自定义的传输层协议。与UDP/TCP一样,它可以与IP层(即网络层)直接进行交互,这类似RAW Socket。在实际应用中,我们常用UDP和TCP作为传输层协议,但有时,底层网络开发人员会认为UDP的可靠性太差,或者TCP虽然可靠性强,但是很耗费时间和内存,他们需要根据实际需求,平衡利弊,定义自己的传输层协议。LwIP的raw模块可以满足他们的需求。
stats.c文件实现了LwIP内核的统计功能,使用户可以实时地查看LwIP内核对网络数据包的处理情况。
sys.c文件和sys.h文件构成了LwIP的sys模块,提供了与临界区相关的操作。
tcp.c、tcp_in.c和tcp_out.c文件实现了TCP,包括对TCP连接的操作、对TCP数据包的输入输出操作和TCP定时器,它们和include目录中名称带tcp的头文件共同构成了LwIP的TCP模块。TCP模块的实现是LwIP的最大特点,它以很小的资源开销几乎实现了TCP中规定的全部内容。TCP是非常复杂的协议,这几个与TCP模块相关的文件占据了LwIP内核的绝大部分。
timeouts.c定义了LwIP内核的超时处理机制。LwIP内核中多个模块的实现需要借助超时处理机制完成,包括ARP表项的时间统计、IP分片报文的重装、TCP的各种定时器、实现各种应用层协议需要的超时处理。
udp.c文件实现了UDP,包括对UDP连接的操作和UDP数据包的操作。