1.Light weight IP(LWIP)轻量化的源码 TCP/IP 协议
2.正点原子lwIP学习笔记——网络数据包管理
3.LWIP分析(三)——启动流程
4.嵌入式网络那些事内容简介
5.正点原子lwIP学习笔记——ICMP协议
Light weight IP(LWIP)轻量化的 TCP/IP 协议
Light weight IP(LWIP)轻量化的 TCP/IP 协议,由Adam Dunkels开发的分析开源协议栈,旨在用少量资源消耗实现完整TCP/IP功能,源码适合嵌入式系统。分析
LWIP支持多种协议,源码如ARP、分析android 小应用源码ICMP、源码IGMP、分析UDP、源码TCP、分析PPP、源码DNS、分析DHCP、源码IP、分析SNMP和AUTOIP等,源码适用于无操作系统环境,仅需少量RAM和ROM即可运行,适合资源受限的嵌入式设备。
LWIP具有多种API,包括RAW API、LWIP API和SOCKET API,提供不同性能和易用性,适应多种网络应用程序需求。
LWIP在嵌入式领域有显著优势:资源开销低、支持完整协议、实现常见应用、高度可移植、开源免费且得到广泛验证。主页指标源码完整
LWIP提供三种模式:RAW API、LWIP API和SOCKET API,其中RAW API将协议栈与应用置于同一进程,RAW API和LWIP API支持多线程,SOCKET API提供UNIX标准API。
LWIP源码结构清晰,包含核心文件、基础类函数、域名解析、校验和、初始化、IP协议、内存管理、网卡操作、网络数据包管理、TCP协议、超时处理和UDP协议等模块。
在STMF微控制器中,LWIP提供网络层、传输层功能,MAC层和PHY层由硬件实现。SMI接口允许访问PHY寄存器,MII和RMII用于MAC与外接PHY的互联,支持/Mbit/s数据传输。
LWIP数据包和网络接口管理通过netif结构体实现,协议栈API包括用户编程接口和内核进程通信机制,支持数据包处理、波段合并指标源码连接管理和内核回调接口。
编程实例展示了如何创建UDP和TCP线程,以实现网络应用程序的开发。
正点原子lwIP学习笔记——网络数据包管理
TCP/IP作为一种数据通信机制,其协议栈的实现本质上是对数据包的处理。为了实现高效率的处理,lwIP数据包管理提供了一种高效的机制。协议栈各层能够灵活处理数据包,同时减少数据在各层间传递时的时间和空间开销,这是提高协议栈工作效率的关键。在lwIP中,这种机制被称为pbuf。
用户的数据经过申请pbuf,拷贝到pbuf结构的内存堆中。在应用层,数据的前面加上应用层首部,在传输层加上传输层首部,最后在网络层加上网络层首部。
pbuf用于lwIP各层间数据传递,避免各层拷贝数据!
lwIP与标准TCP/IP协议栈的区别在于,lwIP是一种模糊分层的TCP/IP协议,大大提高了数据传输效率!
这是定义在pbuf.h中的关键结构体pbuf。通过指针next构建出了一个数据包的单向链表;payload指向的是现在这个结构体所存储的数据区域;tot_len是所有的数据长度,包括当前pbuf和后续所有pbuf;而len就是指当前pbuf的长度;type_internal有四种类型;ref代表当前pbuf被引用的次数。
右边展示的快递站系统源码pbuf_layer就是用来首部地址偏移,用来对应相应的结构体。
PBUF_RAM采用内存堆,长度不定,一般用在传输数据;PBUF_POOL采用内存池,固定大小的内存块,所以分配速度快(一般字节,就是分配3个PBUF_POOL的内存池),一般用在中断服务中;PBUF_ROM和PBUF_REF都是内存池形式,而且只有pbuf没有数据区域,数据都是直接指向了内存区(PBUF_ROM指向ROM中,PBUF_REF指向RAM中)。
左边第一幅对应PBUF_RAM;中间两幅对应PBUF_POOL;最后一幅对应PBUF_ROM和PBUF_REF。
其中PBUF_RAM和PBUF_POOL相对更为常用。
更多的函数,都可以在pbuf.c和.h中找到。pbuf_alloc()如果是PBUF_REF或者是PBUF_ROM,就会如上图所示,创建一个结构体指针p,然后会进入pbuf_alloc_reference;该函数中,会申请一个pbuf结构体大小的内存;然后调用pbuf_init_alloced_pbuf进行初始化,初始化可以如上图所示。
如果是PBUF_POOL,会定义q和last两个pbuf结构体指针,q和last都初始化为NULL,rem_len(剩余长度)初始化为(用户指定需要构建的长度);然后q会经过内存申请,qlen则是去rem_len和当前可申请的数据大小(PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset))取小值,然后同样经过pbuf_init_alloced_pbuf初始化q中的高端引导页源码pbuf结构体;然后会把offset清零,就是说之后的pbuf都没有offset了,只有第一个链表的元素有offset;经过if判断并判断rem_len的大小,只要还有剩余就会回去循环继续执行上述操作,直到完成3个内存块的初始化。
首先会计算payload_len和alloc_len,如果是传输数据,那么LWIP_MEM_ALIGN_SIZE(offset)就是,计算得到payload_len=,alloc_len=;然后进入判断payload和alloc的长度是否
进入判断p是否为空,不为空证明还没有释放;进入while语句,每一次都--ref(引用次数);然后类似链表删除,调用相应的pbuf类型的内存释放(内存堆或者内存池),直到p全部被释放。源码如下:
这个就要看你使用的是什么类型,然后会根据类型来决定payload_len的大小,进行相应的payload指针指向数据区前的首部字段。
这一章主要讲述了lwIP中重要的pbuf缓冲,具体有哪些数据构成,为之后的学习奠定基础,确定了pbuf除了所需传输的数据,还有哪些变量需要添加,如何申请对应的pbuf内存大小,以及对应的内存堆和内存池。
LWIP分析(三)——启动流程
LWIP分析(三)——启动流程
深入分析LWIP启动流程之前,需回顾前文对物理层结构与内存管理底层原理的铺垫。LWIP协议栈在设计上不仅涵盖多种网络硬件接口,如以太网、WiFi和NBIOT等,以实现对多样化联网硬件的支持。为了统一管理多接口,引入了“虚拟网卡”的概念。虚拟网卡实通过操作系统的网络驱动程序或LWIP自身驱动程序实现,与LWIP协议栈交互。
虚拟网卡的主要功能包括建立链表管理多个网卡、配置输出和输入回调函数接口,并能在链表中增删网卡。每张网卡由netif结构体抽象,多网卡链接形成单向链表,此源码关键参数有指针next用于链表连接、output和input函数作为物理层与IP层间数据交换的回调指针。
在虚拟网卡管理中,可实现网卡动态增减、配置及数据处理。网络数据包作为TCP/IP协议的基础处理对象,LWIP高效管理机制通过pbuf结构实现。pbuf管理多样化的数据包,从几百到几千字节不等,且支持在RAM或ROM中存储。
pbuf结构体如下,基于单链表设计,type字段决定不同pbuf结构。
包括PBUF_RAM、PBUF_POOL、PBUF_ROM和PBUF_REF等类型,提供高效数据包管理,适配数据传输需求。
硬件接口初始化,实现LWIP协议栈启动的关键步骤。初始化以太网硬件接口,需配置系统时钟、工作模式和速度,通过MDIO接口管理PHY寄存器实现。接着初始化引脚并记录TX/RX FIFO位置,此流程贯穿硬件配置、驱动实现与数据传输的初始化阶段。
嵌入式网络那些事内容简介
本文将深入探讨嵌入式网络领域中的关键协议栈LwIP,专为网络TCP/IP协议的初学者和嵌入式网络开发人员设计。从LwIP源代码的解析开始,我们将逐一揭示TCP/IP协议各层的机制和其实现原理,帮助读者理解其内在运作。
通过构建简易实验环境,本书详细讲解了LwIP在嵌入式设备组网中的移植过程,包括实际操作和注意事项。此外,书中还提供了丰富的编程案例,让学习者能在实践中掌握LIP的运用,并实现理论知识与实践的结合。
对于TCP/IP学习者而言,本书是一本理想的入门和精通指南,配套的实验平台和实例让学习过程更为直观和高效。对于初入嵌入式领域的人员,实验平台的设计使得入门变得简单,通过实践操作,他们能更快地熟悉嵌入式开发。
最后,无论你是经验丰富的嵌入式网络开发者还是新手,本书都可作为你的实用参考手册,提供丰富的实战指导和深入理解LwIP协议的途径。
正点原子lwIP学习笔记——ICMP协议
ICMP协议是一个网络层协议。一个新搭建好的网络,通常需要先进行一个基本的测试,以验证网络是否畅通;但IP协议并不提供可靠传输。如果数据包丢失了,IP协议并不能通知传输层是否丢失以及丢失的原因。因此,我们需要ICMP协议来完成这样的功能。
总结来说,为了更有效地转发IP数据报和提高交付成功机会。
ICMP协议类型与结构:对于ICMP协议中的差错报告报文,在lwIP中实现的是目的不可达以及超时的报文;对于超时报文,又分为两种,一种是生存时间TTL(在IP首部中),另一种是分片传输中,接收到一个分片后的超时等待时间超时;ICMP协议中的询问报文,lwIP实现的则是回送请求/应答报文。
无论是差错还是询问报文,前4个字节是一样的:第一个是类型,第二个是代码,例如超时就是0/1,0代表生存时间为0、1则是超时等待时间为0;后两个是校验和;之后的4个字节则是取决于ICMP报文的类型;整个ICMP的数据部分,长度取决于类型;整个ICMP报文是在网络层,可以说IP数据包包含了IP首部以及ICMP报文。
ICMP差错报文用于检测IP数据报在传输过程中的异常信息(目的不可达、源站抑制、重定向、超时、参数错误)。
ICMP类型为3,则代表了是目的不可达;lwIP实现了代码值2、3、4的差错;ICMP类型为则代表了是超时错误;代码值0代表传输期间生存时间为0,1代表数据报组装期间生存时间为0。
ICMP查询报文用于诊断两个网络设备之间是否能够通信。
lwIP只处理ICMP类型0/8,代表了回显请求/应答;目的主机收到ICMP回送请求报文后立即回送应答报文,若源主机能收到ICMP回送应答报文,则说明到达该主机的网络正常(PING)。
ICMP报文数据结构:以上结构体位于icmp.h中;包括有ICMP的类型、代码、校验和、标志符以及序号五个变量。
差错报文中,前4个字节是类型、代码和校验后;后4个字节全为0;然后传输的数据就是因其差错的IP首部以及他的pbuf的前8个字节的数据;查询报文的前4个字节与差错报文一样;后4个字节中,2格式标识符,2个事序号;数据部分则是请求报文发送和应答报文重复(就是类型为8,就是回送请求,直接把类型改为0,变成回送应答)。
lwIP只实现目的不可达、超时差错报文,它们分别为icmp_dest_unreach和icmp_time_exceeded函数;这两种差错报文都是调用icmp_send_response发送;其源码和注释如下:
以上源码的逻辑,就是根据当前的type和code判断处理方式,判断得到是差错报文,就把被丢弃数据包的pbuf中的IP首部和前8个字节数据拷贝到差错报文中(同样也是一个pbuf)。
请求报文发送,应答报文重复。简单来讲,应答包是在请求包的基础上修改得来;查询报文的源码和注释如下:
总结来说,ICMP的回送请求,把ICMP结构体的type从8改成0,然后把pbuf的payload上移个字节,添加IP首部,就变成了回送应答包。
这一篇的源码还是比较简单易懂的,没有太多要F跳转的内容,总的原理也比较清晰。
至此,lwIP的大部分协议都学完了,还剩下TCP和UDP协议,现在的lwIP框架如下: