
Modern Embedded Systems

Embedded software engineers that have a proper understanding of the corresponding hardware are hard to find. When application developers were moving to newer languages like Java and C++, embedded programmers were still moving from assembly language to C.
The reason for slower technology adoption is having a lesser number of embedded programmers, who need to thoroughly understand the hardware platform on which their code runs.
The key driver of RTOS adoption is application complexity.
An RTOS will often be used when there are more interrupt sources, more functions, and more standard communications interfaces that need to be supported.
Why RTOS?
The key advantages of a realtime operating system are:
-
Asynchronous message-based System. Actor pattern is implemented with this mechanism.
-
Preemptive multitasking design paradigm
-
Pre-tested and pre-integrated communications stacks and drivers
-
Application portability [1]
-
More efficient use of CPU resources
Simple loop-based run-times typically do a lot of polling to check if interrupts have occurred. Response-time is often abysmal because the interrupt delivered data is not processed accordingly to expected priority. The received data is processed in the next loop iteration of the main scheduler [2].
As a result, a great deal of processor time is occupied doing nothing. Because multitasking RTOS-based applications are interrupt-driven, it is possible to largely eliminate polling from the application. This frees up processor resources for useful work and enables power-saving modes to be invoked during idle periods.
Adversaries of RTOS feud that RTOS are too expensive to deploy in devices. Below some empirical data of the freeRTOS realtime operating system. The memory usage is:
The RTOS kernel itself required about 5 to 10 KBytes of ROM space. The boot cost is the area of a few milliseconds. A small set of static variables will be initialized in this phase. The cost of a context switch depends on the port, compiler, and configuration. A context switch time of 84 CPU cycles was obtained under the following test conditions:
|
Why C++?
With the continued improvements in the language, most C++ features have no impact on code size or on speed [1, 2, 3, 4]. Others have a small impact that is generally worth paying for. To use C++ effectively in embedded systems, you need to be aware of what is going on at the machine code level, just as in C. Armed with that knowledge, the embedded systems programmer can produce code that is smaller, faster and safer than is possible without C++.
One property of C++ is so obvious that it is often overlooked. This property is that C++ is almost exactly a superset of C. If you write a code fragment in the C subset, the compiler will usually act like a C compiler. The machine code generated will be what you would get from a C compiler.
Because of this simple fact, anything that can be done in C can also be done in C++. Existing C code can typically be re-compiled as C++ with about the same amount of difficulty that adopting a new C compiler entails. This also means that migrating to C++ can be done gradually, starting with C and working in new language features at your own pace. Although this is not the best way to reap the benefits of object-oriented design, it minimizes short-term risk and provides a basis for iterative changes.
Many C++ features are strictly front-end issues. [3]. They have no effect on the code generation [4]. The benefits conferred by these features are therefore free of cost at runtime. Default arguments to functions are an example of a cost-free front end feature. The compiler inserts default arguments to a function call where the source specifies none. A less obvious front end feature is function name overloading. Namespaces provide additional scopes and the same name can be used in multiple contexts. |
Common myths about C++
-
C++ is slow.
-
C++ produces bloated machine code. C++ code is at least as efficient as similar C code. C++ compiler inlines per default all concrete class methods.
-
Objects are large.
-
Virtual functions are slow.
-
C++ binary files are not ROMable.
-
Class libraries make large binaries.
-
Abstraction leads to inefficiency.
We are aware of two factual arguments why you should not use C++ in your project.
These are clear reasons why your development group must stay with C. Beware that multiple organizations including the Linux kernel developers are, albeit slowly, moving away from C. |
Links
-
[1] free RTOS FAQ
References
[1] B. Stroustrup, Tour of C++, Third. Pearson Education, Limited Edition, 2021, p. 320 [Online]. Available: https://www.amazon.com/dp/B0B8S35JWV
[2] S. Meyers, Effective Modern C: 42 Specific Ways to Improve Your Use of C11 and C++14. O’Reilly Media, p. 334 [Online]. Available: https://www.amazon.com/dp/B00PGCMGDQ
[3] R. Grimm, C++ Core Guidelines. Pearson Education, Limited, 2021 [Online]. Available: https://www.amazon.com/dp/B09NSGQ4JK
[4] J. Davidson and K. Gregory, Beautiful C++. Pearson Education, Limited, 2021978-0136875673, p. 352 [Online]. Available: https://www.amazon.com/dp/B09HTH1X38