从零移植PYNQ 3.1.2到AXU15EGB开发板:软硬件协同开发实战
1. 项目概述与核心价值最近在折腾一块ALINX的AXU15EGB开发板这是一款基于Xilinx Zynq UltraScale MPSoC的高性能平台自带10G光纤、MIPI CSI-2摄像头接口资源相当给力。官方提供了基础的Petalinux系统但作为一个习惯了在Python环境下快速做算法验证和硬件交互的人我第一时间想到的就是给它移植PYNQ。PYNQ框架能让开发者用Python直接操作PL可编程逻辑侧的IP核比如DMA、视频管线等效率提升不是一点半点。然而官方PYNQ仓库的板级支持包BSP列表里并没有AXU15EGB最新的PYNQ v3.1.2也没有现成的镜像可用。这意味着一件事得自己动手从源码开始为这块板子“定制”一个PYNQ系统。这个过程说白了就是在Ubuntu环境下用Xilinx 2024.1的全套工具链Vivado, Vitis, Petalinux从一个最基础的Vivado硬件设计导出XSA文件开始到配置、编译Petalinux生成Linux内核和根文件系统最后用PYNQ的构建系统把所有东西打包成一个可以直接烧录到SD卡启动的完整镜像。听起来步骤不少但每一步拆解开来都是有迹可循的。本教程就是我这趟“踩坑”之旅的完整记录目标是为同样使用AXU15EGB或类似Zynq US MPSoC板卡的朋友提供一份可复现的、详尽的PYNQ 3.1.2移植指南。无论你是嵌入式软件工程师想拓展Python生态还是算法工程师寻求软硬件协同验证的快速平台这篇内容都能帮你把路铺平。2. 开发环境搭建与关键配置工欲善其事必先利其器。整个移植工作完全在虚拟机中进行这有利于环境隔离和复现。我使用的是Ubuntu 22.04.1 LTS桌面版宿主机的资源分配至关重要直接关系到后续编译的效率甚至成败。2.1 虚拟机与Ubuntu基础配置我的主机配置是i7-12700K/64GB RAM分配给虚拟机的资源如下8个处理器核心、24GB内存、500GB的虚拟硬盘。这里有个血泪教训内存千万别吝啬。之前试过分配12GB在并行编译Petalinux或PYNQ时系统极易因内存不足而卡死甚至导致编译进程被系统OOM内存溢出杀手强制终止。16GB是底线24GB或以上会让你整个过程从容很多。硬盘空间建议直接给到500GB因为Xilinx工具链、多个工程的源码和编译中间文件非常庞大。网络配置取决于你的主机上网方式。如果主机是网线连接虚拟机网络适配器选择“桥接模式”这样虚拟机将获得一个与主机同网段的独立IP方便后续开发板与主机之间的网络通信。如果主机用Wi-Fi则选择“NAT模式”即可。安装Ubuntu的过程比较常规使用VMware的向导即可。系统安装完成后第一件事是更换软件源以加速后续的包下载。在“软件和更新”应用中将“下载自”设置为中国的镜像源例如阿里云或清华源。接着一个影响深远但容易被忽略的设置是关闭自动更新。在“更新”选项卡中将“通知我新的Ubuntu版本”设置为“从不”同时将“自动检查更新”和“安全更新”等都先设置为“从不”。这是为了保证构建环境的绝对稳定避免在漫长的编译过程中系统自动升级某个核心库导致兼容性问题。如果安装过程中弹出更新提示直接关闭窗口不要更新。然后我们需要将Ubuntu默认的shell从dash改为bash。这是因为很多编译脚本尤其是Petalinux和PYNQ的是针对bash语法编写的使用dash可能会遇到语法错误。打开终端执行sudo dpkg-reconfigure dash在出现的图形化界面中选择“No”回车确认。最后进入系统设置找到“隐私”-“屏幕”将自动锁屏功能关闭或设置为一个极长的时间例如“从不”。这是为了防止在长时间编译时系统自动锁屏中断网络连接或某些需要图形界面交互的步骤。2.2 Petalinux 2024.1 安装与依赖处理Petalinux是Xilinx用于构建嵌入式Linux系统的工具是生成我们最终系统内核和根文件系统的核心。2024.1版本的依赖库与旧版本略有不同需要特别注意。首先更新软件包列表并安装一堆必需的依赖库。这条命令很长但建议一次性完整安装sudo apt-get update sudo apt-get install iproute2 gawk python3 python2 build-essential gcc git make net-tools libncurses5-dev tftpd zlib1g-dev libssl-dev flex bison libselinux1 gnupg wget git-core diffstat chrpath socat xterm autoconf libtool tar unzip texinfo zlib1g-dev gcc-multilib automake zlib1g:i386 screen pax gzip cpio python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev pylint安装过程可能会持续一段时间。完成后需要创建一个Petalinux的安装目录并赋予当前用户权限。假设你的用户名是alinx请替换为你自己的sudo mkdir -p /opt/pkg/petalinux sudo chown alinx:alinx /opt/pkg/petalinux将下载好的petalinux-v2024.1-*-installer.run安装包拷贝到Ubuntu中例如~/Downloads目录。进入该目录赋予执行权限并开始安装chmod 755 ./petalinux-v2024.1-*-installer.run ./petalinux-v2024.1-*-installer.run -d /opt/pkg/petalinux/安装程序会启动一个文本界面需要你阅读并同意许可协议按回车翻页按q退出阅读然后输入y同意。安装路径就指定为我们刚才创建的/opt/pkg/petalinux。安装完成后非常重要的一步是配置环境变量而且这个配置是“临时”的只对当前终端生效source /opt/pkg/petalinux/settings.sh执行后可以输入echo $PETALINUX来验证是否设置成功。请记住每新开一个终端窗口如果需要使用Petalinux命令都必须重新执行一次这条source命令。一个常见的做法是将这条命令添加到用户的~/.bashrc文件末尾这样每次登录都会自动配置但为了避免与其他环境冲突我更喜欢按需手动source。2.3 Vivado与Vitis 2024.1 安装及许可Vivado和Vitis是进行FPGA逻辑设计、IP集成以及应用开发如裸机程序的必备工具。安装包通常是一个庞大的压缩文件。解压后进入解压目录首先运行依赖库检测和安装脚本sudo ./installLibs.sh然后给安装程序添加执行权限并运行sudo chmod x xsetup ./xsetup这会启动图形化安装向导。选择“Vivado HL WebPACK”或更高版本取决于你的License并勾选Vitis。安装路径我保持默认的/tools/Xilinx/。安装完成后需要修改安装目录的权限否则普通用户运行工具可能会遇到问题sudo chmod 777 -R /tools/Xilinx/注意在生产环境中777权限过于宽松存在安全风险。这里仅为开发环境图方便。更安全的做法是将当前用户加入到tools目录所属的组并赋予组读写权限。安装完成后同样需要配置环境变量并启动Vivado验证source /tools/Xilinx/Vivado/2024.1/settings64.sh vivado 第一次启动Vivado会提示没有许可证。点击“Help - Manage License…”然后选择“Load License”定位到你拥有的*.lic许可证文件即可。如果没有许可证WebPACK版本支持部分器件通常包括Zynq系列但功能受限。最后安装下载器驱动以便后续通过JTAG给板卡下载比特流或调试cd /tools/Xilinx/Vivado/2024.1/data/xicom/cable_drivers/lin64/install_script/install_drivers/ sudo ./install_drivers3. 硬件设计Vivado工程解析与定制PYNQ系统运行在PS处理系统上但它的强大之处在于能灵活调用PL可编程逻辑资源。因此我们首先需要创建一个基础的硬件设计Vivado工程这个设计定义了PS的配置以及PS与PL之间通信的“通道”。这个工程最终会导出一个.xsa文件它包含了硬件描述信息和初始的比特流可选是Petalinux和PYNQ构建的基石。3.1 基础PS配置与关键接口使能我参考了ALINX的教程从一个最简单的“PS Hello World”工程开始。在Vivado中创建工程选择AXU15EGB对应的器件xczu15eg-ffvb1156-2-i。使用Block Design添加Zynq UltraScale MPSoC IP核。双击IP核进行配置这是最关键的一步因为它决定了PS端哪些资源对PL开放而这些设置在PYNQ系统固化后是无法再更改的。时钟配置在“Clock Configuration”中启用“PL Fabric Clocks”。这里预设了4个PL时钟FCLK我通常保持默认频率或根据后续IP核需求调整。例如给FCLK0设置100MHz作为PL侧的系统主时钟。高性能从接口AXI HP在“PS-PL Configuration - AXI Non Secure Enablement - Slave Interface”中勾选AXI HP0 FPD和AXI HP1 FPD。这是PS与PL之间进行高速数据传输如DMA的关键通道。数据位宽Data Width建议设置为128位。位宽越大理论传输带宽越高。这些HP端口之后会连接到Block Design中的AXI Interconnect。高性能主接口AXI HPM在“Master Interface”中勾选AXI HPM0 LPD。这个主接口允许PS主动访问PL侧的寄存器或存储器。数据位宽设置为32位通常足够。中断配置在“Interrupts”中启用PL-PS Interrupt Ports下的IRQ0和IRQ1。中断是PL向PS发送异步事件通知的机制对于需要PS响应PL事件的场景如DMA传输完成必不可少。保持默认的上升沿触发。GPIO、I2C、UART的EMIO引出在“I/O Configuration”中找到“GPIO”勾选“GPIO EMIO”可以将多达95个PS的GPIO引脚引出到PL侧再由PL分配具体物理引脚。同样地将I2C 1和UART 1也设置为“EMIO”。这意味着这两个外设的控制器在PS端但物理引脚连接在PL端。例如I2C1 EMIO可以用于连接板载的摄像头模块UART1 EMIO可以连接一个额外的RS-232/485转换芯片。完成这些配置后点击“OK”Vivado会自动生成这些接口的外部端口。此时一个最精简的、但包含了关键高速和低速通信接口的PS配置就完成了。3.2 PL侧外设IP集成与设计思路基于AXU15EGB丰富的接口我在PL侧添加了一系列IP核来验证和利用这些硬件资源。这个设计思路可以作为你的参考模板。MIPI CSI-2接收子系统添加MIPI CSI-2 RX SubsystemIP。这是为了接收板载MIPI摄像头的数据。配置时数据格式我选了YUV422 8-bitLane数根据摄像头模组选择2行速率Line Rate设为1000 Mbps需在摄像头支持范围内。Pixels Per Clock设为2意味着每个像素时钟处理2个像素可以提高处理带宽。Shared Logic选择“Include Shared Logic in core”让IP内部处理时钟等逻辑简化外部连接。视频处理流水线MIPI数据经过解析后是AXI-Stream格式。我添加了一个Video Processing SubsystemIP并将其配置为仅做色彩空间转换Color Space Conversion Only从YUV422转换为RGB或YUV444。其Samples Per Clock需与MIPI IP的Pixels Per Clock匹配设为2。最大图像宽度和高度根据摄像头分辨率设置例如1920x1080。视频帧缓存写入添加Video Frame Buffer WriteIP其功能类似传统的AXI VDMA的写通道。它将AXI-Stream视频流转换为AXI内存映射事务通过AXI HP接口将视频帧写入PS的DDR内存中。配置时设置合适的帧缓冲数量例如3个用于乒乓操作和内存位宽与HP接口位宽匹配如128位。网络与串口添加一个AXI EthernetIP配置为1Gbps RGMII接口用于PL侧的以太网功能。添加两个AXI UART 16550IP配置其时钟为PL系统时钟如200MHz用于驱动两个额外的RS-485外设。用户IO与控制添加若干个AXI GPIOIP用于控制PL侧的LED、读取按键状态等。此外ALINX提供了一个名为Extender的自定义IP模块用于测试FMC和40pin扩展口的电气连接性通过环回测试这个模块也需要通过AXI总线连接到PS。系统互联最后使用AXI InterconnectIP将所有从设备MIPI RX Subsystem, Video Frame Buffer Write, AXI Ethernet, AXI UARTs, AXI GPIOs, Extender等的从端口Slave连接到PS的AXI HPM0 LPD主端口。同时将PS的AXI HP0 FPD和AXI HP1 FPD主端口连接到AXI Interconnect以便PS能够访问这些IP的寄存器或作为DMA的读写通道。核心提醒在这个Vivado工程中所有你希望在未来PYNQ系统中能够被Python访问和控制的PL侧IP都必须通过AXI总线正确连接到PS。一旦这个硬件设计定型并用于生成PYNQ镜像PS端开放的AXI总线接口HP, HPM, GPIO, IRQ等就固定了。未来在PYNQ系统中你可以任意重新编程PL加载新的.bit文件但新设计的PL只能使用这些预先定义好的接口与PS通信。因此在初始设计时尽量将可能用到的接口类型和数量考虑周全。设计完成后进行逻辑综合、实现并生成比特流。最后在Vivado中点击“File - Export - Export Hardware”。在弹出窗口中选择“Include bitstream”导出格式为.xsa。这个文件包含了硬件描述和PL的初始编程文件是下一步Petalinux工程的输入。4. Petalinux系统定制与BSP生成有了硬件描述文件.xsa我们就可以用Petalinux来定制一个运行在该硬件上的Linux系统了。目标是为PYNQ构建提供一个基础的、功能正常的Linux系统包BSP。4.1 工程创建与根文件系统配置在配置好Petalinux环境变量的终端中创建一个Petalinux工程cd ~ source /opt/pkg/petalinux/settings.sh petalinux-create -t project --template zynqMP -n alinx_axu15egb cd alinx_axu15egb将之前生成的.xsa文件拷贝到工程目录下然后配置硬件petalinux-config --get-hw-descriptionpath_to_xsa_directory这条命令会启动Petalinux的配置界面。这里有几个关键配置Subsystem AUTO Hardware Settings - Advanced bootable images storage settings - boot image settings将image storage media设置为primary sd。Image Packaging Configuration - Root filesystem type选择SD card。这样根文件系统将直接从SD卡的第二分区加载而不是嵌入到内核镜像里方便后续PYNQ构建系统替换为我们自己的根文件系统。DTG Settings - Kernel Bootargs - generate boot args automatically取消勾选。我们需要手动设置bootargs确保内核从正确的设备mmcblk1p2对应SD卡挂载根文件系统。不过这个设置我们稍后在设备树里修改更直接。配置完成后保存退出。4.2 设备树与内核驱动定制设备树Device Tree是Linux内核识别硬件的关键。我们需要修改系统级的设备树文件。编辑project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi/include/ system-conf.dtsi / { /* 定义几个PL侧IP可能需要的参考时钟 */ clock_ref_pcie: clk100 { compatible fixed-clock; #clock-cells 0; clock-frequency 100000000; }; clock_ref_usb0: clk26 { compatible fixed-clock; #clock-cells 0; clock-frequency 26000000; }; clock_ref_dp: clk27 { compatible fixed-clock; #clock-cells 0; clock-frequency 27000000; }; }; /* 配置PS-GTR高速收发器的参考时钟 */ psgtr { clocks clock_ref_pcie, clock_ref_usb0, clock_ref_dp; clock-names ref0, ref1, ref2; }; /* 配置QSPI Flash这里我们只使用一个分区并删除默认的其他分区 */ qspi { status okay; flash0: flash0 { #address-cells 1; #size-cells 1; compatible jedec,spi-nor; reg 0x0; partition0 { label qspi-0; reg 0x00000000 0x02000000; }; /delete-node/ partition1; /delete-node/ partition2; }; }; /* 配置SD卡接口SDHCI1禁用写保护不使能1.8V信号 */ sdhci1 { disable-wp; no-1-8-v; }; /* 配置USB控制器为HOST模式 */ dwc3_0 { status okay; dr_mode host; };关键修改点默认的Petalinux工程可能假设根文件系统在mmcblk0p2eMMC。对于AXU15EGBSD卡对应的是mmcblk1。虽然我们在system-user.dtsi里没有直接写bootargs但Petalinux的DTG设备树生成器会根据我们的配置SD card rootfs自动生成正确的bootargs指向mmcblk1p2。为了确保万无一失我们后续在PYNQ构建时还会检查一个关键文件。如果要用到板上的M.2接口连接NVMe固态硬盘需要在内核中启用NVMe驱动petalinux-config -c kernel在配置界面中导航至Device Drivers - NVME Support按y键将NVM Express block device编译进内核*。保存退出。4.3 系统编译与功能测试现在可以编译整个Petalinux工程了petalinux-build这个过程会编译U-Boot、设备树、Linux内核以及根文件系统耗时较长。编译成功后在images/linux目录下会生成关键的启动文件BOOT.BIN包含FSBL、PMU Firmware、ARM Trusted Firmware、U-Boot、boot.scrU-Boot脚本、image.ub包含内核、设备树和初始RAM磁盘以及rootfs.tar.gz根文件系统压缩包。接下来进行实地测试。准备一张SD卡将其格式化为FAT32格式在Ubuntu中可用gparted工具。将BOOT.BIN、boot.scr和image.ub拷贝到SD卡的第一个分区FAT32分区。将SD卡插入AXU15EGB开发板连接PS侧的网口、DP显示接口、UART串口到主机。主机使用串口终端工具如minicom或picocom连接波特率设为115200。开发板上电观察串口终端输出。系统启动后会提示登录。2024.1版本的Petalinux默认用户名是petalinux首次登录会要求设置密码。登录成功后进行基础功能测试网络测试输入ifconfig查看网卡是否获得IP地址如果连接了DHCP服务器。使用ping命令测试与主机的连通性。DP显示测试连接显示器由于我们没有安装桌面环境显示器会显示为一个额外的终端framebuffer console。USB测试插入U盘输入dmesg | grep usb查看内核日志中是否识别到了U盘设备。M.2 NVMe测试如果安装了NVMe SSD输入ls /dev/nvme*应该能看到/dev/nvme0等设备节点。4.4 生成BSP包及版本Bug规避确认系统基本功能正常后我们需要将其打包成BSPBoard Support Package供PYNQ构建系统使用。petalinux-package --bsp -p . --output petalinux.bsp然而在Petalinux 2024.1版本中这里可能会遇到一个已知的bug。打包过程可能会错误地将工作目录定位到系统根目录/导致权限问题而失败。错误信息可能包含“Permission denied”或路径错误。解决方法在Ubuntu的根目录下手动创建一个/build目录并赋予权限这个目录是Petalinux打包过程中某些脚本的预期工作目录。sudo mkdir -p /build sudo chmod 777 /build创建完成后再次运行petalinux-package命令应该就能成功生成petalinux.bsp文件了。将这个文件妥善保存它是我们进入PYNQ构建阶段的“门票”。5. PYNQ v3.1.2 源码构建与板级适配这是移植工作的核心阶段我们将使用官方的PYNQ源码为其添加对AXU15EGB开发板的支持并编译生成最终的SD卡镜像。5.1 获取源码与主机环境配置首先在用户目录下创建工作空间并克隆PYNQ仓库建议使用稳定版本的分支mkdir -p ~/Projects/pynq cd ~/Projects/pynq git clone https://github.com/Xilinx/PYNQ.git -b v3.1.2 cd PYNQPYNQ使用sdbuild目录下的脚本来构建镜像。首先运行主机环境配置脚本它会安装一些必要的依赖包如qemu-user-static,debootstrap等cd sdbuild/scripts ./setup_host.sh这个脚本只需要运行一次。5.2 创建板级支持文件PYNQ为每款支持的开发板在boards目录下准备了一个文件夹里面包含了该板子的配置文件。我们需要为AXU15EGB创建这个文件夹。cd ~/Projects/pynq/PYNQ mkdir -p boards/AXU15EGB将上一步生成的petalinux.bsp文件拷贝到boards/AXU15EGB/目录下。然后创建并编辑板级规格文件AXU15EGB.speccd boards/AXU15EGB touch AXU15EGB.spec gedit AXU15EGB.spec文件内容如下ARCH_AXU15EGB : aarch64 BSP_AXU15EGB : petalinux.bsp # BITSTREAM_AXU15EGB : base/base.bit FPGA_MANAGER_AXU15EGB : 1 STAGE4_PACKAGES_AXU15EGB : xrt pynq ethernet pynq_peripheralsARCH: 指定架构为aarch6464位ARM。BSP: 指定我们提供的BSP文件。BITSTREAM: 这里被注释掉了。这意味着构建的镜像不包含初始的PL比特流。PYNQ系统启动后PL部分是未编程的。你也可以取消注释并指定一个.bit文件路径这样生成的镜像在启动时会自动配置PL。FPGA_MANAGER: 设置为1启用Linux内核的FPGA管理器驱动这是PYNQ动态加载比特流.bit文件的基础。STAGE4_PACKAGES: 指定在根文件系统构建的第四阶段需要安装的软件包。xrt是Xilinx运行时库pynq是核心框架ethernet和pynq_peripherals提供了网络和基础外设支持。5.3 关键配置修改与预编译文件由于AXU15EGB的SD卡设备号是mmcblk1而许多板子是mmcblk0我们需要修改PYNQ构建系统中关于根文件系统分区的设置。编辑文件PYNQ/sdbuild/boot/meta-pynq/recipes-bsp/device-tree/files/pynq_bootargs.dtsi找到其中bootargs命令行参数里关于root的部分确保其指向/dev/mmcblk1p2。通常这个文件里可能是一个通用的变量但检查一下是必要的。在我的构建中PYNQ系统能正确识别但为了绝对可靠可以检查并修改。此外为了加速构建过程避免从网络下载所有包可以从资源链接中获取为aarch64架构预编译好的三个Debian软件包xrt.deb,pynq.deb,pynq_peripherals.deb将它们放入sdbuild/prebuilt/aarch64/目录下。构建脚本会优先使用本地预编译的包。5.4 执行构建与问题排查现在进入sdbuild目录配置好Vitis和Petalinux的环境变量开始构建cd ~/Projects/pynq/PYNQ/sdbuild source /opt/pkg/petalinux/settings.sh source /tools/Xilinx/Vitis/2024.1/settings64.sh make BOARDSAXU15EGB这个过程会持续非常长的时间数小时因为它要根据BSP构建一个基础的Linux系统。下载或使用预编译的Debian软件包构建完整的PYNQ根文件系统。将所有组件打包成一个完整的SD卡镜像文件.img。构建过程中最常见的失败原因是网络问题因为脚本会从Debian和GitHub仓库下载大量软件包和源码。如果遇到下载失败可以多次重试make命令。如果遇到其他编译错误可以尝试清理后重新构建make clean make BOARDSAXU15EGB构建成功后最终的镜像文件AXU15EGB-*.img会出现在sdbuild/output/目录下。6. 镜像部署、系统启动与功能验证得到.img文件后最后一步就是将其烧录到SD卡并在开发板上启动验证。6.1 镜像烧录与根文件系统扩容在Ubuntu主机上使用lsblk命令确认SD卡对应的设备节点例如/dev/sdb。务必小心不要选错设备否则可能格式化你的硬盘。使用dd命令或图形化工具如balenaEtcher进行烧录sudo dd if./AXU15EGB-*.img of/dev/sdb bs1M statusprogress convfsync烧录完成后SD卡会被分成两个分区第一个是FAT32格式的BOOT分区第二个是EXT4格式的root分区。在Windows下通常只能看到第一个分区。将SD卡插入开发板连接串口、网线和显示器可选。上电启动。观察串口输出系统启动完成后会自动以用户xilinx登录密码也是xilinx。首次启动关键步骤系统首次启动时会自动执行一个扩容脚本/usr/local/bin/resizefs.sh将root分区扩展到SD卡的最大容量。但是这个脚本默认是针对mmcblk0设备写的因此在第一次启动前我们需要在主机上修改这个脚本。在Ubuntu中重新插入烧录好的SD卡系统会自动挂载两个分区。找到root分区通常是第二个分区挂载在类似/media/username/root的路径下。导航到/usr/local/bin/目录编辑resizefs.sh文件sudo gedit /media/username/root/usr/local/bin/resizefs.sh找到文件中所有出现mmcblk0的地方将其替换为mmcblk1保存退出。然后安全弹出SD卡。现在将SD卡插入开发板上电启动。串口终端会显示启动日志并在首次启动时执行扩容操作这个过程可能需要一两分钟。6.2 PYNQ系统连接与基础测试启动完成后在串口终端输入ifconfig查看eth0PS网口获取到的IP地址。确保开发板和主机在同一个局域网内并能互相ping通。PYNQ最方便的交互方式是通过Jupyter Notebook。在主机电脑的浏览器中输入http://开发板IP地址:9090。会跳转到Jupyter Lab的登录界面用户名是xilinx密码也是xilinx。登录成功后你就进入了PYNQ的Web交互环境。在这里你可以创建Python Notebook导入pynq库并开始与硬件交互。例如可以尝试列出可用的Overlay比特流文件或读取板载的传感器信息。6.3 PL侧Overlay动态加载与DMA测试为了验证PYNQ动态配置PL的能力我们进行一个DMA环回测试。这个测试需要先准备一个简单的Vivado工程其中包含一个AXI DMA IP核其发送S2MM和接收MM2S通道通过AXI Stream互联形成一个环回。创建测试Overlay在Vivado中创建新工程添加Zynq US MPSoC IP使能至少一个AXI HP接口用于DMA和中断。然后添加AXI DMAIP配置为简单模式Scatter Gather禁用并将其S_AXI_LITE接口连接到PS的M_AXI_HPM0_LPD用于控制将M_AXI_MM2S和M_AXI_S2MM连接到PS的S_AXI_HP0_FPD用于数据传输。最后将S_AXIS_S2MM和M_AXIS_MM2S用AXI Stream接口连接器axis_combiner或直接连线环接起来。生成比特流并导出硬件包含bitstream。部署Overlay文件在开发板的PYNQ系统中通过Jupyter的文件浏览器在/home/xilinx/jupyter_notebooks目录下创建一个新文件夹例如dma_test。将Vivado工程生成的比特流文件.bit和对应的硬件描述文件.hwh上传到这个文件夹。确保两个文件的主文件名一致例如design_1_wrapper.bit和design_1_wrapper.hwh。编写并执行测试Notebook在dma_test文件夹下新建一个Jupyter Notebook.ipynb文件。测试代码通常包括以下步骤# 1. 导入pynq库 from pynq import Overlay, allocate import numpy as np # 2. 加载Overlay ol Overlay(\design_1_wrapper.bit\) # 3. 获取DMA IP对象 dma ol.axi_dma_0 # 名称需与.hwh文件中一致 # 4. 分配连续内存缓冲区用于发送和接收 input_buffer allocate(shape(1024,), dtypenp.uint32) output_buffer allocate(shape(1024,), dtypenp.uint32) # 5. 用数据填充发送缓冲区 for i in range(1024): input_buffer[i] i # 6. 启动DMA传输发送 dma.sendchannel.transfer(input_buffer) # 7. 启动DMA接收 dma.recvchannel.transfer(output_buffer) # 8. 等待传输完成 dma.sendchannel.wait() dma.recvchannel.wait() # 9. 验证数据 print(\First 10 sent:\, input_buffer[0:10]) print(\First 10 received:\, output_buffer[0:10]) if np.array_equal(input_buffer, output_buffer): print(\DMA loopback test PASSED!\) else: print(\DMA loopback test FAILED!\)逐段运行Notebook中的代码。你应该能看到发送和接收的数据一致打印出“DMA loopback test PASSED!”。这成功证明了PYNQ系统已正常运行PS可以通过Python控制PL侧的IPDMA通过AXI HP接口进行的高速数据传输功能正常。至此从零开始为ALINX AXU15EGB开发板移植PYNQ v3.1.2的全过程就完成了。你得到了一个功能完整的PYNQ系统可以在Python的便捷环境下充分利用这块MPSoC开发板的PS和PL资源进行开发和原型验证。后续你可以基于这个基础镜像安装更多的Python库开发更复杂的Overlay将其应用于图像处理、网络加速或机器学习等各个领域。整个过程中最深的体会就是耐心和细致的配置是成功的关键尤其是在处理硬件描述、设备树和构建系统适配这些环节任何一个细节的疏忽都可能导致最终系统无法启动或功能异常。