Introduction

If you are a firmware engineer and you have been involved even a little bit in higher-level software development, you must have noticed how much the embedded development and in particular its environment and tooling setup has been lagging behind. Today there are so many modern and useful tools that enable rapid platform- and host-independent development.

Fortunately, gone are the days when you were forced to use tools that were available mostly for Windows only(*). On the top of that, these tools usually only worked with an outdated version of Windows. Updating either your workstation OS or your toolchain was always a stressful challenge, usually followed by a few days of debugging the “why suddenly my tools don’t work anymore” scenarios.

(*): Except when you’re involved in automotive firmware development and you are forced to use tools and certified compilers with text editor interfaces from the stone age. Then I feel sorry for you. Been there, done that. Don’t get me wrong, it was extremely rewarding to develop automotive-grade stuff. I wanted it. I liked it. I learned a lot and gained so much expertise. I draw the line at AUTOSAR though… Read the infamous comment from u/AUTOSAREEEEEEEE in the Embedded subreddit to see why.

Today the situation is much better; almost all of the modern tools are fully cross-platform, the ARM GNU toolchain works flawlessly, we have Docker, we have great open source tools, build systems, a wide variety of modern editors, powerful debuggers, and so on. Yet somehow these tools are not (yet) often utilized when it comes to firmware development. To combat this, I’m actively trying to modernize my (and my team’s) firmware development environment. This not only increases efficiency but also boosts developer satisfaction.

This project includes Docker containers that provide a full-blown development environment, equipped with all the modern tools. The best part? You can use the containers straight away as devcontainers: the development of a firmware project can be started with a single click, regardless of the machine and host environment.

Overview

The project repository contains docker container images with GNU Arm Embedded Toolchain pre-installed. Each image has a specific GCC version. The images are based on akospasztor/docker-python.

Links:

Read more, clone or fork the project at my GitHub repository:

akospasztor/docker-gcc-arm

Pipeline status:

Docker Image CI

Available Images

Available images:

Image: Architecture Base image
10-2020-q4 linux akospasztor/docker-python:3.11-linux-2.0.1
9-2020-q2 linux akospasztor/docker-python:3.11-linux-2.0.1
9-2019-q4 linux akospasztor/docker-python:3.11-linux-2.0.1
8-2019-q3 linux akospasztor/docker-python:3.11-linux-2.0.1

Tags

Check out the GitHub repository’s README for the up-to-date list of available tags.

Components

All latest images contain the following main software packages:

Software: Version
Clang-format latest available in apt
Clang-tidy latest available in apt
CMake 3.29.6
Doxygen latest available in apt
GCC for ARM (arm-none-eabi) depends on the image
Make latest available in apt
Ninja 1.12.1
Python 3.11

Use as a Devcontainer in VSCode

Create a .devcontainer folder in the project folder, then create a devcontainer.json file in it based on the following example:

{
	"name": "docker-gcc-arm:10-2020-q4-linux",
	"image": "docker.io/akospasztor/docker-gcc-arm:10-2020-q4-linux-2.2.0",
	"workspaceFolder": "${localWorkspaceFolder}",
	"workspaceMount": "source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind",
	"runArgs": [
		"--privileged"
	]
}

Whenever you open the project folder in VSCode, it automatically recognizes the devcontainer file and offers to reopen the project inside the container with one click. That’s it. Read more about developing inside a container here: Developing inside a Container

Manual Usage

Pull latest image with gcc version 10-2020-q4 for linux:

docker pull akospasztor/docker-gcc-arm:10-2020-q4-linux-latest

Build image with gcc version 10-2020-q4 for linux:

docker build -t akospasztor/docker-gcc-arm:10-2020-q4-linux-latest 10-2020-q4/linux/

Manually run container and mount a project folder:

docker run --rm -it -v <path-to-project>:<path-to-project> akospasztor/docker-gcc-arm:10-2020-q4-linux-latest

Manually push all tags to Docker Hub:

docker push -a akospasztor/docker-gcc-arm