ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ZynqMP定制板BSP开发全流程:Vivado到PetaLinux的实战指南

ZynqMP定制板BSP开发全流程:Vivado到PetaLinux的实战指南 1. 拿到自定义 ZynqMP 板卡之后整个 BSP 管线是怎么运作的把定制 PCB 从贴片厂拿回来之后第一件事往往不是点灯而是让 ZynqMP 这颗 SoC 跑起 Linux。很多人以为这是个纯软件活装上 PetaLinux 敲几条命令就能出镜像实际上真正决定成败的是你打开 Vivado 之前对 PCB 原理图的审查深度。ZynqMP 不同于普通单片机PS 侧的供电时序、DDR 颗粒选型、MIO 复用方式、启动模式引脚每一样都会在后续编译和启动阶段以各种“莫名其妙”的报错来找你算账。我负责过好几个基于 XCZU3EG/XCZU7EV 的定制板项目这套流程走下来有个很明确的结论**Petalinux Vivado ZynqMP 三者是一个不可分割的闭环硬件设计阶段的疏忽会在软件阶段被放大三倍。**本文就把这套闭环从原理图一直串联到设备树把我踩过的坑和验证过的方法完整写出来给正在做 ZynqMP 定制板 BSP 的工程师一个可以直接参考的路径。1.1 从芯片 pinout 到 Linux 启动镜像的完整顺序粗略来看整个定制板 BSP 的链路是这样的PCB 原理图审查 - Vivado Block Design配置 PS、添加 PL 外设 - 引脚约束 XDC - 综合/实现/比特流 - Export Hardware生成 .xsa - PetaLinux 创建工程 - 内核/设备树/根文件系统配置 - 打包 BOOT.BIN、image.ub - 烧录到 SD / QSPI / eMMC注意这里每一步之间是强依赖关系。比特流里如果没有包含 PL 外设的信息PetaLinux 生成的设备树里就不会出现对应节点XSA 里如果没带.bitFSBL 启动时就不会配置 PL 逻辑。所以流程必须线性推进任何一步回退都可能引发连锁问题。我之前见过一个团队PCB 的二维坐标还没核对完就直接进了 Vivado结果 PS 配置对话框里选错了 DDR 类型板子回来之后 U-Boot 阶段 DDR 训练直接卡死最后只能飞线改板。这个痛苦提醒我软件再熟练也救不了硬件错误前置工作必须放在第一位。1.2 Petalinux 在 BSP 流程里到底负责哪一段Petalinux 本质上是 Yocto 的一个上层封装Xilinx 把内核、U-Boot、设备树生成器、根文件系统构建工具全部收敛成几条petalinux-*命令。它对定制板开发的核心价值有三点自动生成设备树基于 XSA 里的硬件描述把 Vivado Block Design 里的 AXI 外设、PS 外设映射成设备树节点省去手写底层节点的工作量。提供完整工具链交叉编译环境、内核补丁、U-Boot 补丁都是配好的不需要自己从零折腾 Yocto 层的依赖关系。统一的启动镜像产出一条petalinux-package --boot就能把 FSBL、比特流、ATF、U-Boot 打包成 BOOT.BIN。但 Petalinux 也有一个容易让人误判的地方它不是黑盒生成设备树和 U-Boot 配置时仍然依赖你对板卡硬件的理解。例如 DDR 的型号无法通过设备树完全描述U-Boot 阶段还是要靠硬件控制器寄存器配置来训练 DDR。所以我习惯把 Petalinux 看作“能帮你省 60% 重复劳动力的脚手架”剩下 40% 的硬件对齐工作必须自己盯着。1.3 善用官方板卡的“参考痕迹”第一次做 ZynqMP 定制板时我最推荐的做法是打开 Xilinx 官方 ZCU102/ZCU104 的原理图和 Vivado 工程作为对照。不要照抄但要看这几个维度电源树结构PS 侧的 VCCINT、VCCPSAUX、VCCPSIO 对应哪些电源芯片和时序。DDR 布局官方板的颗粒拓扑、终端电阻、VTT 电源连接方式。启动模式引脚MIO[7:0] 附近的上下拉电阻设计。PS-PL 接口BANK 电压如 PSIO_BANK50 接 3.3V 还是 1.8V对后续 XDC 的 IOSTANDARD 有直接影响。我见过很多所谓“定制板”其实只是把官方板子上的器件换了个封装或厂商但 PS 引脚的 BANK 电压改错了导致 MIO 外设死活不通。对照官方原理图并不是偷懒而是用成熟方案规避掉大量射频和信号完整性问题腾出精力去处理你自己真正定制的那部分逻辑。2. Vivado 工程搭建PS 配置不是随便点两下就完事新建工程没什么好说的但 Block Design 里添加zynq_ultra_ps_eIP 之后那六个选项卡的参数配置才是真正决定板卡能不能跑起来的地方。我见过不少人双击 IP 后直接点 OKBlock Automation 也不仔细看生成的硬件描述和 PCB 完全是两个版本后面 Petalinux 生成的设备树自然也错得离谱。2.1 创建 Block Design 时的器件选择与常见误选选器件时ZynqMP 家族的后缀很容易弄混。比如同样是 ZU3EG封装后缀SFVC784和FFVC900对应的可用 PL 引脚数量不同同样是 MPSoCCG 后缀不带 GPUEG 后缀带 GPUEV 后缀带视频编解码单元。定制板贴的是哪颗料Vivado 工程里就要选哪颗选错一拍会导致后面的write_bitstream阶段报出找不到引脚的不明错误。建完工程后创建 Block Design添加 IP搜索zynq_ultra_ps_e然后执行Run Block Automation。这时 Vivado 会基于你选择的 PS IP 自动完成大部分连接但注意 Block Automation 只会默认关联时钟和复位PL 侧的 AXI 外设需要你手动添加和连接。一个很容易踩的坑是Block Automation 生成的复位结构里外设复位是同一个peripheral_reset总线如果后续添加了多个主从接口必须在地址编辑器里手动分配地址空间否则综合阶段或者 U-Boot 阶段会出现总线访问错误。地址分配这件事虽然 Vivado 会自动提议但最好一条条核对确认外设挂到了正确的 AXI 主接口下。2.2 MIO 复用、DDR 颗粒与启动模式的三方博弈ZynqMP 的 PS 引脚里MIO 是固定的软件可配置引脚但它不是真正万能因为 UART、SD、QSPI、eMMC、USB、CAN 等控制器在 MIO 上都有固定位置。配置 PS 时对话框里的I/O Configuration页面本质上是告诉你“哪些 MIO 管脚被内部外设占用了”如果和 PCB 上实际走线对不上后面大概率是 U-Boot 阶段外设初始化失败而不是 Linux 内核阶段。以 UART 为例ZynqMP 的 UART0/UART1 对应固定 MIO 位置。PCB 画板时把 UART1 接到了 MIO 的 UART0 引脚上Vivado 里却启动了 UART0结果就是启动日志完全看不到输出。排查这一类问题其实不难但前提是你第一屏看到no UART detected时立刻去核对 MIO 分配表。DDR 方面PS 配置里要选 DDR 类型和位宽。市面上常见的 ZynqMP 定制板基本是 DDR4 x64 位宽颗粒型号五花八门。Vivado 的 DDR 配置对话框里内置了大量常见颗粒模型选错模型不会立刻导致比特流失败但会在 U-Boot 的 DDR 训练阶段暴露。我的建议是宁可先选一个同厂商同级别的近似颗粒跑通流程再根据实际调试结果微调时序参数也不要跳过这一步直接默认值。启动模式同样关键。ZynqMP 的 BootROM 在芯片上电时会采样一组 boot mode 引脚决定从 QSPI、SD、eMMC 还是 JTAG 启动。这组引脚的上下拉电阻设计在硬件阶段就要定下来Vivado 工程里虽然不需要专门配置启动模式但你要在 PetaLinux 的 U-Boot 配置里写清楚默认启动介质保证打包出来的镜像和板卡跳线一致。2.3 PL 侧外设与 XDC 约束的匹配PL 侧的引脚约束是另一个重灾区。Block Design 里添加 AXI GPIO、AXI UART、SPI 等 IP 后Vivado 不会自动给你分配管脚必须在 XDC 文件里手动指定。Xilinx 的做法是给端口命名比如 AXI GPIO 的双向引脚会导出成gpio_rtl_tri_io[0]然后在 XDC 里做三层约束管脚位置、电平标准、是否启用上拉。set_property PACKAGE_PIN AB10 [get_ports {gpio_rtl_tri_io[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {gpio_rtl_tri_io[0]}] set_property PULLUP true [get_ports {gpio_rtl_tri_io[0]}]这里有两个经验要点。第一IOSTANDARD 必须和该 Bank 的 VCCO 电压匹配比如 Bank 64 接的 3.3V就不能声明 LVCMOS18否则综合会报电压冲突。第二对于 IIC 这类需要开漏输出的信号如果硬件上没有外部上拉电阻XDC 里最好声明PULLUP true否则 Linux 内核里 i2c 探测会超时。我自己的习惯是每画完一块板子就把所有 PL 引脚用到的 BANK、VCCO 电压、参考网络全部整理成一个 Excel 表然后拿这个表和 XDC 逐行比对。听着繁琐但它能直接把“板子回来才发现引脚挪了”的概率降到零。2.4 BD 里的 IP 添加与地址分配添加多个 AXI 外设时很多人图快会在 IP Catalog 里双击一次就加一个然后再双击再添加。这样虽然能加但每次都要重命名 IP 实例连接时钟和复位效率很低。更好的做法是第一次添加时把所有需要的 IP 都拖进来统一重命名再统一连接。连接完引脚后必须打开Address Editor给每个 AXI 外设分配地址。我之前在新板上忘记给 AXI UART 分配地址结果 Linux 内核启动时访问到错误地址然后直接触发 Data Abort。这类问题在仿真里很难发现到了真机上就表现为内核 panic非常难排查。Block Design 做完后记得到Validate Design跑一下规则检查它可以提前指出不少连线错误。然后右键生成 HDL Wrapper选Let Vivado manage wrapper and auto-update后面每次改动 BD重新生成 wrapper 都会自动更新避免手改 wrapper 出低错。3. 生成比特流失败先按这三个方向排查做过 FPGA 的人都有体会Vivado 里最煎熬的环节就是点下Generate Bitstream之后等了十几分钟或半小时突然弹出一个红字[Vivado 12-7878] ERROR: Bitstream generation failed。这个报错信息本身没什么营养真正有用的信息都在日志文件里。针对定制板场景我总结了三个必查方向。3.1 从 runme.log 的报错行反推问题类别运行目录下project.runs/synth_1/runme.log和project.runs/impl_1/runme.log是排查的主战场。用文本编辑器打开后直接搜索ERROR、CRITICAL WARNING和[Place]关键字。ERROR: [Place 30-574] Poor placement for routing between an IO pin and BUFG ERROR: [Place 30-628] IO placement failed due to mismatched IOSTANDARD ERROR: [Common 17-55] set_property expects at least one objectPlace 30-574这类的错误在定制板上极其常见。原因通常是外部输入时钟没有经过全局时钟缓冲或者某个 IO 直接连到 BUFG 的方式不合法。解决思路不是强行改逻辑而是正确插入时钟 IP 或把时钟输入组合到 BUFG 后再用。Common 17-55一般是 XDC 语法问题最常见的是引脚列表写错了。比如get_ports里引用的名字和 Block Design 导出的端口名不一致会导致 Vivado 认为没有这个对象进而报错。排查办法很简单到 Block Design 的 sources 里查看 wrapper 顶层端口名然后逐个对照 XDC。如果日志里出现[DRC RTSTAT-1]这样的规则检查错误通常意味着实现完成后有未连接的电平约束或时序例外。建议在综合之后先跑Report DRC把问题扼杀在早期。3.2 时钟专用路由警告的处理套路定制板经常会用一个外部有源晶振给 PL 提供参考时钟。在 Vivado 里这种时钟引脚输入的信号如果直接接入逻辑很容易出现CLOCK_DEDICATED_ROUTE相关警告或错误。正确做法是在 Block Design 里添加Clocking Wizard把外部时钟引到clk_in1然后从 wizard 输出端借贷到各个模块。时钟约束也要在 XDC 里明确写上create_clock告诉 Vivado 这个引脚的频率是多少。create_clock -period 10.000 [get_ports {clk_in_p}]如果不写create_clockVivado 会把该时钟当作异步信号处理时序分析会出现大量误导性的违规报告这也是很多人“明明没动逻辑却突然时序不过”的根本原因。3.3 时序违例不能光靠压迭代次数另一种比特流失败的常见路径是布局布线后时序不收敛。新手会去调Implementation Strategy里的优化等级甚至把Extra Timing Opt从默认加到最大但这只能治标。定制板场景下时序违例往往对应真实的硬件设计问题比如某个 PL 信号走线过长、扇出过高、跨时钟域没有做同步或者外部时钟约束写错了频率。我一般会先打开report_timing_summary看违例路径集中在哪些模块再回到工程里检查该模块的时钟关系和逻辑层级。如果原时钟确实没问题只是某个扇出极大的复位网络拖了后腿可以在 XDC 里借助set_property MAX_FANOUT 32约束一下关键信号或者改用全局复位网络例如proc_sys_resetIP 的输出。这类问题在定制板上属于正常迭代但持续多轮时序不收敛就要回头查硬件设计了。4. 从 XSA 到 Petalinux 的第一次成功引导比特流生成成功只是让 FPGA 侧“能跑”Linux 要跑起来还得靠 Petalinux 在软件侧做同样完整的闭环。通常我在 Vivado 里做完整实现后会先File - Export Hardware勾上Include bitstream生成一个.xsa文件然后把这个文件交给 Petalinux 工程。4.1 XSA 与 HDF 的区别Vivado 2019.2 之后的版本硬件描述文件统一改成了.xsa老版本用的.hdf已经不再推荐。XSA 本质上是一个 ZIP 包里面包含了硬件描述、驱动信息、比特流等。可以用下面的命令确认 XSA 是否完整unzip -l design_1_wrapper.xsa如果里面同时能看到.hwh文件和比特流数据就说明导入 PetaLinux 时FSBL 阶段会正确加载 PL 逻辑。要是你导出的时候漏勾了Include bitstream那么这个包里没有比特流后续 U-Boot 启动时 PL 侧外设全部不会被初始化Linux 内核访问 PL 寄存器时只能读到全零或随机值。4.2 创建 Petalinux 工程与硬件描述导入接下来就是老熟脸了source /tools/Xilinx/Vivado/2020.2/settings64.sh source /tools/Xilinx/PetaLinux/2020.2/settings.sh petalinux-create -t project --template zynqMP -n zynqmp-custom cd zynqmp-custom petalinux-config --get-hw-description ../hardware/design_1_wrapper.xsa命令跑完会弹出配置菜单。这里通常需要关注三个地方Subsystem AUTO Hardware Settings - U-Boot - U-Boot Configuration确认启动介质是 SD、QSPI 还是 eMMC。DTG Settings设备树生成器使用的硬件描述。Image Packaging Configuration根文件系统的格式。默认配置能覆盖很多常见场景但定制板往往要改 U-Boot 的启动参数比如修改 bootargs 里的 console 终端号。ZynqMP 的 console 通常配置为ttyPS0如果你在 Vivado 里启用的 UART 对应的设备号不同内核起来后 console 就没输出。4.3 内核配置的常用选项执行petalinux-config -c kernel会进入内核的 menuconfig。定制板场景下我通常会重点检查这几项Device Drivers - Character devices - Serial: 确认 UART 驱动被编进内核。Device Drivers - SPI/I2C/GPIO: 确认 Block Design 里用到的外设驱动开启。File systems: 如果用 SD 启动确认 EXT4 和 VFAT 支持。Networking: 如果是网口调试确认对应 PHY 驱动是built-in。很多人的误区是“反正 PetaLinux 默认内核配置很全不需要改”。实际上默认配置面向的是 Xilinx 官方板子你的定制板 PHY 芯片、WiFi 模块、音频 Codec 都可能不在默认内核里。另外如果 PHY 驱动是内核模块而根文件系统还没起来网络就不可用这会陷入鸡生蛋的困境。所以调试阶段尽量把外设驱动编入内核量产阶段再考虑模块化。4.4 打包 boot 镜像PetaLinux 构建完成后目录下会有一堆产物真正需要打包的是petalinux-build petalinux-package --boot \ --fsbl images/linux/zynqmp_fsbl.elf \ --fpga images/linux/design_1_wrapper.bit \ --u-boot --force这条命令生成 BOOT.BIN里面依次放进 FSBL、比特流、ATF 和 U-Boot。SD 卡启动时只需要准备两个分区一个小 FAT 分区放 BOOT.BIN、image.ub 和 boot.scr另一个 EXT 分区放根文件系统。烧录后接上串口如果能看到 U-Boot 的版本号基本说明 BOOT.BIN 链路已经通了。之后 U-Boot 会加载 image.ub 里的内核和设备树然后拉起根文件系统。第一次启动如果卡在Starting kernel ...大概率是设备树里 console 或内存参数不对这部分就得进入设备树调试的环节。5. 设备树才是 PCB 外设在 Linux 里的“户口簿”Petalinux 构建时设备树生成器会根据 XSA 自动生成一套设备树但这套自动生成的东西并不完美。它只保证“Block Design 里有的节点被创建”至于外设的电气属性、板级扩展芯片、引脚默认状态都需要你手动补全。对定制板来说设备树工作是必须经历的阶段。5.1 自动生成设备树为何还要手动改PetaLinux 生成的设备树位于components/plnx_workspace/device-tree/device-tree/核心文件有这几个system-top.dts顶层入口包含内存、启动参数和板级信息。pl.dtsiPL 侧外设的自动生成节点比如 AXI GPIO、AXI UART、SPI。pcw.dtsiPS 配置的镜像描述。system-user.dtsi专门留给用户覆盖和追加的文件。Petalinux 构建时会重新生成这些文件所以直接改pl.dtsi是没用的下次构建会被覆盖。正确的改法是编辑project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi这个文件会被合入最终设备树。我做过一个大意的事直接在pl.dtsi里把 AXI SPI 的status改成了disabled结果重新构建后pl.dtsi被覆盖启动时节点又变成okay外设和 Linux 驱动同时探测互斥浪费了整整一天。所以结论很简单永远只在system-user.dtsi里做板级修改。5.2 自定义外设注册实例假设定制板上有一个 SPI 接口的 ADC挂在 PS 的 SPI0 或其他 AXI SPI 控制器下且片选为 0。设备树里要做的就是给 SPI 控制器追加子节点spi0 { status okay; spidev0: spidev0 { compatible spidev; reg 0; spi-max-frequency 1000000; }; };如果是 I2C 外设类似地追加子节点并填充地址、兼容性字符串。注意如果外设没有明确的 compatible 驱动Linux 可能会提示of: modalias之类的问题一般测试阶段用spidev是没问题的量产阶段就必须换成真正的驱动 compatible。GPIO 方面如果 Block Design 里用的是 AXI GPIO IP设备树会自动生成节点出问题多半在引脚编号。ZynqMP 的 PS GPIO 自带两组控制器分别导出不同的 GPIO 编号。接线时如果一个 LED 连到了 PS GPIO调试时不能想当然拿/sys/class/gpio/gpio0去操作要先看/sys/kernel/debug/gpio里的实际映射表。5.3 用启动日志和 bus 目录验证设备树改完后重新构建启动后用三类方式验证dmesg | grep -i spi看有没有 SPI 控制器的注册信息。ls /sys/bus/spi/devices/看设备节点是否生成、地址和片选对不对。cat /proc/device-tree遍历整个设备树检查节点是否被合入。如果spidev0.0出现了但cat /sys/bus/spi/devices/spidev0.0/of_node/compatible读不到内容说明节点没有正确解析通常是 reg 地址或 compatible 写错了。这类排查不复杂但非常依赖你对硬件实际连接的理解设备树不是凭空写的它每一行都应该能和原理图上的引脚对上号。6. 环境坑集中营Ubuntu 22.04、中文路径与许可证软件开发里最烦人的不是业务逻辑而是环境问题。Petalinux 和 Vivado 这对组合对环境极其挑剔稍微有一点不干净启动阶段就会给出极具误导性的报错。下面这几个问题在我的项目里反复出现值得单开一节说。6.1 Ubuntu 22.04 下 Vivado/Petalinux 的启动问题与修复老版本 Vivado比如 2019.2、2020.2在 Ubuntu 22.04 上经常出现error while loading shared libraries: libtinfo.so.5之类的报错这是因为新版系统默认只有 libtinfo.so.6而老版本 Xilinx 工具链依赖 .so.5。解决办法有两种sudo apt install libtinfo5 libncurses5如果没有对应软件包也可以做软链接sudo ln -s /usr/lib/x86_64-linux-gnu/libtinfo.so.6 /usr/lib/x86_64-linux-gnu/libtinfo.so.5另外Vivado 2020.2 在 Ubuntu 22.04 上还可能缺少libncurses5和libtinfo5之外的一些 32 位兼容库建议把libc6-i386、lib32z1、lib32ncurses6都装上。安装完成后在终端里敲vivado能顺利弹出 GUI才算环境干净。6.2 中文路径与长路径的杀伤力Vivado 和 Petalinux 对工作路径的容忍度很低。工作目录如果包含中文、空格或者路径过长常见的报错千奇百怪许可证工具无法启动、IP 生成器崩溃、综合阶段找不到文件。Petalinux 的构建系统内部用了大量深层目录路径太长会直接触发NAME_MAX限制。我的铁律是所有工程统一放到/home/user/work/下全英文无空格目录深度控制在 5 层以内。别把工程放到桌面的“新建文件夹2”里也别用同步盘同步整个构建目录否则很快就会见识到什么叫“玄学报错”。另外安装 Vivado 本身也不要放在有中文的路径下比如D:\工具\Vivado它会引发安装时的 Java 运行时崩溃。官方安装界面虽然能正常走但编译时各种子工具会找不到动态库。6.3 Vivado 许可证与启动报错的快速自检vivado 安装时显示 a fatal error has been detected by the java runtime environment这个报错我遇到的基本都是三类原因安装目录有特殊字符、磁盘空间不足、安装过程中杀毒软件拦截了临时文件生成。处理方法是清理/tmp用管理员权限安装并且不要改默认安装路径。许可证问题集中在启动时弹[Vivado 12-531] No license found。先检查环境变量echo $XILINXD_LICENSE_FILE如果是本地 license 文件直接在 Tools - License Manager 里添加证书路径然后重启。如果是服务器浮动 license确保网络能通、端口正确。定制板项目里我一般直接申请一个本地节点锁定 license省去团队网络波动带来的开发中断。6.4 跨版本工程迁移与降级的现实方案Vivado 高版本生成的工程低版本打不开这是个老生常谈的问题。新版项目目录里的.xpr文件只是引用链接真正的 IP 版本、约束语法在低版本环境下经常无法解析。如果遇到“Vivado 工程需要进行版本降级”的情况我的建议是这样的如果只是小版本差异2020.2 - 2020.1直接改.xpr里的版本号并手动验证 IP 兼容性问题不大。如果跨大版本2023.1 - 2020.2别奢望无损降级。最可靠的方案是在高版本里导出 RTL 源码和约束在低版本里重新建立工程重新添加 Block Design。BD 部分可以用write_bd_tcl导出脚本再在新版本里执行source恢复但 IP 配置可能有兼容性差异需要逐项核对。所以一开始就要统一团队用的 Vivado/Petalinux 版本这是最省力的方案。我是从 Vivado 2023.1 降级回 2020.2 的花了一个多星期才把所有 BD 和 IP 配置对齐。教训深刻。7. 工程清理与可复现交付团队协作的真正底线Vivado 工程有个臭毛病就是目录体积越滚越大一个工程动不动几十个 GB。这其中有大量中间产物和缓存提交给同事或归档时如果不做清理光拷贝工程就要浪费小半天时间。而且这些垃圾文件还会造成版本冲突、恢复失败等问题。定制板项目通常持续几个月工程清理和可复现构建必须从一开始就建立规范。7.1 Vivado 工程里哪些目录可以放心删一个典型 Vivado 工程里这几个目录是安全删除的Vivado 重新打开时会自动重新生成project.cache project.runs project.sim project.hw project.ip_user_files但删除前要注意project.runs里保存了综合和实现结果如果删掉了下次打开工程要重新跑一遍全流程。对于已经生成比特流的收尾阶段这个问题不大。但如果你还在频繁迭代最好保留project.runs只清理.cache和.hw。**Petalinux 工程同样凶猛。**构建一次后build/目录也是好几个 GB但里面包含内核、U-Boot、根文件系统的中间产物删掉之后下次petalinux-build又要全量重建。我的做法是交付前保留images/linux/下的 BOOT.BIN、image.ub、system.dtb其他中间构建目录根据需要进行清理。7.2 用 Tcl 脚本生成工程的团队协作方案真正靠谱的工程交接不是把整个目录打包发过去而是把“如何生成工程”这件事写成脚本。Vivado 支持批处理模式一条命令就能从零重建整个工程。对于不使用 Block Design、纯 RTL 的定制板工程脚本可以非常简单set part xczu3eg-sfvc784-1e-i create_project zynqmp_custom ./build_project -part $part add_files -norecurse [glob ./src/*.v] add_files -fileset constrs_1 ./constraints/top.xdc set_property top top [current_fileset] synth_design -top top -part $part opt_design place_design route_design write_bitstream -force ./output/top.bit对于带 Block Design 的工程可以在精雕细琢后执行write_bd_tcl把 BD 的创建过程导成一个 Tcl 脚本。后续同事拿到脚本只需要vivado -mode batch -source scripts/build_project.tcl就能重新生成整个工程和比特流。这个方式比传几十 GB 的工程目录优雅得多也让版本管理真正落到实处。7.3 清理与备份的日常节奏我个人的工作节奏是每天下班前删除project.runs里的impl_1中间文件保留最终的.bit每周把.xpr、源码、约束、XSA 和 Petalinux 的meta-user目录提交到版本库。版本库里永远不放生成物只放“原料”。如果同事需要复现我给的标准流程是克隆代码库 - 用 Tcl 脚本重建 Vivado 工程 - 导出 XSA - 创建 Petalinux 工程并导入 - 重新 build。整个过程需要的是干净的工程环境而不是几十 GB 的存量文件。这套流程跑通之后我带的几个 ZynqMP 定制板项目交接时间从原来的三天缩短到了半天。最后再分享一个小习惯每个定制板版本的大改我都会在 Vivado 工程里放一个docs/board_rev_changelog.md把改动过的引脚、DDR 型号、启动模式变化记录下来。这个文件在后续 Petalinux 调试时价值极大。很多“重启后起不来”的诡异问题最后翻 changelog 才发现是同一个引脚被两版硬件给了不同电平标准。硬件和软件在这个流程里从来都是一件事把日志留好就是对自己项目最好的保护。
返回列表