06 LWIP以太网实现

发布时间 2023-09-11 16:22:30作者: 米联客(milianke)

软件版本:vitis2021.1(vivado2021.1)

操作系统:WIN10 64bit

硬件平台:适用AMD-XILINX A7/K7/Z7/ZU/KU系列FPGA

登录"米联客"SOC|SOC社区-www.uisrc.com视频课程、答疑解惑!

1 概述

相比FPGA开发来说,使用软核可以做一些FPGA实现比较困难的事情,比如LWIP以太网传输。

Lwip 是瑞典计算机科学院(SICS)的 Adam Dunkels 开发的一个小型开源的 TCP/IP 协议栈。实现的重点是在保

持TCP 协议主要功能的基础上减少对 RAM 的占用。

LwIP 是 Light Weight (轻型)IP 协议,有无操作系统的支持都可以运行。LwIP 实现的重点是在保持 TCP 协议

主要功能的基础上减少对 RAM 的占用,它只需十几 KB 的 RAM 和 40K 左右的 ROM 就可以运行,这使 LwIP 协议栈适合在低端的嵌入式系统中使用。

lwIP 协议栈主要关注的是怎么样减少内存的使用和代码的大小,这样就可以让 lwIP 适用于资源有限的小型平

台例如嵌入式系统。为了简化处理过程和内存要求,lwIP 对 API 进行了裁减,可以不需要复制一些数据。 lwip 提供三种API:1)RAW API 2)lwip API 3)BSD API。RAW API把协议栈和应用程序放到一个进程里边,该接口基于函数回调技术,使用该接口的应用程序可以不用进行连续操作。不过,这会使应用程序编写难度加大且代 码不易被理解。为了接收数据,应用程序会向协议栈注册一个回调函数。该回调函数与特定的连接相关联,当该关联的连接到达一个信息包,该回调函数就会被协议栈调用。这既有优点也有缺点。优点是既然应用程序和 TCP/IP 协议栈驻留在同一个进程中,那么发送和接收数据就 不再产生进程切换。主要缺点是应用程序不 能使自己陷入长期的连续运算中,这样会导致通讯性能下降,原因是TCP/IP 处理与连续运算是不能并行发生的。这个缺点可以通过把应用程序分为两部分来克服,一部分处理通讯,一部分处理运算。

lwip API 把接收与处理放在一个线程里面。这样只要处理流程稍微被延迟,接收就会被阻塞,直接造成频繁丢

包、响应不及时等严重问题。因此,接收与协议处理必须分开。LwIP 的作者显然已经考虑到了这一点,他为我们提供了tcpip_input() 函数来处理这个问题,虽然他并没有在rawapi 一文中说明。讲到这里,读者应该知道 tcpip_input()函数投递的消息从哪里来的答案了吧,没错,它们来自于由底层网络驱动组成的接收线程。我们在编写 网络驱动时, 其接收部分以任务的形式创建。数据包到达后,去掉以太网包头得到 IP 包,然后直接调用 tcpip_input()函数将其 投递到 mbox 邮箱。投递结束,接收任务继续下一个数据包的接收,而被投递得 IP 包将由TCPIP线程继续处理。这样,即使某个 IP 包的处理时间过长也不 会造成频繁丢包现象的发生。这就是 lwip API。

BSD API 提供了基于open-read-write-close模型的UNIX标准API,它的最大特点是使应用程序移植到其它系统时比较容易,但用在嵌入式系统中效率比较低,占用资源多。这对于我们的嵌入式应用有时是不能容忍的。

4SOC系统工程

4.2 IP设置

 

4.2.1 AXI-DMA

 

4.2.2 axi-ethernet IP

Step4:添加 AXI Ethernet IP,设置 IP 如下,其他默认

TX Memory和RX Memory对应IP核内部的接收和发送缓存,我们这可以将这个将TX Memory和RX Memory都设为2k,缓存越大越有利于提高接收和发送的速率,另外,将TX和RX Checksum Offload全部设置为 FullChecksum Offload,这会使 IP 核完成所有收发数据包中的 TCP IP 协议首部校验和的计算功能,使处理器无需再进 行这些校验和的计算,从而提高处理器中网络协议栈的运行效率。

在独立使用单个 IP 核时,就不需要在整个系统中共享这部分逻辑

配置好后单击OK

4.2.3 axi-timer

 

4.3 设置地址分配

4.4 添加PIN约束

1:选中PROJECT MANAGERà Add SourcesàAdd or create constraints,添加XDC约束文件。

2:打开提供例程,复制约束文件中的管脚约束到XDC文件,或者查看原理图,自行添加管脚约束,并保存。

以下是添加配套工程路径下已经提供的pin脚文件。配套工程的pin脚约束文件在uisrc/04_pin路径

4.5 编译并导出平台文件

1:单击Block文件à右键àGenerate the Output ProductsàGlobalàGenerate。

2:单击Block文件à右键à Create a HDL wrapper(生成HDL顶层文件)àLet vivado manager wrapper and auto-update(自动更新)。

3:生成Bit文件。

4:导出到硬件: FileàExport HardwareàInclude bitstream

5:导出完成后,对应工程路径的soc_hw路径下有硬件平台文件:system_wrapper.xsa的文件。根据硬件平台文件system_wrapper.xsa来创建需要Platform平台。

4 搭建Vitis-sdk工程

创建soc_base sdk platform和APP工程的过程不再重复,如果不清楚请参考本章节第一个demo。

4.1 创建SDK Platform工程

1:以太网芯片使用了RTL8211FD或者YT8531,由于默认的驱动不支持,需要手动自己修改库文件。我们这里已经提供了修改好的库,解压到vivado的安装路径下的对应路径下,库文件可以从我们论坛下载https://www.uisrc.com/t-3247.html

修改好后,需要关闭vitis-sdk然后重新打开sdk,否则无法识别修改的库

2:为了创建lwip工程需要先对soc_base中的board support package简称bsp设置lwip库的支持

3:对lwip库参数修改以达到最佳性能。

本例程使用 RAW API,即函数调用不依赖操作系统。传输效率也比 SOCKET API 高,(具体可参考 xapp1026)。 对于ZYNQ将 use_axieth_on_zynq 和 use_emaclite_on_zynq 设为 0。如下图所示。对于microblaze,默认即可。

修改 lwip_memory_options 设置,将 mem_size,memp_n_pbuf,mem_n_tcp_pcb,memp_n_tcp_seg 这 4 个参数 值设大,这样会提高 TCP 传输效率。如下图所示。

修改 pbuf_options 设置,将 pbuf_pool_size 设大,增加可用的 pbuf 数量,这样同样会提高 TCP 传输效率。如下 图所示。

修改 tcp_options 设置,将 tcp_snd_buf,tcp_wnd 参数设大,这样同样会提高 TCP 传输效率。如下图所示。

修改 temac_adapter_options 设置,将 n_rx_descriptors 和 n_tx_descriptors 参数设大。这样可以提高 zynq 内部 emac dma 的数据迁移效率,同样能提高 TCP 传输效率。如下图所示。

修改完成后重新编译soc_base

特别注意:

我们例程demo使用的703FA-35T开发板硬件设计采用的是A\B网口共用MDIO、MDC控制管脚的设计方式,导致我们使用A网口做Lwip_TCP的时候,会错误的识别B网口。

这个问题产生的原因是因为我们Lwip识别网口地址的时候是从高位31位置以此递减(如下图所示),当我们递减到phy_addr = 3(B网口的addr = 011)的时候,我们系统就认为我们这就是我们绑定的A网口,就不会再递减下去。(文件路径为lwip211_v2_0\src\contrib\ports\AMD-XILINX\netif\xaxiemacif_physpeed.c )展开soc_base也能看到该文件。

我们解决这个问题的方法是额外添加了一个判断#define PHY_ADDR_CNT_UP                          1

然后添加一个if语句控制我们的phy_addr的地址为递增(A网口的addr = 001),寻址到phy_addr为1。如下图所示:

如果各位想使用B网口完成该demo,在修改XDC管脚定义的基础上,仅仅需要修改参数#define PHY_ADDR_CNT_UP0即可。如果各位的开发板网口的MDIOMDC管脚并不是共享的,那就完全没有这方面的问题,仅仅需要检查#define PHY_ADDR_CNT_UP是否为0即可。

4.2 创建lwip_tcp_echo_server工程

使用官方例程

4.3 创建lwip_tcp_perf_client工程

使用官方例程

4.4 创建lwip_udp_perf_client工程

使用官方例程

5 实验演示

5.1硬件连线

 

5.2实验结果

开始实验之前,请检查电脑防火墙是否已关闭,以及电脑端网络监管软件是否关闭(例如:360等各类杀毒软件)

5.2.1 lwip_echo_server APP实验结果

给开发板通电,连接网口, 并且根据以下步骤,设置电脑端IP地址

调试程序

打开网络调试助手,并且设置如下

单击发送数据

5.2.2 lwip_tcp_perf_client APP实验结果

给开发板通电,连接网口, 并且根据以下步骤,设置电脑端IP地址

打开网络调试助手,设置接收数据不显示,否则速度太快会卡死

调试程序

 

可以看到microblaze以太网传输千兆以太网,百兆的速度都达不到,用这个速度无法实现一些图像类的实时传输。但是可以实现一些图片,或者ADC采集数据包集中传输。

5.2.3 lwip_udp_perf_client APP实验结果

给开发板通电,连接网口, 并且根据以下步骤,设置电脑端IP地址

打开网络调试助手,设置接收数据不显示,否则速度太快会卡死

调试程序

可以看到microblaze以太网传输千兆以太网,百兆的速度都达不到,用这个速度无法实现一些图像类的实时传输。但是可以实现一些图片,或者ADC采集数据包集中传输。

6本章小结

本章节借用Microblaze成功使用了Lwip库,完成TCP协议以太网通信。