Ultra96开发板深度解析:从Zynq MPSoC异构架构到动手实践

📅 2026/8/26 4:49:00
Ultra96开发板深度解析:从Zynq MPSoC异构架构到动手实践
2. 硬件与软件双引擎细看 Ultra96 的配置与外设3. 上手前需要搞懂的三个核心概念4. 实操从拿到板子到点亮一个“Hello World”5. 踩坑记录与排查速查表5.1 启动异常排查5.2 显示与网络问题5.3 电源与散热教训6. 后续可以往哪些方向挖说实话第一次拿到Ultra96的时候我的第一反应是这跟树莓派也太像了。同样巴掌大的板子同样用microSD卡启动同样有一堆USB口和视频输出口。可等我把电源接上、串口连上、看到bootlog里出现Zynq UltraScale MPSoC这几个字之后才发现这玩意儿的本质跟树莓派完全是两码事。Ultra96是Avnet和Xilinx合作推出的一块开发板核心芯片用的是Zynq UltraScale MPSoC家族的ZU3EG。它最大的特点在于一颗芯片里同时包含了一个可以完整跑Linux的四核ARM处理器系统PS以及一大片可以随心所欲改电路逻辑的FPGA可编程逻辑PL。也就是说同一块板子既能当一台“电脑”也能当一块“可以重新改线路的电路板”。这篇是《Understanding the Ultra96 Board》系列的第一篇我先不堆细节重点回答三件事这板子到底是什么、为什么值得研究、怎么让它跑起来。适合刚接触FPGA异构计算、或者从树莓派等单板计算机转过来想试试MPSoC的读者已经玩过Zynq-7000系列的老人可以直接跳到第四节看启动细节。1. Ultra96这块板子到底特殊在哪1.1 一颗芯片看懂Ultra96ZU3EG的双域架构先看最核心的芯片Xilinx Zynq UltraScale MPSoC具体型号是ZU3EG。名字里的“EG”代表这是EG系列也就是说它带了GPUMali-400但没有硬核视频编解码器。如果要一边跑AI推理一边做H.264硬件编解码就需要换EV系列那通常是ZU7EV往上走价格完全不是一个级别了。这颗芯片从架构上可以分成两大部分PSProcessing System处理器系统包含四核ARM Cortex-A5364位、双核Cortex-R5F实时处理器、Mali-400 GPU还有DDR内存控制器、USB、UART、SDIO、I2C、SPI、GigE等一系列“电脑该有的外设”。这一整个子系统可以独立启动跑完整的Linux发行版比如Ubuntu。对于跑Linux这件事来说它跟树莓派上的BCM2711没本质区别——都是ARM处理器加一堆控制器只是A53架构更老一些。PLProgrammable Logic可编程逻辑也就是FPGA的那部分ZU3EG有大约154K的逻辑单元换算下来大概相当于20多万个等效门电路。它可以被配置成任意数字逻辑寄存器、状态机、流水线、自定义的接口协议甚至是你自己设计的CPU。PL没有固定功能上电时从配置源读入bitstream跑起来之后内部就是一片专门为你这版需求定制的电路。这两部分不是两片芯片封装在一起而是同一颗die上的两个域通过内部的AXI总线互联。AXI是ARM定义的AMBA总线协议中的一个分支Xilinx把PS和PL之间的数据通路做成了标准AXI接口你只需要把PL逻辑封装成AXI外设就能被PS里的Linux读写访问就像访问一个内存映射的寄存器一样。这一点是Ultra96和其他“能跑Linux的ARM板”的根区别树莓派的CPU、GPU、外设全部是芯片厂在出厂时固定死的而Ultra96的PS侧是固定的PL侧则完全开放。一颗芯片一半是固定世界一半是可重构世界这是异构计算里非常典型的形态。1.2 板级外设逐个盘点Ultra96板子本体尺寸是85mm × 54mm左右确实跟树莓派差不多但它的外设布局很不一样。我用过的感受是这块板子的外设不是“给单板电脑用户准备的”而是“给做嵌入式和FPGA开发的人准备的”。我手上的这块是V1版板载外设大概是这样2GB LPDDR4内存和PS的DDR控制器直连带宽够用跑Ubuntu桌面系统不卡跑轻量AI推理也勉强可以。microSD卡槽最常用的启动介质。官方镜像直接烧进SD卡插上就能开机。一个USB 3.0 Type-A口一个USB Type-C口。Type-C口同时负责供电和DisplayPort视频输出DP Alt Mode这点很容易让人困惑我第一次用还以为是USB转串口结果那是电源口。板载WiFi/蓝牙模组走SDIO和UART接口Ubuntu下可以用网络管理器直接连WiFi。MIPI CSI-2摄像头接口和MIPI DSI显示屏接口用于接图像传感器和屏幕。两个Digilent PMOD兼容扩展口可以插各种PMOD外设模块从简单的拨码开关到高速ADC都有。一个板载JTAG/串口调试排针。这套外设组合的用意很明显它想让你一个板子同时搞定“Linux应用开发”“FPGA逻辑开发”和“图像视频接口调试”三件事。1.3 Part 1的目标先把系统跑起来这篇Part 1我只讲一件事让你手里的Ultra96上电、启动、进入Linux并且理解它和普通单板计算机的启动流程差异。因为很多没玩过Zynq的人第一次会卡在启动环节——它不是像树莓派那样拷个镜像插电就能跑的boot流程里面有FSBL、ATF、U-Boot、bitstream这一堆名词你要是不理解黑屏都不知道去哪儿查。等到Part 2我会专门讲PS和PL之间怎么通过AXI做第一个真正的数据通路以及如何在Linux里写驱动访问PL侧的寄存器。那是把这块板子的价值真正发挥出来的关键但前提是先把这套启动流程跑通。2. 硬件与软件双引擎细看 Ultra96 的配置与外设2.1 PS域四核A53跑Ubuntu只是基本盘Ultra96的PS侧有一颗四核Cortex-A53主频最高约1.5GHz这在今天看起来不算高但在嵌入式设备里完全够用。它的意义在于你能在FPGA板卡上跑一个完整的Ubuntu系统然后直接用gcc编译程序、用Python写脚本、用OpenCV做图像处理。这种开发体验远不是传统单片机开发那种“编译完烧进去、用串口看printf”能比的。Cortex-R5F双核实时处理器通常不跑Linux而是跑裸机代码或FreeRTOS用于那些对实时性要求高的场景比如电机控制、协议栈处理。A53跑Linux做应用和业务逻辑R5F做硬实时控制PL做高速并行处理这三层协同是Zynq UltraScale芯片的核心设计哲学。我实际用下来的感受是你在Ubuntu里写程序跟树莓派上几乎没区别。唯一要注意的是Ultra96只有2GB内存开个大一点的桌面环境、再跑个浏览器就会很紧张所以大多数时候我都是通过SSH命令行操作不接图形界面。2.2 PL域能改的电路比跑分更有意思PL域有154K逻辑单元放在高性能FPGA里算偏入门的规模但作为学习平台非常合适。它能让你自己动手搭一个小型软核CPU、做图像处理流水线、加速某个特定算法这些是ARM芯片永远做不到的。PL域没有固定的“指令集”它由查找表LUT、触发器FF、块RAMBRAM、DSP Slice等基本单元组成。你用Verilog或VHDL描述的逻辑综合工具会把它映射成这些基本单元的连接关系最后生成bitstream。这个bitstream下载到PL之后这块FPGA就变成了你设计的那块电路。我建议新手第一件事不是跑分而是写一个最简单的计数器模块接到PMOD引脚的LED上看着它按你设定的速率闪烁。这件事虽然简单但能让你真正理解“PL里的逻辑是并行的多个always语句是同时执行的”这个核心概念。2.3 双域互联AXI总线到底是什么PS和PL之间通过AXI接口通信。Xilinx在这个体系里提供几种接口类型AXI-GP通用目的接口带宽不高适合控制类访问比如配置寄存器。AXI-HP高性能接口带FIFO缓冲适合大批量数据传输比如DMA往DDR里写数据。AXI-ACP一致性接口可以直接访问PS侧cache适合需要缓存一致性的场景。用生活化的类比来解释PS和PL是两个国家各自有自己的地盘和资源。AXI就像一条连接两国的海关通道GP通道是只允许小包裹通过的普通货运道HP通道是专门走集装箱的港口码头ACP通道则是可以免检直达对方仓库的VIP通道。不同类型的业务走不同的通道效率完全不同。Ultra96上做第一个PL外设通常就是从AXI-GP通道接一个AXI GPIO模块开始的。PS把PL侧的寄存器映射到自己的地址空间里Linux驱动里直接往某个地址写值PL侧的LED就亮了这个过程中数据的流向就是通过AXI总线完成的。这个路线非常直观也最容易验证。3. 上手前需要搞懂的三个核心概念3.1 Boot ROM、FSBL和U-Boot各司其职Zynq芯片上电后片内的BootROM先运行然后从启动介质SD卡、QSPI Flash等加载FSBLFirst Stage Boot Loader。FSBL的主要工作包括初始化DDR、配置PS侧的时钟、根据需要把PL的bitstream加载进去最后跳转到下一个启动阶段——也就是ATFARM Trusted Firmware和U-BootU-Boot再加载Linux内核。理解这条链路很重要。因为如果你改了PL侧的启动PL配置或者是DDR初始化参数有问题系统可能就卡在FSBL阶段表现出来就是串口没有任何输出或者停在某个特定地方不动了。很多新手以为板子坏了其实只是配置文件不对。3.2 什么是XSA和硬件平台文件在Vivado里做完PL设计、生成bitstream之后还要导出一个叫XSA的文件。XSA就像一张“硬件图纸”它把你PS侧的配置、PL侧的bitstream、地址映射信息全部打包到一起。Vitis工具链导入这个XSA后才知道CPU跑在什么频率、DDR怎么初始化、外设地址在哪里、PS和PL之间有哪些接口。这个文件是整个Vivado/Vitis流程的中枢。我见过太多人卡在“导出到Vitis后找不到硬件平台”的问题基本就是XSA没有导出或者导错版本了。3.3 Ultra96到底怎么启动从SD卡到Linux以最常见的SD卡启动为例整个流程是制作一个包含BOOT.BIN和image.ub等文件的SD卡启动分区。上电后BootROM从SD卡读取启动镜像。FSBL初始化DDR、加载PL bitstream。U-Boot加载Linux内核和设备树。Linux启动出现登录提示或桌面系统。BOOT.BIN通常由FSBL、PMU固件、ATF、U-Boot打包而成。如果你用官方提供的Ubuntu镜像这些都已经帮你做好了。如果你自己从源码构建BSP就要用PetaLinux或者手动编译来生成这些文件过程会繁琐不少但也能学到更多底层细节。对于多数想快速上手的人来说直接用官方镜像就是最省事的方式。先跑起来后面再慢慢深入构建流程。4. 实操从拿到板子到点亮一个“Hello World”4.1 准备清单和工具需要的硬件Ultra96开发板一块USB Type-C电源适配器规格必须是12V/2A的PD电源。普通5V手机充电头插上去可能没反应这是很多人的第一个坑microSD卡建议Class 10或A1以上容量8GB以上就够了一条支持DP Alt Mode的USB Type-C转HDMI线或Type-C转DP线用来接显示器USB转TTL串口模块用于看启动日志也可以直接用板载调试串口如果要用WiFi或蓝牙盒子里的天线要装好软件方面需要准备balenaEtcher之类的烧录工具和一个终端工具比如MobaXterm、PuTTY或者macOS/Linux下的minicom。4.2 烧录官方镜像去Avnet或者Xilinx的官方资源页找Ultra96的Ubuntu镜像也可以直接用PYNQ镜像看你想怎么用。PYNQ的好处是内置了Jupyter Notebook环境能直接用Python配置PL很适合快速验证想法。原生Ubuntu则更接近标准Linux开发环境。烧录步骤很简单把SD卡插入读卡器打开balenaEtcher选择镜像文件选择SD卡点Flash。等它写完并校验通过就完成一大半了。有命令行习惯的话也可以用dd但Etcher会校验写入结果更稳妥。4.3 第一次上电看启动日志把烧好的SD卡插入Ultra96接好串口模块再把12V PD电源插上。打开串口终端设置波特率1152008N1然后上电。你会看到类似下面的启动日志序列BootROM - FSBL - ATF - U-Boot - Linux内核。正常会走到Ubuntu登录界面或者串口出现login提示。默认用户名和密码官方文档里有常见是ultra96或ubuntu等以你下载的镜像说明为准。进入系统之后第一件事是ifconfig或ip addr看网络地址然后SSH远程登录以后就不用一直挂着串口了。如果你接的是DP转HDMI显示器显示器能点亮桌面的话就更直观了。桌面环境跑起来后打开终端输入uname -a看到带xilinx字样内核版本就说明系统已经正常跑在Ultra96上了。4.4 第一个PL侧小实验写一个简单的AXI GPIO控制系统跑通之后下一步就是验证PS和PL之间的通路。这一步需要用到Vivado和Vitis版本建议用2020.1或更新的稳定版本。具体步骤如下打开Vivado创建新工程选择器件xczu3eg-sfvc784这是Ultra96所用ZU3EG的封装。创建Block Design添加Zynq UltraScale MPSoCIP然后在配置界面选择Ultra96对应的预设。这一步很关键因为它会自动把DDR、UART、SD等PS外设配置好。在Block Design中添加一个AXI GPIO IP配置为输出模式连到一个PMOD引脚上。然后做地址映射通常默认地址就行。验证设计、生成顶层HDL、生成bitstream。导出XSA文件打开Vitis创建新的平台工程并导入XSA。创建一个Application Project选Hello World模板然后添加一小段代码调用XGpio库函数往LED引脚写入数据。运行程序能看到LED按预期亮灭。这段流程我建议一定亲手走一遍。因为它涵盖了Vivado的PL设计、PS配置、地址映射、Vitis应用编译、板级运行整个闭环把这些串起来之后你再看官方例程会非常顺畅。如果你觉得第一次就搞Vivado有点重可以先在Ubuntu里装PYNQ然后用Python的overlay接口加载官方提供的base.bit再通过pynq.GPIO直接控制引脚。这样能省掉工具链学习成本快速看到效果适合先建立信心。5. 踩坑记录与排查速查表5.1 启动异常排查我把经常遇到的问题整理成一张表对照着查会快很多现象可能原因排查方式上电后完全没有反应供电不足或电源不匹配确认使用12V/2A PD电源换线试试串口没有任何输出串口线接错、波特率不对确认TX/RX交叉波特率设115200启动卡在FSBL阶段SD卡镜像损坏或DDR配置错误重新烧录官方镜像确认XSA和board预设匹配启动卡在U-Boot阶段boot.scr或启动脚本文件缺失检查SD卡分区有没有BOOT.BIN和image.ubLinux启动后频繁重启SD卡速度太慢或供电不稳换A1级别SD卡检查电源显示器黑屏Type-C线不支持DP Alt Mode换专用的Type-C转DP线5.2 显示与网络问题DP输出是很多人会卡住的地方。Ultra96的DP输出走的是USB Type-C口所以你的线材必须支持DP Alt Mode不是随便一根Type-C转HDMI线都行。有些Type-C转HDMI线只支持“DP to HDMI”方向插上电脑输出视频正常但插Ultra96可能没有反应。建议买质量好一些、明确标注支持DP Alt Mode的转接线。WiFi连接在Ubuntu下基本是开箱即用。如果发现WiFi搜不到先确认天线已经接好再检查内核模块是否加载了wl18xx相关的驱动。蓝牙和WiFi是同一个模组如果WiFi能连而蓝牙没有多半是蓝牙服务没起来systemctl status bluetooth看一下。5.3 电源与散热教训Ultra96的功耗不算高但也不是树莓派那种5V直接喂饱的类型。它需要USB-PD协商到12V普通手机充电头基本不可用。我试过用5V/3A的充电头供电结果板子完全没反应折腾了半天才意识到问题在电源上。所以第一件事永远是确认电源。散热方面ZU3EG在跑重负载时温度不容小觑。长期压满四核A53再加PL资源利用率高芯片表面会很烫。建议加一个主动散热风扇或至少贴一片散热片。若是跑模型推理这种重负载任务温升更快不加散热经常会在日志里看到CPU降频提示。还有一个经验不要在系统运行时带电插拔PMOD外设和MIPI接口设备。PMOD接口本身没有过流保护热插拔容易烧坏FPGA引脚。我自己因为这个习惯烧过一个PMOD模块之后所有外设连接都是断电后再操作这个习惯建议所有新手养成。6. 后续可以往哪些方向挖跑通系统之后Ultra96的乐趣才刚刚开始。我列几个我觉得值得深入的方向PL加速计算在PL里实现一个简单FIR滤波器或者矩阵乘法单元用AXI-DMA把DDR里的数据送进去算完再写回。这个过程会用到大数据量搬运对AXI-HP接口理解会更深。PYNQ生态PYNQ框架里有很多现成overlay比如图像处理、DPU、CNN加速器。把它跑起来用Jupyter Notebook写Python调用硬件加速体验一下“软件定义硬件”的思路。MIPI摄像头接入接一个MIPI CSI-2摄像头做实时图像采集和显示。这个方向会用到Vivado里的MIPI CSI-2 IP、VDMA、DP输出是视频处理链路的全家桶也最能体现Ultra96这块板子的设计意图。Linux设备树与驱动把PL侧的自定义外设挂到Linux设备树里写一个简单的字符设备驱动通过/dev节点访问PL寄存器。这一步做完你对“Linux如何管理硬件资源”的理解会有质的提升。我个人在实际使用中最大的体会是Ultra96最宝贵的地方不是性能而是“完整”。它把ARM、FPGA、Linux、外设接口全部放在一个尺寸很小的板子上让你能在一套环境里把嵌入式系统从硬件到软件全部打通。这种体验是单纯玩树莓派或者单纯玩FPGA开发板都体会不到的。如果你也正准备入坑异构计算我给一个实在的建议第一周别急着上复杂算法先把SD卡启动、串口日志、Ubuntu系统、SSH连入这套基础链路跑顺然后花一个周末把Vivado到Vitis的完整流程走一遍。这两个基础打牢之后剩下的就是往上叠应用了。下一篇我会专门写Ultra96上PS和PL之间跑AXI总线的完整流程包括Block Design里的连线细节、Vitis里驱动代码的框架、以及Linux下设备树的取舍。这部分坑更多也更有意思。