Using meson for stm32 development

STM32 Meson

Ive been a big fan of stm32-cmake which simplifies the setup of a stm32 embedded project. All that is required is the STMCubeMX directory and the chip being used. All the rest is automatically generated by stm32-cmake. I’ve recently learned about meson and have decided to create the stm32-meson project as a way to learn how to get something useful done is meson.

First I’ll show the expected usage of the project.

jhamberg@serenity ~/s/stm32-meson> meson build \
-Dstm32_cube_dir=$HOME/STM32Cube/Repository/STM32Cube_FW_G0_V1.3.0/ \
-Dstm32_chip=STM32G071RB \
  • -Dstm32_cube_dir points to to the CubeMX directory that contains all the build files for the STM32G0 family. This directory contains all the HAL source files. The $HOME variable must be used because it doesn’t currently seem that meson is able to expand the ~ character into the user’s home directory.
  • -Dstm32_chip option specifies which STM chip is being used and will be used to configure the build system with the correct flash size and ram size.
  • –cross-fileThe cross-file must also be specified. This contains the name of the ARM compiler that will be used. It also contains all the proper linker arguments for compiling the project.

Here is the meson build code required to setup a simply “blinky” application.

# Normal setup of meson project.
project('stm32_meson', 'c',
  version : '0.1',
  default_options : ['warning_level=3'])

# Include the required modules to compile the projects. 
stm32_hal_components = ['uart', 'uart_ex', 'dma', 'gpio', 'tim', 'tim_ex']

# Include to setup all the board dependencies.

# Define STM32 executable.
  dependencies : [stm32_cube_dep, stm32_cmsis_dep]

The stm32_hal_components variable contains a list of all the HAL components that are required by the project. This allows for shorter build times by only including the required HAL components. The stm32_chip can also be specified in the meson build script instead of being passed along at configuration time as well. All the custom setup logic code in included in the stm32-meson/ script. The output of this script are two dependencies called stm32_cube_dep and stm32_cmsis_dep. stm32_cube_dep contains the linker script dependency and the HAL sources to be included into the stm32-blinky executable. The stm32_cmsis_dep is the dependency that includes the startup files for the particular STM32 chip and CMSIS includes which allow certain abstractions to be used across all ARM architectures.

Future Goals

My future goals for this project are to try to achieve as much feature parity with stm32-cmake as possible. Right now the project only supports the STM32G0 family and has been only tested with the STM32G071RB evaluation board. I would like to add support for other stm32 chip families.

Experience with Meson

One of the first things that took getting used to is that there are no functions. My first though was to create a meson function to setup all the dependencies for each executable by simply calling stm32_meson_setup_executable or something like that. Because I didn’t have access to functions I had to do it the more canonical way which is actually better. I setup a dependency which is included by the executable that contains all the supporting resources. I am still trying to figure out a way to easily setup download targets for executables. It would be really convenient to have a stm32_meson_setup_download_target to automatically, but I haven’t yet figured out an easy way to do this without forcing the user to manually set this up for each executable.

Coming from a background of CMake, the meson language is pleasant to work with. All the data structures and simplicity of the language is very much appreciated. It did take a little getting used to the way things are done in CMake. I ran into a couple of things that I thought should have been easier, but had to find a workaround. This is to be expected for learning a new technology.

linux  gcc  meson