Bare Metal STM32 Setup without STM32CubeIDE

An STM32 development board

While a chip vendor’s IDE (like STM32CubeIDE) offers many great features and is usually the easiest and quickest way to get the first program on a microcontroller, it is a big learning opportunity to set up the toolchain and build system yourself. Additionally, a flexible setup with something like CMake offers great customizability and integrates nicely with your existing editor or CI pipeline.

Although I don’t want to use the IDE or its code generation, I am still interested in the hardware abstraction library (HAL) by ST. Conveniently, this library is available in a git repository. In my opinion it is very important to strictly separate third-party code from application code, especially with something as big as the HAL library. For this reason, I keep the HAL library (as well as other, device-specific code from ST) in their own git submodules. The only thing I copied into my code base is a system file and the linker script, which I modified slightly.

The NUCLEO-L432KC development board I used for setting up this demo project uses an STM32L432KC, which uses an ARM Cortex-M4 CPU. I built the arm-none-eabi toolchain myself using crosstool-ng. The main reason for this was mainly to use the FPU, as I could not link against the standard toolchain’s hard-float libc.

For libc, I use newlib. With this, I can use standard C functions, such as printf(). To actually see this console output, I attached the read and write “syscalls” to the UART driver code.

For debugging, I usually use GDB with st-util acting as a server between the GDB client and the ST-Link on the development board. If I need a more elaborate overview I also like to use Ozone, which integrates nicely with my SEGGER J-Link.