LwIP协议栈源码详解
- 格式:pdf
- 大小:1.32 MB
- 文档页数:99
lwip协议栈中的pub_alloc
dev pbuf alloc函数简介
netdev_pbuf_alloc是网卡驱动中的内存申请函数,申请一块缓冲区用于存放网络报文数据。
2.pbuf结构分析
netdev_pbuf_alloc函数以pbuf结构申请内存空间。
3.pbuf_alloc函数封装
netdev_pbuf_alloc函数是pbuf_alloc函数的函数封装,对外
提供的函数接口只带有一个参数用于指定申请的缓冲区大小。
而
pbuf_alloc函数有三个参数,分别是申请的pbuf数据缓冲区是否带有偏移,数据缓冲区大小及缓冲区类型。
在netdev_pbuf_alloc函数中,申请的pbuf结构缓冲区数据偏移固定为0,缓冲区类型为
PBUF_POOL。
netdev_pbuf_alloc函数传入的第二个参数缓冲区大小
在调用pbuf_alloc函数申请pbuf结构时会被增加一个reserve长度,用于协议栈中的部分特殊操作。
3.1 pbuf_alloc函数第一个参数分析
在网络中通信的数据报文,除了真正的数据段外,还包括了
TCP/IP各层协议的报文头。
如用户有特殊需求,要在应用层构建报
文并直接通过网卡驱动发送,则需要申请pbuf结构的数据缓冲区带
有各层偏移。
⼏种开源的TCPIP协议栈分析1:BSD TCP/IP协议栈,BSD栈历史上是其他商业栈的起点,⼤多数专业TCP/IP栈(VxWorks内嵌的TCP/IP栈)是BSD栈派⽣的。
这是因为BSD栈在BSD许可协议下提供了这些专业栈的雏形,BSD许⽤证允许BSD栈以修改或未修改的形式结合这些专业栈的代码⽽⽆须向创建者付版税。
同时, BSD也是许多TCP/IP协议中的创新(如⼴域⽹中饿拥塞控制和避免)的开始点。
2:uC/IP是由Guy Lancaster编写的⼀套基于uC/OS且开放源码的TCP/IP协议栈,亦可移植到操作系统,是⼀套完全免费的、可供研究的TCP/IP协议栈,uC/IP⼤部分源码是从公开源码BSD发布站点和KA9Q(⼀个基于DOS单任务环境运⾏的TCP/IP协议栈)移植过来。
uC/IP 具有如下⼀些特点:带⾝份验证和报头压缩⽀持的PPP协议,优化的单⼀请求/回复交互过程,⽀持IP/TCP/UDP协议,可实现的⽹络功能较为强⼤,并可裁减。
UCIP协议栈被设计为⼀个带最⼩化⽤户接⼝及可应⽤串⾏链路⽹络模块。
根据采⽤CPU、编译器和系统所需实现协议的多少,协议栈需要的代码容量空间在 30-60KB之间。
3、 LwIP是瑞⼠计算机科学院(Swedish Institute of Computer Science)的Adam Dunkels等开发的⼀套⽤于嵌⼊式系统的开放源代码TCP/IP协议栈。
LwIP的含义是Light Weight(轻型)IP协议,相对于uip。
LwIP可以移植到操作系统上,也可以在⽆操作系统的情况下独⽴运⾏。
LwIP TCP/IP实现的重点是在保持TCP协议主要功能的基础上减少对RAM的占⽤,⼀般它只需要⼏⼗K的RAM和40K左右的ROM就可以运⾏,这使 LwIP协议栈适合在低端嵌⼊式系统中使⽤。
LwIP的特性如下:⽀持多⽹络接⼝下的IP转发,⽀持ICMP协议,包括实验性扩展的的UDP(⽤户数据报协议),包括阻塞控制,RTT估算和快速恢复和快速转发的TCP(传输控制协议),提供专门的内部回调接⼝(Raw API)⽤于提⾼应⽤程序性能,并提供了可选择的Berkeley接⼝API。
LWIP协议栈的分析和设计LWIP(轻量级IP)协议栈是一个基于嵌入式系统设计的开源TCP/IP协议栈,它具有高度的可移植性和灵活性。
在分析和设计LWIP协议栈时,我们需要考虑以下几个方面:架构设计、模块功能、代码实现等。
首先,LWIP协议栈的架构设计非常重要。
它采用了分层的设计结构,将整个协议栈分为多个模块,每个模块负责处理不同的功能。
整个架构可以分为三层:网络层、传输层和应用层。
网络层包括IP协议、ARP协议和ICMP协议等,主要负责网络地址分配、路由选择和数据包转发等功能。
传输层包括TCP协议和UDP协议等,主要负责可靠的数据传输和提供对应用层的接口。
应用层包括HTTP协议、FTP协议和DHCP协议等,主要负责各种应用程序的数据传输。
其次,每个模块的功能需要进行详细的分析。
例如,在网络层中,IP协议负责将数据包从源主机发送到目的主机。
它需要实现IP地址分配、路由选择和数据包转发等功能。
在传输层中,TCP协议负责提供可靠的数据传输。
它需要实现三次握手、拥塞控制和重传等机制。
在应用层中,HTTP协议负责进行超文本传输。
它需要实现URL解析、数据传输和页面呈现等功能。
然后,我们需要进行代码实现的设计。
在LWIP协议栈中,每个模块的代码都可以独立实现。
这样可以提高代码的可读性和可维护性。
同时,可以根据实际需求选择需要的模块进行组合。
例如,如果只需要实现一个简单的网络通信功能,可以只选择TCP/IP协议和网络驱动层进行实现,其他模块可以根据实际需求进行添加。
最后,我们需要考虑LWIP协议栈的可移植性和灵活性。
作为一个嵌入式系统的TCP/IP协议栈,它需要能够适应不同的硬件平台和操作系统。
因此,在设计代码时应该考虑到这一点,保持代码的可移植性。
同时,LWIP协议栈也应该具备灵活性,能够根据不同的应用场景进行配置和定制。
总结起来,对于LWIP协议栈的分析和设计,我们需要考虑架构设计、模块功能和代码实现等方面。
LWIP总结介绍Lwip,light weight IP;是由Adam Dunkels 开发的⼀个⼩型开源的协议栈;⽬前已经为全球共同开发的开源协议;⽀持TCPIP协议族的核⼼协议;包括:ARP/ICMP/TCP/UDP/IPV4/IPV6/DHCP等;其核⼼特点是:功能齐全、运⾏需求的RAM和ROM少;编程模型所有的功能和性能都可进⾏裁剪和配置;相关⽂件为:lwipopts.h内部实现⽀持带操作系统和不带操作系统;核⼼框架是:外部单线程驱动协议栈状态机;底层使⽤中断进⾏数据的接收;其提供三种API :1)RAW API 2)lwip API 3)BSD API。
其中BSD API就是⼤家最熟悉的socket API了。
Linux和Windows平台中的socket接⼝都与此⼤同⼩异;移植将lwip移植到不同的平台主要包括两个部分⼯作:1. MAC+PHY层移植,包括初始化、数据的收发;2. 应⽤层框架移植,如操作系统层的线程创建、定时器、消息邮箱;平台硬件:STM32F107 PHY芯⽚:DM9161AEP软件:UCOS-ii移植核⼼点ST公司针对STM32F107 不带操作系统版本的LWIP移植版本,⽂件名为STM32F107_ETH_LwIP,版本为V1.0.0;由于其版本不再更新且与本软件平台不⼀致,所以不做参考;由于STM32F1 STM32F2 STM32F4的以太⽹驱动都是⼀致的。
所以到ST官⽹下载stm32cubdf2。
其中有LWIP针对FREERTOS的移植;⽽FREERTOS与UCOS⼤同⼩异;所以只要针对其修改应⽤层框架移植的实现即可;相关代码位于:stm32cubef2\STM32Cube_FW_F2_V1.1.0\Projects\STM322xG_EVAL\Applications\LwIP\LwIP_UDPTCP_Echo_Server_Netconn_RTOS; LWIP的代码使⽤1.4.1版本,可到LWIP官⽹上下载;也包含在stm32cubef2中;移植的理论基础来源于lwip 1.4.1源码包中doc⽂件夹中的⽂件;同时官⽅也有移植到各个平台中的⽰例,⽂件为:contrib-1.4.1.zip,到官⽹上下载即可;1. MAC+PHY移植:需要修改的⽂件为:app_ethernet.c/hethernetif.c/h同时需要将stm32cubef2驱动库中的stm32f2xx_hal_eth.c/h拷贝过来;以上⽂件只需要配置好,保证编译没问题,则MAC+PHY层移植完成;2. 应⽤层框架移植:修改1个⽂件sys_arch.c,位于stm32cubef2\STM32Cube_FW_F2_V1.1.0\Middlewares\Third_Party\LwIP\system;所有的移植即完成;注意点STM32Cube_FW_F2_V1.1.0此版本中关于lwip的驱动MAC代码是有bug的,具体表现在当以太⽹包数量加⼤时,会出现底层收数据很慢的情况;使⽤PING命令经常出现TIMEOUT;此bug在STM32cubeF4中得到解决;相关问题原因描述见参考资料;参考资料1. 核⼼论⽂ <<Design and Implementation of the lwIP TCP/IP Stack>> By Adam Dunkels.20012. 移植资料<<lwIP TCP/IP stack demonstration for STM32F107xx connectivity line microcontrollers >> By ST。
关于Big Endian和Little Endian还有一点需要说明的是:软件只需要关注字节顺序就可以了,硬件除了要处理字节顺序外,还需要处理位序。
如果你觉得Big Endian和Little Endian很难理解,可以这么理解,Big Endian就是最先读出最高(最大)的字节,而Little Endian最先读出最低(最小)的字节。
通常在TCP/IP协议栈所说的网络序(Network Order)就是遵循Big-Endian规则。
在TCP/IP网络通信中,通信双方把消息按照如图1的方式进行编码,然后按从MSB(Bit0)到LSB的顺序在网络上传送;而通常我们说的主机序(Host Order)(X86架构CPU)就是遵循Little-Endian规则。
所以当两台主机之间要通过TCP/IP协议进行通信的时候就需要调用相应的函数进行主机序(Little-Endian)和网络序(Big-Endian)的转换。
了解了这些基本概念后,我们进入正题。
lwip由于考虑到移植性问题,因此它没有默认主机序为Little En dian,而是两种情况都进行了处理;而且处于灵活性考虑,还允许我们用自己定义的代码替换lwip提供的函数:#if LWIP_PLATFORM_BYTESWAP#define htons(x) LWIP_PLATFORM_HTONS(x)#define ntohs(x) LWIP_PLATFORM_HTONS(x)#define htonl(x) LWIP_PLATFORM_HTONL(x)#define ntohl(x) LWIP_PLATFORM_HTONL(x)#elseu16_t htons(u16_t x);u16_t ntohs(u16_t x);u32_t htonl(u32_t x);u32_t ntohl(u32_t x);#endif如果我们需要采用自己定义的函数,只需要定义LWIP_PLATFORM_BYTESWAP为1,并编写相应的函数即可:#define LWIP_PLATFORM_BYTESWAP 1#define LWIP_PLATFORM_HTONS(x) <your_htons>#define LWIP_PLATFORM_HTONL(x) <your_htonl>考察了lwip实现的灵活性后,我们再来看看其移植性问题。
GD32是一款由国产芯片设计公司GigaDevice推出的32位微控制器系列,它基于ARM Cortex-M核心。
LwIP (Lightweight IP)是一个开源的轻量级TCP/IP协议栈,适用于嵌入式系统。
在GD32微控制器上使用LwIP可以实现网络功能。
下面是一个使用GD32与LwIP的简单例程:1. 在GD32的开发环境中,下载并安装LwIP软件包(或者将LwIP源码添加到项目中)。
2. 在项目中包含LwIP的头文件以及相关的配置文件,例如"lwip.h"、"lwipopts.h"。
3. 在项目中初始化LwIP:包括网络接口的初始化、协议栈的初始化等。
初始化的代码可以参考LwIP提供的示例代码或者文档。
4. 配置网络参数:例如IP地址、子网掩码、网关等。
这些参数可以在初始化代码中设置,也可以通过用户交互方式进行配置。
5. 实现网络功能:例如TCP客户端/服务器、UDP通信等。
可以使用LwIP提供的API进行网络编程,例如"tcp_new()"创建TCP连接、"udp_new()"创建UDP连接等。
6. 实现数据的发送与接收:根据需求实现数据的发送和接收功能,可以使用LwIP提供的API,例如"tcp_write()"和"tcp_read()"。
7. 处理网络事件:LwIP的协议栈会触发一些网络事件,例如连接建立、数据到达等。
可以通过回调函数或者轮询的方式处理这些事件,并进行相应的操作。
需要注意的是,GD32与LwIP的使用可能会因具体芯片型号和开发环境而有所差异,因此建议参考GD32和LwIP的官方文档和示例代码,以获得更详细和准确的使用指导。
此外,如果需要更具体的例程或代码示例,建议联系GD32的官方技术支持或参与GD32的开发者社区,以获取与GD32和LwIP相关的更多资源和支持。