ZYNQ+linux网口调试笔记(3)PL-ETH
发布时间:2025-08-24 11:10:27 发布人:远客网络
一、ZYNQ+linux网口调试笔记(3)PL-ETH
在ZYNQ上使用gigE Vision协议的网络接口相机。
第一步:调通PS侧网口GEM0(Xilinx BSP默认配好)。
第二步:调通PS侧网口GEM1(见前一篇文档:开发笔记(1))。
第三步:调通PL侧网口(本文阐述)。
第四步:在PL侧网口上验证Jumbo Frame特性,并在应用层适配gigE Vision协议。
根据《xapp1082》可知,PL侧的PHY支持1000Base-X和SGMII两种配置,这两种配置对应两种不同的PHY引脚接口(连接到MAC)。而我们的hdf文件使用的是1000Base-X的配置。
关于网口的Linux驱动,我们在官网找到一份资料: Xilinx Wiki- Zynq PL Ethernet。资料很长,我们只看与我们相关的2.4.1 PL Ethernet BSP installation for 1000Base-X”这一章节就可以了。
首先导入FPGA设计同事提供的hdf文件:
在弹出的图形界面里,进入Subsystem AUTO Hardware Settings——Ethernet Settings——Primary Ethernet,确认可以看到PL侧网络设备axi_ethernet_0,说明hdf文件里已包含了必要的网口硬件信息:
上图中被选中的网口将成为Linux上的设备eth0。这里我们默认选择ps7_ethernet_0,即使用GEM0作为首选网口。
进入Device Drivers-- Network device support–选中Xilinx AXI Ethernet(以及Xilinx Ethernet GEM,这是PS侧网口的驱动)
进入Networking support–选中 Random ethaddr if unset
进入Device Drivers-- Network device support-- PHY Device support and infrastructure–启用Drivers for xilinx PHYs
进入~~~~Device Drivers-- DMA Engine Support-–禁用~~~~Xilinx AXI DMAS Engine~~~(对应的配置项名为~~ CONFIG_XILINX_DMA~~~)
注意: Xilinx Wiki里对设备树节点的引用有误(&axi_ethernet),导致编译报错,应改为&axi_ethernet_0。
注:PL-ETH驱动所在路径:<project>/build/tmp/work-shared/plnx_arm/kernel-source/drivers/net/ethernet/xilinx/xilinx_axienet_main.c和xilinx_axienet_mdio.c。对应的内核配置项为CONFIG_NET_VENDOR_XILINX和CONFIG_XILINX_AXI_EMAC。
启用ethtool和tcpdump(调试用,非必须):
然后将生成的BOOT.BIN和image.ub拷贝到SD卡根目录下,将SD卡插入板子上,上电运行。
上电后,使用ifconfig eth1查看网口信息,观察MAC地址与设置的一致,且ifconfig eth1 192.168.1.11 up没有报错。
测试网络通路:ping PC是通的。说明网口工作正常。
Linux下eth1(即PL-ETH)的MAC地址有误
MAC地址是错的,驱动里解析出的是GEM0的MAC地址。
试验发现,即使在system-user.dtsi里不写local-mac-address,也照样解析出的是GEM0的MAC。
而将system-user.dtsi里的local-mac-address改名为pl-mac-address,并将驱动里解析的字符串也对应更改为pl-mac-address,则可以正确解析出来:
Passing MAC address to kernel via Device Tree Blob and U-Boot:
通过更改u-boot环境变量和设备树,为每个板子设置一个独特的MAC地址:
U-Boot里的环境变量ethaddr会覆盖掉设备树里pl-eth的local-mac-addr字段,从而影响Linux启动后的网卡MAC地址;
但U-Boot里的环境变量ipaddr不会对Linux启动后的配置产生任何影响。因为设备树里根本就没有关于IP地址的配置。
phy-mode怎么会是sgmii?查了下官方的提供的BSP里,也是“sgmii”。说明这个没问题。具体原因不清楚。
@TODO:设备树里的中断号的顺序如何影响功能?
为何读出来的IRQ号不对呢?这是因为这里读到的不是硬件的中断号,而是经过系统映射之后的软件IRQ number。两者不具有线性关系。
Linux上的网口eth0、eth1的顺序,似乎是按照phy地址从小到大来排布的。
Xilinx xapp1082-zynq-eth.pdf(v5.0) July 16, 2018
Xilinx Wiki- Zynq PL Ethernet:
Xilinx Wiki- Linux Drivers- Macb Driver:
Xilinx Wiki- Zynq Ethernet Performance:
查到关于Jumbo frame MTU的定义,当前值为9000,可否改大一些?
驱动源码里关于jumbo frame的说明:
设置MTU为9000,发现ping包最大长度只能设为ping 192.168.1.10-s 1472
二、安卓系统和平时的linux系统有什么不同
1、从底层来讲,linux一般是要安装在pc,pc-server,及部分小型机上的。那大体来说呢,架构属于X86-64或者安腾。
而android一般是安装在手机跟平板电脑上的。现在市面上,其CPU型号千变万化,一个厂家一个架构。而且手机跟PC的硬件也不同。必然导致其内核的不同
也就是说,从底层来讲,linux与android的内核支持架构有很大区别。即便同样是android系统本身,由于不同型号的手机,使用的硬件也不同,
所以使用的内核也就不同,这也是为什么普遍的,没一款手机几乎都有自己的底包,不能像PC那样互通。关键是由于现在的手机CPU,硬件架构没有一个同一的标准。
2、架构上内核之上的则是lib了,也就是模块。这个两者没有太大的差别。 linux的lib也是可以随便定制的。android也一样。但是lib是要依赖底包的。
3、应用的区别,lib之上是各种应用。这个可以理解为软件。这一个层面就没啥不同之处可讲了。就是一个开发问题了。
总体来说呢,android采用了linux系统的开发思想跟工作原理。 lib这个中间层很多都是照搬linux核心lib重新定制开发的。所以,说android是一种嵌入式定制的linux系统也是可以的。
三、Linux下USB设备图像采集
1、FFmpeg在Linux环境下提供了一种强大的方法来采集USB设备图像。在进行图像采集时,首先通过调用`av_find_input_format`接口来获取到`AVInputFormat`对象,然后利用`avformat_open_input`函数来启用采集设备。
2、在Linux系统中,视频采集的核心组件名为`v4l2`,即video4linux2的简称。Linux将视频设备视为设备文件,可通过`/dev/video0`路径进行访问,类似于操作普通文件。
3、为查看相机设备,有几种方法。方法一,直接使用`ls`命令查看`/dev/`目录下的设备列表。方法二,利用FFmpeg的`ffprobe`命令来查看连接到系统中的摄像头设备。通过这种方式,可获取到设备名称、裸帧格式(如`yuyv422`)、帧率(如30fps)和分辨率(如640x480)等信息。
4、在采集数据时,需要将`yuyv422`格式转换为更通用的`yuv420p`格式,随后再进行编码保存为`h264`文件。通过`ffprobe`命令查看到`video1`设备无法进行采集,这可能意味着该设备未被正确识别或配置。
5、在Linux环境下进行`v4l2`设备的交互,可以通过一系列命令实现。例如,获取设备列表、查看相机参数以及测试相机的可用性。此外,可能需要通过依赖库`libv4l2`来支持某些功能,通常需要重新编译FFmpeg,并在编译配置中加入`--enable-libv4l2`参数。
6、在进行源码开发时,需要声明并设置关键参数,如开启输入流通道、设置解码器以及配置H.264输出文件的刷新机制。还需要管理编解码缓存区,以确保数据的正确处理和传输。最终启动编解码流程,并利用SDL2进行渲染,完成整个图像采集和处理任务。