跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C

PetaLinux 配置 Zynq-7000 PS 端外设实战指南

在 PetaLinux 环境下配置 Zynq-7000 PS 端外设(UART、SPI、I2C、GPIO 等)的完整流程。涵盖 Vivado 硬件 IP 配置、PetaLinux 工程初始化、内核驱动编译选项设置、设备树节点修改以及系统构建部署。重点讲解了如何通过修改 system-user.dtsi 启用默认禁用的外设,并提供了常见问题的排查方法,如设备节点缺失、SPI 通信失败及 GPIO 中断未触发等场景的解决方案。

ArchDesign发布于 2026/2/6更新于 2026/7/2645 浏览

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

  1. 创建新工程,添加 ZYNQ7 Processing System IP。
  2. 双击进入配置界面,切换到'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)
  • sdio_ps_clk → 一般设为 100MHz(兼容高速 SD 卡)

🔍 小知识:Zynq 的 PS 有独立的时钟管理单元(PMC)。如果某外设时钟未开启,其寄存器将无法访问,即使设备树正确也无法工作。

导出 HDF 文件

完成配置后,执行:

Tools → Export → Export Hardware 

勾选'Include bitstream',输出.hdf 文件(通常位于 .sdk/system.hdf)。

✅ 最佳实践:每次修改 PS 配置后都重新导出 HDF,并同步更新 PetaLinux 工程,避免软硬不一致。

Step 2:PetaLinux 工程搭建 —— 让系统'认得清'硬件

有了 HDF,就可以开始构建嵌入式 Linux 系统了。

初始化 PetaLinux 项目

petalinux-create -t project --name zynq-demo
cd zynq-demo
petalinux-config --get-hw-description=/path/to/hardware/description/

第二条命令会触发 PetaLinux 解析 HDF,生成基础配置文件,包括:

  • project-spec/configs/config(系统通用配置)
  • project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi
  • 自动生成的内核与 u-boot 模板

💡 提示:不要手动编辑 system-conf.dtsi!它是自动生成的,下次 petalinux-config 可能被覆盖。所有自定义都应写在 system-user.dtsi 中。

内核配置:确保驱动编译进内核

进入内核配置菜单:

petalinux-config -c kernel

导航至以下路径并确认选项:

功能路径推荐设置
UART 驱动Device Drivers → Serial drivers → ARM AMBA PL011 FPGA modeY
SPI 驱动Device Drivers → SPI support → Xilinx SPI controllerY
I2C 驱动Device Drivers → I2C support → Xilinx I2C adapterY
SDIO/MMCDevice Drivers → MMC/SD/SDIO card support → AMD/Xilinx Zynq 7xxx/MPSoC SDHCIY
GPIO 子系统Device Drivers → GPIO Support → GPIO Support for Xilinx devicesY

❗ 强烈建议将关键驱动设为 Y(内置)而非(模块),避免因根文件系统缺少 modprobe 而无法加载。

Step 3:设备树定制 —— 给外设'发通行证'

现在来到最关键的一步:修改设备树,启用那些默认禁用的外设。

编辑文件:

vim project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi

示例 1:启用 UART1 作为用户串口

&uart1 { status = "okay"; };

就这么简单?没错。原始设备树中 uart1 节点已经存在,只是 status="disabled"。我们在这里用同名节点进行'覆盖',将其状态改为'okay'。

验证方法:

petalinux-build # 烧录后登录系统
ls /dev/ttyPS* # 应能看到 ttyPS0 和 ttyPS1

🛠 调试技巧:若看不到 ttyPS1,查看 dmesg | grep uart 是否有错误日志。常见报错如:zynq_uart e0001000.uart: no clock defined,表明 HDF 中未启用 UART1 时钟。

示例 2:挂载 W25Q32 Flash 通过 SPI0

假设你的 SPI Flash 接在 SPI0 上,片选为 CS0。

&spi0 { status = "okay"; num-cs = <1>; flash@0 { compatible = "jedec,spi-nor"; reg = <0>; // 片选索引 spi-max-frequency = <50000000>; // 最大 50MHz }; };

保存后构建系统。启动后执行:

ls /dev/mtd* # 应出现 mtd0
dmesg | grep spi # 查看是否识别到 flash 型号

⚠️ 注意:某些 Flash 芯片需要特定的 compatible 字符串。例如 MX25L 系列可用 "winbond,w25q32" 更精确匹配。

示例 3:配置 EMIO 按键输入

你想用 PL 端扩展的 GPIO 作为按键检测。

&gpio0 { status = "okay"; };
&amba_pl {
    gpio_keys {
        compatible = "gpio-keys";
        user_btn {
            label = "User Button";
            gpios = <&gpio0 54 0>; // EMIO 起始于 54
            linux,code = <0x100>; // KEY_ENTER
            debounce-interval = <20>; // 消抖 20ms
        };
    };
};

解释一下关键字段:

  • gpios = <&gpio0 54 0>:表示使用 gpio0 bank,第 54 号引脚(即 EMIO[0]),触发方式为下降沿有效(最后一个参数 0 表示 active low)
  • linux,code = <0x100>:上报事件类型为 KEY_ENTER
  • debounce-interval = <20>:软件消抖 20ms

构建烧录后:

cat /proc/interrupts | grep gpio # 检查中断是否注册
evtest /dev/input/event0 # 监听按键事件(需安装 evtest)

Step 4:构建与部署 —— 生成可启动镜像

一切准备就绪,开始构建完整系统:

petalinux-build

成功后生成两个关键镜像:

  • images/linux/BOOT.BIN:包含 FSBL、bitstream、u-boot
  • images/linux/image.ub:整合了 kernel、dtb、rootfs 的 U-Boot 镜像

打包启动文件:

petalinux-package --boot --fsbl images/linux/zynq_fsbl.elf --fpga system.bit --u-boot --force

将 BOOT.BIN 和 image.ub 拷贝至 FAT32 格式的 SD 卡根目录,插入开发板,串口连接,上电!

Step 5:现场验证与排错 —— 让外设'动起来'

系统启动后,进入第一个 Shell,立刻执行以下命令快速验证:

快速诊断四件套

# 1. 查看内核启动日志
dmesg | grep -i "uart\|spi\|i2c\|mmc"
# 2. 列出设备节点
ls /dev/ttyPS* # UART
ls /dev/spi* # SPI
ls /dev/i2c* # I2C
ls /dev/mmcblk* # SD/eMMC
ls /sys/class/gpio/ # GPIO
# 3. 检查中断注册情况
cat /proc/interrupts | grep -i "spi\|uart\|gpio"
# 4. 测试 SPI 通信(使用 spidev_test 工具)
spidev_test -D /dev/spidev0.0 -l 10

常见问题与解决方案(实战经验总结)

❌ 问题 1:/dev/ttyPS1 不存在,但 dmesg 无明显报错

排查步骤:

  1. 检查 system-user.dtsi 中是否写了 &uart1 { status = "okay"; };
  2. 检查 Vivado 中是否真的启用了 UART1 并分配了 MIO
  3. 执行 grep -r "uart1" build/tmp/work/ 查看最终合并的设备树内容
  4. 使用 devmem 0xe0001000 读取 UART1 基地址寄存器,看能否访问(非法地址会段错误)

✅ 解决方案:多数情况下是因为 HDF 旧了。重新导出 HDF,删除 PetaLinux 缓存目录(rm -rf components/plnx_workspace),再 petalinux-config --get-hw-description 重导入。

❌ 问题 2:SPI 设备识别失败,提示'No response from device'

spi_nor_read_id failed: -2

可能原因:

  • Flash 未供电或焊接虚焊
  • SCK/MOSI 等信号未输出(可用示波器测量)
  • spi-max-frequency 超过 Flash 规格(W25Q32 最高支持 104MHz,但 PCB 走线差的话建议降频至 50MHz)
  • 片选极性不匹配(有些 Flash 是低有效,有些是高有效)

✅ 解决方案:先降低频率测试:

spi-max-frequency = <10000000>; // 先试 10MHz

若能识别,再逐步提高。

❌ 问题 3:GPIO 按键无法触发中断

检查点:

  1. 是否启用了 CONFIG_GPIO_XILINX?
  2. EMIO 引脚对应的 Bank 电压是否与外部电路一致?(如 Bank 0 为 3.3V,Bank 1 为 1.8V)
  3. 是否需要内部上下拉?可通过设备树添加:
&gpio0 {
    xlnx,has-ip-reset = <0>;
    xlnx,external-intr-enable = <1>;
    xlnx,gpio-width = <64>; // 总共 64 位(MIO+EMIO)
};

也可在用户空间强制设置上下拉(需内核支持):

echo "in" > /sys/class/gpio/gpio54/direction
echo "pull_up" > /sys/class/gpio/gpio54/bias # 需 configfs 支持

工程级建议:提升稳定性和可维护性

1. 做一张 MIO 资源分配表

MIO功能备注
48UART1_RX不可复用
49UART1_TX不可复用
50SPI0_MOSI可用于普通 GPIO
………

避免后期新增功能时冲突。

2. 使用版本控制系统

将整个 PetaLinux 工程纳入 Git 管理,提交时附带说明:

git commit -m "enable spi0 and w25q32 flash, update hdf from vivado v2023.1"

3. 自动化构建脚本

编写 build.sh 简化流程:

#!/bin/bash
petalinux-build && petalinux-package --boot --fsbl images/linux/zynq_fsbl.elf --fpga ../vivado/system.bit --u-boot --force

目录

  1. PetaLinux 配置 Zynq-7000 PS 端外设实战指南
  2. 理解 Zynq 的三层控制模型
  3. 第一层:硬件固化 —— Vivado 里的 PS IP 配置
  4. 第二层:软件映射 —— 设备树(Device Tree)
  5. 第三层:运行时驱动加载
  6. Step 1:Vivado 阶段 —— 把硬件“画”清楚
  7. 启动 Vivado 并创建 Block Design
  8. 关键操作清单
  9. 时钟配置不能省!
  10. 导出 HDF 文件
  11. Step 2:PetaLinux 工程搭建 —— 让系统“认得清”硬件
  12. 初始化 PetaLinux 项目
  13. 内核配置:确保驱动编译进内核
  14. Step 3:设备树定制 —— 给外设“发通行证”
  15. 示例 1:启用 UART1 作为用户串口
  16. 示例 2:挂载 W25Q32 Flash 通过 SPI0
  17. 示例 3:配置 EMIO 按键输入
  18. Step 4:构建与部署 —— 生成可启动镜像
  19. Step 5:现场验证与排错 —— 让外设“动起来”
  20. 快速诊断四件套
  21. 1. 查看内核启动日志
  22. 2. 列出设备节点
  23. 3. 检查中断注册情况
  24. 4. 测试 SPI 通信(使用 spidev_test 工具)
  25. 常见问题与解决方案(实战经验总结)
  26. ❌ 问题 1:/dev/ttyPS1 不存在,但 dmesg 无明显报错
  27. ❌ 问题 2:SPI 设备识别失败,提示“No response from device”
  28. ❌ 问题 3:GPIO 按键无法触发中断
  29. 工程级建议:提升稳定性和可维护性
  30. 1. 做一张 MIO 资源分配表
  31. 2. 使用版本控制系统
  32. 3. 自动化构建脚本
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Python 安装与环境配置指南
  • FIS3 构建工具安装与发布指南
  • 统一大型语言模型和知识图谱:研究路线图与未来方向
  • 开源智慧云智能教育平台:支持 Web、App 及小程序全端覆盖
  • 红黑树原理与实现
  • GLPI 实战指南:开源 IT 资产与工单管理
  • 基于 DeepFace 与 OpenCV 的实时情绪分析器
  • 归并排序实战:计算右侧小于当前元素个数与翻转对
  • C++11 核心新特性解析:列表初始化、声明优化与右值引用
  • 2026 年 2 月 AIGC 行业模型发布及前沿资讯
  • B/S 架构核心原理与实战指南
  • Python dotenv 库 load_dotenv() 使用指南:环境变量管理与安全实践
  • 基于 PSO-DWA 融合的无人机三维动态避障路径规划及 MATLAB 实现
  • 基于 Spring Boot 和 WebSocket 的 Java 实时聊天室系统
  • 胸部 X 光片肺炎检测数据集:5824 张医学影像与模型训练实战
  • 2025 蓝桥杯网络安全 CTF 省赛真题详解 (Web/Misc/Crypto/Reverse)
  • coqui-ai/TTS 源码安装与 Python 高效调用实践
  • 基于大模型的 AI 销售机器人在奢侈品零售中的应用
  • Linux 进程等待机制:wait/waitpid 与僵尸进程治理
  • Python3 基础语法与核心数据类型详解

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online