Vitis AI 加速 GMSL 摄像头人脸检测 - 第三部分
Vitis AI 运行时库打包
截至目前,Vitis AI 运行时库在 docker 容器中提供。虽然可以将 facedetect 的源代码复制到运行时 docker 中编译,但本教程将街上另一种方法,支持用户在 petalinux 中构建,无需使用 docker 进行构建(在主机上至少第一次创建库时仍然需要运行时 docker)。该方法是将依赖项从 docker 复制到本地库中,该库在 petalinux 构建期间由 Yocto reciperecipe获取。生成文件目标如下所示:

该目标的主要任务是:1) 准备 docker 和主机之间共享的目录 2) 在 docker 容器内执行 scripts/copy_libs.sh 脚本并 3) 清理。scripts/copy_libs.sh 脚本只是将 docker 容器中交叉编译环境中的一些库和报头文件复制到 repos/Vitis-AI/Rebuild-Model-Zoo/libs 目录中。 完成后,生成文件会将其组织为 repos/vitis-ai-pfm。在稍后的步骤中,Petalinux recipe 将选取这些文件并插入到目标的 rootfs 中。
PetaLinux 项目
Petalinux 项目创建
有了 .xsa 文件之后,可以创建一个 petalinux 项目来生成 Linux 映像、启动文件和 sysroot。
source
make petalinux
该目标可实现如下目标:
- 使用--template zynqMP创建一个初始 petalinux 项目
- 将预定义的 petalinux 配置复制到项目中
- 将预定义的 rootfs 配置拷贝到项目中
- 导入.xsa 文件
- 将预定义的器件树复制到项目中
- 将以下recipe复制到项目中
- bringupcam - 用于图像传感器、串行器、解串器及其相关 V4L2 和媒体控制配置的初始化软件
- autostart – 在启动或登录时自动运行以准备环境并执行其他初始化任务的脚本(包括 bringupcam 应用)
- facedetect – Vitis AI 应用使用 OpenCV 捕获帧,使用 DPU 进行处理,在人脸周围绘制边界框,并输出结果显示
- recipes-apps/vitis-ai – 应用– 导入 Vitis AI 和 DPU 所需的运行时的相关项/报头
- recipes-kernel – 导入 dummy_src 补丁
- 配置 petalinux 项目以启用导入的recipe
- 构建 petalinux 项目
- 封装引导文件
Petalinux 配置
petalinux 配置位于 petalinux/configs/config_2019.2 ,包含以下修改
- ZCU102 设为目标

- Rootfs 设置为 EXT4 分区,位于 /dev/mmcblk0p2 (SD 卡的第二个分区)

- 内核引导参数修改为从 /dev/mmcblk0p2 挂载 rootfs

Rootfs 配置
Rootfs 配置位于 petalinux/configs/rootfs_config_2019.2,包含以下修改
- i2c-tools 已启用,这对调试很有用

- xrt, xrt-dev 和 zocl 支持加速

- gdb 用于调试并打印来自 media-ctl 的点图(同样用于调试)

- json-c 用于 DPU 元数据

- v4l 和 media-ctl 用于配置图像采集管道

- X11的火柴盒桌面和窗口管理器

- 用于处理流水线创建的 Gstreamer 软件包组

- 用于 DPU 处理和边界框绘制的 OpenCV 软件包组

- V4l 软件包组

- 用于显示的 X11 软件包组

- 自定义应用和recipe已启用

修改器件树
为了设置图像采集流水线和Zynq OpenCL框架,需要对器件树进行大量修改。器件树定制位于 petalinux/devicetree/system-user_2019.2. dsi。
MIPI RX 子系统和 Demosaic 通常通过适当的设计设置连接


Demosaic 的输出为 Framebuffer Write IP 提供视频捕获节点

通常,MIPI CSI2 RX 子系统的输入将与上游用于图像传感器驱动程序的 V4L2 节点连接,用于实现流水线。在这种情况下,摄像头传感器驱动程序并存在一定难度,因为需要配置并管理 I2C 路径中的串行器/解串器。bringupcam用户空间应用代替该驱动程序并处理所有 I2C 对串行器/解串器和图像传感器的访问。但是,MIPI CSI2 RX 子系统输入不能在器件树中保持未连接状态,否则将无法正确创建 /dev/media 节点。针对这一问题有3 种选项可供使用:
- 在静态路由模式下使用 AXI Stream Switch IP(其它情况下可用于在没有任何实际硬件访问的情况下对 V4L2 流水线配置的更改进行建模)——不起作用,因为 xlnx,num-si-slots 属性必须 > 1,否则驱动程序会失效
- 在使用 Xilinx TPG 驱动程序的器件树中添加一个“虚拟”节点——这个选项同样也不会直接起作用,因为 TPG 驱动程序实际上需要访问 TPG 中的寄存器来对其进行配置。如果 PL 设计中不存在 TPG,驱动会挂起系统
- 此选项可扩展为实际在 FPGA 设计中包括一个“虚拟”TPG/VTC,但 AXI流接口未连接。这样虽然可以满足驱动程序,但并不理想,因为这么做浪费了宝贵的 FPGA 资源
- 自定义驱动实现充当虚拟源代码以满足流水线
最终选择上面的选项 3 用于最纯净的实现。此驱动程序在 repos/dummy_src_driver 中作为内核补丁提供。
该 dummy_src 驱动程序还需要一个器件树节点。由于其实现是基于赛灵思 TPG 驱动程序,因而属性相似。

最后,需要向 ZOCL 驱动程序发送有关 AXI 中断控制器可用的中断信息

Bringupcam 应用说明
Bringupcam应用属于模块化软件服务,其目的是在 FMC 卡上完成图像传感器、串行器和解串器的 I2C 配置。它在目标文件系统的 /etc 中查找 hardware.conf 文件,是一个相对较大的代码库,其实现/操作超出了本文的范围。源文件已向感兴趣的人提供。
Autostart 应用说明
petalinux/recipes/autostart 是 Yocto recipe,它将一些初始化脚本插入到自动运行的根文件系统中。
petalinux/recipes/autostart/autostart.bb 为recipe本身,如此处显示

使用 Vitis AI 为基于 GMSL 摄像头的人脸检测加速第三部分
此recipe由 Petalinux 选取并在构建期间由 Yocto 后端处理。SRC_URI 变量指示安装到 rootfs 中的两个文件(autostart.sh 和 loginenv.sh)。 INITSCRIPT_NAME 和 INITSCRIPT_PARAMS 是关于 update-rc.d 如何处理插入 autostart.sh 作为初始化脚本的说明。do_install() 回调可处理将脚本安装/复制到目标 rootfs 中的 /etc/init.d 和 /etc/profile.d。
autostart.sh 脚本本身如下所示

注意,dpu.xclbin 是从 SD 卡上的第一个分区复制到 /usr/lib 中的。当 facedetect 应用运行时,XRT 会对其定位并加载。
Facedetect 应用说明
Facedetect 应用是本教程的主要应用。main() 函数如下所示

OpenCV VideoCapture 分类用于从 Gstreamer 捕获流水线中捕捉帧。默认情况下,v4l2src 使用 /dev/video0。cur_frame Mat 对象通过 ml_task(其本身是一个 xilinx::ai::FaceDetect 对象)传递给 DPU。人脸检测算法的输出传递给 process_result() 函数,该函数使用 OpenCV rect() 函数绘制边界框。最终输出帧写入 OpenCV VideoWriter 分类,再到 Gstreamer 显示管道,该管道使用 Mali GPU 将显示渲染到 Displayport 接口(glimagesink 插件)上。XR24 是对应于所用 RGB 像素格式的源代码。 详情见 https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/videodev.html#videodev
Vitis AI库recipe
petalinux/recipes/vitis-ai 只包含一个 bitbake recipe,如下所示

注意,FILESEXTRAPATHS_prepend 和 SRC_URI 指向之前创建的 repos/vitis-ai-pfm。有许多依赖项和配置可以对这些库进行打包。随后将运行时依赖项安装到目标 rootfs 中。