3. 开发环境搭建与交叉编译工具链
STM32MP 系列属于异构多核处理器:Cortex-A7 运行 Linux,Cortex-M4 运行实时固件。这种结构决定了开发环境不是单一 IDE 就能覆盖的,而是由“配置工具 + 集成开发环境 + 交叉编译工具链 + 烧录与调试通道”四部分共同组成。本节围绕 STM32CubeMX、STM32CubeIDE、OpenSTLinux SDK 的安装与配合使用展开,并给出交叉编译、镜像烧录和串口调试的完整操作路径。
一、工具链分工与整体关系
先明确各工具的职责边界,避免混用:
- STM32CubeMX:图形化完成引脚分配、时钟树配置、外设初始化,并生成设备树片段(.dtsi)、TF-A/U-Boot 配置以及 M4 侧工程骨架。它解决的是“硬件资源怎么分配”。
- STM32CubeIDE:基于 Eclipse 的集成环境,内置 GCC 交叉编译器,主要用于 Cortex-M4 固件开发、编译、下载与 SWD 调试,也可用于 A7 侧裸机或小规模工程。它解决的是“M4 代码怎么写、怎么调”。
- OpenSTLinux SDK:ST 官方提供的 Yocto 交叉编译环境,包含 arm-ostl-linux-gnueabi 工具链、sysroot 和内核头文件,用于编译 A7 侧 Linux 应用、内核模块和驱动。它解决的是“Linux 用户态/内核态程序怎么编”。
三者关系可以用下面的信号与数据流图表示:CubeMX 输出的配置同时喂给 CubeIDE 和 OpenSTLinux 构建系统,最终由 CubeProgrammer 把 TF-A、U-Boot、内核、根文件系统烧入 eMMC/SD 卡,串口则贯穿整个启动与调试过程。
二、安装与版本匹配
安装顺序建议为:先装 STM32CubeMX,再装 STM32CubeIDE,最后安装 OpenSTLinux SDK。原因是 CubeMX 生成的工程需要被 CubeIDE 直接导入,而 SDK 的安装脚本会检查主机依赖(如 Python3、git、chrpath、diffstat 等)。
版本匹配是常见踩坑点。以 STM32MP157 为例,若使用 OpenSTLinux 5.0 发行版,应选择对应的 STM32CubeMX 6.11 及以上版本,并确保 CubeIDE 版本不低于 1.15。版本错配最典型的表现是:CubeMX 生成的设备树节点名称与 SDK 中内核源码的绑定文档不一致,编译时出现 undefined node label 或 no matching binding 错误。
SDK 安装的核心命令如下(以 Linux 主机为例):
# 1. 解压 SDK 安装包
tar xf en.SDK-x86_64-stm32mp1-openstlinux-6.1-yocto-mickledore-x86_64-toolchain-5.0.sh.tar.gz
# 2. 执行安装,指定安装目录
./en.SDK-x86_64-stm32mp1-openstlinux-6.1-yocto-mickledore-x86_64-toolchain-5.0.sh -d /opt/st/stm32mp1/5.0
# 3. 激活环境(每次新开终端都要执行)
source /opt/st/stm32mp1/5.0/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
# 4. 验证工具链
arm-ostl-linux-gnueabi-gcc --version
echo $SDKTARGETSYSROOT
第 4 步中 $SDKTARGETSYSROOT 应输出类似 /opt/st/stm32mp1/5.0/sysroots/cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi 的路径。若为空,说明环境脚本未正确 source,后续交叉编译会退化为主机本地编译,生成 x86 可执行文件,烧到板子上必然报 Exec format error。
三、交叉编译实操
交叉编译的本质是:在 x86_64 主机上,用目标架构的编译器生成 ARM 指令。以编译一个简单的 GPIO 控制程序为例:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(void) {
int fd = open("/sys/class/gpio/gpio14/value", O_WRONLY);
if (fd < 0) { perror("open gpio"); return 1; }
write(fd, "1", 1);
close(fd);
printf("GPIO14 set high\n");
return 0;
}
编译命令使用 SDK 提供的 $CC 变量,它已包含 --sysroot 和 -march=armv7-a 等参数:
$CC gpio_test.c -o gpio_test
file gpio_test
# 输出应包含:ELF 32-bit LSB executable, ARM, EABI5
若 file 显示为 x86-64,说明 $CC 未生效,需重新 source 环境脚本。编译内核模块时则需额外指定内核构建目录:
make -C $KERNEL_SRC M=$PWD modules ARCH=arm CROSS_COMPILE=arm-ostl-linux-gnueabi-
四、镜像烧录与串口调试
STM32MP157 支持三种启动介质:SD 卡、eMMC、NOR Flash。开发阶段推荐先用 SD 卡启动,因为烧录失败不会锁死板载 eMMC,恢复成本低。烧录方式有两种:
- SD 卡直接写入:用
dd把.img写入卡设备,适合首次部署。 - STM32CubeProgrammer + USB DFU:把 BOOT 拨码切到 DFU 模式,通过 USB 烧写 eMMC,适合量产或恢复。
串口调试是贯穿始终的观察窗口。STM32MP157 的 Cortex-A7 调试串口通常为 UART4,参数 115200-8-N-1。上电后应依次看到 TF-A、U-Boot、内核、systemd 的日志。判断启动是否成功的三个关键标志:
- U-Boot 阶段出现
Hit any key to stop autoboot,说明 TF-A 和 U-Boot 正常。 - 内核阶段出现
Kernel command line和mmc0: new high speed SDHC card,说明存储识别正常。 - 用户态出现
stm32mp1 login:,说明根文件系统挂载成功。
五、环境验证清单
完成上述步骤后,建议按以下清单逐项确认,避免把环境问题带入后续开发:
| 检查项 | 验证命令/现象 | 合格标准 |
|---|---|---|
| CubeMX 版本 | Help → About | 与 SDK 发行版匹配 |
| CubeIDE 编译器 | Project → Build | 无 toolchain not found |
| SDK 环境变量 | echo $SDKTARGETSYSROOT | 输出非空且路径存在 |
| 交叉编译产物 | file gpio_test | ARM 32-bit ELF |
| 串口连接 | 上电观察日志 | 出现 login 提示符 |
| 网络连通 | ping 主机 IP | 可互通,便于 NFS 调试 |
这套环境一旦跑通,后续的驱动开发、应用部署和现场集成才有稳定的基础。建议把 SDK 环境激活命令写入 ~/.bashrc 或独立脚本,减少重复操作带来的版本漂移风险。