Die branchenweit populärsten Codierrichtlinien verbessern die Software in Bezug auf Safety und Security.
Jüngst kündigte die MISRA Working Group zwei neue Updates ihrer MISRA‑C-Guidelines an, nämlich MISRA C:2012 Amendment 4 (AMD4) sowie MISRA C:2023. Was die Unterstützung der Anforderungen der Entwickler von Embedded-Software betrifft, ist dies ein wichtiger Meilenstein. Das seit Langem als Industriestandard für die Entwicklung von Safety- und Security-kritischen Geräten etablierte MISRA C gibt Entwicklern Programmier- und Prozessleitlinien an die Hand, die dazu beitragen, das Risiko von unerwartetem oder undefiniertem Verhalten in ihren Anwendungen zu reduzieren.
Angesichts der wachsenden Zahl von Geräten, die einen reichhaltigen Funktionsumfang aufweisen und vernetzt sind, wenden die Hersteller von Safety- und Security-kritischen Produkten immer ausgefeiltere Techniken an, um mit Mikroprozessoren, Mikrocontrollern und Peripheriebausteinen, denen nur knappe Ressourcen zur Verfügung stehen, immer umfangreichere Fähigkeiten zu implementieren. Nach jahrelanger praxisorientierter Forschungs- und Entwicklungsarbeit tragen die neuen Editionen der MISRA‑C-Guidelines diesen modernen Techniken Rechnung, indem sie Leitlinien zum Multithreading und zu atomaren Datentypen bereithalten, um die C-Standards ISO/IEC 9899:2011 und 2018 – auch als C11 bzw. C18 bekannt – zu unterstützen.
MISRA C ist keineswegs nur eine Anleitung für den Programmierstil, sondern umfasst eine ganze Reihe von Regeln und Vorschriften. Sie zielen darauf ab, die Verwendung von syntaktischen und semantischen Sprachelementen, die als risikobehaftet bekannt sind, zu minimieren oder ganz zu eliminieren. Im Rahmen eines umfassenden Software-Entwicklungsprozesses wenden viele Entwicklungsteams jedoch auch einen Sprachleitfaden als Ergänzung zu den MISRA‑C-Guidelines an.
Weshalb brauchen C-Entwickler
die MISRA‑C-Guidelines?
Entwickler von Embedded-Systemen nehmen routinemäßig Safety-, Security- und Zuverlässigkeitsanforderungen an die Software in ihre Entwicklungsprozesse auf. Die Spanne reicht dabei von KFZ-Motorsteuerungen bis zu Industriemaschinen. Wenn sich solche Systeme nicht exakt so verhalten wie von den Entwicklern vorgesehen, sondern unerwartet reagieren, führt dies mit großer Wahrscheinlichkeit zu Problemen mit der funktionalen Sicherheit (Safety) sowie zu Security-Schwachstellen.
Die tatsächliche Gewährleistung der Safety und Security stellt Embedded-Entwickler allerdings vor Probleme. Zunächst einmal gibt die C-Sprache den Entwicklern die Möglichkeit, das Verhalten der Anwendung und den Speicher auf eine Weise zu steuern, die das vorgesehene Verhalten beeinträchtigen kann. Hinzu kommt, dass C11 und C18 nur eine unvollständige Spezifikation des beabsichtigten Laufzeitverhaltens bieten, sodass einige Entscheidungen stattdessen der Implementierung und dem jeweiligen Entwickler überlassen bleiben. Dies führt zu nicht deterministischen Komponenten in der C-Sprache und lässt den Entwicklern einen Freiraum, aus dem Risiken für das entwickelte System erwachsen können:
Ein Beispiel für undefiniertes Verhalten liegt vor, wenn Variablen großer Array-Typen nicht initialisiert werden. Zur Vermeidung des Verarbeitungsaufwands, der mit dem Initialisieren von Speicher mit Null-Werten unter Verwendung von memset()-Aufrufen einhergeht, verzichten Entwickler gelegentlich auf die Initialisierung solcher Datentypen. Da im C-Standard jedoch nicht spezifiziert ist, wie Implementierungen mit nicht initialisierten Array-Typen umzugehen haben, kann eine solche Praxis zur Laufzeit unvorhersagbare Konsequenzen haben. Viele Compiler und statische Analysatoren markieren dies deshalb als Problem.
Dies ist ein einfaches Beispiel für die Schlupflöcher, die mithilfe der MISRA‑C-Guidelines geschlossen werden sollen. Es gibt jedoch noch weitere Beispiele:
MISRA C findet sich in vielen Functional-Safety-Standards wieder, an die sich Entwickler halten müssen. Direkt angeführt oder üblicherweise angewandt werden die Guidelines in Projekten gemäß Autosar, IEC 62304, IEC 61508, ISO 26262 und DO-178C, und zusätzlich bildet MISRA C unter anderem auch die Grundlage des Joint Strike Fighter C++ Coding Standard sowie des NASA Jet Propulsion Library C Coding Standard.