赫忠天,曾庆立,芮天喆
(吉首大学 通信与电子工程学院,湖南吉首,416000)
目前FPGA 器件具有的并发处理数据的显著优势,而且功耗低,可用于实时处理视频图像数据.但是有外设控制能力不足的缺陷。本文介绍了Xilinx 公司推出的ZYNQ 高性能芯片[1],并指出了ZYNQ 系列芯片采用了ARM 处理器和FPGA 逻辑资源的高效结合,以及处理器与FPGA 之间通过高速的AXI 总线互联的特性[2~3]。这些特点能够最大化处理速度、控制能力和传输速率,并且通过Xilinx 官方的PetaLinux 工具可以更方便地移植Linux 系统,FPGA 也可以在Linux 系统中作为可编程外设使用。ZYNQ 在单芯片内实现了ARM+FPGA 架构,为应用和设计带来了诸多方便和优点。
综上所述,ZYNQ 高性能芯片具有强大的处理能力和灵活的可编程性,是应用和设计的理想选择。对于设计人员来说,了解ZYNQ 芯片的架构和特性,并掌握ARM 处理器和FPGA 之间的数据连通技术,将有助于更好地利用ZYNQ 芯片的潜力,实现高效的系统设计。ZYNQ 面临着有开发人员要求高,开发成本高的缺点。
ARM 和FPGA 交互有三种接口,分别是GP,HP,ACP,这三个接口都是PS 端的接口[3]。而PS 与PL 最主要的连接方式则是一组AXI 接口。AXI 互联接口作为MPSOC PS 和PL 之间的桥梁,能够使两者协同工作,进而形成一个完整的、高度集成的系统。在逻辑环境下,控制PL 端资源,需要通过硬件资源与参考的库文件,操作寄存器来实现,需要较多的知识储备和对AXI 的理解。如果把PL 资源映射为Linux下的一个设备,方便用户的控制。本文尝试将在ARM 端移植Linux[4~5],并通过编写设备树与驱动文件,将PL 的PWM 逻辑块映射为块设备,有较大的灵活性。
ZYNQ 是由赛灵思公司推出的新一代可拓展平台,采用异构架构,同时拥有ARM 端处理器的软件可编程性与FPGA 端的硬件可编程性,并且双核通过AXI 高速接口相连接,具备高效的系统性能与可扩展性。根据官方的信息,可以看到ZYNQ 可以大致分为三个系列,低端的7000 系列,中端的MPSoC 系列,高端的RFSoc 系列。
Zynq UltraScale+MPSoC 属于ZYNQ 的中端系类产品,主要针对控制、网络和图形这几大领域,基于ZynqMPSoC的硬件系统在视频监视、物联网、工厂自动化等领域有广泛应用,既能利用FPGA 的逻辑资源实现数据的高速并行处理,又能利用ARM 移植操作系统带来的控制便利性与拓展性。Zynq MPSoC 在单个芯片上集成了四核Arm Cortex-A53 芯片与赛灵思可编程逻辑资源,采用这种交互式协同工作的方式具有显著优势。其中一个优势是它可以大大缩小嵌入式系统的体积,同时提供适当的性能功耗比和功能安全性。这种方式可以增强系统的性能,方便嵌入式系统的设计。另一个优势是它可以提高系统的功能安全性。通过多个处理单元或处理器的协作,系统可以更加可靠地进行操作,从而增强系统的性能和可靠性。
由图1 可知,在Vivado 下采用Block Design 的方式,连接IP 核,其中PWM 为Verilog 的IP 核,ZYNQ 为ARM 端,Processor System Reset 为复位控制模块,AXI Interconnect为官方IP 核,通过AXI 协议实现ARM 与FPGA 的数据传输。生成硬件资源后,输出xsa 文件。
图1 系统原理框图
PWM 在嵌入式设备中使用很多,常用于控制电机、控制振动器件、调节背光、呼吸灯等等。可以通过调节脉冲的占空比来调节 LED 的亮度。
通过编写Verilog 代码,并把它封装成IP 核的形式方便调用。控制PWM 输出有两个关键参数,一是频率,二是占空比。自定义IP 可以理解为配置FPGA 的寄存器资源变成我们想要的设备,添加IP 后,我们就可以像操作ARM 资源一样,通过操作寄存器来操作FPGA 的资源。框图连接完成后,点击Assign Address 实现地址的分配。
图2 PWM 配置模块
图3 ZYNQ 硬核
通过配置嵌入式最小系统生成需要的硬件环境,最小系统有两个要求,第一它是以PS 端为主,是使系统正常工作的最小条件;第二它为其他系统建立起基础。ZYNQ 硬核的架构图通过图形界面配置,连接时钟与信号后,设置自动连接,并点击Validate Design 验证连接图。通过该图形界面,配置PS 端口的DDR、串口、时钟等模块。
PetaLinux 操作系统是Xilinx 公司推出的全功能嵌入式Linux 操作系统,将针对ZYNQ 定制的u-boot 源码、Linux内核源码以及开发板相应的硬件平台配置,集成到一个对应的开发包,方便开发人员生成、配置、编译及自定义 Linux系统。PetaLinux 根据嵌入式开发的需求采用板级支持包,并且PetaLinux 包含部分常用IP 核的驱动程序,方便用户移植,减少驱动编写的工作量。通过PetaLinux 与Xilinx硬件设计工具Vivado 协同工作,帮助开发者简化了ZYNQ移植Linux 系统的开发工作。
虚拟机安装PetaLinux 环境。利用Xilinx 公司的Vivado 软件进行FPGA 开发,然后使用PetaLinux 软件构建与硬件平台适配的嵌入式Linux 系统,最终将驱动软件及应用程序导入嵌入式Linux 系统中。此外,通过配置zynq_altk_defconfig 文件与makefile 等文件来增加驱动模块。
ZYNQ 中MPSoC 系列的嵌入式软件栈。可以以uboot作为分界线,uboot 之前的与硬件的关系比较密切,我们借助PetaLinux 工具进行配置。先使ZYNQ UltraScale+MPSoC 上电,开始由BootROM 对ZYNQ 进行初始化启动,进而加载fsbl 到OCM 用于启动fsbl;fsbl 之后加载PMU Firmware,进而加载ARM Trusted Firmware 用于配置DDR,之后将uboot 加载到DDR 以启动uboot。Uboot 配置与Linux 内核与硬件平台关系不大,可以参考类似的设计,采用uboot 来加载Linux 系统镜像文件到DDR 成功启动Linux。
PetaLinux 的设计流程:通过Vivado 创建硬件平台,得到xsa 文件。
通过xsa 硬件配置文件获取fsbl、uboot、内核等的配置信息。使用Petalinux 开发工具,根据xsa 文件自动分析ZYNQ MPSoC PS 端的配置,从而自动配置uboot 和linux 内核,相当于自动移植了uboot 和linux 内核。
Uboot 介绍:这是一个常用的开源bootloader。在系统启动过程中,bootloader 是一个重要的组成部分。它在操作系统运行之前执行,通过初始化硬件设备,建立内存空间的映射表,为操作系统内核做好准备。Uboot 是一款广泛使用的bootloader,支持多种处理器架构。它的主要功能是将Linux 内核从闪存(如SD 卡、eMMC、NAND 和NOR FLASH 等)中复制到DDR 内存中,初始化和配置硬件设备,然后启动Linux 内核。这使得Uboot 成为开发嵌入式系统的关键组成部分,可以在各种不同的硬件平台上运行。在启动过程中,Uboot 首先会初始化外设(如DDR、串口、网卡等),然后通过读取闪存中的配置文件,将Linux 内核加载到DDR 中,并将控制权交给Linux 内核。在此过程中,Uboot 还提供了一些有用的功能,例如通过网络或串口进行远程调试和更新固件。
Bootloader 不仅依赖于CPU 的体系结构,而且依赖于嵌入式系统板级设备的配置。这意味着即使两个不同的嵌入式开发板使用相同的处理器,要想让在一个板子上运行的bootloader 也能在另一个板子上运行,通常需要修改bootloader 的源代码以适应不同的硬件环境。因此,由于嵌入式系统中存在大量的不同的硬件平台和处理器架构,建立通用的bootloader 几乎是不可能的。每个嵌入式系统都需要定制的bootloader 来确保正确的初始化和配置硬件设备,并启动操作系统内核。
总之,bootloader 是嵌入式系统中重要的组成部分,它确保了正确地初始化和配置硬件设备,并为操作系统内核做好准备。但由于嵌入式系统中存在大量的不同的硬件平台和处理器架构,建立通用的bootloader 几乎是不可能的。每个嵌入式系统都需要特定的bootloader 来满足不同的硬件环境和要求。
ps 端的基本配置使用设备树来描述,pl 作为ps 的外设,也是作为设备树中的一部分。通过打开 system-user.dtsi文件,在根节点中添加pwm 的节点。配置compatible 节点兼容性与物理地址。设备树devicetree,也称作Open Firmware(OF)或FlattenedDevice Tree(FDT)。本质上是一个字节码格式的数据结构,其中包含信息在内核启动时非常有用。bootloader 在跳到内核入口点之前将这一组数据复制到RAM 中的已知地址。
设备树的严格的规范,却没有规定哪些内容可以放置其中以及放置的位置。内核可以搜索设备树中的任意路径和参数。程序员来决定哪些配置作为参数放进设备树里,以及放置在什么地方。采取标准的树结构,则可用一套方便的APl来操作。例如,约定好如何定义总线上的外设,那么API 可以获取到驱动所需的基本信息:地址、中断和自定义变量。后面会介绍更多。对于我们大多数人来说,我们用设备树来向内核描述对硬件的添加或删除操作,作为响应,内核就可以加载或卸载相应的驱动。硬件的特殊信息也可以通过设备树来向内核传达。
本文讨论了硬件设备的分类以及它们在内核中的驱动编写和维护的问题。标准设备的驱动可以参考类似设计,作为主内核源码树的一部分。与此同时,更多的非标准设备的驱动不属于内核子系统,并且通常使用内核内部函数和宏,这增加了驱动的编写和维护的复杂性,并且这些驱动不能进入主内核源码。为了解决这个问题,提出了用户空间I/O 框架(Userspace I/O framework)。
用户空间I/O 框架采用用户态驱动和uio 机制来实现FPGA 驱动的控制。用户空间I/O 框架通过将设备的控制流程从内核转移到用户空间,实现了驱动的解耦和灵活性,减少了驱动编写和维护的复杂性,并且可以将这些驱动加入到主内核源码中。这种方法的一个优点是可以利用用户空间库和工具,例如C 和C++库和调试工具。另一个优点是可以利用现有的用户空间应用程序和框架,例如网络协议栈和文件系统。
总之,用户空间I/O 框架是一个解决驱动编写和维护的复杂性问题的创新方法。它可以通过将设备的控制流程从内核转移到用户空间,实现驱动的解耦和灵活性,并且可以将这些驱动加入到主内核源码中。这种方法不仅可以利用用户空间库和工具,还可以利用现有的用户空间应用程序和框架。
使用 PetaLinux 新建名为“ax-pwm”的驱动程序,编写ax-pwm.c 代码。完成编写后执行PetaLinux-config-c rootfs 命令选上新增的驱动程序。本PWM 驱动按照字符设备编写,使用结构体alinx_char_dev,设置该字符设备号、设备地址与映射的虚拟地址。驱动完成后,可以通过操作/dev/ax-pwm 控制该驱动。pwm 的处理也很简单,从设备树中获取地址,然后在操作函数中操作地址。也可在Vitis 中采用交叉编译环境,生成Linux 下可执行的elf 文件来测试。
本文涉及了ARM 和FPGA 之间的互联以及使用AXI总线来传输数据和外设控制数据的内容。在这种互联中,FPGA被视为ARM的外设,需要通过AXI总线进行数据交互。为了完成这种交互,需要驱动两者之间的总线。由于嵌入式软件功能通常在Linux 系统上进行开发,因此AXI 总线的驱动软件开发需要遵循Linux 驱动框架。
总之,ARM 和FPGA 的互联非常重要,AXI 总线是实现这种互联的关键。对于嵌入式软件开发人员来说,熟悉Linux 驱动框架是必要的,因为这可以帮助他们开发出符合标准的AXI 总线驱动程序,从而实现ARM 和FPGA 之间的数据交互。
本次设计使用的仿真工具为Vivado 自带仿真器Simulate,通过编写Testbench 文件仿真。在仿真文件中提供25MHz 时钟信号,采用状态机的方式,周期性的让占空比在最小值最大值之间变化。图4 为信号的变化图。通过图中波形可发现,占空比随着时钟周期变换,仿真结果表明,该PWM 控制器逻辑功能正确,符合本次设计要求。
图4 PWM 波形仿真
本文提到了利用Xilinx 公司的Vivado 软件完成FPGA侧的开发并导出硬件平台文件,然后使用PetaLinux 软件构建与硬件平台适配的嵌入式Linux 系统,最终将驱动软件及应用程序导入嵌入式Linux 系统中,以完成嵌入式设备的开发。最后,需要重新给设备加电以使其生效。
在这个过程中,FPGA 的开发需要使用Xilinx 公司的Vivado 软件进行。Vivado 提供了许多工具和资源,可以帮助设计师完成从电路设计到综合和验证的各个步骤。在开发完成后,需要将硬件平台文件导出,以便在PetaLinux 中使用。
PetaLinux 是一个嵌入式Linux 系统开发工具,可以根据硬件平台文件构建与硬件平台适配的嵌入式Linux 系统。使用PetaLinux 可以简化Linux 系统的开发和调试,同时提高开发效率。完成系统移植后,需要将驱动软件及应用程序导入嵌入式Linux 系统中。这可以通过文件传输协议(FTP)或者其他通信方式实现。在将驱动软件和应用程序导入系统之前,需要确保它们与硬件平台和嵌入式Linux 系统的适配性。
最后,在完成上述操作后需要重新给设备加电,以使其生效。这个步骤非常重要,因为只有重新加电才能使设备正确地加载并运行新的软件和驱动程序。在QT 中编写测试代码,使得PL 端占空比不断改变,操作/dev/ax_pwm 模块,可以观察到PL 端的LED 呼吸灯闪烁。
BOOT.BIN 的文件由fsbl、uboot、设备树文件、linux内核、根文件系统与PL 端的system.bit 组成。System.bit 为FPGA 配置文件,在启动的第二阶段FSBL 中,由BootROM 引导加载到片上RAM,配置FPGA。PeteLinux根据xsa 文件可以配置并生成设备树文件,在/device-tree目录,其中pl.dtsi 为部分IP 核的设备树文件,systemuser.dtsi 是我们根据需要修改的用户文件。
本文首先对比分析MPSoC 裸机硬件平台ZYNQ 的优缺点,提出一种在Linux 下将FPGA 端作为可编程外设的方法。经过测试,验证了MPSoC 硬件平台Linux 控制FPGA 端可行,并将映射到ARM 端的dev 设备。本方案的成功实现对后续ZYNQ 设计具有一定的指导意义,同时,对其他系统高性能、高实时的嵌入式应用具有一定的参考价值。