WIP
Cheatsheet for working with C++ in an embedded bare-metal environment.
- Intro
- CPUs
- Hosted vs. Freestanding
- Compilers
- Assembler
- Linker
- Tools
- Build System
- Libraries
- IDE
- Debugging
- Examples
- No MMU (most of the time)
- 32 Bit
- Cortex-M Series
Numbers for Frequency, Flash & RAM where taken from the STM product lineup. Others manufacturers may vary, but will probably have a similar offering.
Feature | M0/M0+ | M3 | M4 | M7 |
---|---|---|---|---|
Microarchitecture | ARMv6-M | ARMv7-M | ARMv7E-M | ARMv7E-M |
Interrupts | 1-32 | 1-240 | 1-240 | 1-240 |
Frequency | 32-64 Mhz | 24-120 Mhz | 48-180 Mhz | 200-600 Mhz |
Flash | 8-256 kBytes | 16-1024 kBytes | 16-2048 kBytes | 64-2048 kBytes |
RAM | 2-36 kBytes | 4-128 kBytes | 16-640 kBytes | 128-1024 kBytes |
Floating Point (single) | ❌ | ❌ | ✔️ (optional) | ✔️ (optional) |
Floating Point (double) | ❌ | ❌ | ❌ | ✔️ (optional) |
STM Series | L0, G0 | F1, F2, L1 | F3, F4, L4 | F7, H7 |
For the complete list see: GCC manual
Flag | Description | gcc | clang |
---|---|---|---|
-mcpu= |
This specifies the name of the target ARM processor. | ✔️ | ✔️ |
-mthumb |
Use thumb instructions. | ✔️ | ✔️ |
-mfloat-abi |
Specifies which floating-point ABI to use. | ✔️ | ✔️ |
- 8 Bit
- Arduino
Flag | Description | gcc | clang |
---|---|---|---|
-mmcu= |
Select the MCU chip. See GCC manual | ✔️ | ✔️ |
-mint8 |
Assume int to be 8-bit integer. Not standard! See GCC manual | ✔️ | ❌ |
- 32 Bit
- Open Source ISA
- Headers
- Exceptions
- RTTI
Flag | Description | gcc | clang |
---|---|---|---|
-std=c++17 |
Set the language standard for C++. Possible values: 98, 11, 14, 17, 20 | ✔️ | ✔️ |
-std=gnu++17 |
Same as above, but with GNU extensions enabled. | ✔️ | ✔️ |
-ffreestanding |
Enables freestanding C/C++. Default is hosted. | ✔️ | ✔️ |
-fno-exceptions |
See fno-exceptions. | ✔️ | ✔️ |
-fno-rtti |
See fno-rtti. | ✔️ | ✔️ |
-nostdinc++ |
Do not search for header files in the standard directories specific to C++. | ✔️ | ✔️ |
Disable exception handling. See GCC manual for more details.
Disable generation of information about every class with virtual functions for use by the C++ run-time type identification features dynamic_cast
and typeid
. Can save space if not needed. Mixing code compiled with -frtti
with that compiled with -fno-rtti
may not work.
Flag | Description | gcc | clang |
---|---|---|---|
-O |
Sets optimization level. Possible values: 0,1,2,3,s,g & z on clang. |
✔️ | ✔️ |
-flto |
Enables link time optimization. | ✔️ | ✔️ |
-fno-unroll-loops |
Disable loop unrolling. Can save space. | ✔️ | ✔️ |
Flag | Description | gcc | clang |
---|---|---|---|
-Og |
Enable optimization level which is tuned for best debuggability while still performing OK. | ✔️ | ✔️ |
-g |
Include debug symbols. | ✔️ | ✔️ |
-ggdb |
✔️ | ✔️ |
Flag | Description | gcc | clang |
---|---|---|---|
-Wall |
Basic warnings. Should always be used. | ✔️ | ✔️ |
-Wextra |
Everything from -Wall plus more. |
✔️ | ✔️ |
-Wpedantic |
Issue all the warnings demanded by strict ISO C and ISO C++. | ✔️ | ✔️ |
-Werror |
Make all warnings into errors. | ✔️ | ✔️ |
Flag | Description | gcc | clang |
---|---|---|---|
-x assembler-with-cpp |
Enables the C preprocessor for assembly files. | ✔️ | ✔️ |
When using g++ or clang++ as the linker front end prefix all flags with -Wl. Example: -Wl,--no-undefined
Flag | Description | gcc | clang |
---|---|---|---|
-Tpath/to/linkerscript |
Path to the location of the linker script | ✔️ | ✔️ |
-fstack-usage |
✔️ | ❌ | |
--print-memory-usage |
✔️ | ❌ | |
-static |
✔️ | ✔️ |
In this section will take a detailed look at a couple of build system, that can be used for embedded bare-metal development. The two most common right now are Makefile or CMake projects, so let's start with those.
First a quick comparison:
Makefile | CMake |
---|---|
Easy initial setup | The first CMake toolchain file can be a little tricky. |
Portable across Unix-like development hosts | Portable across all development hosts (Linux,macOS,Unix,Windows) |
Clear output showing the set flags & options | Default output does not show direct compiler invocation |
Easy management of multiple executables & libraries (shared code) | |
Combine host tests with device code in same project | |
Some IDE support | Supported by many IDEs and editors |
Generate compile-commands.json via the bear cli utility |
Generate compile-commands.json directly with CMake |
- STL
- STL-like
- Boost
- Terminal + Editor
- VS Code
- CLion
# Launches QEMU as an Arduino Uno and printing USART to stdio.
qemu-system-avr -machine uno -bios firmware.elf -serial mon:stdio -nographic
The examples folder contains some basic Makefile & CMake based projects.