2. *YOU* are full of bullshit.
C++ is a horrible language. It's made more horrible by the fact that a
lot of substandard programmers use it, to the point where it's much
much easier to generate total and utter crap with it. Quite frankly,
even if the choice of C were to do *nothing* but keep the C++
programmers out, that in itself would be a huge reason to use C.
-Linus Torvalds (2007)
http://harmful.cat-v.org/software/c++/linus
3. What is an embedded system?
Well, a lot of different things, but generally speaking:
● Dedicated to a single purpose
● Minimalist approach to reduce cost
● “Always on”
● Has stiff reliability requirements
● uses safeguards like watchdogs for recovery
4. Software selection based on
hardware?
Bare metal:
ATtiny85, 8K of flash
512 byte of SRAM
512 bytes of EEPROM
general-
purpose OS
(hopefully
ruggedized)
● Bare metal or
microkernel / RTOS
● Lots of C!
(ok, NASA uses some ADA)
5. Myths about C++ in embedded systems
● C++ code is slow compared to C
● C++ produces binaries too big for embedded systems
● Templates create too much code “bloat”
● Dynamic dispatch is slow. Virtual functions are too “heavyweight”.
● C++ is synonymous with dynamic allocation
● It’s too hard to port C++ to other architectures
● STL is the devil for embedded systems, therefore you shouldn’t use C++
6. Myth #1: C++ is slow
Truth: If you use C++ as
“C with classes” you will
get virtually indistinguishable
performance. Other lightweight
features add minimal overhead.
Certain features of C++ can be too slow or otherwise
unsuitable for certain embedded applications.
7. Myth #2: C++ Binaries Are Too Big
Truth:
Using a reasonable subset of features leads to similar
binary files sizes.
Frequently, higher level abstractions can reduce
copy/paste coding.
libstdc++ is big. It’s also frequently not available!
8. Myth #3: Templates create too much code bloat
Truth:
If you factor template independent code outside of your
templates, you can minimize this effect. Every good C++
programmer knows this.
Extensive use of macros in C produce bloat just as easily,
with more obfuscation, and with less type safety.
9. Myth #4: Dynamic Dispatch is “Slow”
Truth: The overhead from virtual functions &
vtables is actually pretty acceptable for almost
all applications.
● one vtable per class (not per object)
● one pointer to the vtable per object
● one dereferencing operation per call (a couple cycles on most hardware)
Virtual functions can be abused like any language feature. However, abstraction via
interfaces (abstract classes in C++) is too powerful a tool for building APIs and testing code
to ignore.
11. Myth #5: C++ == dynamic allocation
Truth:
There is nothing about C++
that forces you to use dynamic
allocation.
If you don’t like the STL, don’t
use it. The STL is a library not
the language.
12. Myth #6: C++ leads to non-portable code
Truth:
This used to be true. C++ compilers have made
enormous strides in recent years for a number of
reasons. Clang and GCC are now driving progress, and
even MSVC++ is quite compliant to the standard.
If you develop with multiple compilers frequently and
avoid platform extensions, you’ll have excellent
portability. C++ abstractions make it easier to separate
platform-specific code.
13. Lulz
“I'm glad to know that Ultrix CC
has a bug optimizing switch()
statements lacking an explicit
`case 0:' construct. But Ultrix has
been dead for more than 15 years,
really. Don't give it any reason to
move out of its coffin.”
http://freshbsd.org/commit/openbsd/111423c9d25cd2128223242f0a3d7dcaa9acb3b5
14. Why is C++ “better now”?
● Renewed interest in native languages
● Clang (C-family front-end compiler for LLVM) has been pushing GCC to
improve
● Coopetition between Intel/Microsoft/OSS tools to be “conformant”
● Many embedded vendors have switched from proprietary toolchains to
GCC-based tools (expect even more to switch to Clang/LLVM)
15. What is Clang/LLVM?
LLVM is a language-agnostic compiler architecture. It separates language-
specific lexing / early-stage compilation from the translation & optimization of
specific targets.
Interested in creating a new language? No problem, it will easily be able to
target different architectures if your compile to LLVM.
Interested in adding support for a new architecture? Great, you only have to
translate LLVM instructions to your target.
16. “Lightweight” C++ for MCUs (MISRA?)
Free (no significant overhead vs. C)
● Classes
● Constructors / destructors & OOP modularity
● Single inheritance
● C++11 lambdas, constexpr, access modifiers
● templates (if factored appropriately)
Cheap:
● Virtual methods
Costly to some metric (performance / determinism / code size / runtime / memory / etc)
● dynamic allocation
● Virtual inheritance
● Run-time type information (RTTI == dynamic_cast<> & typeid)
● Exceptions
17. How can C++ improve robustness/security?
● More powerful abstractions
o private members - data hiding / encapsulation
o const correctness - enforce immutability
o deterministic destructors - guaranteed resource release
● Wrappers to that mediate access to dangerous resources
o e.g. buffer views (wrappers)
● Better type-safety means that you make fewer assumptions in code.
● Powerful design patterns can be applied to encourage better practices
18. Simple pattern, big effect: RAII
The Problem (pseudo code in C)
int stupidprefix_some_function_that_returns_error_code(.... arguments)
{
int err = 0;
stupidprefix_acquire_resource(&resource);
stupidprefix_do_stuff_with_resource(&resource);
// … yada yada lots of code branches that require resource
// from which you can’t return (hint: use GOTO)
CLEANUP:
stupidprefix_release_resource(&resource);
return err;
}
19. C++ version w/ RAII
namespace kickasswehavenamespaces
{
int some_function_that_returns_error_code(.... arguments)
{
Acquisition mediator(raw_resource);
do_stuff_with_resource(mediator);
//... Code branches
//... Any return calls mediator’s destructor
return 0;
}
}
The act of acquiring a resource
guarantees its release.
“Resource Acquisition Is
Initialization”.
Java doesn’t even have an
acceptable substitute.
C# has “using” statement.
20. “embeddable” C++11 features
● static_assert - Compile time assertions complete with custom compiler
error messages. Ensure that your library is being configured with safe
constants / types.
● constexpr - Compile time calculations (yet another Turing complete
metaprogramming language)
● Access modifiers for method (override final)
21. What specific design aims guided
the committee?
“Improve performance and ability to
work directly with hardware -- make
C++ even better for embedded
systems programming and high-
performance computation.”
http://www.stroustrup.com/C++11FAQ.html
23. AVR DNP3 Demo
● C++11 using GCC 4.8.1 and 8-bit AVR backend
● USART only at this point
● Level 3 stack - more feature-rich than many RTUs / IEDs
● All statically allocated
● All interrupt based event-loop
● Makes use of AVR sleep mode
● SAv5? maybe possible? Definitely on ARM Cortex (Arduino DUE)
● Community members have been prototyping on TI ARM & PIC
● Need an interesting I/O shield to make a real “IED”