软件版本:vitis2021.1(vivado2021.1)
操作系统:WIN10 64bit
硬件平台:适用AMD-XILINX A7/K7/Z7/ZU/KU系列FPGA
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,它的最大特点是使应用程序移植到其它系统时比较容易,但用在嵌入式系统中效率比较低,占用资源多。这对于我们的嵌入式应用有时是不能容忍的。
4 SOC系统工程
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约束
- 选中PROJECT MANAGERà Add SourcesàAdd or create constraints,添加XDC约束文件。
- 打开提供例程,复制约束文件中的管脚约束到XDC文件,或者查看原理图,自行添加管脚约束,并保存。
以下是添加配套工程路径下已经提供的pin脚文件。配套工程的pin脚约束文件在uisrc/04_pin路径
4.5 编译并导出平台文件
- 单击Block文件à右键àGenerate the Output ProductsàGlobalàGenerate。
- 单击Block文件à右键à Create a HDL wrapper(生成HDL顶层文件)àLet vivado manager wrapper and auto-update(自动更新)。
- 生成Bit文件。
- 导出到硬件: FileàExport HardwareàInclude bitstream
- 导出完成后,对应工程路径的soc_hw路径下有硬件平台文件:system_wrapper.xsa的文件。根据硬件平台文件system_wrapper.xsa来创建需要Platform平台。
4 搭建Vitis-sdk工程
创建soc_base sdk platform和APP工程的过程不再重复,如果不清楚请参考本章节第一个demo。
4.1 创建SDK Platform工程
- 以太网芯片使用了RTL8211FD或者YT8531,由于默认的驱动不支持,需要手动自己修改库文件。我们这里已经提供了修改好的库,解压到vivado的安装路径下的对应路径下,库文件可以从我们论坛下载 https://www.uisrc.com/t-3247.html:
- 修改好后,需要关闭vitis-sdk然后重新打开sdk,否则无法识别修改的库
- 为了创建lwip工程需要先对soc_base中的board support package简称bsp设置lwip库的支持
- 对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
文档创建者:uisrc 文档引用 个人拿来备份的
1-2-06 Microblaze LWIP以太网实现 - AMD-FPGA - UISRC工程师学习站 - Powered by uisrc.com!
评论区