Zynq-7020实战:从硬件设计到嵌入式Linux开发全流程解析

📅 发布时间:2026/7/5 5:50:20 👁️ 浏览次数:
Zynq-7020实战:从硬件设计到嵌入式Linux开发全流程解析
1. 从零认识Zynq-7020它到底是什么能做什么如果你对嵌入式开发感兴趣或者正在寻找一个既能跑Linux又能做高速硬件处理的平台那么Zynq-7020这个名字你肯定绕不开。我第一次接触它的时候感觉就像发现了一个“瑞士军刀”式的芯片它把两个强大的ARM Cortex-A9处理器核心和一大片FPGA可编程逻辑硬生生地塞进了同一个硅片里。这可不是简单地把两个芯片用电路板连起来而是真正意义上的“片上系统”SoC处理系统PS和可编程逻辑PL之间有着超高速的内部总线连接延迟极低带宽巨大。简单来说你可以把Zynq-7020想象成一个“双核大脑”加一个“万能乐高积木区”。大脑ARM核负责运行复杂的操作系统比如Linux、处理上层应用逻辑、管理网络和文件系统而旁边的乐高积木区FPGA逻辑则可以根据你的需求随时被“捏”成任何你想要的硬件电路比如一个专用的图像处理加速器、一个高速数据采集接口或者一个精密的电机控制单元。这种组合带来的最大好处就是灵活与高效的统一通用计算交给ARM确定性的、需要并行高速处理的任务则由你自定义的硬件电路来完成效率远超纯软件实现。这颗芯片特别适合那些既需要智能控制又对实时性、吞吐量有苛刻要求的场景。比如在工业自动化里ARM核可以运行人机界面和网络通信而FPGA部分则可以实时处理多个高速传感器的数据并直接控制伺服电机。在汽车领域它可以一边运行ADAS高级驾驶辅助系统的感知算法一边用FPGA实现摄像头数据的实时拼接与畸变校正。我当年用它做过一个高速数据记录仪ARM跑Linux负责数据存储和网络上传FPGA部分则被配置成一个高速的PCIe采集卡逻辑完美解决了软件采集延迟高、丢数据的老大难问题。所以无论你是嵌入式软件工程师想探索硬件加速的奥秘还是FPGA工程师希望给自己的逻辑设计找一个强大的“管家”和“窗口”Zynq-7020都是一个绝佳的起点。它模糊了软硬件的边界让你能在一个平台上完成从底层硬件到上层应用的完整设计。接下来我就带你走一遍从硬件设计到跑起Linux系统的全流程分享一些我踩过的坑和总结出来的实用技巧。2. 开发环境搭建别在第一步就卡住工欲善其事必先利其器。玩转Zynq-7020你得先准备好“家伙事儿”。主要就是Xilinx现在是AMD了官方的一套工具链。别被它的体积吓到跟着步骤来其实没那么复杂。2.1 软件工具三件套Vivado, Vitis 与 PetaLinux现在Xilinx主推的是Vitis统一软件平台但它的核心依然是我们熟悉的Vivado。对于Zynq开发我们主要需要这三样Vivado Design Suite这是硬件设计的核心。你用它在电脑上画原理图实际上是画“块设计”Block Design、写或生成FPGA逻辑Verilog/VHDL、进行功能仿真、综合、布局布线最终生成那个可以下载到芯片PL部分的比特流文件.bit。它还有个强大的IP集成器里面有很多现成的“积木块”IP核比如ARM处理器、内存控制器、UART、GPIO等你可以用鼠标拖拽的方式把它们连起来大大降低了硬件设计门槛。Vitis IDE这是软件开发环境。以前叫Xilinx SDK现在整合进了Vitis。你在这里为ARM处理器编写C/C应用程序。无论是直接在“裸机”Bare-Metal上跑还是在Linux操作系统下开发应用都在这里完成编译、调试。它和Vivado是联动的Vivado生成的硬件描述文件.xsa可以直接导入Vitis它会自动为你配置好底层的硬件驱动和库。PetaLinux Tools这是为Zynq构建定制化嵌入式Linux系统的利器。它基于Yocto项目但针对Xilinx平台做了大量优化和集成。你可以用它来配置Linux内核、设备树、根文件系统裁剪掉不需要的组件添加自己的驱动和应用程序最终生成一个可以烧录到SD卡或QSPI Flash里的完整系统镜像。安装实战建议去AMD官网下载安装包时选择“Vitis Unified Software Platform”的安装器它会让你勾选需要安装的组件。务必勾选Vivado、Vitis和PetaLinux。安装路径千万不要有中文和空格我吃过亏有些工具在带空格的路径下会出诡异错误。另外这整套工具体积巨大超过100GB请确保你的C盘或安装盘有充足空间。安装过程比较漫长泡杯茶等着就好。2.2 硬件准备选一块合适的开发板自己从头设计PCB焊接Zynq芯片对于初学者和大多数项目来说完全没必要。市面上有几款非常经典的Zynq-7020开发板它们把芯片、内存、Flash、常用接口如USB、以太网、HDMI都做好了还引出了大量扩展IO直接买来就能用。ZedBoard这是最经典的一款社区资源极其丰富。它接口齐全有HDMI输出、千兆网口、音频编解码器甚至还有FMC扩展口来接高速AD/DA子卡。适合做多媒体、通信等相对复杂的原型验证。缺点是价格稍贵。ZYBO (Zynq Board)性价比之王特别适合学生和爱好者。它保留了基本的外设USB、以太网、HDMI、音频价格亲民。虽然资源比ZedBoard少一些比如没有FMC但对于学习Zynq软硬件协同开发和运行Linux来说完全够用。我最初就是用这块板子入门的。MicroZed体型小巧更像一个核心模块适合二次集成和产品化开发。它提供了邮票孔连接器你可以把它当作一个“电脑主板”焊在自己的底板上。适合那些对尺寸有要求或者想快速推出产品的开发者。对于新手我强烈推荐从ZYBO开始。它的性价比最高学习资料和社区问题解答也很多足够你完成从硬件设计到Linux应用开发的全流程学习。买板子的时候别忘了顺便买一条Micro USB线用于串口调试和JTAG下载和一张8GB以上的Micro SD卡。3. 硬件设计初体验用Vivado“画”出你的第一块电路很多人一听到“硬件设计”就发怵觉得要写一大堆Verilog代码。其实对于Zynq的基础入门借助Vivado的图形化工具你几乎可以不用写一行HDL代码就能搭建起一个可用的硬件系统。我们来创建一个最简单的、能让ARM核跑起来的“最小系统”。3.1 创建工程与块设计Block Design打开Vivado点击“Create Project”新建工程。工程名和路径再次提醒用英文和数字。在“Project Type”页面选择“RTL Project”并勾选“Do not specify sources at this time”。在“Default Part”页面通过搜索框找到你的芯片对于ZYBO板子型号是xc7z020clg484-1。确认后完成工程创建。接下来是核心步骤——创建块设计。在左侧“Flow Navigator”窗口找到“IP INTEGRATOR”点击“Create Block Design”。给你的设计起个名字比如system。这时会打开一个空白的画布。添加Zynq处理器IP点击画布上方工具栏的“”按钮搜索“zynq”找到“ZYNQ7 Processing System”这个IP核双击添加。画布上会出现一个代表Zynq处理系统的模块。运行自动连接添加后Vivado通常会弹出一个提示问你是否要“Run Block Automation”。一定要点“OK”这个自动化操作会帮你把DDR内存控制器、时钟、复位等基本外设配置好并连接到处理系统上省去大量手动工作。双击配置Zynq核点击画布上的Zynq模块在左侧会出现“Re-customize IP”的按钮点击它进入详细配置界面。这里需要根据你的开发板进行关键设置PS-PL Configuration在“PS-PL Configuration - General - Enable Clock Resets”中确保“FCLK_RESET0_N”是使能的这会生成一个PL侧的复位信号。Clock Configuration在“Clock Configuration - PL Fabric Clocks”中勾选“FCLK_CLK0”并设置一个频率比如50MHz或100MHz。这个时钟是提供给PL部分使用的。DDR Configuration在“DDR Configuration”中根据你的板子选择正确的DDR型号。对于ZYBO通常是“MT41J128M16 JT-125”。这一步至关重要选错了系统无法启动。MIO Configuration这里配置芯片引脚复用。对于ZYBOUART0通常被映射到MIO 48, 49用于USB转串口调试。你可以保持默认或者参考板子原理图核对。 配置完成后点击“OK”。3.2 添加用户外设并连接现在我们的“大脑”和“内存”都有了再加个简单的“手脚”来互动。我们添加一个由ARM控制的LED。添加AXI GPIO IP再次点击画布“”按钮搜索“gpio”找到“AXI GPIO”IP核并添加。这个IP核提供了一个可以通过AXI总线由ARM处理器访问的通用IO接口。运行连接自动化添加AXI GPIO后Vivado会提示“Run Connection Automation”。点击它然后勾选新添加的axi_gpio_0模块的S_AXI接口。Vivado会自动帮你做三件事创建一个AXI互联Interconnect模块、把Zynq的M_AXI_GP0接口连接到互联器、再把互联器连接到GPIO的AXI从接口。同时它还会自动连接时钟和复位信号。配置GPIO双击AXI GPIO模块进行配置。在“Board”标签页你可以直接选择“LED”但更建议在“IP Configuration”里手动设置将“GPIO Width”改为4假设我们用4个LED并勾选“All Outputs”。引出外部端口我们需要把GPIO的信号引到芯片引脚上。在AXI GPIO模块的GPIO接口上右键选择“Make External”。画布上会出现一个名为GPIO_0的外部端口。创建HDL包装器设计完成后在左侧“Sources”窗口找到你的块设计如system.bd右键选择“Generate Output Products”。完成后再次右键选择“Create HDL Wrapper”。这会生成一个顶层的Verilog文件把我们的图形化设计包装起来。3.3 引脚约束与生成比特流硬件设计最后一步是告诉工具我们刚刚引出的GPIO_0信号具体对应到芯片的哪个物理引脚上。添加约束文件在“Sources”窗口右键“Constraints - constrs_1”选择“Add Sources”然后“Create File”创建一个新的XDC约束文件比如叫zybo.xdc。编写约束打开这个文件根据你的开发板原理图添加引脚位置和电平标准约束。例如对于ZYBO板上的4个LD开头的LED约束可能如下# ZYBO LED 引脚约束示例 set_property PACKAGE_PIN M14 [get_ports {GPIO_0_tri_o[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_tri_o[0]}] set_property PACKAGE_PIN M15 [get_ports {GPIO_0_tri_o[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_tri_o[1]}] set_property PACKAGE_PIN G14 [get_ports {GPIO_0_tri_o[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_tri_o[2]}] set_property PACKAGE_PIN D18 [get_ports {GPIO_0_tri_o[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_tri_o[3]}]你需要根据自己板子的原理图修改PACKAGE_PIN后面的引脚编号。生成比特流在左侧“Flow Navigator”点击“Generate Bitstream”。Vivado会开始综合、布局布线、生成最终的比特流文件。这个过程视电脑性能可能需要十几分钟到半小时。第一次运行时可能会提示“No Implementation Results Available”点击“Yes”即可。当看到“Bitstream Generation successfully completed”的提示时恭喜你硬件设计部分就完成了你得到了一个.bit文件和一个.xsa文件在project_name.runs/impl_1目录下。.bit文件用于配置FPGA逻辑.xsa文件则包含了完整的硬件描述信息是进行软件开发的桥梁。4. 裸机软件开发让ARM核“动”起来有了硬件描述文件.xsa我们就可以为ARM处理器编写程序了。我们先从最简单的“裸机”程序开始不依赖操作系统直接操控硬件这样能最直观地理解软硬件是如何协同工作的。4.1 在Vitis中创建平台与应用项目打开Vitis IDE。它可能会自动关联到你的Vivado工程如果没有你需要先创建一个工作空间Workspace。创建平台项目Platform Project平台项目代表你的硬件。点击“File - New - Platform Project”。输入项目名如zybo_platform。在“Hardware Specification”页面点击“Browse”定位并选择你刚才在Vivado中生成的.xsa文件。Vitis会解析这个文件提取出硬件信息。在“Operating System”页面选择“standalone”裸机。点击“Finish”。生成平台在“Explorer”视图里右键点击你的平台项目选择“Build Project”。这会为你的硬件生成对应的BSP板级支持包里面包含了操作GPIO、UART等外设的底层驱动库。创建应用项目Application Project点击“File - New - Application Project”。第一步选择刚才创建的平台项目zybo_platform。下一步输入应用名比如led_blink。再下一步Vitis会提供一些模板这里我们选择最基础的“Empty Application”。点击Finish。现在你会在led_blink项目的src文件夹下看到一个空的main.c文件。这就是我们写代码的地方。4.2 编写LED闪烁程序在main.c中我们可以直接调用Xilinx提供的驱动库函数来控制GPIO。代码如下#include stdio.h #include platform.h #include xgpio.h #include xparameters.h // 包含硬件参数如GPIO设备ID int main() { XGpio gpio; // GPIO驱动实例 int status; // 初始化GPIO status XGpio_Initialize(gpio, XPAR_AXI_GPIO_0_DEVICE_ID); if (status ! XST_SUCCESS) { print(GPIO Initialization Failed!\n); return XST_FAILURE; } // 设置GPIO方向为输出1表示输出0表示输入 // 第二个参数是通道号我们只有一个通道设为1 XGpio_SetDataDirection(gpio, 1, 0x00); // 0x00表示所有引脚为输出 print(Starting LED Blink Demo...\n); while (1) { // 向GPIO写入0x0F点亮所有4个LED假设高电平点亮 XGpio_DiscreteWrite(gpio, 1, 0x0F); // 延时一段时间 for (int i 0; i 10000000; i); // 简单的软件延时不精确 // 向GPIO写入0x00熄灭所有LED XGpio_DiscreteWrite(gpio, 1, 0x00); for (int i 0; i 10000000; i); } return 0; }这段代码做了几件事首先包含必要的头文件然后初始化GPIO驱动设置引脚为输出模式。在一个死循环里它交替地向GPIO写入全高电平和全低电平并辅以简单的软件延时从而实现LED的闪烁效果。注意XPAR_AXI_GPIO_0_DEVICE_ID这个常量是在xparameters.h中自动生成的它对应我们在Vivado块设计中添加的AXI GPIO IP核。如果你在设计中改了IP的名字这个常量也会变。4.3 下载与调试看到第一缕光芒编写完代码右键点击应用项目led_blink选择“Build Project”进行编译。如果没有错误就可以准备下载了。硬件连接用Micro USB线将开发板的“PROG/UART”口连接到电脑。ZYBO板子上这个口通常也负责供电。确保开发板上的启动模式跳线设置为“JTAG”模式具体请查你的板子手册。配置硬件服务器在Vitis中点击“Window - Show View - Other...”搜索并打开“Hardware”视图。点击“Open New Hardware Target”按照向导操作通常一路Next直到连接到你的板子。连接成功后在“Hardware”视图里应该能看到你的Zynq设备。下载硬件比特流在“Hardware”视图里右键点击你的设备选择“Program Device”。在弹出的对话框中确保“Bitstream”一栏指向你Vivado工程生成的.bit文件。点击“Program”。这时FPGA的逻辑部分就被配置好了我们设计的包含GPIO的硬件电路已经运行在芯片里。下载并运行软件回到“Explorer”视图右键点击你的led_blink应用项目选择“Run As - Launch on Hardware (Single Application Debug)”。Vitis会自动将编译好的可执行文件.elf下载到Zynq的DDR内存中并开始执行。如果一切顺利你应该能看到开发板上的LED开始有规律地闪烁同时在Vitis的“Console”视图里你应该能看到“Starting LED Blink Demo...”这行打印信息通过UART输出。这是你第一次完成Zynq的软硬件协同“闭环”意义重大。如果LED没亮首先检查引脚约束是否正确硬件比特流是否成功下载以及代码里控制的GPIO引脚号是否对应板子上实际的LED。5. 构建嵌入式Linux系统让Zynq变身微型计算机裸机程序适合控制简单的、实时性要求高的任务但要想发挥Zynq双核ARM的全部潜力运行复杂的应用程序、使用网络、文件系统我们就需要一个操作系统。嵌入式Linux是最常见的选择。PetaLinux工具就是帮我们定制和构建这个系统的。5.1 创建与配置PetaLinux工程首先确保你的PetaLinux工具已正确安装且环境变量已设置安装时通常会自动设置。打开一个终端Linux环境或者在Windows上使用WSL或Linux虚拟机PetaLinux原生支持Linux主机。创建工程找一个合适的目录执行以下命令。这会在当前目录下创建一个名为zybo_petalinux的工程文件夹。petalinux-create --type project --template zynq --name zybo_petalinux cd zybo_petalinux导入硬件描述将之前Vivado生成的.xsa文件复制到工程目录下。然后运行以下命令让PetaLinux根据你的硬件配置内核、设备树等。petalinux-config --get-hw-description.这条命令会启动一个图形化配置界面基于ncurses。这是PetaLinux的核心配置界面。关键配置在配置界面中你需要关注几个地方Subsystem AUTO Hardware Settings这里应该已经自动识别了你的硬件平台。检查一下“Memory Settings”里的DDR容量是否正确。Image Packaging Configuration在这里可以选择根文件系统的类型。对于初学者选择“INITRAMFS”会比较简单它把根文件系统也打包进内核镜像启动时全部加载到内存中运行不需要额外的存储设备分区。对于产品你可能会选择“EXT4 (SD card)”等。DTG Settings设备树生成设置。通常保持默认即可PetaLinux会根据你的.xsa文件自动生成设备树。其他设置如内核版本、网络配置、文件系统内包含的软件包等可以后续再调整。初次使用可以先按“Exit”保存退出。5.2 定制内核与根文件系统PetaLinux的强大之处在于可以深度定制。配置Linux内核运行petalinux-config -c kernel。这会进入内核的详细配置菜单。你可以在这里启用或禁用特定的内核驱动、协议栈等。例如如果你需要USB Wi-Fi网卡就需要在这里找到对应的驱动并编译进内核或编译为模块。对于第一次尝试建议先保持默认。配置根文件系统运行petalinux-config -c rootfs。在这里你可以选择需要安装到根文件系统里的软件包。比如你可以添加openssh以便通过SSH登录添加iperf3测试网络性能或者添加python3等开发环境。这是一个按需裁剪的过程可以让你系统的体积最小化。编译整个系统配置完成后运行编译命令。这个过程会下载各种源代码包首次编译时间较长建议保持网络通畅并依次编译U-Boot启动引导程序、设备树、Linux内核和根文件系统。petalinux-build编译成功结束后所有的镜像文件都会生成在images/linux目录下。5.3 制作启动SD卡与上电启动Zynq芯片上电后会先执行芯片内部ROM的一段固化代码BootROM它根据模式引脚跳线的设置从指定的外部设备如QSPI Flash或SD卡加载第一阶段的启动代码FSBL。对于SD卡启动流程通常是BootROM - FSBL - U-Boot - Linux内核。准备SD卡将SD卡插入电脑并使用fdisk或图形化工具将其格式化为FAT32分区。注意对于ZYBO等板子启动分区必须是FAT32格式。复制启动文件将images/linux目录下的以下文件复制到SD卡的根目录BOOT.BIN这个文件是由FSBL、硬件比特流.bit和U-Boot打包而成的。注意如果你希望Linux启动时FPGA逻辑已经配置好就需要在打包BOOT.BIN时包含比特流文件。这通常在PetaLinux配置中设置。image.ub这个文件包含了设备树.dtb、Linux内核镜像Image和根文件系统rootfs.cpio.gz。这是PetaLinux默认生成的打包镜像。或者你也可以复制独立的system.dtb设备树、Image内核和rootfs.cpio.gz根文件系统但需要修改U-Boot的启动命令来分别加载它们image.ub的方式更简单。设置启动模式将开发板的启动模式跳线设置为从SD卡启动参考板子手册ZYBO通常是MIO6和MIO5的跳线设置。上电与串口连接将制作好的SD卡插入开发板用USB转串口线连接电脑和开发板的UART接口通常是Micro USB口。在电脑上打开一个串口终端软件如Putty、Minicom、Picocom设置正确的串口号在设备管理器中查看、波特率115200、数据位8、停止位1、无校验位。上电启动给开发板上电。在串口终端中你应该能看到U-Boot的启动信息滚动紧接着Linux内核开始解压、启动最后出现登录提示符。对于使用INITRAMFS根文件系统的配置登录用户名通常是root无需密码。当看到熟悉的Linux命令行提示符rootzynq:~#时那种成就感是无与伦比的。这意味着你已经成功地在Zynq-7020上运行起了一个完整的、可定制的嵌入式Linux系统。你可以运行ls、ifconfig等命令甚至可以挂载网络文件系统安装额外的软件。6. 软硬件协同实战在Linux下控制FPGA逻辑系统跑起来了但故事还没完。Zynq的精髓在于PS处理器系统和PL可编程逻辑的协同。我们如何在运行Linux的ARM核上去控制我们之前在FPGA里设计的那个LED硬件呢这就需要用到Linux的驱动模型。6.1 理解Linux下的FPGA管理在Linux中FPGA逻辑配置比特流可以被看作一种“硬件资源”。Xilinx提供了一套标准的机制来管理它FPGA Manager这是Linux内核的一个子系统负责将比特流文件.bit或.bin加载到FPGA中实现动态重配置。你可以通过/sys/class/fpga_manager下的文件节点来操作它。设备树Device Tree这是描述硬件拓扑结构的数据结构。我们的AXI GPIO外设需要在设备树中有一个节点Linux内核在启动时读取这个节点就会知道“哦这里有一个符合AXI GPIO规范的设备”并为其加载对应的驱动程序。字符设备驱动像GPIO这样的设备在驱动加载后通常会在/dev目录下生成对应的设备文件如/dev/uio0或者通过/sys/class/gpio的sysfs接口暴露给用户空间。用户程序可以通过读写这些文件来与控制硬件。6.2 更新设备树与编译内核模块首先我们需要确保设备树包含了我们的自定义IP信息。PetaLinux在导入.xsa时生成的设备树可能已经包含了基础信息但有时需要手动补充。定位设备树源文件在PetaLinux工程目录下系统级的设备树源文件通常在project-spec/meta-user/recipes-bsp/device-tree/files/目录下文件名可能是system-user.dtsi。这是用户自定义设备树片段的存放位置。添加GPIO节点编辑这个文件添加类似以下内容。具体的reg地址需要根据Vivado中AXI GPIO的地址范围来填写在Address Editor标签页查看。/ { amba_pl: amba_pl { #address-cells 1; #size-cells 1; compatible simple-bus; ranges ; axi_gpio_0: gpio41200000 { #gpio-cells 2; compatible xlnx,xps-gpio-1.00.a; gpio-controller ; reg 0x41200000 0x10000; xlnx,all-inputs 0x0; xlnx,all-outputs 0x1; xlnx,dout-default 0x00000000; xlnx,gpio-width 0x4; xlnx,tri-default 0xFFFFFFFF; }; }; };这段代码描述了一个位于地址0x41200000、宽度为4位的GPIO控制器并将其标记为输出。重新编译设备树保存文件后回到PetaLinux工程根目录运行petalinux-build -c device-tree来重新编译设备树。编译完成后新的设备树会包含在image.ub中。配置内核启用GPIO驱动确保Linux内核配置中启用了Xilinx GPIO驱动。可以运行petalinux-config -c kernel然后导航到Device Drivers - GPIO Support - Xilinx GPIO support确保其被编译进内核*或编译为模块M。6.3 编写用户空间测试程序更新系统镜像将新的image.ub复制到SD卡并启动后我们的GPIO设备就应该被系统识别了。在Linux用户空间我们有多种方式控制它。最简单的是通过sysfs。查找GPIO编号系统启动后在终端输入ls /sys/class/gpio/。你应该能看到一个名为gpiochipXXX的目录其中的XXX是GPIO控制器的基号。进入这个目录查看label文件确认它是否是我们的axi_gpio_0。导出GPIO引脚假设基号是906那么我们的4个GPIO对应的系统编号就是906, 907, 908, 909。要控制第一个LED对应906执行echo 906 /sys/class/gpio/export这会在/sys/class/gpio/下创建一个gpio906的目录。设置方向并控制echo out /sys/class/gpio/gpio906/direction # 设置为输出 echo 1 /sys/class/gpio/gpio906/value # 输出高电平LED亮 echo 0 /sys/class/gpio/gpio906/value # 输出低电平LED灭编写C程序自动化当然我们更倾向于写一个C程序。下面是一个简单的示例#include stdio.h #include stdlib.h #include unistd.h #include fcntl.h #define GPIO_EXPORT /sys/class/gpio/export #define GPIO_DIR_TEMPLATE /sys/class/gpio/gpio%d/direction #define GPIO_VAL_TEMPLATE /sys/class/gpio/gpio%d/value int main() { int gpio_base 906; // 根据实际情况修改 char path[50]; // 导出4个GPIO引脚 for (int i 0; i 4; i) { int fd open(GPIO_EXPORT, O_WRONLY); if (fd -1) { perror(open export); return 1; } dprintf(fd, %d, gpio_base i); close(fd); usleep(100000); // 稍作延迟 // 设置为输出 snprintf(path, sizeof(path), GPIO_DIR_TEMPLATE, gpio_base i); fd open(path, O_WRONLY); write(fd, out, 3); close(fd); } // 流水灯效果 while (1) { for (int i 0; i 4; i) { snprintf(path, sizeof(path), GPIO_VAL_TEMPLATE, gpio_base i); int fd open(path, O_WRONLY); write(fd, 1, 1); // 点亮当前LED close(fd); usleep(200000); // 延时200ms fd open(path, O_WRONLY); write(fd, 0, 1); // 熄灭当前LED close(fd); } } return 0; }将这个程序交叉编译使用PetaLinux工程里的SDK环境source petalinux安装路径/settings.sh然后aarch64-xilinx-linux-gcc -o led_flow led_flow.c或者直接在板子上用gcc编译如果根文件系统里安装了开发工具运行它你就能看到LED开始流水灯效果。至此我们完成了一个完整的循环从Vivado设计包含AXI GPIO的硬件 - 用Vitis编写裸机程序控制 - 用PetaLinux构建包含该硬件描述的Linux系统 - 在Linux用户空间通过标准接口控制同一个硬件。这个过程充分展示了Zynq软硬件协同开发的完整流程和灵活性。你可以在此基础上将GPIO替换成更复杂的自定义IP比如一个图像处理加速器然后在Linux应用中通过驱动向其发送数据并取回结果实现真正的硬件加速。