2. 调试环境搭建

Zynq 复杂系统一旦出现“上电无输出”“Linux 起不来”“PL 逻辑不响应”这类问题,能否快速定位,往往取决于调试环境是否在动手之前就已经搭好。本节把调试环境拆成两条相互独立的链路来理解:一条是控制与观测链路(JTAG、串口、以太网),用于下载、断点、打印和登录;另一条是启动介质链路(SD、QSPI),决定芯片从哪里取到 FSBL、bitstream、U-Boot 和系统镜像。两条链路在物理上共用同一块板卡,但在电气连接、工具配置和故障表现上完全不同,必须分开搭建、分开验证。

一、物理连接:先分清“调试口”和“启动口”

以常见的 Zynq-7000 开发板(如 ZC702、ZedBoard 类结构)为例,板卡上通常有以下几组接口:

  • JTAG:14 针或 20 针排针,信号为 TCK、TMS、TDI、TDO,参考电平 VREF 一般接 3.3V,GND 必须与下载器共地。若使用 Digilent/Xilinx Platform Cable USB II,需注意 VREF 由目标板提供,不要反向供电。
  • UART:Zynq PS 的 UART0/UART1 经板载 USB-UART 桥(如 CP210x、FT232)引出,典型参数 115200-8-N-1,无流控。MIO 引脚映射由 Vivado 的 PS 配置决定,例如 UART1 常映射到 MIO48/MIO49。
  • 以太网:PS 侧 GEM0/GEM1 经 RGMII 接 PHY(如 Marvell 88E1510),再经 RJ45 输出。调试时既可用于 U-Boot 的 tftp、nfs,也可用于 Linux 的 ssh、scp。
  • SD:PS 的 SD0/SD1 控制器接 microSD 卡座,注意卡座供电(3.3V)与 CD 检测引脚。
  • QSPI:PS 的 QSPI0 接板载 NOR Flash(如 16MB/32MB),用于固化 BOOT.BIN。

启动模式由 MIO[8:7] 等 strapping 引脚在上电复位时采样决定:00 为 JTAG,01 为 QSPI,10 为 SD。因此“能不能从 SD 启动”首先不是软件问题,而是拨码开关或跳线是否真的把 MIO 拉到了对应电平。上电前用万用表确认 strapping 电平,是排障中最省时间的一步。

Zynq 调试环境:控制链路与启动介质链路 主机 / 开发 PC Vivado / Vitis 硬件服务器 XSCT / xsdb 命令行 串口终端 / SSH / TFTP JTAG 下载器 TCK/TMS/TDI/TDO VREF 3.3V · 共地 USB-UART 桥 115200-8-N-1 MIO48 / MIO49 以太网 PHY RGMII · 88E1510 tftp / nfs / ssh Zynq-7000 SoC PS 处理系统 ARM Cortex-A9 ×2 UART / GEM / SD QSPI / MIO 复用 PL 可编程逻辑 bitstream ILA / VIO 调试核 AXI 互联 BootROM 启动判定 上电采样 MIO[8:7] strapping 00 → JTAG 01 → QSPI 10 → SD 加载 FSBL → bitstream → U-Boot microSD 卡 BOOT.BIN / image.ub FAT32 第一分区 QSPI NOR Flash BOOT.BIN 固化 16MB / 32MB JTAG UART ETH

二、JTAG 链路:从“能识别到芯片”开始

JTAG 是所有调试手段里最底层的一条。它的价值在于:即使板卡没有可启动镜像、串口没有任何打印,只要 PS 的 JTAG 链路正常,就能通过 xsdb 直接读写寄存器、加载 FSBL、复位 CPU。配置顺序建议如下:

  1. 安装 Vivado/Vitis 时勾选 Cable Drivers,Windows 下确认设备管理器出现 “Xilinx USB Cable”,Linux 下确认 lsusb 能看到 03fd:0008/000f 等 ID,并安装 udev 规则。
  2. 连接下载器,先只上电、不启动系统,执行 xsdb 后输入 connect,再执行 targets。正常应看到 APU、ARM Cortex-A9 MPCore #0/#1 以及 PL 的 xc7z020 等目标。
  3. 若 targets 为空或报 “no targets found”,依次检查:VREF 是否有 3.3V、TCK 是否有波形、nTRST/nSRST 是否被拉死、JTAG 时钟是否过高(可先降到 1MHz)。
  4. 识别到目标后,用 rst -system 复位,再用 fpga -file system.bit 下载 PL,用 dow fsbl.elf + con 启动 FSBL,观察串口是否出现 FSBL 打印。

这一步的意义在于把“硬件是否活着”和“启动镜像是否正确”解耦:JTAG 能识别芯片,说明 PS 供电、时钟、复位和 JTAG 物理链路没问题;此时若串口仍无输出,问题就集中在 UART 配置或 FSBL 本身。

三、串口链路:最可靠的“黑盒观测窗”

串口是 Zynq 调试中使用频率最高的观测手段。配置要点是:主机端打开对应 COM 口(Windows)或 /dev/ttyUSB0(Linux),参数 115200-8-N-1、无流控;板端确认 UART 控制器已在 Vivado 的 PS 配置中使能,且 MIO 映射与原理图一致。常见坑有两个:一是把 UART0 和 UART1 的 MIO 搞混,导致“有波形但无字符”;二是 USB-UART 桥的驱动未装,主机侧根本看不到端口。

验证方法很直接:给板卡上电,若 FSBL 正常,串口应打印类似 Xilinx First Stage Boot Loader Release 2020.2 以及后续 U-Boot 的 U-Boot 2020.01 信息。如果 JTAG 能识别芯片但串口全无输出,优先怀疑 UART MIO 映射或波特率,而不是先怀疑 DDR。

四、以太网链路:从 U-Boot 阶段就要打通

以太网在调试中的角色是“批量传输通道”。U-Boot 阶段常用 tftp 加载 image.ub 和 rootfs,Linux 阶段用 nfs 挂载根文件系统或 ssh 登录。配置时需确认:PHY 地址(MDIO 地址,常见 0 或 7)、RGMII 时序(是否加 delay)、以及主机侧 IP 规划。一个可用的示例规划是:主机 192.168.1.100/24,板卡 192.168.1.10/24,主机开启 tftp 服务并把镜像放在 /srv/tftp。

# U-Boot 下验证以太网
Zynq> setenv ipaddr 192.168.1.10
Zynq> setenv serverip 192.168.1.100
Zynq> ping 192.168.1.100
Zynq> tftpboot 0x2000000 image.ub

若 ping 不通,先看 PHY 是否 link up(mii info),再看 RGMII 是否因缺少 RX/TX delay 导致大量 CRC 错误。这类问题在 JTAG 和串口上完全看不出来,只有以太网链路本身能暴露。

五、SD 与 QSPI 启动:把镜像放到正确的位置

SD 启动的物理准备是:一张 FAT32 格式的 microSD 卡,第一分区放入 BOOT.BIN(含 FSBL + bitstream + U-Boot)和 image.ub,必要时再放根文件系统。上电前把启动模式拨到 SD(MIO[8:7]=10)。QSPI 启动则是先用 JTAG 或 SD 启动进入 U-Boot,再通过 sf probe、sf erase、sf write 把 BOOT.BIN 写入 Flash,之后把模式拨到 QSPI(MIO[8:7]=01)。

# U-Boot 下固化 QSPI(示例)
Zynq> sf probe 0 0 0
Zynq> sf erase 0 0x100000
Zynq> tftpboot 0x2000000 BOOT.BIN
Zynq> sf write 0x2000000 0 0x100000

判断启动是否成功,最直接的依据仍是串口:SD 启动应看到 FSBL 从 SD 读取镜像的打印,QSPI 启动应看到从 QSPI 读取的打印。如果两种介质都失败,而 JTAG 下载 FSBL 能跑,则问题基本锁定在启动模式 strapping 或镜像本身,而不是 PS 硬件。

建议把“JTAG 识别 → 串口有 FSBL 打印 → 以太网 ping 通 → SD 启动成功 → QSPI 固化成功”作为调试环境搭建的验收顺序。每一步只验证一件事,出现异常时就能把故障范围压缩到当前链路,而不是在多个子系统之间反复猜测。

六、工具链配置速查

链路关键工具/命令典型参数成功判据
JTAGxsdb / connect / targetsTCK ≤ 1MHz 起调列出 APU 与 PL 目标
串口PuTTY / minicom / screen115200-8-N-1出现 FSBL/U-Boot 打印
以太网ping / tftpboot / mii info192.168.1.10 ↔ .100ping 通、tftp 传输完成
SDBOOT.BIN + image.ubFAT32 第一分区串口显示从 SD 加载
QSPIsf probe / erase / write偏移 0,长度按镜像串口显示从 QSPI 加载

把这张表当作搭建时的检查清单:每完成一行,就在对应链路上做一次最小验证。调试环境的价值不在于“接了很多线”,而在于每条链路都能独立回答一个明确的问题——芯片是否活着、程序跑到哪、镜像从哪来、网络是否通。只有这些问题的答案都可控,后续的软硬件故障定位才有稳定的立足点。