PetaLinux 配置 Zynq-7000 PS 端外设实战指南
本文以真实项目视角,带你一步步打通'Vivado 硬件配置 → PetaLinux 系统构建 → 外设驱动加载 → 应用层验证'这条完整链路。重点解决如何让 Zynq-7000 的 PS 端外设,在 PetaLinux 下真正跑起来的问题。
理解 Zynq 的三层控制模型
Zynq-7000 的 PS(Processing System)部分虽然集成了双核 Cortex-A9 和一堆标准外设控制器,但这些外设并不是'通电即用'的。它们需要经过三个层级的协同配置才能正常工作:
第一层:硬件固化 —— Vivado 里的 PS IP 配置
这是整个流程的起点。你在 Vivado 中打开 Zynq UltraScale+ Processing System IP 核,做的每一步选择都会被固化到比特流中:是否启用 UART1?SPI0 的工作模式是 Master 还是 Slave?MIO48 接的是 UART1_RX 还是 CAN0_RX?UART 参考时钟是 50MHz 还是 100MHz?这些设置一旦生成.bit 和.hdf 文件,就不可更改。哪怕你在 Linux 里把设备树写得再完美,如果这里没开对应功能,硬件层面就是'不存在'的。
第二层:软件映射 —— 设备树(Device Tree)
Linux 内核不会主动去扫描硬件寄存器来识别外设有多少个、地址在哪。它完全依赖设备树提供的信息。PetaLinux 会根据.hdf 文件自动生成初始设备树(如 system-conf.dtsi),但它默认只启用关键外设(比如 UART0 用于调试)。其他外设节点即使存在,状态也是 status = "disabled"。所以你需要手动修改设备树,告诉内核:'这个 UART1 是真的要用了,请加载驱动。'
第三层:运行时驱动加载
当内核启动时,解析设备树,发现某个外设节点的 status = "okay" 且 compatible 属性匹配已编译的驱动模块,就会自动加载相应驱动,创建设备节点(如 /dev/ttyPS1)。但如果内核根本没有编译那个驱动(比如 CONFIG_SPI_XILINX 被设为 或 ),即使设备树写了也没用。
总结一句话:外设要工作 = Vivado 中启用 + 设备树中标记 okay + 内核中编译驱动。三者缺一不可。
Step 1:Vivado 阶段 —— 把硬件'画'清楚
这是最容易忽视却又最关键的一环。很多后期问题,根源都在这里。
启动 Vivado 并创建 Block Design
- 创建新工程,添加 ZYNQ7 Processing System IP。
- 双击进入配置界面,切换到'Peripheral I/O Pins'标签页。
关键操作清单
| 外设 | 配置要点 |
|---|---|
| UART | 勾选 UART1,并为其分配 MIO 引脚(如 MIO48=RX, MIO49=TX) |
| SPI | 勾选 SPI0,设置为主模式(Master),分配 MOSI/MISO/SCLK/SS0 |
| I2C | 勾选 I2C0,连接 EEPROM 或传感器时需外接上拉电阻 |
| SDIO | 若使用 eMMC 或 SD 卡,务必勾选,并注意电压选择(1.8V/3.3V) |
| GPIO | 使用 EMIO 扩展时,可在'GPIO'标签页中指定数量(如 4 位 LED+4 位按键) |
⚠️ 注意:每个 MIO 只能属于一个外设。如果你把 MIO48 既给了 UART1_RX 又给了 CAN0_RX,Vivado 会报错:'Pin conflict'。
时钟配置不能省!
切换到'Clock Configuration'页面,检查各外设时钟是否已使能:
- uart0_ref_clk → 推荐设为 100MHz(便于生成标准波特率)
- spi0_ref_clk → 至少 50MHz(支持高速 Flash)

