# real-time-cpp: a portable reference application from a book on embedded C++

> The real-time-cpp repository carries the companion code for Christopher Kormanyos' book Real-Time C++, and its centrepiece is a reference application whose application layer is written once and then compiled for around thirty microcontroller targets, from an ATmega328P to an ESP32-P4 and a Raspberry Pi Pico 2, plus the host. It suits embedded developers who want to see modern C++ applied to a real scheduler and HAL, and it is a poor fit if you want a library to drop into a product rather than a worked teaching example.

**ckormanyos/real-time-cpp** — Source code for the book Real-Time C++, by Christopher Kormanyos

- Repository: https://github.com/ckormanyos/real-time-cpp
- Stars: 817 · Forks: 198
- Language: C++
- License: BSL-1.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/ckormanyos-real-time-cpp

## Companion code, and a reference application that actually boots

The repository is the source code for the book Real-Time C++ by Christopher Kormanyos, specifically the fourth edition, titled Efficient Object-Oriented and Template Microcontroller Programming, and it is made available for educational and exploratory use.

That framing matters for how you read everything else. This is not a library you link against and it is not a product. It is a worked example, and the value is in the reading.

The repository has several main parts. The Reference Application lives in ref_app, and that directory also includes the benchmarks under ref_app/src/app/benchmark. There is a directory of Examples from the book and a directory of Code Snippets from the book. The examples directory is organised by chapter, with directories named chapter02_02, chapter02_03, chapter02_03a and onward through chapter17_03a, which is a useful signal that each example corresponds to a specific place in the text.

The reference application is the part worth spending time on, and the README describes its startup path in detail. It boots with a small startup code and subsequently initialises a skinny microcontroller abstraction layer, and control is then passed to a simple multitasking scheduler that manages the LED application, calls a cyclic benchmark task and services the watchdog.

That sequence, startup code, MCAL, scheduler, tasks, watchdog, is the skeleton of a small real time system, and it is presented in a form you can compile and run rather than a form you have to imagine.

The project is licensed under the Boost Software License 1.0, the primary language is C++, the last push to the repository was on 2026-10-16, and there are no published releases, so the code is read from master rather than consumed as a versioned dependency.

## The scheduler runs a half hertz LED and a cyclic benchmark

The behaviour of the reference application is described precisely enough that you can predict what it does on the bench.

The LED application toggles a user LED with a frequency of one half hertz, so the result is LED on for one second and LED off for one second. It runs cyclically and perpetually without break or pause.

That is a deliberately dull workload, and the dullness is the point. A blinking LED is the smallest program that exercises the whole path: startup code runs, the MCAL initialises, the scheduler takes over, a task is dispatched on a cyclic basis, and the watchdog is serviced. If the LED blinks at the right rate, the timing path works. If it blinks at the wrong rate, you have a clock configuration problem, and the reference application is the thing that tells you so.

The cyclic benchmark task serves the second purpose. The benchmarks are the part of the repository that produces numbers, and they exist here to be run on the target rather than on a desktop, which is the only way to get an idea of what a given core and compiler combination actually does with the code you care about.

One more line in the README is worth noting for anyone porting the code: the reference application is compatible with C++14, 17, 20, 23 and beyond. So the same application source is expected to build under four different language standards, which is a strong constraint on how the code is written and a good test of whether the design really is portable rather than merely claiming to be.

## Write once, and change only the bottom two layers

The portability section is short and it is the design thesis of the project.

The application software is implemented once and used uniformly on each supported target in the reference application. Differences among the individual targets arise only in the lower software layers pertaining to chip-specific and board-specific startup and MCAL details.

Two layers is the number to hold on to. Startup code is chip specific by definition, since every microcontroller has its own reset vector, clock tree and memory map. The MCAL is board specific, since it is where the pins, timers and serial ports of a particular board get named. Everything above that, which is where the scheduler, the tasks, the LED application and the benchmark live, is written once.

That is a much stronger statement than the usual embedded claim of portable code, because it is a statement about where the variation is allowed to live. It also means the interesting engineering is in the shared part. The scheduler, the task dispatch and the benchmark harness are the same code everywhere, and if the abstraction leaks, the leak shows up as a target specific change in a file that was supposed to be identical across targets.

The repository root shows the supporting infrastructure for that claim. There is a CMakeLists.txt at the top level, a .clang-tidy configuration with a .tidy directory, a sonar-project.properties file for the SonarCloud analysis, and the cross compilation toolchains are not in this repository at all, but in a separate one, ckormanyos/real-time-cpp-toolchains, which holds the GNU and GCC cross compilers and other tools that run on Windows for certain builds.

## Around thirty targets, from an ATmega to an ESP32-P4

The supported target table is long, and the spread of it says more about the design than any paragraph would.

The list covers an ATmega2560 and the book's own ATmega328P target, an ATmega4809, a BeagleBone with a TI AM335x, a PocketBeagle2 with the multicore AM6254, a Raspberry Pi Zero with the ARM1176JZF-S, an NXP OM13093 LPC11C24 board with Cortex-M0+, a Teensy 4.0 with the iMXRT1062 Cortex-M7, a Renesas R7FA4M1AB Cortex-M4F, a Renesas RX630 and RX631, a Renesas RL78/G13, a SiFive RISC-V FE310, a BL602 single core RISC-V, an Espressif ESP32-P4 multicore RISC-V SoC, the Raspberry Pi Pico with the RP2040, the Pico 2 with the RP2350, and a spread of STMicroelectronics parts: the STM32F100, F407, F429, F446, H7A3, L100C, L152 and L432.

A few of the names also carry a breadboard marker, which tells you which of them are on a development board you can buy and hold.

```bash
atmega2560
rpi_pico_rp2040
stm32f429
esp32p4_riscv_soc
```

Then there are the two non-hardware targets, which matter as much as the boards. The host target is a PC or workstation on Windows, MinGW or any Unix like system, built with the host compiler. The Debug and Release target is a PC on Windows via the MSVC x64 compiler.

Having a host build is what makes the rest of the project practical. You can compile the scheduler, the tasks and the benchmark on your workstation, run them there, and use the same source on the target. The topics attached to the repository reflect the same spread, with arduino, arm, avr, bare-metal, cortex-m, cpp11 through cpp23, stm32, realtime and high-performance among them.

## Five build workflows and several static analysers

The badge row at the top of the README is long, and each badge corresponds to a check that runs on the repository.

There is a build workflow for the reference application itself, a separate workflow to build the examples, one for the code snippets, and one for the benchmarks. Four distinct pipelines, which is the sensible arrangement when the examples and the reference application have different toolchain requirements, since the snippets are small enough to build quickly and the reference application is the slow one.

Then there are the analysis badges. CodeQL runs as a workflow of its own, Coverity Scan is present with a project badge, and SonarCloud carries a quality gate status badge, which is the strictest of the three because a quality gate is a pass or fail condition on new code rather than a report.

The repository also carries a .clang-tidy configuration, with a .tidy directory for any custom checks, and a sonar-project.properties file, so the static analysis configuration is part of the source tree rather than being set in a web interface.

This is a project where the tooling is part of the argument. A portability claim is only credible if the same code is compiled for thirty targets on every commit, and if the analysis gates are configured to fail on regressions. The workflows are what turn the portability claim into something a reader can check.

## Two licence files and an educational-use statement

The licence arrangement is worth a paragraph, because it is not the usual single file.

The README badge names the Boost Software License 1.0, and the repository root contains both LICENSE_1_0.txt and a file called COPYING3. The file named COPYING3 is conventionally the GNU General Public License version 3 text, which is presumably why it is there rather than a second permissive grant.

What the README states is that the repository provides companion code for the book and is made available for educational and exploratory use. That is a statement of intent about the distribution, and it is worth reading alongside the licence file itself if you intend to reuse the code in a product, because a book companion repository and a reusable library are not the same thing and the terms may differ.

This is not a licence opinion, and the point to make is procedural: the repository carries more than one licence file, so the text that governs your use is in the repository rather than in the badge.

The other thing the repository makes clear is what it is for. A reference application that blinks an LED, a set of examples organised by chapter, and a set of snippets is a teaching artefact, and the value is that you can compile it, run it on a board, and read the same code the book describes.

## Conclusion

real-time-cpp suits an embedded developer who wants to read a scheduler, a microcontroller abstraction layer and modern C++ in one place, and who will learn more from a complete application than from a set of isolated snippets, since the reference application boots, schedules, benchmarks and services a watchdog on real silicon. It does not suit a team looking for a production RTOS component, since the project exists to support a book and is presented as being made available for educational and exploratory use. Before you build on it, pick your target from the supported list and confirm a cross toolchain for it, remember that the application layer is shared and the differences live in the startup and MCAL code, and note the licensing detail: the code is offered under the Boost Software License 1.0 with a COPYING3 file also present in the repository, and the last push was on 2026-10-16.

## FAQ

### What is the real-time-cpp repository?

It is the companion source code for the book Real-Time C++ by Christopher Kormanyos, fourth edition, made available for educational and exploratory use. It contains a reference application, examples from the book, and code snippets, with cross toolchains kept in a separate real-time-cpp-toolchains repository.

### How does the real-time-cpp reference application work?

It boots with a small startup code, initialises a skinny microcontroller abstraction layer, and then hands control to a simple multitasking scheduler that manages the LED application, calls a cyclic benchmark task and services the watchdog. The LED toggles at one half hertz, on for one second and off for one second, running cyclically and perpetually.

### How portable is the real-time-cpp reference application?

The application software is implemented once and used uniformly on every supported target. Differences between targets arise only in the lower layers dealing with chip-specific and board-specific startup and MCAL details, and the same application is compatible with C++14, 17, 20 and 23.

### Which targets does the real-time-cpp reference application support?

The table lists around thirty, including the ATmega2560, the ATmega4809 and the book's ATmega328P, the BeagleBone AM335x, the PocketBeagle2 AM6254, the Raspberry Pi Zero and Raspberry Pi, the NXP LPC11C24, the Teensy 4.0, several Renesas parts, the SiFive FE310, the BL602, the ESP32-P4, the Raspberry Pi Pico and Pico 2, a range of STM32 devices, and a host build on Windows, MinGW or Unix, plus an MSVC Debug and Release build for Windows.

### How is the real-time-cpp code licensed?

The README names the Boost Software License 1.0, and the repository root contains LICENSE_1_0.txt alongside a file called COPYING3. The README also states that the code is made available for educational and exploratory use, so read the licence files in the repository if you plan to reuse it.

## Sources

- [ckormanyos/real-time-cpp on GitHub](https://github.com/ckormanyos/real-time-cpp)
- [Issues](https://github.com/ckormanyos/real-time-cpp/issues)
- [License: BSL-1.0](https://github.com/ckormanyos/real-time-cpp/blob/master/LICENSE)
- [README](https://github.com/ckormanyos/real-time-cpp/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ckormanyos-real-time-cpp
