What is a build server?

Working on an STM32 MCU project? Looking to connect your source code to an automatic build server? This post will detail how to create an STM32 build server that automatically compiles your STM32 project every time new code is pushed to your repository. The value of this tool is huge. Every time a code push breaks your build, you’ll get a notification. Think about it – no more code updates that break your local build!

Creating an STM32 build server is just one of the steps towards a full continuous integration for embedded software. We’ll be discussing test automation in the next series of posts.

A working demo of an STM32 build server

Let’s start with the following working demo. Checkout this GitHub repo. It’s connected to CircleCI and Travis CI. Both tools offer free versions that are satisfactory when you’re working on small projects. When you want your code to be closed source, there’s a paid option for that. We’re using Git as we think it’s perfect for embedded software (check out this link).

How did we do that?

Step 1 – you need a project that you can build from the command line

First, you will need to compile your project using a command line tool. This is critical in being able to run it in a UI-less build server. I used a Makefile project generate using STM32CubeMX, and followed these steps:

  1. Create a project.
  2. Choose your board (in this case – the Nucleo STM32F411RE).
  3. Using the project menu, hit Generate Code.
  4. On Toolchain/IDE, choose Makefile.

makefile project setting

Due to a bug in STM32CubeMX, you will need to manually remove duplicate entries in the Makefile: main.c, stm32f###_hal_msp.c and stm32f###_it.c entries.

makefile c source files duplicate entries

Next, set the BINPATH to look like this – BINPATH = /usr/bin


To make things easy, we created a Docker container that has the toolchain preinstalled. It’s going to be helpful in the CI tools.

To try it locally, follow the next steps:

  1. Install Docker (if you’re looking to implement a continuous integration process, Docker is one of the building blocks you’ll need).
  2. Run
    1. docker pull jumperio/vlab-gcc-arm
    2. git clone https://github.com/Jumperr-labs/stm32_cubemx_sample.git
    3. cd stm32_cubemx_sample
    4. docker run -v $PWD:/my_files_in_docker --entrypoint /usr/bin/make jumperio/vlab-gcc-arm -C my_files_in_docker
  3. Our build files will be in the build folder of the downloaded repo. Sweet!

Makefile is just one option. Checkout the following post for more build tools.

Step 2 – connecting the STM32 build server to a continuous integration service

I chose 2 commonly used services to implement the automatic build server. The value from these services is huge. From the moment you connect the service to your code, you’ll get email notifications whenever the build breaks.

How to setup continuous integration with Circle CI?

Let’s start with CircleCI and follow these steps:

  1. Login – I recommend logging in with your GitHub account as it’ll automatically connect to your projects.
  2. Hit Add Projects button on the left.
  3. Search the project you wish to set up:

CircleCI stm32 build server automation

4. Click on ‘Set Up Project’.

Circle CI uses a config.yml file that should be located under your project root-folder/.circle. Once that file is present in your repo, you can hit the ‘Start Building’ button.

Here’s the config file I’m using in the demo project:

version: 2
      – image: jumperio/vlab-gcc-arm:latest
      – checkout
      – run:
        name: build
        command: make
     – store_artifacts:
       path: build/

I chose our own custom Docker image as the default CircleCI container does not include the ARM-GCC compiler (not a huge surprise :)). Circle CI automatically checks out your project, and will then hit the command ‘make’ as the config file depicts. We’ll then store the artifacts created in the build folder.

And that it! Once you hit ‘Start Building’, a build task will be generated. If it worked locally using Docker, there’s no reason it should not work in the continuous integration server.

Checkout the resulting dashboard in this link.

CircleCI successful result

How to setup continuous integration with Travis CI?

  1. Let me demonstrate another useful continuous integration tool – Travis CI. Travis is highly useful, though it doesn’t provide as many built-in capabilities like Circle CI. For example, artifacts management is only available through Amazon S3 uploading. To setup Travis CI, follow these steps:Log in to Travis-CI
  2. Hit the + button to add a project.

TravisCI setup

  3. Search for your project. If you connected your GitHub account, it’ll find your project. Just search for it and toggle the widget on the right to the on state.

Travis works with a .travis.yml file located in the root folder of your repo. In this sample I used the same container to

build the project:

sudo: required

language: ruby
  – docker
  – docker pull jumperio/vlab-gcc-arm:latest
  – docker run -v $PWD:/my_files_in_docker –entrypoint /usr/bin/make jumperio/vlab-gcc-arm -C my_files_in_docker

And it works too! Here’s a link to the dashboard.

TravisCI successful result of stm32 build server automation

Try it yourself

If you want to take it for a test spin yourself, just fork the sample repo and connect it to CircleCI or Travis-CI. Then, change the code locally and push it to GitHub. You’ll see how the continuous integration services pick up the build task and send you a notification if something broke. Let me know how it works for you in the comment below or at contact@jumper.io

Next steps

Looking to learn how to connect test automation to run right after the automatic build? Check out our latest post on test automation for embedded software.