4. 开发环境搭建与工具链
i.MX VPU 的开发不是“装个编译器就能跑”的简单任务。VPU 是 SoC 内部一个带独立固件的协处理器,主机侧需要内核驱动(如 mxc_vpu、hantro 系列)、用户态库(libvpu、GStreamer 插件 vpuenc/vpudec)以及一段必须与硬件版本匹配的固件二进制。因此,开发环境的核心目标可以概括为:让目标板上的内核、驱动、固件、用户态库四者版本自洽,并让主机具备可复现的交叉编译与调试能力。
一、硬件与软件基线选择
常见参考板包括 i.MX6 系列的 SabreSD、i.MX8M 系列的 EVK、i.MX8QXP MEK 等。选板时优先确认三件事:VPU 型号(如 i.MX6 的 CODA960、i.MX8M 的 Hantro VC8000)、BSP 版本(NXP 官方 Yocto BSP 或 Linux 主线)、以及是否有可用的固件包。以 i.MX8M Plus EVK 为例,典型基线是 NXP Yocto BSP(如 imx-5.15.71-2.2.0)配合 imx-vpu-hantro 与 imx-vpu-hantro-vc 固件包。
Yocto 与 Buildroot 的取舍:Yocto 生态完整、NXP 官方支持好、便于生成 SDK,适合产品化;Buildroot 构建快、配置直观,适合快速验证或资源受限场景。若目标是长期维护与量产,建议以 Yocto 为主,Buildroot 作为对照验证手段。
二、Yocto 环境搭建与 SDK 生成
在 Ubuntu 20.04/22.04 主机上,先安装依赖:
sudo apt install gawk wget git diffstat unzip texinfo gcc build-essential \
chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils \
iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev pylint3
随后获取 BSP 并初始化构建目录:
repo init -u https://source.codeaurora.org/external/imx/imx-manifest \
-b imx-linux-kirkstone -m imx-5.15.71-2.2.0.xml
repo sync
DISTRO=fsl-imx-xwayland MACHINE=imx8mp-lpddr4-evk source imx-setup-release.sh -b build-vpu
bitbake core-image-base
构建完成后生成 SDK,供主机交叉编译使用:
bitbake core-image-base -c populate_sdk
# 产物位于 tmp/deploy/sdk/,例如 fsl-imx-xwayland-glibc-x86_64-core-image-base-aarch64-imx8mp-lpddr4-evk-toolchain-5.15.71.sh
./fsl-imx-xwayland-...-toolchain-5.15.71.sh
安装后执行 source /opt/fsl-imx-xwayland/5.15-kirkstone/environment-setup-aarch64-poky-linux,此时 $CC、$CXX、$SDKTARGETSYSROOT 均已就绪,可直接用 $CC 编译 VPU 应用。
三、交叉编译 VPU 用户态程序
VPU 应用通常链接 libvpu 或直接调用 /dev/mxc_vpu 的 ioctl。一个最小验证程序只需打开设备节点并查询版本:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/mxc_vpu.h>
int main(void) {
int fd = open("/dev/mxc_vpu", O_RDWR);
if (fd < 0) { perror("open /dev/mxc_vpu"); return 1; }
struct vpu_version ver;
if (ioctl(fd, VPU_IOC_GET_VERSION, &ver) == 0)
printf("VPU fw %d.%d.%d\n", ver.fw_major, ver.fw_minor, ver.fw_release);
close(fd);
return 0;
}
编译命令:$CC vpu_probe.c -o vpu_probe,将产物通过 scp 或 NFS 传到板端运行。若返回 open: No such file or directory,说明内核未加载 VPU 驱动或设备树未使能节点,需回到内核配置排查。
四、VPU 固件加载机制
VPU 固件通常以 .bin 形式放在根文件系统的 /lib/firmware/ 下,由内核驱动在 probe 阶段通过 request_firmware() 加载。以 i.MX8M 的 Hantro 为例,固件文件为 hantro/vpu_fw.bin 或 vc8000e_fw.bin。若固件缺失,dmesg 会出现 Direct firmware load for ... failed,VPU 节点虽存在但编解码会返回 -EINVAL。
验证固件是否加载成功,可查看:
dmesg | grep -i vpu
cat /sys/kernel/debug/vpu/version # 部分 BSP 提供
ls -l /lib/firmware/hantro/
五、调试工具链
板端常用工具包括:v4l2-ctl 用于枚举 VPU 暴露的 V4L2 设备与格式;gst-launch-1.0 配合 vpuenc/vpudec 做端到端编解码验证;perf 与 top 观察 VPU 中断与 CPU 占用;strace 跟踪 ioctl 调用。主机侧则用 gdb-multiarch 配合 gdbserver 调试用户态程序。
一个典型的 GStreamer 验证命令:
gst-launch-1.0 videotestsrc num-buffers=300 ! video/x-raw,width=1920,height=1080 \
! vpuenc_h264 bitrate=8000 ! filesink location=test.h264
若输出文件可被 ffprobe 正常解析且帧数正确,说明 VPU 编码链路已通。
六、环境自检清单
在进入实际编解码开发前,建议逐项确认:主机 SDK 可正常 $CC 编译 aarch64 程序;板端 /dev/mxc_vpu 或 /dev/video* 节点存在;dmesg 无固件加载失败;gst-inspect-1.0 | grep vpu 能列出插件;v4l2-ctl --list-formats 能看到 H.264/H.265 格式。这五项全部通过,说明工具链与固件链路已打通,后续的编码参数调优、多路并发、性能分析才有可靠基础。
make menuconfig 中勾选 BR2_PACKAGE_IMX_VPU 与对应固件包,并确保 BR2_LINUX_KERNEL 使用 NXP 内核分支,否则 VPU 驱动可能缺失。vpu_fw.bin 可能导致编码花屏或 VPU 挂死,且 dmesg 不一定报错,需通过实际编码输出判断。