Die Herausforderung der Embedded-Industrie, immer schneller immer komplexere Software zu liefern, erhöht das Risiko von Softwarefehlern, die die Qualität der Produkte beeinträchtigen und Sicherheitsprobleme verursachen können. Für die RISC-V-Codebasis gilt das umso mehr, da der Quellcode oft wiederverwendet oder von anderen Architekturen migriert wird. Dabei soll das gleiche Ergebnis erzielt werden, obwohl sich die meisten Entwickler erst mit der Architektur, dem neuen Befehlssatz und den umfangreichen Erweiterungen vertraut machen müssen.
Prototyp eines RISC-V Mikroprozessors aus dem Jahr 2013
Wenn wir davon sprechen, die Kontrolle über die RISC-V-Codebasis zu übernehmen, gibt es zwei Aspekte. Zum einen geht es um die Wiederverwendung der Codebasis für zukünftige Projekte. Der zweite Aspekt ist, dass schlechte Code-Qualität tatsächlich ein weitverbreitetes Problem ist. Es gibt eine ganze Reihe von Beweisen dafür, dass schlechte Programmierpraktiken direkt zu Sicherheitslücken führen. Das heißt, dass jeder Entwickler und jedes Unternehmen die Qualität des Codes verbessern muss, damit die Software auf lange Sicht fehlerfrei oder zumindest so fehlerarm wie möglich ist.
Code wiederverwenden
Bild 1: Boehms COCOMO-Methode für nichtlineare Effekte bei der Wiederverwendung.
(Bild: Rose-Hulman Institute of Technology)
Die in Bild 1 dargestellte COCOMO-Methode von Boehm schätzt ab, wie stark die relativen Kosten für die Erstellung des Codes davon abhängen, wie viele Änderungen an der wiederverwendeten Software vorgenommen werden. Die x-Achse gibt an, wie viel Prozent des wiederzuverwendenden Codes geändert werden, während die y-Achse die prozentualen Kosten zeigt, die bei einem neu geschriebenen Code entstehen würden. In zwei der drei Codebeispiele müsste nicht viel an dem vermeintlich wiederverwendeten Code geändert werden, um plötzlich 50 % des Aufwands zu erreichen, der beim Neuschreiben des Codes anfällt. Der springende Punkt dabei ist, dass die Wiederverwendung von Code nur dann kosteneffizient ist, wenn dieser von hoher Qualität und gut designt ist.
Fokus auf Code-Qualität
Es gibt mehrere Gründe, warum die Code-Qualität ein wichtiges Thema ist: Erstens kann je nach Reifegrad der Entwicklungsabteilung bis zu 80 % der Zeit beim Debuggen verbracht werden. Wenn Fehler schnell isoliert werden könnten, bevor sie in ein formales Build einfließen, wäre die Fehlerinjektionsrate geringer. Das wiederum bedeutet, dass die Qualitätsanforderungen des Unternehmens viel schneller erfüllt werden können. Das bedeutet aber auch, dass der Code insgesamt weniger Fehler aufweist, was ihn zu einem guten Kandidaten für die Wiederverwendung macht. Denn bei einer erneuten Verwendung des Codes ist die Gefahr geringer, dass ein zuvor unentdeckter Fehler aufgespürt wird. Qualitativ hochwertiger Code ist aufgrund der geringeren Anzahl von Fehlern leichter zu pflegen und – wenn er guten Software-Engineering-Prinzipien folgt – leichter zu erweitern, sodass die Wiederverwendung tatsächlich zu schnelleren Folgeprojekten führt. Es ist auch einfacher, Sicherheitszertifizierungen zu erhalten, wenn die Anwendung das erfordert. Letztlich führt eine höhere Code-Qualität zu einer geringeren „technischen Schuld“ bei der Wiederverwendung von Code.
Es gibt eine ganze Reihe von Programmierstandards, aber nur wenige, die weitverbreitet sind. MISRA C ist ein Softwareentwicklungsstandard für die Programmiersprache C, der von der Motor Industry Software Reliability Association entwickelt wurde. Das Ziel ist die Sicherstellung von Codesicherheit, Portabilität und Zuverlässigkeit im Zusammenhang mit Embedded-Systemen, insbesondere mit Systemen, die in ISO C programmiert sind.
Die erste Ausgabe des MISRA C-Standards, „Guidelines for the use of the C language in vehicle-based software“, wurde 1998 erstellt und ist offiziell als MISRA C:1998 bekannt. Im Jahr 2004 und 2012 wurde der Standard aktualisiert, um weitere Regeln hinzuzufügen. Außerdem gibt es einen MISRA C++ 2008 Standard, der auf C++ 2003 basiert.
Einige gute Standardregeln für die Programmierung finden sich auch in der CWE Common Weakness Enumeration von MITRE . Die Liste wurde erstellt, als die Mitarbeiter von mitre.org eine Umfrage durchführten, welche Arten von Fehlern Entwickler versehentlich in ihren Code einbringen. Überraschenderweise neigen Entwickler aller Couleur – ob Web, App, Desktop oder Embedded – dazu, die gleichen Fehler zu machen. So entstand die CWE, eine Liste dieser häufigen Fallstricke, die Entwickler vermeiden sollten, etwa Allokationen ohne Deallokationen in C++-Code (oder sogar in C-Code). Auch Funktionen, die ohne Prototyping verwendet werden, sind ein interessanter Punkt in Bezug auf gute Programmierpraxis. Wenn die Funktion nicht prototypisiert wird, findet zur Kompilierzeit keine strenge Typüberprüfung statt, aber der Code kann auch weniger effizient sein, da die Regeln der Sprache C besagen, dass ohne Prototyp alle Argumente zu Integerwerten gemacht werden. Dadurch kann es zu Casting und Fließkommaoperationen kommen, wenn die MCU nicht über eine FPU verfügt. Deshalb sollte immer ein Prototyp verwendet werden. Der wichtigste Punkt der CWE ist jedoch, dass sie riskantes und schlechtes Programmierverhalten aufdeckt.
Stand: 08.12.2025
Es ist für uns eine Selbstverständlichkeit, dass wir verantwortungsvoll mit Ihren personenbezogenen Daten umgehen. Sofern wir personenbezogene Daten von Ihnen erheben, verarbeiten wir diese unter Beachtung der geltenden Datenschutzvorschriften. Detaillierte Informationen finden Sie in unserer Datenschutzerklärung.
Einwilligung in die Verwendung von Daten zu Werbezwecken
Ich bin damit einverstanden, dass die Vogel Communications Group GmbH & Co. KG, Max-Planckstr. 7-9, 97082 Würzburg einschließlich aller mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen (im weiteren: Vogel Communications Group) meine E-Mail-Adresse für die Zusendung von redaktionellen Newslettern nutzt. Auflistungen der jeweils zugehörigen Unternehmen können hier abgerufen werden.
Der Newsletterinhalt erstreckt sich dabei auf Produkte und Dienstleistungen aller zuvor genannten Unternehmen, darunter beispielsweise Fachzeitschriften und Fachbücher, Veranstaltungen und Messen sowie veranstaltungsbezogene Produkte und Dienstleistungen, Print- und Digital-Mediaangebote und Services wie weitere (redaktionelle) Newsletter, Gewinnspiele, Lead-Kampagnen, Marktforschung im Online- und Offline-Bereich, fachspezifische Webportale und E-Learning-Angebote. Wenn auch meine persönliche Telefonnummer erhoben wurde, darf diese für die Unterbreitung von Angeboten der vorgenannten Produkte und Dienstleistungen der vorgenannten Unternehmen und Marktforschung genutzt werden.
Meine Einwilligung umfasst zudem die Verarbeitung meiner E-Mail-Adresse und Telefonnummer für den Datenabgleich zu Marketingzwecken mit ausgewählten Werbepartnern wie z.B. LinkedIN, Google und Meta. Hierfür darf die Vogel Communications Group die genannten Daten gehasht an Werbepartner übermitteln, die diese Daten dann nutzen, um feststellen zu können, ob ich ebenfalls Mitglied auf den besagten Werbepartnerportalen bin. Die Vogel Communications Group nutzt diese Funktion zu Zwecken des Retargeting (Upselling, Crossselling und Kundenbindung), der Generierung von sog. Lookalike Audiences zur Neukundengewinnung und als Ausschlussgrundlage für laufende Werbekampagnen. Weitere Informationen kann ich dem Abschnitt „Datenabgleich zu Marketingzwecken“ in der Datenschutzerklärung entnehmen.
Falls ich im Internet auf Portalen der Vogel Communications Group einschließlich deren mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen geschützte Inhalte abrufe, muss ich mich mit weiteren Daten für den Zugang zu diesen Inhalten registrieren. Im Gegenzug für diesen gebührenlosen Zugang zu redaktionellen Inhalten dürfen meine Daten im Sinne dieser Einwilligung für die hier genannten Zwecke verwendet werden. Dies gilt nicht für den Datenabgleich zu Marketingzwecken.
Recht auf Widerruf
Mir ist bewusst, dass ich diese Einwilligung jederzeit für die Zukunft widerrufen kann. Durch meinen Widerruf wird die Rechtmäßigkeit der aufgrund meiner Einwilligung bis zum Widerruf erfolgten Verarbeitung nicht berührt. Um meinen Widerruf zu erklären, kann ich als eine Möglichkeit das unter https://contact.vogel.de abrufbare Kontaktformular nutzen. Sofern ich einzelne von mir abonnierte Newsletter nicht mehr erhalten möchte, kann ich darüber hinaus auch den am Ende eines Newsletters eingebundenen Abmeldelink anklicken. Weitere Informationen zu meinem Widerrufsrecht und dessen Ausübung sowie zu den Folgen meines Widerrufs finde ich in der Datenschutzerklärung, Abschnitt Redaktionelle Newsletter.
SEI CERT C und C++ definiert ebenfalls häufige Schwachstellen, die sich aus Fallstudien ergeben, wie die Überprüfung von Floats auf Out-of-Bounds-Bedingungen und die Sicherstellung, dass keine Konstante überschrieben wird. Außerdem werden Stilkonventionen vorgeschrieben, um den Code lesbarer und verständlicher zu machen.
Praktische Beispiele für MISRA C 2012
MISRA C 2012 wird häufig zur Sicherung der Code-Qualität in Embedded-Anwendungen verwendet. Ein Blick auf einige Regeln und Richtlinien lohnt sich, um besser zu verstehen, welche Auswirkungen die Programmierstandards auf den Quellcode haben.
Laut Directive 4.6 ist es zum Beispiel nicht erlaubt, einen primitiven Datentyp zu verwenden. Auf den ersten Blick mag das seltsam erscheinen, aber wenn man den Grund dafür versteht, ist es sehr sinnvoll. Verschiedene Compiler behandeln Dinge wie int unterschiedlich, sowohl in Bezug auf die Größe als auch auf die Vorzeichenbehaftung. Das kann auch die Überprüfung von Code erschweren. Der Reviewer wird sich fragen, ob der ursprüngliche Autor des Codes verstanden hat, wie der Compiler diesen Code interpretiert. Wenn auf die Verwendung primitiver Typen verzichtet wird, wird der Code für alle Compiler und Architekturen einheitlich.
Bild 2: MISRA C 2012 – Codebeispiel für Regel 13.
(Bild: IAR System)
In den meisten Fällen werden Entwickler etwas wie uint16_t verwenden, das dem Compiler mitteilt, dass es sich bei der Variablen um eine vorzeichenlose 16-Bit-Zahl handelt, da die Größe und Vorzeichenhaftigkeit ausdrücklich im Variablentyp angegeben sind. Diese sind Teil von stdint.h.
Eine weitere interessante Richtlinie ist Regel 13, die besagt, dass die rechte Seite eines AND- oder OR-Operators keine Zusätze enthalten darf. Der Codeschnipsel aus Bild 2 sieht zwar völlig korrekt aus, ist es aber nicht.
Das Problem ist, dass die rechte Seite nur ausgeführt wird, wenn der Ausdruck auf der linken Seite falsch ist. Nur dann wird der Zeiger p nachinkrementiert. Beim Schreiben von Code kann dieses Verhalten leicht vergessen werden, und jeder, der den Code prüft, testet oder pflegt, muss sich über die Auswirkungen des Codes im Klaren sein. Kommentare in diesem Abschnitt des Codes könnten natürlich helfen, aber in der Realität ist dieser nur selten gut dokumentiert.
Bild 3: MISRA C 2012 – Codebeispiel für Regel 14.
(Bild: IAR Systems)
Ein weiteres gutes Beispiel ist Regel 14, die besagt, dass der Inhalt einer if- oder while-Anweisung in geschweifte Klammern eingeschlossen werden muss. Der Codeschnipsel in Bild 3 ist ein Beispiel dafür.
Es ist schwer zu erkennen, ob die Anweisung z=1 Teil des else-Blocks sein soll. Das liegt daran, dass sie genauso eingerückt ist wie die vorherige Anweisung. Sollte dies beabsichtigt sein, handelt es sich um einen Fehler, da die Anweisung eindeutig nicht so in den Codeblock gehört, wie sie geschrieben ist. Mit der Regel wird diese Art von Programmierfehlern vermieden. Und das ist nur ein kleiner Auszug aus den über 200 Regeln, die MISRA C zur Verfügung stellt, um den Code zuverlässiger und portabler zu machen und so das Design zukunftssicher zu gestalten.
Schnell zu besserem Code
Der schnellste Weg zur Verbesserung der Code-Qualität ist die Verwendung von Code-Analyse-Tools. Bei der Erstellung einer für funktionale Sicherheit zertifizierten Anwendung ist der Einsatz einer statischen Analyse sogar vorgeschrieben. Diese Art von Tools hilft, die häufigsten Fehlerquellen im Code ausfindig zu machen. Aber sie hilft auch, Probleme zu finden, über die sich Entwickler in der Regel keine Gedanken machen, wenn sie ihren Code schreiben, insbesondere wenn sie nur ein Code-Gerüst erstellen, um eine Anwendung zum Laufen zu bringen. Diese Art von Tools hilft nachweislich bei der Entwicklung von besserem Code, weil sie Programmierstandards durchsetzen.
Bild 4: Standard- und Regelauswahl.
(Bild: IAR Systems)
Abhängig von der Qualität der statischen Analyselösung kann das Tool viele andere potenzielle Probleme aufdecken, während der Code noch am Schreibtisch geprüft wird. Um zu sehen, wie es funktioniert, sehen wir uns das C-STAT Static Analysis Tool von IAR Systems (das in IAR Embedded Workbench für RISC-V integriert ist) in Aktion an. C-STAT bezieht seine Regeln aus den MISRA C 2004 und 2012 Regelsätzen, dem MISRA C++ 2008 Regelsatz, der Common Weakness Enumeration (CWE) von MITRE und von SEI CERT C. Bild 4 zeigt die verfügbaren Regeln, die aktiviert werden können, um die Einhaltung der Programmierstandards durchzusetzen.
Bild 5: Meldungen aus der Code-Analyse.
(Bild: IAR Systems)
Es kann nach Kategorien aufgeschlüsselt werden, um nur die Regeln auszuwählen, die für das jeweilige Projekt relevant sind. Darüber hinaus ist es möglich, diese Auswahl auf Gruppen-, Datei-, Funktions- oder sogar auf Ebene einer einzelnen Zeile zu überschreiben, um eine vollständige Granularität über das, was geprüft wird, zu erhalten. Sobald die Tools konfiguriert sind, kann das Projekt (oder eine Gruppe oder eine einzelne Quelldatei) analysiert werden. Nach Abschluss der Analyse ist es möglich, die einzelnen Dateien zu untersuchen, um die aufgetretenen Probleme zu überprüfen:
Bild 6: Kontextsensitive Hilfe in C-STAT.
(Bild: IAR Systems)
Das erkannte Problem CERT-ERR33-C_c in Bild 5 gehört zu den CERT-C-Regeln. Die meisten Regeln sind selbsterklärend, aber weitere Informationen können in den Anwenderhandbüchern oder in der kontextsensitiven Hilfe (F1) gefunden werden, wie in Bild 6 dargestellt.
Bild 7: Codebeispiele für fehlerhafte und bestandene Prüfungen.
(Bild: IAR Systems)
Im Hilfefenster erhält der Entwickler eine vollständige Beschreibung des Problems, die Einschätzung, inwieweit es sich um einen echten Fehler handelt, und den Schweregrad, der bei Manifestierung der Fehler eintritt, sowie alle Codierungsstandards, gegen die er verstößt. Am wichtigsten ist jedoch, dass unten, wie in Bild 7 gezeigt, ein bis drei Codebeispiele zu sehen sind. Sie enthalten ein schlechtes Beispiel und zeigen, wie dieses schlechte Beispiel korrigieren werden kann, damit es die Prüfung besteht und der Code robuster wird. Das hilft dabei, die Fehler, die die statische Analyse im Quellcode aufgedeckt hat, schnell zu beseitigen.
Automatisierte Arbeitsabläufe
Bild 8: Automatisierte Arbeitsabläufe.
(Bild: IAR Systems)
Die Sicherstellung der Code-Qualität ist wichtig für die Entwickler, die tagtäglich am Schreibtisch arbeiten, aber noch wichtiger ist sie in den modernen und skalierbaren Build-Server-Topologien für CI/CD-Pipelines, die virtuelle Maschinen, Container (Docker) und Runner umfassen. Code-Analyse-Tools sollten gut skalierbar sein, damit die automatisierte Aufgabe, die Einhaltung der Programmierstandards zu gewährleisten, für größere Teams und solche, die an verschiedenen Standorten rund um den Globus verteilt sind, leicht zu bewältigen ist. Bild 8 zeigt die Verwendung des statischen Analysetools C-STAT, das über die Kommandozeile in Linux – Ubuntu verwendet wird. Für viele automatisierte Arbeitsabläufe ist die plattformübergreifende Unterstützung ein Standard zur Verbesserung der Effizienz von Entwicklungsteams.
Unterstützung durch Code-Analyse
Einer der größten theoretischen Vorteile der statischen Analyse besteht darin, dass sie sich nicht auf die Leistung eines Systems auswirkt, da das System während der Durchführung der Analyse nicht einmal läuft. Sie ist auch unabhängig von der Qualität der Testsuiten. Um einen bestimmten Fehler im laufenden Code zu finden, muss ein bestimmter Pfad durch das Programm mit einem bestimmten Datensatz ausgeführt werden, während ein Tool für statische Analyse theoretisch alle möglichen Pfade durch den Code untersuchen kann.
Durch die Einführung einer Code-Qualitätskontrolle zu einem frühen Zeitpunkt im Entwicklungszyklus oder bei der Wiederverwendung von Code und der Zukunftssicherung des Quellcodes können die Auswirkungen von Fehlern minimiert werden. Die Bereitstellung einer statischen Analyse direkt in den Händen der Entwickler, die mit RISC-V-Prozessoren mit gut definierten Codierungsstandards arbeiten, kann dabei helfen, Probleme im Quellcode während der Entwicklung zu finden, wo die Kosten für Fehler geringer sind als im freigegebenen Produkt.