Cover....1
FM....2
Foreword....5
Contributors....6
Table of Contents....8
Preface....18
Part I: Introduction to C++ in Embedded Development....26
Chapter 1: Debunking Common Myths about C++....28
Technical requirements....29
A short history of C++....29
C with Classes....31
Modern C++....31
Generic types....33
Ring buffer in C....33
Ring buffer in C++....40
constexpr....42
Bloat and runtime overhead....46
Constructors and destructors....46
Optimization....51
Templates....53
RTTI and exceptions....55
Summary....58
Join our community on Discord....59
Chapter 2: Challenges in Embedded Systems with Limited Resources....60
Technical requirements....61
Safety-critical and hard real-time embedded systems....61
Airbag control unit and real-time requirements....61
Measuring firmware performance and non-determinism....64
A-B timing and real-time execution....64
Sotware instrumentation with GCC....65
Determinism vs. Non-Determinism in Firmware....66
Dynamic memory management....67
Memory fragmentation....68
Safety-critical guidelines for dynamic memory management in C++....69
Dynamic memory management in the C++ standard library....70
Disabling unwanted C++ features....76
Summary....78
Chapter 3: Embedded C++ Ecosystem....80
Technical requirements....81
Compilers and development environments....81
Arm Keil MDK and Arm Compiler for Embedded....83
IAR C/C++ Compiler and IAR Embedded Workbench for Arm....84
Vendor-supported IDEs and GCC....85
GCC....85
Compiler Explorer....87
Static analyzers....89
Unit testing....93
Profiling....98
Summary....100
Join our community on Discord....100
Chapter 4: Setting Up the Development Environment for a C++ Embedded Project....102
Technical requirements....103
Requirements for a modern software development environment....103
Compiler....103
Build automation....104
Simulator....105
Code editor....105
Containerized development environment....106
Building the Hello, World! program using CMake....108
Building a firmware using CMake....111
Containerized development environment and Visual Studio Code....112
Summary....116
Part II: C++ Fundamentals....118
Chapter 5: Classes – Building Blocks of C++ Applications....120
Technical requirements....121
Encapsulation....121
Setters and getters....123
Static methods....124
Structs....125
Storage duration and initialization....126
Non-static member initialization....127
Default member initializers....127
Constructors and member initializer lists....127
Converting constructors and explicit specifiers....129
Static member initialization....131
Inheritance and dynamic polymorphism....133
Virtual functions....135
Virtual function implementation....136
UML class diagrams....138
Dynamic polymorphism....139
Summary....141
Join our community on Discord....141
Chapter 6: Beyond Classes – Fundamental C++ Concepts....142
Technical requirements....142
Namespaces....143
Unnamed namespaces....145
Nested namespaces....145
Function overloading....146
Interoperability with C....148
External and Language Linkage in C++....149
C standard library in C++....149
References....150
Value categories....150
Lvalue references....152
Rvalue references....152
Standard library containers and algorithms....154
Array....154
Container adaptors....156
Algorithms....157
std::copy and std::copy_if....157
std::sort....158
Summary....159
Chapter 7: Strengthening Firmware – Practical C++ Error Handling Methods....160
Technical requirements....161
Error codes and asserts....161
Global error handlers....164
Asserts....166
Exceptions....170
std:: optional and std::expected....174
Summary....177
Join our community on Discord....177
Part III: C++ Advanced Concepts....178
Chapter 8: Building Generic and Reusable Code with Templates....180
Technical requirements....181
Template basics....181
Making a call to the template function....182
Template specialization....184
Template metaprogramming....185
Concepts....189
Compile-time polymorphism....191
Using Class Templates for Compile-Time Polymorphism....191
Curiously recurring template pattern (CRTP)....193
Summary....195
Chapter 9: Improving Type-Safety with Strong Types....196
Technical requirements....197
Implicit conversion....197
Numeric promotions and conversions....199
Array-to-pointer conversion....203
Function-to-pointer conversion....205
Explicit conversion....206
const_cast....206
static_cast....207
dynamic_cast....210
reinterpret_cast....212
Type punning....214
Type punning – the correct way....216
Strong types....217
Summary....223
Join our community on Discord....223
Chapter 10: Writing Expressive Code with Lambdas....224
Technical requirements....225
Lambda expression basics....225
Storing lambdas using std::function....228
The command pattern....231
GPIO interrupt manager....232
std::function and dynamic memory allocation....237
Summary....239
Chapter 11: Compile-Time Computation....240
Technical requirements....240
Templates....241
constexpr specifier....243
Example 1 – MAC address parser....245
Example 2 – Generating a lookup table....248
Generating a lookup table....252
Writing a signal representing the Steinhart-Hart equation....255
Analyzing the usage example firmware code....259
consteval specifier....260
Summary....262
Join our community on Discord....262
Part IV: Applying C++ to Solving Embedded Domain Problems....264
Chapter 12: Writing C++ HAL....266
Technical requirements....267
Memory-mapped peripherals....267
CMSIS memory-mapped peripherals....267
Memory-mapped peripherals in C++....269
Type-safe memory-mapped peripherals in C++....272
Modeling HSION and HSITRIM bit fields from the RCC register....274
Generic versions of hsion and hsi_trim....277
Timers....278
Summary....283
Chapter 13: Working with C Libraries....284
Technical requirements....284
Using C HAL in C++ projects....285
UART interface for flexible software design....285
The UART interface in the Adapter pattern....289
Introducing static classes....290
Using RAII for wrapping the littlefs C library....292
LittleFS – a filesystem for microcontrollers....293
Introducing an RAII-based C++ wrapper....296
Cleaner file management with RAII....299
Summary....300
Join our community on Discord....300
Chapter 14: Enhancing Super-Loop with Sequencer....302
Technical requirements....303
Super-loop and motivation for a sequencer....303
Designing a sequencer....305
Storing a callable....308
Implementing a sequencer....312
Summary....315
Chapter 15: Practical Patterns – Building a Temperature Publisher....316
Technical requirements....317
The Observer pattern....317
Runtime implementation....319
Compile-time implementation....322
Leveraging variadic templates....323
Improving the compile-time implementation....327
Summary....329
Join our community on Discord....329
Chapter 16: Designing Scalable Finite State Machines....330
Technical requirements....331
FSM – a simple implementation....331
Describing states and events....333
Tracking current state and handling events – the FSM class....334
Using the ble_fsm class....336
Analyzing the output....337
FSM – implementation using the State pattern....338
Understanding state class interfaces....338
Refactoring the ble_fsm class....341
Implementing the State pattern....342
State design pattern....344
State pattern implementation using tag dispatching....345
Boost SML....347
Chapter 17: Libraries and Frameworks....352
Technical requirements....353
Standard library....353
Freestanding and hosted implementations in GCC....353
Numeric and math....354
....354
....354
....355
Containers and algorithms....355
std::array....355
std:: priority_queue....355
std:: span....355
Iterators....356
Algorithms....357
Template metaprogramming....357
Parts of the standard library to avoid in embedded applications....358
Embedded template library....358
Fixed-size containers....359
Storing a callable with etl::delegate....359
Other utilities provided by ETL....359
Pigweed....360
Pigweed’s Sense tutorial....360
RPC and Protocol Buffers....365
Compile-time Initialization and Build....368
Using CIB in a temperature publisher example....369
Extending the temperature publisher example....371
Summary....375
Chapter 18: Cross-Platform Development....376
Technical requirements....376
Importance of writing portable code....377
SOLID design principles....377
Single Responsibility Principle (SRP)....381
Open/Closed Principle (OCP)....382
The Liskov Substitution Principle (LSP)....382
The Interface Segregation Principle (ISP)....382
The Dependency Inversion Principle (DIP)....382
Testability....383
Summary....386
Join our community on Discord....387
Why subscribe?....388
Other Books You May Enjoy....390
Index....394
Go beyond C by applying modern C++ in embedded systems to enhance code readability, maintainability, and scalability
Transitioning from C can be daunting, with concerns about performance overhead, added complexity, and unfamiliar tooling. Addressing these challenges, Amar Mahmutbegovic, an advocate for modern C++ in embedded development, shows you how to harness zero-cost abstractions, compile-time checks, and powerful modern C++ capabilities to preserve performance while achieving safer, cleaner code. This book bridges the gap between traditional C and advanced C++, helping you retain the efficiency C developers demand while unlocking the safety and expressiveness of modern C++. Starting with a modern development environment setup, including a Docker container for seamless example replication, you’ll overcome the hurdles of using the C++ standard library in memory-constrained settings and get acquainted with the Embedded Template Library (ETL) as an alternative. The book walks you through essential C++ concepts before exploring advanced topics such as templates, strong typing, error handling, compile-time computation, and RAII. Through practical examples, you'll implement a sequencer, write a type-safe HAL, and apply patterns like Command, State, and Observer to solve common embedded development problems. By the end of this book, you’ll have learned how to apply modern C++ to develop robust, modular firmware with performance matching or exceeding hand-coded C solutions.
This book is for embedded developers who primarily use C and want to adopt a modern C++ approach. It introduces fundamental C++ concepts, making it suitable for beginners, while also assuming basic familiarity to fully leverage advanced features like compile-time computation. Even those with prior C++ experience will discover new ways to apply modern best practices to write more efficient and maintainable embedded applications.