2. 开发环境搭建与系统烧录

STM32MP1 系列(如 STM32MP157A/D、STM32MP135)与普通 STM32 MCU 最大的不同在于:它内部集成了 Cortex-A7 应用核与 Cortex-M4 实时核,运行的是完整 Linux 系统。因此开发环境不是“装一个 IDE 就能跑”,而是由裸机/实时侧工具链、Linux 侧交叉编译 SDK、镜像烧录工具和串口/网络调试通道四部分共同组成。本节按“装工具 → 烧系统 → 通调试 → 跑第一个程序”的顺序展开,最终目标是在开发板上看到自己的 Hello World 输出。

一、三类工具的分工

先厘清每个工具负责什么,避免装错、装重:

  • STM32CubeMX:图形化配置工具,用于生成设备树片段、引脚复用(Pinmux)、时钟树以及 Cortex-M4 协处理器的工程骨架。它输出的是“配置”,不直接编译 Linux 应用。
  • STM32CubeIDE:基于 Eclipse 的集成开发环境,主要面向 Cortex-M4 裸机/RTOS 工程,也可用于调试 A7 侧通过 OpenOCD 连接的场景。
  • OpenSTLinux SDK:ST 官方提供的交叉编译工具链(含 arm-ostl-linux-gnueabi-gcc、sysroot、库文件),用于在 PC 上编译能在开发板 Linux 中运行的应用程序。这是“Hello World”真正要用的工具。
判断标准:如果程序要在开发板的 Linux 终端里执行(如 ./hello),用 SDK 交叉编译;如果程序要跑在 M4 核上,用 CubeIDE。两者不要混用同一份 Makefile。

二、OpenSTLinux SDK 安装

以 Ubuntu 22.04 主机为例,从 ST 官网下载对应版本的 SDK 安装包(示例文件名 en.SDK-x86_64-stm32mp1-openstlinux-6.1-yocto-mickledore-x86_64-toolchain-5.0.sh),执行:

chmod +x en.SDK-x86_64-*.sh
./en.SDK-x86_64-*.sh
# 安装路径示例:/opt/st/stm32mp1/5.0-snapshot
source /opt/st/stm32mp1/5.0-snapshot/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
echo $CC
# 期望输出:arm-ostl-linux-gnueabi-gcc -mthumb -mfpu=neon-vfpv4 ...

关键验证点是 echo $CC 能打印出交叉编译器路径。若为空,说明 environment-setup 脚本未生效,需检查安装路径与 shell 类型(bash 与 zsh 的 source 行为一致,但需确认没有在子 shell 中执行)。

三、TF 卡与 eMMC 启动镜像烧录

STM32MP157 的启动链为:BootROM → TF-A(FSBL)→ U-Boot(SSBL)→ Linux 内核 → 根文件系统。官方镜像通常打包为 .img 或通过 flashlayout.tsv 描述分区。两种常见烧录方式:

  • TF 卡启动:用 dd 将完整镜像写入卡,插卡即启动,适合快速验证,不破坏板载 eMMC。
  • eMMC 烧录:通过 STM32CubeProgrammer 经 USB OTG 或串口,按 flashlayout 分区写入,适合量产与固化系统。
# TF 卡烧录(确认 /dev/sdX 是卡设备,切勿写错盘)
sudo umount /dev/sdX* 2>/dev/null
sudo dd if=st-image-core-openstlinux-6.1.img of=/dev/sdX bs=1M conv=fsync
sync
dd 的 of 参数一旦指向系统盘会直接破坏主机系统。执行前务必用 lsblk 核对设备名与容量,确认是 TF 卡再操作。

四、串口与网络调试环境

串口是开发板最重要的“生命线”,U-Boot 与内核日志都从这里输出。开发板调试串口通常为 115200-8-N-1,连接后可用:

sudo picocom -b 115200 /dev/ttyUSB0
# 或
sudo minicom -D /dev/ttyACM0 -b 115200

网络调试用于文件传输与远程登录。开发板默认 IP 常为 192.168.7.2(USB RNDIS)或由 DHCP 分配。主机侧可用:

ssh root@192.168.7.2
scp hello root@192.168.7.2:/home/root/

若 ping 不通,依次检查:网线/USB 是否插好、开发板 ip addr 是否拿到地址、主机防火墙是否拦截、是否在同一网段。

五、第一个 Hello World 程序

在 SDK 环境已 source 的终端中,创建源码并交叉编译:

mkdir -p ~/hello && cd ~/hello
cat > hello.c <<'EOF'
#include <stdio.h>
int main(void) {
    printf("Hello STM32MP1 from Linux!\n");
    return 0;
}
EOF
$CC hello.c -o hello
file hello
# 期望:ELF 32-bit LSB executable, ARM, EABI5 ...

用 file 确认生成的是 ARM 架构可执行文件,而不是 x86 主机程序,这是交叉编译是否成功的关键判据。随后通过 scp 或 TF 卡拷入开发板,赋予执行权限并运行:

chmod +x hello
./hello
# 输出:Hello STM32MP1 from Linux!

看到该输出,说明“工具链 → 镜像 → 串口/网络 → 应用运行”整条链路已经打通。若报 cannot execute binary file,多为架构不匹配;若报 No such file or directory 而文件确实存在,通常是动态链接器路径不对,可改用 $CC hello.c -o hello -static 静态编译验证。

STM32MP1 开发环境与启动链路 主机(Ubuntu) STM32CubeMX / CubeIDE OpenSTLinux SDK(交叉编译) STM32CubeProgrammer 启动镜像 TF-A(FSBL) U-Boot(SSBL) Kernel + RootFS .img / flashlayout.tsv STM32MP157 开发板 TF 卡 / eMMC 启动介质 Cortex-A7 Linux 系统 Cortex-M4 实时核 编译/打包 烧录 调试通道 串口 115200-8-N-1 SSH / SCP 网络 OpenOCD / JTAG ./hello → Hello STM32MP1 from Linux! 交叉编译成功 + 板端运行成功 = 环境闭环

整条链路可以概括为:主机侧用 SDK 产出 ARM 可执行文件,用 CubeProgrammer 或 dd 把镜像写入 TF 卡/eMMC,开发板经串口输出启动日志、经网络接收文件,最终在 Linux 终端运行程序并观察输出。任一环节断开,都会在串口日志或 file 命令结果中留下可定位的线索。