Learning how to use STM32 MCUs by setting up a build environment with CMake and Meson, downloading the ARM compiler, exploring the STM32CubeIDE directory structure, and modifying it to suit personal needs and style.
The CMake build automatically downloads the ARM GNU toolchain into .tools/ on
first configure if it is not already present. No manual toolchain setup needed.
Configure:
cmake -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE=cmake/arm-none-eabi-toolchain.cmakeBuild:
ninja -C buildTo target a different MCU (default is STM32U545xx):
cmake -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE=cmake/arm-none-eabi-toolchain.cmake \
-DTARGET_MCU=STM32H503xxSupported MCUs are defined in cmake/MCU.cmake. Add an elseif block there
to support a new device.
Optional: Symlink compile_commands.json to the root directory for
clangd/ccls.
Linux
ln -sfn ./build/compile_commands.json .Windows (requires admin)
New-Item -ItemType SymbolicLink -Path "compile_commands.json" -Target "./build/compile_commands.json"Use meson to configure your build directory and ninja to compile:
meson setup build --cross-file toolchain/cross.ini
ninja -C buildThe Meson build requires the ARM toolchain to be on PATH. See the
platform-specific sections below for how to set that up.
Download arm toolchains for Linux.
mkdir -p .tools && cd .tools
wget "https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi.tar.xz"
tar -xf arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi.tar.xz
mv ./arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi/* .
rm arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabiSet environment in the current shell environment.
export PATH="$(pwd)/.tools/bin:$PATH"Download arm toolchains for Windows.
mkdir .tools; cd .tools
Invoke-WebRequest `
-Uri "https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-mingw-w64-x86_64-arm-none-eabi.zip" `
-OutFile "arm-gnu-toolchain-14.2.rel1-mingw-w64-x86_64-arm-none-eabi.zip"
unzip arm-gnu-toolchain-14.2.rel1-mingw-w64-x86_64-arm-none-eabi.zipSet environment in the current shell environment. The example below uses
powershell.
$env:PATH = "$(pwd)/.tools/bin;$env:PATH"Linux:
docker build --build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g) -t hellostm32 .Windows:
docker build -t hellostm32 .Run container:
docker run -it --rm -v "$(pwd):/app" hellostm32You can flash your firmware onto the target MCU using various tools. Choose the one that matches your hardware/debug adapter.
Download stlink.
st-flash write build/firmware.bin 0x8000000Windows
If you're downloading through the github release page make sure to copy the
stlink directory under Program Files (x86) in the zip file to the real
Program Files (x86).
And you'll also need to download libusb and put the
dll either in the same path as stlink binaries or expose it in the system
path environment.
openocd -f interface/stlink.cfg -f target/stm32u5x.cfg \
-c "program build/firmware.elf verify reset exit"openocd -f interface/stlink.cfg -f target/stm32u5x.cfgarm-none-eabi-gdb build/firmware.elfgdb
(gdb) target remote localhost:3333
(gdb) load
(gdb) monitor reset init
(gdb) b main
(gdb) cJLinkGDBServer -device STM32U545RET6 -if SWD -speed 4000arm-none-eabi-gdb -ex "target remote localhost:3333" -ex "load" -ex "monitor reset init" -ex "b main" -ex "c" build/firmware.elfFollow the same step as the openocd.
You'll need an account if you want to download anything from ST.
Tutorials
AArch32 bare-metal target (arm-none-eabi)