之前有介绍过TCP/IP协议的实现是通过轻量级LWIP协议实现的,具体在FPGA中实现又可以分为多种方式,具体如下:
![](http://xilinx.eetrend.com/files/2020-06/%E5%8D%9A%E5%AE%A2/100049805-99430-tu_8-98_lwipxie_yi_zai_fpgazhong_de_shi_xian_fang_shi_.png)
图8‑98 LWIP协议在FPGA中的实现方式
LWIP可以通过硬核实现或者软核实现,具体要看FPGA的选型,其中硬核可以通过硬核自带的GMAC通过直连PHY或者EMIO扩展到PHY都可以实现相应功能,同时硬核也可以通过AXI总线与相应的IP相连然后再同外部PHY连接实现相应功能。这部分Xilinx官方提供详细的文档xapp1306-ps-pl-ethernet-performance-lwip和测试例程,本人也会提供zynq035的测试例程。
软核MicroBlzae也可以通过AXI总线与IP相连实现相关功能,这部分Xilinx官方也提供了详细的文档xapp1026和测试例程,本人提供了K7的例程。
这里在说明一下,其实ZYNQ系列芯片也可以内部通过软核通过AXI总线实现相关功能,但是需要注意一点就是在添加MicroBlaze软核的时候一定要添加ZYNQ的硬核,否则在向SDK导入硬件工程后,通过SDK进行调试的时候,会报错,主要原因就是ZYNQ系列芯片是通过硬核进行启动的。
8.5.6.1 LWIP库移植
整个系统的实现最重要的就是LWIP的库移植,虽然Xilinx SDK 目录下面 xaxiemacif_physpeed.c 文件里面对 PHY 芯片有驱动,但是目前仅支持 MARVEL 和 TI 的部分 PHY 芯片,如果使用其他厂家的 PHY 芯片,需要更改驱动,否则协商不能通过。
另外如果使用方式不同也需要进行库文件的修改,例如通过EMIO扩展RGMII接口的应用场景,或者使用AXI接口进行通信时,下面针对几种情况进行库移植的说明。
1、将 PS 的 ENET0/ENET1 通过 EMIO 的方式扩展至 PL,在 PL 中再通过 RGMII 接口连接外部PHY 芯片。
由于 ETH 通过 EMIO 连接了GMII to RGMII 这个 IP 核,若直接使用原版 LWIP 库会存在数据收发异常的现象。
导致收发异常的主要原因在于GMII to RGMII 这个 IP 核需要MDIO接口配置其相关寄存器,如下:
![](http://xilinx.eetrend.com/files/2020-06/%E5%8D%9A%E5%AE%A2/100049805-99431-tu_8-99_gmii_to_rgmii_ip_he_ji_cun_qi_.png)
图8‑99 GMII to RGMII IP 核寄存器
PS 需要通过 MDIO 正确配置该寄存器的值,来选择当前 PHY 芯片的工作速率。而 GMII to RGMII IP 核则根据该寄存器的值来切换其于 PHY芯片连接的 RGMII 接口的时钟频率(125M、 25M、 15.5M)和数据位宽。因此,若 PS 无法正确配置该寄存器,则 IP 核将无法正常工作。
2、在 PL 中分别通过 AXI 1G/2.5G Ethernet Subsystem 和 AXI Direct Memory Access ,PS 通过 AXI总线控制这两个 IP 核实现 LWIP 网络通信或者MicroBlaze通过AXI总线实现LWIP网络通信。
由于原版LWIP库缺少当 PS 连接 AXI 1G/2.5G Ethernet Subsystem IP 核时对于 PHY芯片的配置驱动程序,若直接使用原版 LWIP 库将使 PHY芯片无法正常工作,从而无法进行数据传输。因此,需要手动修改库文件添加驱动程序。
详细的移植过程见下面例程简介。
上面提到的所有例程都可以通过官方文档和官方代码实现,还有一种偷懒的形式,就是通过搜索官方的相关开发板例程就会更简单的进行移植和测试(大部分开发板都有LWIP的测试例程)。
下一篇将针对具体芯片的Microblaze实现LWIP进行简单介绍,其他例程具体请大家参考官方文档。
其他例程列表如下:
![](http://xilinx.eetrend.com/files/2020-06/%E5%8D%9A%E5%AE%A2/100049805-99435-03.png)