Preface
C++ is a general-purpose, multi-paradigm programming language, supporting procedural, object-oriented, and, to some extent, functional programming paradigms. It started out as C with classes, but over time it transformed into a modern language that enables writing highly expressive code without sacrificing performance. Despite this, C remains the dominant language in embedded development, primarily due to its simplicity and gentler learning curve.
However, the simplicity of C often makes writing complex systems overly verbose, increasing the cognitive burden on developers and making code more error-prone. This is where C++ excels. With features such as generic programming, runtime and compile-time polymorphism, compile-time computation, and enhanced type and memory safety, it is a superb choice for embedded system development.
Myths about C++, such as code bloat and runtime overhead, are still widespread. This book begins by debunking these misconceptions and guiding you through C++ fundamentals. It then shifts focus to more advanced modern C++ concepts, applying them to solve real-world problems in embedded development.
The goal of this book is to show you how modern C++ can be effectively used in embedded systems through carefully selected examples and by applying good software development practices.
Who this book is for
This book is for embedded developers who mainly use C in their daily jobs and would like to discover modern C++. Some familiarity with C++ is expected but not necessary, as the book also covers C++ basics.
What this book covers
Chapter 1, Debunking Common Myths About C++, explores widespread misconceptions about C++ and systematically debunks them. You will also gain insight into the history of C++ and the zero-overhead principle.
Chapter 2, Challenges in Embedded Systems with Limited Resources, examines the design challenges faced in resource-constrained embedded systems, with a focus on profiling techniques and memory management. It also shows how to avoid potentially problematic language features such as exceptions and RTTI.
Chapter 3, Embedded C++ Ecosystem, reviews the tools available for C++ development in the embedded domain, including toolchains, static analyzers, profiling tools, and testing frameworks.
Chapter 4, Setting Up the Development Environment for a C++ Embedded Project, walks you through setting up a modern development environment for C++ embedded projects, including using a simulator to test your code in a virtual setting.
Chapter 5, Classes - Building Blocks of C++ Applications, guides you through understanding classes in C++, including storage duration and initialization and inheritance and dynamic polymorphism.
Chapter 6, Beyond Classes - Fundamental C++ Concepts, covers fundamental C++ features such as namespaces and function overloading. It also discusses interoperability with C and introduces standard library containers and algorithms.
Chapter 7, Strengthening Firmware - Practical C++ Error Handling Methods, goes through various error handling techniques in C++, including error codes, asserts, and global handlers. It also explains the mechanics of exceptions and how they work.
Chapter 8, Building Generic and Reusable Code with Templates, goes through templates and concepts. It also provides an introduction to template metaprogramming and compile-time polymorphism.
Chapter 9, Improving Type-Safety with Strong Types, discusses implicit and explicit type conversions in C++ and introduces the concept of strong types. A practical example from an embedded library demonstrates how to improve type safety.
Chapter 10, Writing Expressive Code with Lambdas, introduces lambdas and shows you how to use them within a command design pattern to implement an expressive interrupt manager.
Chapter 11, Compile-Time Computation, explores C++'s compile-time computation capabilities and demonstrates how to use them to build a signal generator library that generates lookup tables at compile time.
Chapter 12, Writing C++ HAL, demonstrates the implementation of HAL in C++, using template-metaprogramming to ensure type-safety.
Chapter 13, Working with C Libraries, shows how to effectively use C libraries in C++ projects. It demonstrates the RAII principle in an example of using a filesystem C library.
Chapter 14, Enhancing Super-Loop with Sequencer, shows how to improve simple super-loop-based designs using a sequencer. It also introduces the Embedded Template Library (ETL) and its container class templates with fixed sizes known at compile time.
Chapter 15, Practical Patterns - Building a Temperature Publisher, guides you through the Observer design pattern and demonstrates how to apply it in systems such as thermostats and HVAC controllers.
Chapter 16, Designing Scalable Finite State Machines, explores different ways to implement finite state machines. It begins with a basic enum-switch approach, introduces the State design pattern, and then presents the Boost.SML library.
Chapter 17, Libraries and Frameworks, highlights parts of the C++ Standard Template Library that are useful for firmware development in constrained systems. It also features the CIB and Pigweed libraries.
Chapter 18, Cross-Platform Development, discusses the importance of good software design for achieving portability and testability in embedded software.
To get the most out of this book
Many examples in the book can be run in Compiler Explorer (https://godbolt.org/). Use it to observe the assembly output of the compiler. Experiment with the examples, tweak them, and compile them with different optimization levels and compiler flags to understand how those changes affect the compiler output.
Most of the examples can also be run in the Renode simulator. The book is accompanied by a Docker container, which includes the GCC toolchain and the Renode simulator, enabling you to run the code in an embedded target simulation.
Software/hardware covered in the book
Operating system requirements
Docker
Windows, macOS, or Linux
If you are using the digital version of this book, we advise you to type the code yourself or access the code from the book's GitHub repository (a link is available in the next section). Doing so will help you avoid any potential errors related to the copying and pasting of code.
Download the example code files
The code bundle for the book is hosted on GitHub at https://github.com/PacktPublishing/Cpp-in-Embedded-Systems. We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing. Check them out!
Download the color images
We also provide a PDF file that has color images of the screenshots/diagrams used in this book. You can download it here: https://packt.link/gbp/9781835881149.
Conventions used
There are a number of text conventions used throughout this book.
CodeInText
: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. For example: "The PT100
class is also a TemperatureSensor
class, and the TemperatureController
class has a member (object) of TemperatureSensor
and a PidController
class."
A block of code is set as follows:
#define N 20 int buffer[N]; for(int i = 0; i < N; i ++) { printf("%d ", buffer[i]); }
Any command-line input or output is written as follows:
The output of this simple program might be surprising: resistance = 3.00
Bold: Indicates a new term, an important word, or words that you see on the screen. For instance, words in menus or dialog boxes appear in the text like this. For example: "Now, we need to add the Google Test library by clicking on the Libraries button in the execution pane."
Warnings or important notes appear like this.
Tips and tricks appear like this.
Get in touch
Feedback from our readers is always welcome.
General feedback: Email feedback@packtpub.com
and mention the book's title in the subject of your message. If you have questions about any aspect of this book, please email us at questions@packtpub.com
.
Errata: Although we have taken every care to ensure the accuracy of our...