Common Automotive Safety-critical Template Library for Embedded engineers
Prototype version 2.0
CASTLE is a lightweight, header-only CPP17-based template library built for safety-critical embedded systems where every byte of RAM, every millisecond of jitter, and every allocation counts. It is inspired by the ETL (Embedded Template Library) and is intended as a drop-in replacement for parts of the C++ standard library and common enterprise frameworks that are otherwise unsuitable for automotive ECUs, MCUs, and other resource-constrained targets.
The main idea is simple: make common C++ jobs easier without bringing the runtime costs that are often unwanted on small targets.
CASTLE 2.0 focuses on:
CASTLE is a good fit for firmware, device drivers, control software, protocol stacks, communication buffers, sensor pipelines, schedulers, and other code where memory and timing are important.
Most of the C++ standard library (std::function, std::string,
std::vector, std::unordered_map, most logging frameworks, ...) relies on
dynamic memory allocation, exceptions, and virtual dispatch. That combination
is often unacceptable in automotive and safety-critical environments where:
CASTLE addresses these constraints by providing stack-allocated,
fixed-capacity, constexpr/noexcept-friendly alternatives whose behaviour
is predictable, testable, and traceable.
vector, array, ring_buffer, stack, optional, variant, and the
storage helpers keep their data in objects with known bounds.
That means the application can choose the memory budget at compile time.
A fixed-size container can become full or empty. CASTLE reports these cases
through return values such as castle::status::ok, castle::status::full, and
castle::status::empty, or through bool for simple operations.
There is no need to throw an exception for a normal capacity condition.
The public headers do not require the C++ STL. CASTLE uses compiler features and small low-level building blocks instead.
Many utilities can be evaluated at compile time.
This is useful for register definitions, buffer sizes, time periods, and other firmware configuration.
| Module | Main purpose |
|---|---|
atomic | Atomic values and memory ordering |
bit | Low-level bit operations and bit math |
callbacks | Fixed-storage callbacks and callback policies |
chrono | Durations, time points, clocks, and literals |
container | array, fixed-capacity vector, ring_buffer, stack |
core | Types, compiler abstraction, traits, configuration, assertions |
design_patterns | Small embedded-oriented observer, singleton, and visitor helpers |
error | Status/error values |
events | Event dispatching, signals/slots, IPC events, tick timers |
iterator | Iterator tags, traits, bounded/circular/reverse iterators |
math | Integer math, ratios, square root, mean, logarithms, etc. |
memory | Placement construction, destruction, storage, addresses, lifetimes |
mutex | Mutex and scoped locking |
utility | move, forward, swap, optional, variant, pair, tuple, bitset, etc. |
See the module guides in docs/.
A typical project can use a compiler mode such as:
-std=c++17
-fno-exceptions
-fno-rtti
-nostdinc++
CASTLE is header-only. Any of the following is enough:
Copy include/castle/ into your project and add include/ to your
compiler's include path. Then:
#include "castle/container/array.h"
#include "castle/events/tick_timer.h"
...
add_subdirectory)add_subdirectory(third_party/castle)
target_link_libraries(my_app PRIVATE castle)
The castle target is an INTERFACE library that propagates the include
directory and enforces cxx_std_17.
FetchContent)include(FetchContent)
FetchContent_Declare(
castle
GIT_REPOSITORY https://github.com/nguyenchiemminhvu/castle.git
GIT_TAG v1.0.0
)
FetchContent_MakeAvailable(castle)
target_link_libraries(my_app PRIVATE castle)
# Samples
./build_samples_linux.sh # or build_samples_win.bat on Windows
# Tests
./build_test_linux.sh # or build_test_win.bat on Windows
Equivalent CMake options:
cmake -S . -B build \
-DCASTLE_BUILD_SAMPLES=ON \
-DCASTLE_BUILD_TESTING=ON \
-DCASTLE_FETCH_GTEST=ON
cmake --build build -j
Prototype 2.0 provides a small set of building blocks that are useful in embedded firmware:
Planned for upcoming releases:
MIT License © 2026 nguyenchiemminhvu — see LICENSE.
3 commits
C++
98.1%
C
1.2%
Common Automotive Safety-critical Template Library for Embedded engineers
Prototype version 2.0
CASTLE is a lightweight, header-only CPP17-based template library built for safety-critical embedded systems where every byte of RAM, every millisecond of jitter, and every allocation counts. It is inspired by the ETL (Embedded Template Library) and is intended as a drop-in replacement for parts of the C++ standard library and common enterprise frameworks that are otherwise unsuitable for automotive ECUs, MCUs, and other resource-constrained targets.
The main idea is simple: make common C++ jobs easier without bringing the runtime costs that are often unwanted on small targets.
CASTLE 2.0 focuses on:
CASTLE is a good fit for firmware, device drivers, control software, protocol stacks, communication buffers, sensor pipelines, schedulers, and other code where memory and timing are important.
Most of the C++ standard library (std::function, std::string,
std::vector, std::unordered_map, most logging frameworks, ...) relies on
dynamic memory allocation, exceptions, and virtual dispatch. That combination
is often unacceptable in automotive and safety-critical environments where:
CASTLE addresses these constraints by providing stack-allocated,
fixed-capacity, constexpr/noexcept-friendly alternatives whose behaviour
is predictable, testable, and traceable.
vector, array, ring_buffer, stack, optional, variant, and the
storage helpers keep their data in objects with known bounds.
That means the application can choose the memory budget at compile time.
A fixed-size container can become full or empty. CASTLE reports these cases
through return values such as castle::status::ok, castle::status::full, and
castle::status::empty, or through bool for simple operations.
There is no need to throw an exception for a normal capacity condition.
The public headers do not require the C++ STL. CASTLE uses compiler features and small low-level building blocks instead.
Many utilities can be evaluated at compile time.
This is useful for register definitions, buffer sizes, time periods, and other firmware configuration.
| Module | Main purpose |
|---|---|
atomic | Atomic values and memory ordering |
bit | Low-level bit operations and bit math |
callbacks | Fixed-storage callbacks and callback policies |
chrono | Durations, time points, clocks, and literals |
container | array, fixed-capacity vector, ring_buffer, stack |
core | Types, compiler abstraction, traits, configuration, assertions |
design_patterns | Small embedded-oriented observer, singleton, and visitor helpers |
error | Status/error values |
events | Event dispatching, signals/slots, IPC events, tick timers |
iterator | Iterator tags, traits, bounded/circular/reverse iterators |
math | Integer math, ratios, square root, mean, logarithms, etc. |
memory | Placement construction, destruction, storage, addresses, lifetimes |
mutex | Mutex and scoped locking |
utility | move, forward, swap, optional, variant, pair, tuple, bitset, etc. |
See the module guides in docs/.
A typical project can use a compiler mode such as:
-std=c++17
-fno-exceptions
-fno-rtti
-nostdinc++
CASTLE is header-only. Any of the following is enough:
Copy include/castle/ into your project and add include/ to your
compiler's include path. Then:
#include "castle/container/array.h"
#include "castle/events/tick_timer.h"
...
add_subdirectory)add_subdirectory(third_party/castle)
target_link_libraries(my_app PRIVATE castle)
The castle target is an INTERFACE library that propagates the include
directory and enforces cxx_std_17.
FetchContent)include(FetchContent)
FetchContent_Declare(
castle
GIT_REPOSITORY https://github.com/nguyenchiemminhvu/castle.git
GIT_TAG v1.0.0
)
FetchContent_MakeAvailable(castle)
target_link_libraries(my_app PRIVATE castle)
# Samples
./build_samples_linux.sh # or build_samples_win.bat on Windows
# Tests
./build_test_linux.sh # or build_test_win.bat on Windows
Equivalent CMake options:
cmake -S . -B build \
-DCASTLE_BUILD_SAMPLES=ON \
-DCASTLE_BUILD_TESTING=ON \
-DCASTLE_FETCH_GTEST=ON
cmake --build build -j
Prototype 2.0 provides a small set of building blocks that are useful in embedded firmware:
Planned for upcoming releases:
MIT License © 2026 nguyenchiemminhvu — see LICENSE.
3 commits
C++
98.1%
C
1.2%