2. 开发环境搭建

在STM32MP边缘AI推理部署工程中,开发环境搭建是后续所有工作的物理与软件基础。本节围绕“选板—装SDK—配工具链—通调试链路”四个环节展开,目标是让宿主机能够编译出目标板可运行的AI推理程序,并通过串口与网络完成部署与观测。

一、开发板选型:从算力、内存与接口倒推

STM32MP系列目前主流用于边缘AI的型号包括STM32MP157、STM32MP135与STM32MP257。选型时不能只看CPU主频,而应围绕“模型规模—内存带宽—外设接口”三个约束判断。以STM32MP157为例,其双核Cortex-A7@650MHz搭配Cortex-M4@209MHz,集成3D GPU与DDR3/DDR3L控制器,适合运行TFLite Micro或ONNX Runtime轻量后端;若模型参数量超过2MB或需要摄像头实时推理,则应优先考虑STM32MP257,其Cortex-A35@1.5GHz与NPU(0.6TOPS)能显著降低推理延迟。

实际选型可参考以下判断顺序:先确认模型输入分辨率与量化方式(如INT8、输入224×224),估算单帧计算量;再核对开发板DDR容量(常见512MB/1GB)与是否支持硬件NPU;最后确认摄像头接口(DCMI/MIPI CSI)、以太网PHY与USB是否满足数据采集与部署需求。对于本课程示例,我们以STM32MP157D-DK1为基准平台,其板载1GB DDR3L、千兆以太网、USB OTG与Arduino兼容接口,便于串口与网络双通道调试。

二、Yocto/OpenSTLinux SDK安装:构建可复现的交叉编译环境

ST官方推荐使用OpenSTLinux发行版,它基于Yocto Project构建。宿主机建议使用Ubuntu 20.04/22.04 LTS,并预留至少120GB磁盘空间。安装流程分为三步:获取仓库、初始化构建目录、执行bitbake生成SDK。

# 1. 安装依赖
sudo apt-get 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

# 2. 获取OpenSTLinux层
mkdir -p ~/stm32mp && cd ~/stm32mp
repo init -u https://github.com/STMicroelectronics/oe-manifest.git -b refs/tags/openstlinux-5.15-dunfell-mp1-22-06-28
repo sync

# 3. 初始化构建环境
DISTRO=openstlinux-weston MACHINE=stm32mp1 source layers/meta-st/scripts/envsetup.sh
bitbake st-image-weston
bitbake meta-toolchain

执行完成后,SDK安装包位于tmp-glibc/deploy/sdk/目录下,通常命名为openstlinux-weston-glibc-x86_64-meta-toolchain-cortexa7t2hf-neon-vfpv4-toolchain-*.sh。运行该脚本并指定安装路径(如/opt/st/stm32mp1),即可获得完整的交叉编译工具链、sysroot与Qt/Weston开发库。安装后需执行source /opt/st/stm32mp1/environment-setup-cortexa7t2hf-neon-vfpv4-openstlinux-weston,使$CC、$CXX、$SDKTARGETSYSROOT等变量生效。

若仅需编译TFLite Micro等纯C/C++推理程序,可跳过完整镜像构建,直接使用ST预编译SDK,节省数小时构建时间。但若需修改内核驱动或设备树,则必须走完整Yocto流程。

三、交叉编译工具链配置:从hello到推理程序

工具链生效后,可用一个最小程序验证环境是否可用。创建hello_mpu.c,内容为打印目标板架构信息:

#include <stdio.h>
int main(void) {
    printf("Hello STM32MP1, cross compile OK\n");
    return 0;
}

编译命令为$CC hello_mpu.c -o hello_mpu,随后用file hello_mpu检查输出,应显示ELF 32-bit LSB executable, ARM, EABI5。若显示x86_64,说明环境变量未正确加载。对于AI推理程序,还需在编译时链接TFLite Micro静态库,并指定-mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard以启用NEON加速。

实际工程中建议使用CMake管理交叉编译,在toolchain.cmake中显式设置:

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER $ENV{CC})
set(CMAKE_CXX_COMPILER $ENV{CXX})
set(CMAKE_SYSROOT $ENV{SDKTARGETSYSROOT})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

这样可避免宿主机头文件污染,确保链接到目标板sysroot中的库。

四、串口与网络调试环境:建立双向观测通道

串口是开发板启动阶段最可靠的观测手段。STM32MP157D-DK1的调试串口通常为/dev/ttySTM0,波特率115200。宿主机使用USB转TTL模块连接板载UART引脚(GND、TX、RX交叉连接),然后执行:

sudo picocom -b 115200 /dev/ttyUSB0

上电后应能看到U-Boot与Linux内核启动日志,最终进入root@stm32mp1:~#提示符。若乱码,优先检查波特率与地线;若无输出,检查TX/RX是否接反。

网络调试用于文件传输与远程登录。开发板通过以太网连接路由器后,可用udhcpc -i eth0获取IP,或设置静态IP:

ifconfig eth0 192.168.1.100 netmask 255.255.255.0 up
route add default gw 192.168.1.1

宿主机随后可用scp hello_mpu root@192.168.1.100:/home/root/传输程序,用ssh root@192.168.1.100远程执行。对于AI推理,建议同时开启gdbserver进行远程调试:在目标板运行gdbserver :1234 ./infer_demo,宿主机用arm-openstlinux_weston-linux-gnueabi-gdb连接,即可单步跟踪推理流程。

STM32MP边缘AI开发环境搭建链路 宿主机 (Ubuntu 22.04) Yocto / OpenSTLinux repo sync + bitbake SDK 安装 /opt/st/stm32mp1 交叉编译工具链 arm-openstlinux-gcc CMake 交叉配置 toolchain.cmake 串口终端 picocom /dev/ttyUSB0 STM32MP157D-DK1 U-Boot / TF-A 启动日志输出 Linux 内核 OpenSTLinux 5.15 根文件系统 Weston + TFLite AI 推理程序 infer_demo (ARM ELF) 网络服务 ssh / scp / gdbserver 镜像烧录 SDK 匹配 sysroot 链接 scp 部署 串口/网络调试 关键验证:file 输出 ARM ELF → 串口登录成功 → scp 传输成功 → gdbserver 远程断点命中

五、环境验证与常见问题

完成上述配置后,建议按以下顺序验证:第一步,在宿主机执行echo $CC,应输出交叉编译器完整路径;第二步,编译hello程序并用file确认ARM架构;第三步,串口登录目标板,执行uname -a确认内核版本与SDK匹配;第四步,通过scp传输hello程序并在目标板运行,输出正确字符串;第五步,启动gdbserver并在宿主机GDB中连接,确认可命中断点。

常见问题包括:bitbake因网络超时失败,可配置DL_DIR使用本地镜像源;串口无输出,检查板载启动拨码是否设置为SD卡启动;scp连接被拒绝,确认目标板sshd已启动且防火墙未拦截22端口。若交叉编译时提示找不到tflite-micro头文件,需将TFLite源码路径加入CMAKE_FIND_ROOT_PATH或直接使用-I指定。

注意:OpenSTLinux SDK中的sysroot与目标板根文件系统必须来自同一版本。若混用不同版本的SDK与镜像,可能出现GLIBC版本不匹配,导致程序在目标板报version 'GLIBC_2.33' not found。建议在SDK安装后记录版本号,并在烧录镜像时核对。