STM32以太网通信简介与LWIP详解

LwIP全名:Light weight IP,意思是轻量化的TCP/IP协议,是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。

LwIP的设计初衷是:用少量的资源消耗实现一个较为完整的TCP/IP协议栈,其中“完整”主要指的是TCP协议的完整性,实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。此外LwIP既可以移植到操作系统上运行,也可以在无操作系统的情况下独立运行。

LwIP具有主要特性
1.支持ARP协议(以太网地址解析协议)。
2.支持ICMP协议(控制报文协议),用于网络的调试与维护。
3.支持IGMP协议(互联网组管理协议),可以实现多播数据的接收。
4.支持UDP协议(用户数据报协议)。
5.支持TCP协议(传输控制协议),包括阻塞控制、RTT 估算、快速恢复和快速转发。
6.支持PPP协议(点对点通信协议),支持PPPoE。
7.支持DNS(域名解析)。
8.支持DHCP协议,动态分配IP地址。
9.支持IP协议,包括IPv4、IPv6协议,支持IP分片与重装功能,多网络接口下的数据包转发。
10.支持SNMP协议(简单网络管理协议)。
11.支持AUTOIP,自动IP地址配置。
12.提供专门的内部回调接口(Raw API),用于提高应用程序性能。
13.提供可选择的Socket API、NETCONN API (在多线程情况下使用) 。

LwIP 内核是由一系列模块组合而成,这些模块包括:TCP/IP协议栈的各种协议、内存管理模块、数据包管理模块、网卡管理模块、网卡接口模块、基础功能模块、API模块。每个模块是由相关的几个源文件和头文件组成的,通过头文件对外声明一些函数、宏、数据类型。使得其他模块可以方便的调用次模块的功能。

LwIP 本质是对数据的处理,其中也使用了大量的数据结构。

LwIP的三种编程接口
LwIP提供了三种编程接口,分别为 RAW/Callback API、Netconn API、Socket API。他们的易用性从左到右依次提高,而执行效率从左到右依次降低,用户可以根据实际情况,平衡利弊,选择合适的API进行网络应用程序的开发。以下内容将分别介绍这三种API。

1. RAW/Callback API
RAW/Callback API是指内核回调型的API,这在许多通信协议的C语言实现中都有所应用。

RAW/Callback API是LwIP的一大特色,在没有操作系统支持的裸机环境中,只能使用这种API进行开发,同时这种API也可以用在操作系统环境中。

"回调"概念:新建立一个TCP或UDP连接,你想等它接收到数据以后去处理它们,这时你需要把处理该数据的操作封装成为一个函数,然后将这个函数的指针注册到LwIP内核中。LwIP内核会在需要的时候去检测该函数是否收到数据,如果接收到数据,内核会在第一时间调用注册的函数,这个过程成为“回调”。这个注册函数被称为“回调函数”。

这个回调函数中装着你想要的业务逻辑,在这个函数中,你可以自由地处理接收到的数据,也可以发送任何数据,也就是说,这个回调函数就是你的应用程序。

在回调编程中,LwIP内核把数据交给应用程序的过程就只是一次简单的函数调用,这是非常节省时间和空间资源的。每一个回调函数实际上只是一个普通的C函数,这个函数在TCP/IP内核中被调用。每一个回调函数都作为一个参数传递给当前TCP或UDP连接。而且,为了能够保存程序的特定状态,可以向回调函数传递一个指定的状态,并且这个指定的状态是独立于TCP/IP协议栈的。

2. NETCONN API
在操作系统中,可以使用 Netconn API 或者 Socket API 编程进行网络应用程序开发。NETCONN API是基于操作系统的IPC机制(即信号量和邮箱机制)实现的,它的设计将LwIP内核代码和网络应用程序分离成了独立的线程。如此一来,LwIP内核线程就只负责数据包的TCP/IP封装和拆封,而不用进行数据的应用层处理,大大提高了系统对网络数据包的处理效率。

在操作系统环境中,LwIP内核会被实现为一个独立的线程,名为tcpip_thread,使用NETCONN API或者Socket API的应用程序处在不同的线程中,我们可以根据任务的重要性,分配不同的优先级给这些线程,从而保证重要任务的时效性,分配优先级的原则具体如下:

NETCONN API使用了操作系统的IPC机制,对网络连接进行了抽象,用户可以像操作文件一样操作网络连接(打开/关闭、读/写数据)。但是NETCONN API并不如操作文件的API那样简单易用。

举个例子,调用f_read函数读文件时,读到的数据会被放在一个用户指定的数组中,用户操作起来很方便,而NETCONN API的读数据API,就没有那么人性化了。用户获得的不是一个数组,而是一个特殊的数据结构netbuf,用户如果想使用好它,就需要对内核的pbuf和netbuf结构体有所了解,我们会在后续的章节中对它们进行讲解。

NETCONN API之所以采取这种不人性的设计,是为了避免数据包在内核程序和应用程序之间发生拷贝,从而降低程序运行效率。当然,用户如果不在意数据递交时的效率问题,也可以把netbuf中的数据取出来拷贝到一个数组中,然后去处理这个数组。

3. Socket API
Socket 即套接字,它对网络连接进行了高级的抽象,使得用户可以像操作文件一样操作网络连接,它十分易用,许多网络开发人员最早接触的就是 Socket 编程,Socket 已经成为了网络编程的标准。

相较于NETCONN API, Socket API具有更好的易用性。使用Socket API编写的程序可读性好,便于维护,也便于移植到其它的系统中。Socket API在内核程序和应用程序之间存在数据的拷贝,这会降低数据递交的效率。另外,LwIP的Socket API是基于NETCONN API实现的,所以效率上相较前者要打个折扣。

物联沃分享整理
物联沃-IOTWORD物联网 » STM32以太网通信简介与LWIP详解

发表评论