Skip to content

HardFOC core library

RTOS Wrapper

C++ classes for threads, mutexes, semaphores, queues, event flags and timers, over one C portability layer with a backend for FreeRTOS, ThreadX, CMSIS-RTOS2 and no RTOS at all.

Quickstart API guide Source on GitHub

HardFOC handlers and drivers need to lock, wait, sleep and run worker loops, and they must build for an ESP32 with FreeRTOS today, an STM32 with ThreadX or CMSIS-RTOS2 later, and a PC for host tests. This library gives them one API for all of it. Component code includes these headers and never names a kernel; a compile definition picks the backend.

Layer diagram: your code uses the C++ wrapper classes, which call the C portability layer of OsAbstraction.h and OsUtility.h, which includes one backend header chosen at build time: FreeRTOS, ThreadX, CMSIS-RTOS2, or the no-RTOS backend for host tests.Layer diagram: your code uses the C++ wrapper classes, which call the C portability layer of OsAbstraction.h and OsUtility.h, which includes one backend header chosen at build time: FreeRTOS, ThreadX, CMSIS-RTOS2, or the no-RTOS backend for host tests.
One API, one backend per scheduler
Figure description and sources

From top to bottom. Your code uses the C++ classes (listed from include/.h). Every class calls the C portability layer, the OS_ types and os_* functions of OsAbstraction.h and OsUtility.h, and nothing else. That layer includes exactly one backend header from include/os/, chosen by a compile definition (read from the table in OsAbstraction.h); with no definition the no-RTOS backend is used, for host tests and bare metal. The backend is the only code that names a kernel.

Drawn from: include classes; include/OsAbstraction.h backend table; figure module docs/diagrams/figures/rtos-layers.py.

What you get

  • Worker threads with a lifecycle. BaseThread runs Setup(), then Step() in a loop, then Cleanup(), and can be started and stopped again with verification. See BaseThread.
  • Locks that work with the standard library. RtosMutex satisfies std::lock_guard and std::unique_lock. See Synchronization.
  • Typed queues and event flags. OsQueue<T, N> with inline storage and OsEventFlags with WaitMode::Any / WaitMode::All. Timeouts are uint32_t milliseconds; UINT32_MAX waits forever. See Queues.
  • Shared state without locks. hf::FlagsSaver, hf::SeqlockSnapshot and hf::ErrorHistory, each split into a reader and a writer interface. See Generic templates.
  • Four backends, one contract. FreeRTOS (ESP-IDF SMP or vanilla), ThreadX, CMSIS-RTOS2 and no RTOS. See Backends.
  • Host builds that keep time. The no-RTOS backend can take its clock and delays from your test harness, so timeouts expire without real waiting. See Backends.

Used by

Repository Uses
hf-core-utils Carries this library as a submodule next to hf-utils-general and hf-utils-canopen
hf-core RtosMutex in the handlers, PeriodicTimer, and BaseThread with the no-RTOS backend in the host build

Where to go next

  • Quickstart


    A worker thread in 30 lines.

  • Architecture


    The three layers and the rules between them.

  • Backends


    Select a kernel, run without one, add one.