这儿的 UIO 即 Userspace I/O,本文中 UIO 泛指 UIO 设备和 UIO 驱动。它在 Linux kernel 的国际里比较小众,主要是一些定制设备和相应的驱动。UIO内核驱动指担任将中止和设备内存露出给用户空间,再由UIO用户态驱动(ApplicaTIon)来完结详细的事务,为所欲为的玩。学术点叫做高度定制化,柔性规划。
那怎样和 FPGA 扯上了联系呢?是的,FPGA在硬件国际里也是为所欲为的玩,这一硬一软还真是登对,在一起啊在一起。
本试验工程将介绍怎么利在赛灵思异构多处理器产品系列 Zynq UtralScale+ MPSoC ZCU102 嵌入式评价板上完结多个 UIO,一起凭借赛灵思的东西完结硬件工程和 linux BSP 的开发,最终经过测验运用程序完结测验。
ZCU102上的 MPSoC 集成固化了四核 ARM Cortex-A53,双核Cortex-R5 以及 Mali-400 MP2 GPU,这部分官方称为PS(Processing System)。别的一部分便是FPGA,即 PL(Programmable Logic)。PS端完结操控,PL用来完结运用加快,两者经过AXI衔接。跑这个小试验,呵呵,大材小用。仅仅自己手头正好有这个板子不得不装。筒子们能够去买了个Zybo 或许ZedBoard 开发板, 在板子试试身手。
实 验 报 告
试验材料:
硬件规划
树立Vivado工程,适配 ZCU102 EVB。经过 IP Integrator 参加PS,在 PL 侧参加5个UIO输入,其间1个是GPIO模块(包括中止输出和设备内存),别的4个是PIN衔接到ZCU102 EVB上的DIP开关,作为中止输入经过一个concat IP衔接到PS的ps_pl_irq管脚。板级细节请参阅[1] UG1182,芯片材料参阅[2] UG1085
添加PIN束缚文件,
set_property PACKAGE_PIN AN13 [get_ports pl_irq_ll]
set_property IOSTANDARD LVCMOS33 [get_ports pl_irq_ll]
set_property PACKAGE_PIN AM14 [get_ports pl_irq_lh]
set_property IOSTANDARD LVCMOS33 [get_ports pl_irq_lh]
set_property PACKAGE_PIN AP14 [get_ports pl_irq_ef]
set_property IOSTANDARD LVCMOS33 [get_ports pl_irq_ef]
set_property PACKAGE_PIN AN14 [get_ports pl_irq_er]
set_property IOSTANDARD LVCMOS33 [get_ports pl_irq_er]
Vivado的图形化的模块规划,丰厚的IP库,加上能够上天的智能衔接。有点数字电路规划的根底,很快就能完结这个小规划。整个规划如下图。
软件规划
这儿用到 Xilinx 针对 Linux BSP 开发的 Petalinux。它根据Yocto,参加Xilinx的Layers完结硬件工程的导入,将杂乱的Yocto的规划流程打包简化,支撑必定的用户自界说功用,如QEMU仿真运转,添加 out-of-tree 的驱动,Device tree 修正,运用程序编译打包,等等。详细信息请移步 https://china.xilinx.com/products/design-tools/embedded-software/petalinux-sdk.html
这儿简略展现一下详细的指令进程。
$petalinux-create -t project –template zynqMP -n zcu102-pl2ps_irq
$cd ./ zcu102-pl2ps_irq
$petalinux-config –get-hw-descripTIon
$petalinux-config -c kernel
Enable UIO_PDRV_GENIRQ driver
CONFIG_UIO=y
# CONFIG_UIO_CIF is not set
CONFIG_UIO_PDRV_GENIRQ=y
$petalinux-build -c device-tree
PL侧的dtsi文件生成与./components/plnx_workspace/device-tree-generaTIon/pl.dtsi
这儿只要GPIO UIO。 PIN UIO由于不是IP,所以相关信息无法由东西主动生成。所以要做如下修正:
1. 修正GPIO UIO设备端点
1) 将中止号改为93
2) 将compaTIble改成“generic-uio” //咱们后边要用 Linux 自带的 UIO_PDRV_GENIRQ 驱动
2. 添加 DIP UIO 端点
1) 将compatible改成“generic-uio”
2) 顺次设置中止值89到93
3) 依照每个 DIP PIN 的 interrupt trigger type 设置特点值
*DTS里的中止号与硬件中止号有32的 offset。
Petalinux 供给了自界说DTS文件./project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi,将以上修正界说到system-user.dtsi.
有两个办法来适配UIO端点和 UIO_PDRV_GENIRQ 驱动
1. bootargs use “uio_pdrv_genirq.of_id=generic-uio”,能够经过DTS界说。
2. insmod uio_pdrv_genirq.ko of_id=generic-uio when install the driver
修正完后,编译出Image.
$petalinu-build
$cd ./images/linux
$petalinux-package –boot –fsbl zynqmp_fsbl.elf –fpga –atf –pmufw –u-boot –force
将生成的BOOT.bin(bootloader)和image.ub(FIT uImage)拷贝到SD卡用于发动。\
测验
这儿引证下关于uio_pdrv_genirq驱动的介绍
https://01.org/linuxgraphics/gfx-docs/drm/driver-api/uio-howto.html
结合驱动代码./drviver/uio/uio_pdrv_genirq.c)可知,每个UIO设备会有对应的/dev/uioX的设备节点。用户态驱动程序的读操作会堵塞直到UIO硬件中止产生。UIO的中止处理程序uio_pdrv_denirq_handler()会封闭该硬件中止。用户态驱动程序需求经过write函数来触发uio_pdrv_genirq_irqcontrol()以完结中止的使能和封闭。代码如下,
发动内核及加载uio_pdrv_genirq驱动
查看/proc/interrupts
仔细的你必定发现了一个坑,少了2个UIO中止(IRQ122和IRQ124),原来是硬件不支撑Edge falling和Level Low的触发形式。kernel log如下。
测验DIP UIO办法一
经过拨动2个DIP,观察到
2个DIP中止产生了,但是不论怎样再拨动DIP开关,始终是1。前文铺垫过,这个中止在驱动的中止处理程序里会被关掉,需求经过运用程序调用write()来翻开。这儿有个easy way,运用全能的echo指令“echo 0x1 > /dev/uioX”,再合作DIP能够触发屡次中止。
测验DIP UIO办法二
前面的办法比较low,这儿有略微高档的享用。写个简略的用户态驱动程序,上代码。
凭借petalinux供给的穿插编译东西编译出bin文件,拷贝到发动SD卡。
运转测验程序并合作DIP开关测验。(为了更好的表现测验运转状况,在UIO内核驱动里添加了irqcontrol的调用打印)
测验GPIO UIO
UIO驱动会将设备内存(寄存器)空间枚举出来,由用户态驱动程序经过mmap导出进行读写操控。拜见AXI_GPIO IP的文档pg144-axi-gpio.pdf,其寄存器如下。
测验运用程序会经过设置GIER和IP_IER来使能中止。上代码。
测验进程
或许你觉得这么贴图代码不宽厚而不能发挥仿制黏贴大法,可不知我拙与WORD,没try出好排版。莫急莫急,这儿有GIT,https://gitenterprise.xilinx.com/AlexHe/UIO_Linux_Demo
硬件资源文件和Image,测验代码一个都不能少,通通献上。酸爽否?
实 验 结 论
UIO这种可高度自界说的设备结合Xilinx的MPSoC能够完结十分灵敏的运用。Xilinx供给的齐备的东西集,给用户带来了高效的开发体会。本例尽管简略,但Xilinx所推重的All Programmable的概念和实践的FPGA加快运用的确实确是树立在这些软硬件协同技能之上。忘周知!