4. 开发环境与工具链

在 i.MX 机器视觉边缘平台上,开发环境不是“装个编译器”那么简单。你最终要在目标板上跑起摄像头采集、NPU 推理、显示输出和网络回传,而目标板的 CPU 架构是 ARM Cortex-A(如 i.MX 8M Plus 的 Cortex-A53),与开发主机 x86_64 不同。因此整条工具链必须解决三件事:为目标板生成可启动的 Linux 系统、在主机上编译出目标板可执行的程序、把程序与依赖可靠地部署到板端并验证。NXP 官方推荐的主线方案是 Yocto Project + i.MX Linux BSP,再叠加 SDK 与交叉编译工具链。

一、四个概念的分工

先把角色分清,后面操作才不会混:

  • Yocto Project:构建框架。它用 BitBake 解析配方(recipe,.bb 文件),按层(layer)组织元数据,最终产出 U-Boot、Linux 内核、设备树、根文件系统镜像。
  • Linux BSP:NXP 针对具体 i.MX 芯片发布的板级支持包,包含 U-Boot、内核、设备树、驱动补丁和 Yocto 层(如 meta-imx、meta-freescale)。BSP 决定“这块板能不能被正确初始化”。
  • 交叉编译工具链:在 x86_64 主机上生成 ARM64 代码的编译器集合,含 aarch64-poky-linux-gcc、g++、ld、gdb、sysroot。它保证头文件与库版本和目标板根文件系统一致。
  • SDK:把工具链、sysroot、环境脚本打包成可安装产物(.sh 自解压脚本),安装后通过 source environment-setup-* 一键进入交叉编译环境。

四者关系可以用一张数据流图看清:BSP 提供元数据,Yocto 消费元数据并产出镜像与 SDK,SDK 提供工具链,工具链编译应用,应用部署到目标板。

i.MX 视觉平台开发环境数据流 开发主机 (x86_64 Ubuntu) i.MX Linux BSP meta-imx / 内核 / U-Boot Yocto Project BitBake + 层 + 配方 SDK 安装包 .sh 自解压 交叉编译工具链 aarch64-poky-linux-gcc 应用工程 (CMake / Makefile) 视觉采集 · NPU 推理 · 显示 · 网络 产物:可执行文件 + 依赖库 ELF aarch64 · .so · 模型文件 目标板 (i.MX 8M Plus, aarch64) U-Boot + 内核 + 设备树 imx8mp-evk.dtb · 启动链 根文件系统 (rootfs) 含运行时库 · 驱动模块 部署与运行 scp / NFS / SD 卡 · 串口日志 验证:摄像头 / NPU / 显示 /dev/video0 · /dev/galcore 部署 烧录镜像

二、搭建 Yocto 构建环境

以 i.MX 8M Plus EVK 为例,主机建议 Ubuntu 20.04/22.04,至少 8 核 CPU、16 GB 内存、200 GB 空闲磁盘(Yocto 构建缓存很大)。先安装依赖:

sudo apt install -y 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 \
  xterm zstd liblz4-tool file locales
sudo locale-gen en_US.UTF-8

然后获取 NXP BSP 发布包(以 imx-5.15.71-2.2.0 为例,具体版本以官方为准):

mkdir ~/imx-yocto-bsp && cd ~/imx-yocto-bsp
repo init -u https://github.com/nxp-imx/imx-manifest \
  -b imx-linux-kirkstone -m imx-5.15.71-2.2.0.xml
repo sync -j8

接着用 imx-setup-release.sh 初始化构建目录,选择图形后端(视觉平台通常选 wayland 或 fb):

DISTRO=fsl-imx-wayland MACHINE=imx8mp-lpddr4-evk \
  source imx-setup-release.sh -b build-imx8mp

初始化完成后,conf/local.conf 与 conf/bblayers.conf 已自动生成。此时可执行构建:

bitbake imx-image-multimedia      # 含多媒体与图形栈的完整镜像
# 或
bitbake core-image-minimal        # 最小系统,用于快速验证启动

构建产物位于 tmp/deploy/images/imx8mp-lpddr4-evk/,关键文件包括 imx-boot(含 U-Boot 与 SPL)、Image(内核)、*.dtb(设备树)、*.wic.gz(可烧录 SD 卡镜像)。

三、生成并安装 SDK

应用开发不必每次重跑 BitBake,而是生成 SDK:

bitbake imx-image-multimedia -c populate_sdk

产物形如 fsl-imx-wayland-glibc-x86_64-imx-image-multimedia-armv8a-imx8mp-lpddr4-evk-toolchain-*.sh。安装到主机:

chmod +x fsl-imx-wayland-*.sh
./fsl-imx-wayland-*.sh -d ~/imx-sdk
source ~/imx-sdk/environment-setup-armv8a-poky-linux

执行 source 后,环境变量 CC、CXX、SDKTARGETSYSROOT 被设置,aarch64-poky-linux-gcc 进入 PATH。可用 echo $CC 确认,输出应类似 aarch64-poky-linux-gcc -mcpu=cortex-a53 ...。这一步是判断“工具链是否就绪”的最直接依据。

四、交叉编译一个视觉应用

以一个读取摄像头并打印分辨率的示例说明流程。工程用 CMake 组织:

cmake_minimum_required(VERSION 3.16)
project(cam_probe C)
find_package(PkgConfig REQUIRED)
pkg_check_modules(V4L2 REQUIRED libv4l2)
add_executable(cam_probe main.c)
target_include_directories(cam_probe PRIVATE ${V4L2_INCLUDE_DIRS})
target_link_libraries(cam_probe PRIVATE ${V4L2_LIBRARIES})

在已 source SDK 的终端中构建:

mkdir build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE=$OECORE_NATIVE_SYSROOT/../toolchain.cmake ..
make -j8
file cam_probe

file 输出应显示 ELF 64-bit LSB executable, ARM aarch64。若显示 x86-64,说明没有正确进入交叉编译环境,需重新 source。

五、部署到目标板并验证

目标板启动方式有两种:把 .wic.gz 解压后用 dd 写入 SD 卡,或通过 uuu(NXP 的 MFGTool 命令行版)经 USB 烧录 eMMC。首次启动建议接串口(115200 8N1),观察 U-Boot 与内核日志,确认 imx8mp-evk 设备树加载、/dev/video0 与 /dev/galcore 出现。

应用部署常用三种方式:

  • scp:scp cam_probe root@192.168.1.100:/opt/,适合单文件快速迭代。
  • NFS:主机导出 /srv/nfs,板端 mount -t nfs -o nolock 192.168.1.10:/srv/nfs /mnt,改代码后无需重新拷贝。
  • 打包进镜像:把应用写成 Yocto 配方加入 local.conf 的 IMAGE_INSTALL,适合量产固化。

部署后运行 ./cam_probe,若打印出 1920x1080 MJPG 之类信息,说明采集链路通;再运行 NPU 推理样例,观察 /dev/galcore 是否被打开、推理耗时是否在预期范围。若程序报 cannot execute binary file,通常是架构不匹配;若报 libxxx.so not found,则是 sysroot 与板端库版本不一致,需用 SDK 重新编译或把对应库一并部署。

建议把 source environment-setup-* 写入一个 env.sh,每次开终端先执行,避免误用主机原生 gcc 编译出 x86 程序。
Yocto 构建对磁盘和内存消耗大,且首次构建可能耗时数小时。不要在主目录空间不足时启动 bitbake,否则中途失败会留下难以清理的缓存。