Anbieter zum Thema
Polymorphie, Exceptions, Templates und Bare Bones: Passt das?
Standard-C++-Bibliothek: Grundsätzlich steht dem Entwickler jetzt die gesamte Sprachvielfalt von C++ und fast die gesamte C++-Bibliothek zur Verfügung. Nicht unterstützt sind lediglich einige Erweiterungen des C++ Standards von 2011 wie die Thread Support Library, die zusätzliche Unterstützung eines Betriebssystems benötigen würden.
Allerdings ist die GNU C++-Bibliothek (libstdc++) nicht unbedingt für kleinen Speicherbedarf (sowohl gemessen am ausführbaren Code als auch am RAM) optimiert. Wir erinnern uns, dass die GNU C-Bibliothek (libc) auch aus diesem Grund durch die Newlib ersetzt wurde. Ein entsprechendes platzsparendes Äquivalent der libstdc++ gibt es noch nicht.
Damit die Programme klein bleiben, sollte daher mit den C++-Bibliotheksfunktionen vorsichtig umgegangen werden. So schlägt die „Input/output Library“ (z.B. „cout“) schnell mit mehreren hundert Kilobytes zu Buche. Der einfache C++-String („std::string“) kommt auf moderatere ca. 10 kB.
Namespaces: C++ Namespaces haben keinen Einfluss auf die Größe des kompilierten Programms und können daher nach Bedarf eingesetzt werden. Nur die Debug-Informationen werden ein klein bisschen größer, aber die landen ja nicht auf dem Mikrocontroller.
Polymorphie: Polymorphie und damit verwandte Features wie virtuelle Methoden und abstrakte Klassen haben nur einen minimalen Einfluss auf die Größe des Programms und können daher auch nach Bedarf verwendet werden.
Etwas „teurer“ ist die Funktion „dynamic_cast“, die RTTI (Run-Time Type Information) voraussetzt.
Exceptions: Auch Exceptions können gegen einen geringen Aufpreis von wenigen Kilobytes verwendet werden. Richtig eingesetzt ermöglichen Exceptions eine sauberere Programmstruktur, und der „Aufpreis“ an Abhängigkeiten relativiert sich, weil alternative Strukturen zur Fehlerbehandlung auch zusätzlichen Code bedeuten. Gegenargumente sind, dass durch Exceptions der Programmfluss und die Laufzeit im Fehlerfall etwas intransparenter werden.
Dies sind aber Argumente, die je nach Projekt abgewogen werden sollten – aus technischer Sicht spricht erst einmal nichts gegen Exceptions.
Allerdings ist in der ARM-Toolchain die Unterstützung von Exceptions in der Standard-C++-Bibliothek abgeschaltet. Das bedeutet, dass undefiniertes Verhalten auftreten kann, wenn im Rahmen einer C++-Bibliotheksfunktion eine Exception geworfen wird, also z.B. beim Einfügen eines Elements in einen Vektor.
Die Verwendung von Exceptions in eigenem Programmcode ist von dieser Einschränkung aber nicht betroffen.
Templates: Der Name ist Programm: Templates ermöglichen die Wiederverwendung von Code-Schablonen. Auch Templates sind zunächst einmal harmlos, solange sie bewusst eingesetzt werden. Zum Problem werden Templates erst, wenn sie zu oft instanziiert werden.
Das „zu oft“ ist dabei natürlich auch sehr projektspezifisch. So könnte zum Beispiel eine Template für eine Liste von Datenobjekten sinnvoll sein. Wenn diese Template aber dann für viele ähnliche Datentypen verwendet wird, sollte diese Abstraktion neu überdacht werden.
Performance und andere Vorurteile: C++ hat immer noch einen Ruf, von der Performance hinter C herzuhinken. So wird gerne behauptet, dass insbesondere virtuelle Methoden und Exceptions langsam seien. Diese und andere Vorurteile wurden bereits in einem lesenswerten Report des C++-Standardkomitees entkräftet [7].
Natürlich ist zum Aufruf einer virtuellen Methode eine zusätzliche Indirektion über die „vtable“ einer Klasse nötig. Und natürlich entsteht Aufwand, wenn beim Auftreten einer Exception der passende Exception Handler gesucht werden muss. Das alles muss aber auch im Vergleich zu alternativen Implementierungen ähnlicher Konzepte z.B. zur Fehlerbehandlung gesehen werden. Durch die Verwendung dieser C++-Features entsteht kein zusätzlicher Aufwand, sondern nur „anderer.“
Lizenzmodelle von Open Source-Software
Gerade im Embedded-Bereich gibt es noch viele Missverständnisse, was die Lizenzmodelle von Open Source-Software angeht. Die kurze Antwort ist, dass alle Software, die in diesem Artikel vorgestellt wurde, auch im kommerziellen Umfeld zur Entwicklung von potentiell kostenpflichtiger Software genutzt werden darf, ohne dass diese Software von einer offenen Lizenz „infiziert“ wird.
Grundsätzlich darf jede Open Source-Software intern zur Entwicklung eingesetzt werden. Es zeichnet Open Source ja gerade aus, dass die Verwendung von Software nicht eingeschränkt ist. Von Interesse ist nur die explizite oder auch implizite Weitergabe von Software. Bei der Weitergabe von Software werden Kopien angefertigt, so dass das Copyright greift.
Bei der Entwicklung und Vertrieb von Software für einen Mikrocontroller wird ja beispielsweise der Compiler (z.B. GNU GCC) gar nicht weitergegeben, sondern nur das entstandene Kompilat – ein lizenzrechtlich völlig unproblematischer Vorgang.
Bei der Auslieferung von Software werden allerdings Programmcode und Funktionsbibliotheken weitergegeben, die explizit und implizit mit unserem Programm mitgelinkt werden. In unserem Fall sind dies die C-Standardbibliothek Newlib und die C++-Standardbibliothek GNU libstdc++. Eine Sonderrolle nimmt noch die Bibliothek libgcc ein, die implizite Funktionen des GNU C Compilers bereitstellt– zum Beispiel für Soft-Float oder auch Funktionen zur 64-Bit-Integer-Arithmetik. Hier ist also ein Blick auf die Lizenzen angebracht.
Dabei stellt sich heraus, dass Newlib eine Kollektion von Software vieler verschiedener Autoren ist. Die in den Dateien „COPYING.NEWLIB“ und „COPYING.LIBGLOSS“ gesammelten Einzellizenzen erlauben allesamt die kommerzielle Wiederverwendung, fordern aber teilweise – die sogenannte „3 Clause BSD License,“ dass auch bei einer Weitergabe in kompilierter Form ein Copyright-Vermerk in der Dokumentation der Software auftauchen muss. Um diesen Lizenzbedingungen Genüge zu tun, reicht es also, diese beiden Dateien in das ausgelieferte Softwarepaket zu übernehmen.
Das Lizenzmodell für die GNU libstdc++ und libgcc ist die „GNU Lesser General Public License“ (LGPL), die zusätzliche Anforderungen stellt, die eventuell eine Weitergabe des Quelltextes erfordern würden. Allerdings gilt darüber hinaus noch die „GCC Runtime Library Exception:“
When you use GCC to compile a program, GCC may combine portions of certain GCC header files and runtime libraries with the compiled program. The purpose of this Exception is to allow compilation of non-GPL (including proprietary) programs to use, in this way, the header files and runtime libraries covered by this Exception.
Diese Ausnahmebedingung erlaubt es uns wiederum, auch kommerzielle Software mit dem GCC zu entwickeln und zu vertreiben.
C++ auf einem Mikrocontroller: Zusammenfassung und Fazit
Dass der Einsatz von C++ statt C auch auf einem Mikrocontroller Sinn macht, hat dieser Artikel gar nicht in Frage gestellt. Stattdessen wurde widerlegt, dass C++ zu groß oder zu komplex für einen Mikrocontroller ist. Ein aktuelles Projekt des Autors besteht aus ca. 10,000 Zeilen C++ und passt in 40 k ROM und 4 k RAM. Es gibt also keine technischen Probleme, die einem Einsatz von C++ widersprechen würden.
Auch zeigt sich, dass der Einsatz von Open Source-Software kein Problem ist. Für größere Projekte, bei denen Lizenzkosten vernachlässigbar sind, mag es weiterhin sinnvoll sein, eine Entwicklungsumgebung und dazugehörigen Support einzukaufen. Für kleinere Labormuster oder Einzelentwicklungen, bei denen solche Lizenzkosten prohibitiv wären, sind GCC&Co. eine Option. Der Einsatz der Debugging-Tools ist im „Bare Metal“-Bereich noch etwas hakelig, aber vielversprechend. Dank der stark wachsenden Homebrew-Szene ist hier eine weitere Verbesserung zu erwarten.
Als Nebeneffekt erfährt man beim Aufsetzen eines BSP mit GCC viel über die untersten Schichten der Software, und über die Verzahnung der Puzzleteile wie Compiler, Standardbibliothek und Prozessor.
Literatur- und Quellenverzeichnis
[1] GNU Tools for ARM Embedded Processors, https://launchpad.net/gcc-arm-embedded/
[2] The Newlib Homepage, https://sourceware.org/newlib/
[3] PM0215, „STM32F0xxx Cortex-M0 Programming Manual“, http://www.st.com/st-web-ui/static/active/en/resource/technical/document/programming_manual/DM00051352.pdf
[4] RM0360, „Reference Manual, STM32F030x4/x6/x8 advanced ARM-based 32-bit MCUs“, http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/DM00091010.pdf
[5] Contiki: The Open Source OS for the Internet of Things, http://www.contiki-os.org/
[6] ISO/IEC 14882, „Information technology – Programming languages – C++“.
[7] C++ TR 18015, „Technical Report on C++ Performance“, Februar 2006. Siehe http://www.open-std.org/jtc1/sc22/wg21/docs/18015.html
[8] Open On-Chip Debugger, http://openocd.sourceforge.net/
[9] QT Creator, http://qt-project.org/wiki/Category:Tools::QtCreator
[10] Eclipse CDT, http://www.eclipse.org/cdt/
* Frank Pilhofer ist seit 2010 Software-Entwickler im Bereich Embedded Systems Solutions bei der Zühlke Engineering GmbH. Mit freundlicher Genehmigung wurde dieser Beitrag dem Tagungsband Embedded Software Engineering Kongress 2014 entnommen.
(ID:43690572)