尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

LabVIEW 与 ZYNQ 演进:从异构 SoC 到测控工具包的落地实践

LabVIEW 与 ZYNQ 演进:从异构 SoC 到测控工具包的落地实践 做测控这么多年我一直有个很深的感受LabVIEW 工程师和 ZYNQ 之间隔着一道看不见的墙。LabVIEW 玩得再溜一碰到 ZYNQ面前就是 Vivado、Vitis、FSBL、设备树这一整套完全陌生的东西。很多团队项目卡就卡在这个地方。神电测控在写《LabVIEW ZYNQ FPGA宝典》的时候第一章 1.5 节专门聊了一个问题为什么我们要费这么大劲去开发一套 LabVIEW ZYNQ FPGA 软件工具包这篇文章就把这个思考过程完整摊开来讲顺便把 ZYNQ 芯片本身的特点和优势掰碎了说清楚。如果你正在用 LabVIEW 做上位机又恰好接触到了 ZYNQ 板卡或者你只是想知道 LabVIEW 和 FPGA 到底怎么结合起来用这篇内容应该能给你一个比较落地的参考。1. 先弄明白 ZYNQ 到底是一颗什么样的芯片1.1 异构 SoC一颗芯片里同时住着 ARM 和 FPGA很多人第一次听说 ZYNQ下意识会把它归类为“FPGA”。这句话对了一半。ZYNQ 确实包含可编程逻辑PLProgrammable Logic但它真正特殊的地方在于芯片里还集成了一整套完整的处理器系统PSProcessing System也就是双核 ARM Cortex-A9。这意味着它不是一块“纯 FPGA”而是一颗异构 SoC。我用一个生活化的类比来解释。PS 侧的 ARM 就像一个办公室经理擅长处理复杂决策、跑操作系统、管理网络协议栈但它的执行方式是串行的一件事一件事地处理。PL 侧的可编程逻辑则像一条流水线一旦配置好就能并行处理海量数据稳定、高速、绝不“分心”但它不擅长做复杂的逻辑判断。传统方案里这两部分通常分属两颗芯片一颗 ARM 主控加一颗 FPGA 协处理器。而 ZYNQ 把两者放进了同一颗芯片通过片内的 AXI 总线把两边高速连接起来。片内互联和板级互联的差别是巨大的。以前 ARM 和 FPGA 之间走 SPI 或者并行总线速度能到几十 MB/s 就算不错了而且还要考虑电平转换、时序匹配、信号完整性。ZYNQ 内部 PS 和 PL 之间通过 AXI 接口通信AXI_HP 高性能从接口能做到理论带宽上千 MB/s延迟也远低于外部总线。这颗芯片解决的第一件事就是“高速数据搬运”这个物理层面的瓶颈。1.2 从测控行业的实际需求来看 ZYNQ 的优势测控行业接触的活通常有几个特点多通道同步采集、实时控制、复杂触发、大吞吐量数据回传。传统方案各有各的难受之处。用 MCU 或者 DSP 做数据采集控制编程相对简单但遇到高速 ADC、多通道并行采样、或者需要精确到纳秒级的时序控制时软件轮询和中断根本跟不上。用纯 FPGA 做实时性和并行性没有问题但以太网协议栈、文件系统、UI 交互这些活让它来干就非常痛苦你等于用硬件描述语言去写一个操作系统级别的应用。用 PC 加 PCIe 采集卡性能是够了但设备体积大、功耗高、便携性差而且整套系统成本不低。ZYNQ 的异构架构几乎是为这类需求量身定做的。PL 侧负责高速采集、信号调理、精确时序控制、并行信号处理PS 侧跑 Linux 或者裸机程序负责网络通信、协议解析、数据存储、人机交互。一板解决既有了 FPGA 的确定性响应又有了 ARM 的软件灵活性。再加上赛灵思现在的 AMD成熟的 Vivado/Vitis 工具链以及庞大的 IP 核生态ZYNQ 在工业控制、仪器仪表、软件无线电、机器视觉这些领域快速铺开也就顺理成章了。我整理了一个简单的对比可以更直观地看出差距方案实时性开发难度灵活性集成度典型场景MCU/DSP中低中中简单控制、低速采集纯 FPGA高很高低中高速信号处理、协议实现PC 采集卡中中中低实验室测量、自动化测试ZYNQ 异构 SoC高高但有工具包后降低高高嵌入式测控、便携仪器、边缘计算这也是为什么我们在宝典里花了整节篇幅去讲 ZYNQ——它是后续所有 LabVIEW 开发工作的物理基础。你只有把这颗芯片的脾气摸透了后面调驱动、写通信协议、做在线升级的时候遇到问题才知道该往哪个方向去查。2. LabVIEW 生态的边界就是工具包的起点2.1 LabVIEW 工程师在 ZYNQ 面前会遇到什么LabVIEW 在测控领域的地位不用多讲图形化编程、海量驱动库、快速搭建测试界面的能力让它在实验室和产线自动化里几乎是标配。但 LabVIEW 也有一个明显的边界它最擅长的是“上位机”和“系统集成”对于底层硬件它通常是通过驱动和通信接口来间接控制。NI 自家的 RIO 平台比如 CompactRIO底层用的其实也是 Xilinx 的 FPGANI 通过 LabVIEW FPGA 模块让用户用图形化方式写 FPGA 逻辑。这套方案做得很成熟但它是一个相对封闭的生态你必须用 NI 的硬件板卡扩展性、成本、定制自由度都受限。很多项目做到后面会发现NI 的硬件要么接口不满足需求要么单价超出预算要么体积和功耗不适合现场部署。这时候ZYNQ 的吸引力就出来了。它价格相对可控硬件接口灵活PL 侧想接什么 ADC、LVDS、MIPI、CAN 都由你说了算。但问题是ZYNQ 的开发流程对 LabVIEW 工程师来说几乎是另一个世界。你要会 Verilog 或者 VHDL 写 RTL 逻辑要用 Vivado 做综合布局布线要用 Vitis/SDK 写 ARM 端的 C 代码要配置设备树要做启动镜像还要自己定义一套上位机通信协议。一个完整的 ZYNQ 项目通常需要一个硬件工程师加一个嵌入式软件工程师加一个上位机工程师三个人各管一段。很多测控公司恰恰是 LabVIEW 工程师多HDL 和 Linux 人才稀缺。结果就是明明 ZYNQ 这颗芯片性能很合适但团队根本啃不动。我们见过太多项目评估阶段觉得 ZYNQ 完美真到了实施阶段光是把第一个 LED 点亮、把第一帧数据从 PL 搬到 PC就耗掉了一个月。2.2 神电测控的定位给 LabVIEW 和 ZYNQ 之间搭一座桥神电测控做这个工具包并不是突发奇想。我们团队自己就是测控系统集成商出身常年用 LabVIEW 帮客户搭测试系统也替客户做过不少 ZYNQ 板卡的底层开发。两边的辛酸都体会过才意识到市场缺的不是板卡也不是教程而是一个能让 LabVIEW 工程师直接上手 ZYNQ 的中间件层。打个比方LabVIEW 工程师用仪器的时候从来不需要关心 GPIB 控制器内部的寄存器怎么配也不需要关心 VISA 驱动底层是怎么实现的。他要做的就是调用一个“读取波形”的 VI把数据拿回来用。ZYNQ 板卡在理想状态下也应该像一个“可编程的智能仪器”通过一套统一的 API 暴露给 LabVIEW。但现状是每个团队都在重复造轮子自己定义通信协议自己写数据解析自己处理丢包重传自己写固件里的命令分发逻辑。这些工作技术含量不低但又不产生核心竞争力纯粹是耗时耗力。神电测控开发这套 LabVIEW ZYNQ FPGA 工具包目标就是把这些重复劳动一次性做掉。工具包提供主机端 LabVIEW API、ZYNQ 固件端库、以及一套完整的示例工程。LabVIEW 工程师拿到板卡之后不需要懂 Verilog不需要会配 Linux只需要调用几个 VI就能实现数据采集、寄存器读写、波形显示、固件升级这些功能。而硬件工程师和嵌入式工程师也只需要基于工具包的固件框架去扩展自己的 PL 逻辑不用再为上位机通信的事情分心。当然这里要强调一下工具包的能力边界。它不是要替代 Verilog也不是要替代 Vivado。PL 侧该写的逻辑还是得写PS 侧该配的硬件还是得配。工具包解决的是从“板卡能跑”到“LabVIEW 能用”之间的那段路这段路恰恰是 LabVIEW 工程师最不熟悉、最容易卡住的部分。3. 工具包的核心架构与关键技术3.1 总体分层主机端、通信链路、固件端整套工具包的架构我习惯把它分成三块来看主机端 LabVIEW API、通信链路、ZYNQ 固件端框架。三块各有各的设计考量。主机端是 LabVIEW 工程师直接接触的部分设计要求是简单、稳定、文档清晰。我们参考了 NI 硬件的编程习惯把功能封装成“打开设备—配置通道—启动采集—读取数据—停止—关闭设备”这样一个标准的仪器控制流程。这样 LabVIEW 工程师不需要改变自己的编程习惯学习成本很低。通信链路是整个工具包的技术核心。我们主推千兆以太网作为物理层原因很简单成熟、跨平台、支持远距离传输而且千兆网实测有效吞吐能做到 100MB/s 上下对于绝大多数测控场景已经绰绰有余。相比 USB以太网不需要安装特定驱动即插即用相比 PCIe以太网不受机箱和板卡槽位的限制灵活性更高。工具包里还预留了 UDP 广播做设备自动发现插上网线LabVIEW 端就能自动找到板卡不需要手动填 IP。固件端跑在 ZYNQ 的 PS 侧是一个轻量级的 C 语言框架内部做了网络服务、命令分发、数据缓存、中断处理这几个模块。LabVIEW 发过来的命令固件解析之后通过 AXI 总线去控制 PL 侧的逻辑PL 侧产生的高速数据流则通过 DMA 方式搬运到 PS 侧的内存再通过网络发送到上位机。3.2 数据通路从 PL 到 LabVIEW 到底经历了什么很多第一次接触工具包的人都会问一个问题数据是怎么从 FPGA 逻辑里出来最后到 LabVIEW 波形图上的我拿一个典型的高速采集场景来拆解。PL 侧的逻辑从 ADC 拿到原始采样数据实时性好但 PL 内部没有大容量存储数据必须立刻搬走。这时一般会例化 AXI DMA 或者 AXI Stream 接口把数据流送到 PS 侧的 DDR 内存中。这里有个常见误区很多人想省事直接在 PL 和 PS 之间做寄存器级别的数据搬运这种方案的带宽非常有限只适合传控制字和状态字不适合传波形数据。一旦采样率上了兆赫兹级别寄存器搬运瞬间就崩了必须走 DMA。数据到了 DDR 之后PS 侧的网络服务线程会从内存里取数据加上帧头帧尾、时间戳、通道号这些信息封装成网络包发出去。LabVIEW 端收到网络包之后经过解析、校验、去抖动最后才变成前面板上的波形。整个链路里的每个环节都可能成为瓶颈DMA 描述符不够用、DDR 带宽被占满、网络发送线程优先级太低、LabVIEW 接收端处理不过来。工具包在开发时针对每个环节都做了优化比如 DMA 采用多描述符环形缓冲网络发送采用独立的线程加双缓冲LabVIEW 端使用队列机制把接收和显示解耦。3.3 命令与事件不只是搬数据还要能控制、能通知仪器类设备光有数据通路是不够的还必须具备“控制”和“通知”能力。控制好理解比如设置采样率、启动停止采集、校准偏移这些本质上是往 PL 侧的寄存器里写值。工具包里的实现方式是在 PS 侧挂一组 AXI GPIO 或者 AXI Lite 接口网络收到控制命令后通过 AXI 总线把值写到对应寄存器。事件通知则是一个容易被忽视但极其重要的功能。比如 PL 侧检测到触发电平、温度超限、FIFO 快满、DMA 传输完成这些事件需要及时上报给上位机。不能靠 LabVIEW 端一直去轮询效率太低而且实时性差。工具包的做法是PL 侧产生中断PS 侧中断服务程序捕获之后在网络层面主动向 LabVIEW 端推送一条事件消息。LabVIEW 端用事件结构去响应就像处理面板按钮事件一样自然。这里我特别想强调一点工具包的 API 设计逻辑和 NI 的 DAQmx 很像但底层实现完全不同。DAQmx 是 NI 自家驱动你只能用它控制 NI 的设备而工具包面向的是通用 ZYNQ 板卡用户完全可以基于工具包的固件框架改造出适合自己的数据采集、图像处理、运动控制等各类系统。4. 落地过程中躲不开的坑与排查经验4.1 固件烧写与启动为什么老报 FSBL 错误工具包开发过程中我们踩过最多坑的环节不是通信协议而是最基础的“让板子跑起来”。很多用 ZYNQ 的工程师都被启动问题折磨过这里我把高频问题整理一下。先说烧写。ZYNQ 的启动镜像分为几个部分第一阶段引导程序FSBL、FPGA 比特流bitstream、U-Boot、内核和设备树通常打包成 image.ub。在官方工具链里FSBL、bitstream、U-Boot 会打包成一个 BOOT.BIN。很多新手在这个环节第一次崩溃因为前期调试时用的 boot.bin 可能只包含 FSBL 和 bitstream不包含 U-Boot也能跑起来但一旦要做 flash 在线升级就发现不行。有个高频报错是“valid fsbl file is required for flash operation”中文环境里经常看到“没有有效的 FSBL 文件”。这个错误绝大部分情况是工程版本不匹配导致的比如 Vivado 工程是 2019.2但 Vitis 工作区是 2020.1生成的 FSBL 格式不兼容。还有就是烧写工具找不到 FSBL 文件或者路径里有中文。排查思路很简单确认所有工具链版本统一确认 FSBL 文件确实生成成功了确认路径是纯英文且没有空格。工具包里我们直接把完整的启动镜像制作过程脚本化了用一键脚本生成 BOOT.BIN 和 image.ub从源头避免这类手误。相比烧写SD 卡启动会稍微温和一点但依然有讲究。SD 卡启动其实就是把 BOOT.BIN 和 image.ub 拷贝到 FAT32 格式的第一个分区然后调整启动跳线。坑通常出现在两个地方一是分区格式不对用了 NTFS 或者 exFATZYNQ 的 BootROM 认不出来二是拷贝的时候文件没拷全或者文件名大小写不对。制作 SD 卡启动卡的步骤我建议直接固化成标准操作流程先格式化一张最小 2GB 的 SD 卡为 FAT32把 BOOT.BIN、image.ub 按顺序拷贝进去安全弹出再插到板卡上上电。不要用劣质读卡器我在实际项目中遇到过读卡器导致的启动文件损坏排查了一个下午。4.2 在线升级设计不能把鸡蛋放在一个篮子里工具包里做了一个很实用的组件固件在线升级。这个功能对应了热词里出现频率很高的“基于 ZYNQ 的 bootloader 在线升级设计”。做在线升级的前提是 Flash 分区方案要合理一般会在 QSPI Flash 里划分出 bootloader 区、应用程序区和一个备份区。bootloader 负责在最开始的时候决定引导哪个区的程序应用程序运行过程中如果收到升级指令就把新的固件写入备用区写完校验通过后修改引导标志位重启切到新固件区。这个方案里最关键的环节是“升级失败怎么办”。如果新固件写入一半网络断了或者校验没过重启之后系统就变砖了。工具包的处理方式是加一个回滚机制bootloader 检测到应用程序区的镜像无效会自动回退到上一个可用版本。这个机制听着简单但实现的时候有很多细节比如备份区空间够不够放两份完整镜像、升级过程中的断电保护、写入 Flash 之前要不要先擦除整个扇区这些问题不踩一遍很难意识到。跟在线升级一起出现的高频问题还有“zynq 烧写”。很多工程师会混淆 QSPI Flash 烧写和 SD 卡固件更新。如果是产品量产建议用 SD 卡方式批量灌镜像速度比 JTAG 快很多而且不需要额外的烧录器。如果追求远程维护就一定要把在线升级通道做进去。工具包的固件端框架已经把这两条路径都打通了用户在 LabVIEW 端调用升级 VI 就能完成整个流程。4.3 LabVIEW 环境问题版本和 Runtime 永远是最常见的坎工具包发布之后用户反馈的问题里有很大一部分其实跟 ZYNQ 没关系而是 LabVIEW 环境本身的问题。这里我花点篇幅专门说一下因为这可能是新手最容易卡住的地方。首先是 LabVIEW 安装错误。我遇到过的原因五花八门安装包镜像文件损坏、杀毒软件拦截了 NI 的驱动服务、安装路径带中文导致部分组件注册失败、电脑用户名是中文导致 NI 的配置文件路径出错。最离谱的一次是用户电脑的 UAC 权限设置过高安装过程看起来正常但 OllyDbg 和 NI 的服务相关组件一个都没装上。统一的解决方法就一句话用纯英文路径安装安装前关掉杀毒软件右键以管理员身份运行安装程序安装完重启一次再装驱动。其次是 Runtime Engine 版本问题。很多用户在自己开发机上装了完整的 LabVIEW 开发环境程序跑得好好的一部署到目标机就报错“LabVIEW Runtime Engine 版本不匹配”。这是因为目标机上只有运行时引擎没有开发环境而 VI 是用更高版本的 LabVIEW 编译的。这个问题没有捷径要么目标机装上对应版本的 Runtime要么开发机降低版本重新生成 exe。工具包内所有 VI 都做了版本说明同时尽量兼容旧版本的 LabVIEW就是为了少给用户添这种麻烦。还有一个基础但高频的问题串口通信。很多 LabVIEW 工程师上手 ZYNQ 的第一反应是用串口连毕竟最简单。串口通信最常见的问题是连接不上或者数据乱码。排查方向无非就那么几个串口号是否选对、波特率是否一致、数据位停止位校验位是否匹配、USB 转串口芯片的驱动是否装好、TX/RX 是否接反。ZYNQ 的 PS 侧 UART 一般默认是 115200-8-N-1如果你上位机用了 9600那收到的肯定是乱码。工具包里我们虽然主推以太网通信但串口通道也保留着方便用户在 Linux 控制台做底层调试。4.4 数据通路性能小包传不快、大包丢帧都是为什么工具包装好之后用户最容易遇到的性能问题是两个极端小包传输吞吐量上不去大流量传输时丢帧。小包传不快原因往往在 TCP 协议本身。TCP 有 Nagle 算法会把一些小包合并后再发送这本来是为了减少网络拥塞但在实时性要求高的场景里反而增加了延迟。还有一个典型原因是 LabVIEW 端每收到一个包就刷新一次前面板图形刷新的开销远大于数据接收的开销。解决办法是开启 TCP_NODELAY 选项禁用 Nagle 算法同时在 LabVIEW 端把接收、解析、显示放到不同的循环里显示循环降采样刷新。大流量丢帧问题通常出在接收端处理不过来。ZYNQ 端网卡发送速度很快如果 LabVIEW 接收端的网络读取循环优先级不够高或者接收队列太短系统缓冲区满了之后新的数据包就会被丢弃。这种问题排查时先看板卡端是否有发送超时重传的日志再看 PC 端接收缓冲区大小。工具包在设计时把 ZYNQ 端的发送做成了独立线程加多级缓冲区同时建议用户在 LabVIEW 端使用队列机制。实际操作中我们还遇到过一个特别隐蔽的问题PC 的电源管理把网卡节能开了导致高负载时网卡自动降速数据大量超时。把网卡的“允许计算机关闭此设备以节约电源”关掉之后问题彻底消失。4.5 FPGA 侧的常见问题IO 配置、LVDS、图像接口最后聊几个 PL 侧的问题这些问题严格来说不属于工具包范畴但确实是在 ZYNQ 开发中高频出现的而且容易误导方向。一个是 FPGA 的 IO 模式。很多做 ARM 开发的工程师初接触 FPGA 时会问FPGA 的 IO 有没有类似 ARM 的那种推挽、开漏、上拉模式答案是有但不完全一样。FPGA 的 IO 可以配置成多种电气标准比如 LVCMOS、LVDS、HSTL每种标准下又有驱动强度、摆率、上拉下拉等选项。在 Vivado 里这些通过 XDC 约束文件配置。实际开发中容易犯的错是把 LVCMOS 的引脚和 LVDS 的引脚混用导致电平不匹配、数据错位。遇到这类问题第一件事查原理图和 XDC不要上来就怀疑代码逻辑。另一个是图像处理相关的应用。热词里频繁出现的“fpga 图像处理”“fpga 实现 mipi”说明现在很多人想用 ZYNQ 做视觉检测。MIPI 接口在 FPGA 上实现比普通并行接口麻烦得多因为 MIPI 是差分信号有复杂的协议层。Xilinx 有现成的 MIPI CSI-2 IP 核但配置起来需要认真阅读文档。工具包里提供了一个图像采集的参考设计PL 侧接 MIPI 摄像头通过 VDMA 写到 DDRPS 侧用 GStreamer 或者直接裸机方式读取图像最后通过以太网传给 LabVIEW。第一次做的时候我们花了三天才把摄像头初始化和 MIPI 通道对齐搞定后来把整套配置整理成了标准的初始化序列新项目直接复用。还有 fpga 与 PCB 开发如何互动的问题。这个属于项目前期硬件设计阶段就要考虑的当你在做 PCB 布局布线的时候FPGA 的引脚分配、bank 电压、去耦电容设计都会直接影响后端的 FPGA 逻辑和 LabVIEW 程序稳定性。工具包解决不了硬件设计的问题但如果板卡设计不合理工具包能做的也只是稳定地暴露错误。实际项目中我强烈建议硬件工程师和 FPGA 工程师从一开始就同步引脚约束文件芯片选型确定后先做可行性评估避免画完板子才发现关键信号没法布线。5. 神电测控开发这个工具包的一些幕后思考聊完技术再说点幕后的事情。神电测控开发这套工具包的初衷除了填补市场空白还有一个很重要的原因是我们自己也被这个痛点折磨过。做过一个多通道振动采集项目前期选型定了 ZYNQ结果硬件做完了嵌入式工程师写了两个月固件LabVIEW 工程师等得很着急。后来复盘发现真正的瓶颈不是什么高深的技术而是两边的接口没有标准化。LabVIEW 工程师不知道底层数据什么时候准备好嵌入式工程师不知道上位机想要什么格式两边来回扯皮。所以这套工具包在设计的时候我们特别强调“接口契约”的概念。板卡端和主机端之间所有的通信、数据格式、错误码、事件定义全部在前期定义清楚并写进文档。LabVIEW 工程师和嵌入式工程师只需要各自按照这份契约开发最后联调时基本不会出现大问题。这也是宝典里第一章要专门讲的核心理念工具包不是玄学它是一套被固化了的最佳实践。另一个幕后考虑是我们希望通过这个工具包拉低 ZYNQ 在测控行业的门槛。ZYNQ 这颗芯片本身足够优秀但它的开发复杂度把很多中小型团队挡在了外面。如果工具包能让一个只懂 LabVIEW 的工程师用一周时间就完成以前三个人一个月才能做完的事情那 ZYNQ 在测控领域的普及速度会快很多。这也是我们持续维护这套工具包、写《LabVIEW ZYNQ FPGA宝典》的根本动力。如果你也是做测控的正在纠结要不要引入 ZYNQ我个人的建议是先别急着上 Verilog 和 Linux 这些大件。先把 ZYNQ 的优势和团队现有的技术栈结合起来用工具包快速跑通一个最小系统感受一下数据从 FPGA 到 LabVIEW 的完整链路。有了体感之后再从底层慢慢深入那时候你会有完全不同的理解。
返回列表