Skip to content

STM32Cube*

STM32CubeMX and STM32CubeCLT allow the user to write, compile, and flash code to the STM32 microcontroller! STM32CubeCLT contains the GCC compiler and GDB debugging tool for firmware compilation and debugging, and STM32CubeMX contains the interface for configuring the microcontroller and project environment, and provides a very powerful interface for automatic code generation, allowing the user to initialize an entire module with a few clicks of a button, and have that code show up automatically in the main file.

Downloading and Installing the Cube Tools (Linux)

Section titled “Downloading and Installing the Cube Tools (Linux)”

On Ubuntu/Debian, the whole toolchain (CubeMX, CubeProgrammer, CubeCLT, the ARM GNU toolchain, uv, and everything else scripts/build.sh needs) is set up by one script, run once from the repo root:

Terminal window
./scripts/bootstrap.sh

This installs ansible (if it isn’t already present) and runs the ansible/bootstrap.yml playbook, which installs system packages, the ARM GNU toolchain, uv, the cube tools, initializes git submodules, writes your PATH and application launcher entries, and sets up the python virtual environment at tools/.venv.

The cube tools can’t be downloaded automatically as ST gates all of them behind a login (a free MyST account; you may use any email address) with no stable download URL. Partway through, ./scripts/bootstrap.sh will pause and ask you to:

  • Go to the CubeMX download page, select the Linux installer, and download it into install/ at the repo root.

    ST Get Software table, with the Linux CubeMX build and its version picker

  • Go to the CubeProgrammer download page, select the Linux installer, and download it into install/ as well.

  • Go to the CubeCLT download page, select the Debian Linux installer, and download it into install/ as well.

    ST Get Software table, with the Debian CubeCLT build selected

  • Optionally, if you want a graphical debugger other than VS Code, go to the CubeIDE download page, select the Debian Linux installer, and download it into install/ too. It is a ~3 GB download and is skipped when absent, since nothing in the build flow needs it.

  • Press Enter in the terminal running bootstrap.sh to continue.

The script then unpacks and installs each archive it finds. CubeMX and CubeProgrammer use graphical installers with no silent-install flag, so two installer windows will open. Click through both, accepting the default install location (/usr/local/STMicroelectronics/STM32Cube/...). CubeCLT and CubeIDE install without prompting, but you may see a system prompt related to licensing depending on your OS.

Afterwards, the script adds the tools to your PATH via /etc/profile.d/mrover-esw.sh. Open a new terminal to pick it up. The script also writes launcher entries for STM32CubeMX and STM32CubeProgrammer into ~/.local/share/applications, so they show up in your applications menu (STM32CubeIDE installs its own launcher entry system-wide).

The ARM cross-compiler comes from CubeCLT itself; a standalone copy is installed as a fallback but is ordered after CubeCLT on PATH, so CubeCLT’s is the one you get. CubeCLT also ships STM32_Programmer_CLI, which is the copy on your PATH; the standalone CubeProgrammer is the GUI you launch from the applications menu when you want to flash or inspect a board interactively.

Open a new terminal and run:

Terminal window
./scripts/doctor.sh --build

This reports the version and location of every required tool, confirms arm-none-eabi-gcc is coming from CubeCLT, and then builds a small firmware project end to end. If it finishes with all checks passed, your environment is ready. See Build Tools for what each check means.

If bootstrap fails partway through, it’s safe to re-run ./scripts/bootstrap.sh. Every step skips itself if it’s already done, including the two graphical installers.

Upgrading, and Installing Over an Existing Setup

Section titled “Upgrading, and Installing Over an Existing Setup”

Bootstrap is safe to run on a machine that already has the cube tools installed by hand. It never removes an existing install; it installs over it and takes ownership of PATH and the launcher entries.

To upgrade a cube tool, download the newer installer into install/ and re-run ./scripts/bootstrap.sh. Each installer is gated on a stamp file named after the installer itself, not after the directory it installs into, so a new archive always runs and an unchanged one never re-runs. Delete the matching install/.installed-* file to force a reinstall.

To redo just one step, for example the PATH setup after a CubeCLT upgrade, run the following:

Terminal window
ansible-playbook ansible/bootstrap.yml --connection=local --ask-become-pass --tags path-profile

Valid tags are packages, clang-format, uv, arm-toolchain, submodules, stm, path-profile, desktop-entries, python-venv and vscode.

CubeIDE is installed as a debugger only, it does not build anything. The build stays with scripts/build.sh and CMake; CubeIDE attaches to the .elf that build produced. That split is what keeps the terminal build and CI as the build mechanism, while still giving you breakpoints, watch expressions, a call stack, live registers and the peripheral (SFR) view.

If you skipped CubeIDE during bootstrap, drop its archive into install/ and re-run ./scripts/bootstrap.sh (see install/README.md).

CubeIDE will not build for you, so produce the ELF in a terminal:

Terminal window
./scripts/build.sh --src src/bmc --preset Debug

Use the Debug preset. Release is optimized, so breakpoints land in surprising places and half your locals read <optimized out>. The ELF lands at a predictable path:

<src>/build/<preset>/<target>.elf e.g. src/bmc/build/Debug/bmc.elf

Launch STM32CubeIDE from your applications menu. When it asks for a workspace directory, pick somewhere outside the repository (~/cubeide-workspace is fine). CubeIDE writes a large .metadata/ tree into its workspace, and you do not want that inside a git checkout.

File -> Import... -> C/C++ -> Existing Code as Makefile Project -> Next.

  • Existing Code Location: the project directory, e.g. src/bmc
  • Toolchain for Indexer Settings: STM32 Cortex-M GCC
  • Leave “C” and “C++” both ticked, then Finish.

This does not set up a build - it just gives CubeIDE the source tree so it can map addresses back to your files and let you set breakpoints. Turn off Project -> Build Automatically so the IDE never tries.

Run -> Debug Configurations... -> select STM32 C/C++ Application -> New Configuration.

On the Main tab:

  • Project: the project you just imported
  • C/C++ Application: the ELF from step 1, e.g. src/bmc/build/Debug/bmc.elf
  • Under Build (if required) before launching, choose Disable auto build, otherwise CubeIDE tries to build a project that has no build configured and refuses to launch.

On the Debugger tab:

  • Debug probe: ST-LINK (ST-LINK GDB server)

  • Interface: SWD

  • Reset behavior: Connect under reset, the reliable choice if the firmware reconfigures clocks or pins early in main.

  • SFRs / Device: point the SVD at the file for your MCU so the peripheral view is populated. For the STM32G431 boards used here:

    /opt/st/stm32cubeclt_<version>/STMicroelectronics_CMSIS_SVD/STM32G431.svd

    ./scripts/doctor.sh prints the CubeCLT version in use if you are unsure which directory that is.

Apply, then Debug.

5. The Edit-Build-Debug Loop (With CubeIDE)

Section titled “5. The Edit-Build-Debug Loop (With CubeIDE)”
  1. Edit code in your normal editor.
  2. ./scripts/build.sh --src <project-path> --preset Debug in a terminal.
  3. Back in CubeIDE, hit Debug again. It reloads the ELF from disk and re-flashes.

You do not need to re-import or re-create the configuration; only step 2 changes anything.

CubeIDE is not the only option, and nothing here depends on it. CubeCLT ships ST-LINK_gdbserver and arm-none-eabi-gdb, which any GDB front end can drive. The Cortex-Debug extension for VS Code and CLion’s embedded GDB server configuration both work against the same ELF, and ./scripts/doctor.sh already verifies the gdbserver is present and on PATH.

./scripts/bootstrap.sh supports macOS as well as Ubuntu/Debian. It uses Homebrew instead of apt, and Homebrew is the one prerequisite it cannot install for you, get it from brew.sh first, then run the same command as Linux users:

Terminal window
./scripts/bootstrap.sh

The flow is identical: it installs ansible (via brew), the build tools, uv, the ARM toolchain and the cube tools, then writes your PATH and syncs tools/.venv. Download the same archives into install/, picking the macOS build on each ST download page rather than the Linux one.

Two things differ under the hood:

  • PATH setup. macOS has no /etc/profile.d, so the snippet is written to /etc/mrover-esw.sh and sourced from both /etc/zshenv and /etc/profile. As on Linux, opening a new terminal is enough; you do not need to log out.
  • Application shortcuts. .desktop files are an XDG concept and are skipped. ST’s macOS installers register their own .app bundles, so CubeMX, CubeProgrammer and CubeIDE appear in Launchpad on their own.

ST packages its macOS tools inconsistently: each download may arrive as a .zip, a .tar.gz, a .tar.gz wrapped in a .zip, or a .dmg wrapped in a .zip. Bootstrap takes whatever the download page gives you, so do not unpack or convert anything first. It unpacks one level of nesting, then installs by what it finds rather than by filename:

  • .pkg: installed non-interactively with installer.
  • .app: opened with open -W, so a window appears for you to click through, exactly like the Linux CubeMX and CubeProgrammer installers.
  • .dmg: mounted with hdiutil, and the .pkg inside is installed or the .app inside is copied to /Applications. The image is unmounted again whether or not the install succeeded. CubeIDE is normally the one that arrives this way.

Open a new terminal and run:

Terminal window
./scripts/doctor.sh --build

The checks are PATH-based and work the same on macOS; it knows ST’s macOS install roots (/opt/ST, /Applications/STMicroelectronics). The .desktop and /etc/profile.d checks are Linux-only and are skipped rather than reported as problems.

This quick guide will teach you how to make a new project for your STM32G431RB Nucleo board that you will be developing on.

To create a new project, use the scripts/new.sh script. The script accepts either an MCU or Development Board ID, project source, and optionally any number of cmake libraries defined under lib. To create a project for the Nucleo G431RB developer kit, run the following.

Terminal window
./scripts/new.sh --board NUCLEO-G431RB --src <path/to/project>

When prompted to select default peripheral configurations, select “Unselect All” and “continue”.

The CubeMX software component prompt, with Unselect All highlighted

If this is the first time STM32CubeMX is being run on a machine, it may need to download the firmware repository. Select “Download” and continue.

Once the script completes, try to build the generated project as follows.

Terminal window
./scripts/build.sh --src <path/to/project>

If this completes successfully, then STM32CubeCLT is correctly installed on the system.

Open the <project>.ioc file in STM32CubeMX to modify the project configuration.

Congratulations! You have successfully created a new project with CubeMX!

For how the CMake build actually works (the toolchain file, the presets, and the generated libraries) see the Build System reference.