Software-Defined Vehicle Rust in Automotive

Von Dipl.-Ing. Jonas Wolf und Lukas Wirth* 8 min Lesedauer

Anbieter zum Thema

Das Software-Defined Vehicle (SDV) erfordert einen Wandel hin zu ganzheitlichen E/E-Architekturen im Fahrzeug. Viel wichtiger aber ist ein Umdenken in der Softwareentwicklung, denn diese wird zukünftig für den Markterfolg von noch entscheidenderer Relevanz sein. Doch wie kann eine hochkomplexe Software kosteneffizient und qualitativ hochwertig realisiert werden?

Schnell und sicher: Rust ist in IT-Anwendungen seit Jahren etabliert, dringt aber  zunehmend in Embedded- und Automotive-Software vor.(Bild:  Vector Informatik)
Schnell und sicher: Rust ist in IT-Anwendungen seit Jahren etabliert, dringt aber zunehmend in Embedded- und Automotive-Software vor.
(Bild: Vector Informatik)

In der Softwareentwicklung von Embedded-Systemen, insbesondere in der Automobilbranche, ist C die derzeit am häufigsten eingesetzte Programmiersprache. Passende Compiler sind daher meist als erstes für oft verwendete Hardware-Plattformen verfügbar.

Software für SDVs günstiger entwickeln

Bild 1: Beispiel eines in Rust geschriebenen Programms.(Bild:  Vector Informatik)
Bild 1: Beispiel eines in Rust geschriebenen Programms.
(Bild: Vector Informatik)

Die Verfügbarkeit des Compilers für die im Automobilbau aktuell meistgenutzten Hardware-Plattformen eröffnet die Möglichkeit, eine alternative Programmiersprache für das zukünftige Software-Defined Vehicle einzusetzen: Rust. Im Gegensatz zu C und C++ ist Rust eine recht junge Programmiersprache. Allerdings weist sie einige Alleinstellungsmerkmale auf, die sie für qualitativ hochwertige Software besonders interessant macht. So gehören beispielsweise Out-of-Bounds-Zugriffe und Race-Conditions in der Softwareentwicklung zu den am schwierigsten zu testenden Szenarien. Diese können durch den Rust-Compiler zur Compile-Zeit verhindert werden.

Rust wird von einer großen Entwicklergemeinde vorangetrieben und orientiert sich in Bezug auf die Syntax an C, C++ oder Java. Darüber hinaus ist eine hohe Ausführungsgeschwindigkeit bei gleichzeitiger Sicherheit eines der erklärten Ziele dieser Programmiersprache. Die in Rust erstellte Software weist hinsichtlich ihrer Performance eine vergleichbare Leistung wie die Programme in den Sprachen C oder C++ auf. Bild 1 zeigt ein Beispiel für einen in Rust geschriebenen Code.

Bild 2: Relative Aufwände bei der Nutzung von C/C++ und Rust.(Bild:  Vector Informatik)
Bild 2: Relative Aufwände bei der Nutzung von C/C++ und Rust.
(Bild: Vector Informatik)

Durch jahrzehntelange Erfahrungen mit C und C++ lässt sich das Potenzial durch den Einsatz von Rust auf Basis erster Erkenntnisse abschätzen. Die Effizienzsteigerung ist dabei in die direkten Entwicklungskosten sowie die Aufwände für Wartung, Support und Erweiterung der Software zu unterteilen. Bild 2 zeigt die aktuellen und geschätzten Aufwände in einzelnen Prozessschritten bei der Entwicklung von Software mit den Sprachen C und C++ im Vergleich mit Rust. Die programmiersprachenunabhängigen Aufwände sind der Vollständigkeit halber ebenfalls dargestellt.

Die größten Effizienzgewinne werden in den Bereichen Implementierung, Test sowie Review erwartet:

  • Implementierung: Rust animiert zur Wiederverwendung von Code. Während in C für jeden Typ unter Umständen eine eigene Queue implementiert wird, erlaubt Rust mit starker Typisierung, typgenerischen Parametern und sehr hoher Laufzeitperformance, diese nur einmal zu implementieren. Der Compiler generiert anschließend für die verschiedenen Anwendungsfälle den Code.
  • Test: Eine dedizierte Analyse, wie sie beim Softwareanbieter Vector gegenwärtig für out-of-bounds-Zugriffe im C/C++-Umfeld durchgeführt wird, dürfte künftig überflüssig werden. Diese Sicherheit ist der Programmiersprache inhärent. Die statische Code-Analyse, die bei C und C++ die Anwendung langlaufender, zusätzlicher Werkzeuge voraussetzt, wird bei Rust neben dem Compiler durch ein Tool übernommen, das Teil der Standardinstallation ist.
  • Review: Der Fokus liegt auf essenziellen Aspekten wie funktionaler Korrektheit. Formalitäten wie Formatierung, Namensregeln und Unachtsamkeitsfehler werden ebenfalls durch die Sprache und das Ökosystem mittels Automatisierung behoben oder weitestgehend unterstützt. Beim Testen entsteht weniger Aufwand, da das zugehörige Framework bereits in die Programmiersprache integriert wurde.

Bild 3: Grundsätzliche Aufwände in der Entwicklung mit und ohne Rust.(Bild:  Vector Informatik)
Bild 3: Grundsätzliche Aufwände in der Entwicklung mit und ohne Rust.
(Bild: Vector Informatik)

Durch die so reduzierte Fehlerdichte während der Entwicklung ist davon auszugehen, dass die Wartung der Software deutlich weniger Aufwand erfordern wird. So zeigt Bild 3 einen signifikanten Effizienzgewinn von 20% über den kompletten Lebenszyklus der Software. Diese Zahlen decken sich mit den Erfahrungen, die bei Google mit Rust gesammelt wurden.

Das Ökosystem – eine Übersicht

Neben den Faktoren für die Effizienzsteigerung der Softwareentwicklung spielt das Ökosystem eine wichtige Rolle. Das Herz einer jeden Programmiersprache bilden der Compiler und die zugehörige Standard-Bibliothek. Der Compiler für Rust ist einfach zu installieren und unterstützt eine Vielzahl an Plattformen. Die Grundlage (Compiler-Backend) für den Rust-Compiler ist das LLVM-Framework, auf dem auch der Clang-Compiler basiert. Dadurch profitiert Rust direkt von der Serienreife und den Optimierungen, die dort verfügbar sind, beispielsweise Link-Time-Optimization.

Für den Markterfolg von Rust in der Automobilindustrie ist die Verfügbarkeit eines qualifizierten Compilers für die weit verbreiteten TriCore-Architektur von Infineon von entscheidender Bedeutung. Für Prozessoren mit ARM-Architekturen existieren qualifizierte Compiler, wie beispielsweise Ferrocene.

Es wird an einer Portierung des Compiler-Frontends von Rust für gcc gearbeitet. Dieses Projekt weist jedoch eine Verzögerung im Hinblick auf die Hauptentwicklung auf.

Ein Defizit etablierter Programmiersprachen wie C und C++ für Embedded-Systeme ist das Fehlen eines einheitlichen Paket-Verwaltungssystems. Außerdem existiert zum Zusammenbauen der Software eine verwirrende Vielzahl an Tools. Rust hingegen bietet in diesem Kontext von Beginn an ein sehr komfortables System: Cargo. Cargo erlaubt das Verwalten von Abhängigkeiten und kann die komplizierteren Aufrufe des Compilers vor dem Nutzer verstecken. Eine Einheit, also eine Bibliothek oder ein Programm, das Cargo verwaltet und bauen kann, wird dabei „crate“ (deutsch: Kiste) genannt.

Rust ist mit einer umfangreichen Standard-Bibliothek ausgestattet, die eine hohe Funktionalität aufweist und somit eine Vielzahl von Anforderungen erfüllt. Für Bereiche, die nicht abgedeckt sind, existieren ausgereifte Bibliotheken. Für eine Programmierung von Embedded-Systemen ohne Betriebssystem ist lediglich ein reduzierter Funktionsumfang erforderlich, während die Garantien, die Rust grundsätzlich bietet, weiterhin Gültigkeit besitzen. Die Qualifizierung der ersten Anteile für die Nutzung in sicherheitsrelevanten Projekten erfolgt derzeit durch verschiedene Akteure.

Jetzt Newsletter abonnieren

Verpassen Sie nicht unsere besten Inhalte

Mit Klick auf „Newsletter abonnieren“ erkläre ich mich mit der Verarbeitung und Nutzung meiner Daten gemäß Einwilligungserklärung (bitte aufklappen für Details) einverstanden und akzeptiere die Nutzungsbedingungen. Weitere Informationen finde ich in unserer Datenschutzerklärung. Die Einwilligungserklärung bezieht sich u. a. auf die Zusendung von redaktionellen Newslettern per E-Mail und auf den Datenabgleich zu Marketingzwecken mit ausgewählten Werbepartnern (z. B. LinkedIn, Google, Meta).

Aufklappen für Details zu Ihrer Einwilligung

EinTest-Framework für geschriebene Software ist bereits in Rust integriert. Dies erleichtert das Schreiben von Tests merklich, da keine weiteren Abhängigkeiten zu berücksichtigen sind. Darüber hinaus führt dies zu einer Vereinheitlichung der Testverfahren zwischen verschiedenen Bibliotheken (crates), was wiederum die Wiederverwendung von bereits gut getestetem Code erleichtert.

An Stellen, an denen heute eine Vielzahl freier und/oder kommerzieller Werkzeuge bei C und C++ zum Einsatz kommen, übernimmt clippy bei Rust, unauffällig, aber nicht weniger mächtig, eine wertvolle Aufgabe: die statische Code-Analyse. Der Regelsatz von clippy wird stetig erweitert. Er liefert Entwicklern nicht nur Hinweise zu möglicherweise schlechtem Code, sondern auch Vorschläge zur Verbesserung.

Wer sich in C++ etwas auskennt, weiß, dass selbst die C++ Standard-Bibliothek und die wichtigsten Bibliotheken (Google Test, Boost) mit völlig unterschiedlichen Namenskonventionen und Formatierungsregeln umgesetzt sind. Anders in Rust: Durch rustfmt (ein Bestandteil der Standard-Installation), wird eine einheitliche Code-Formatierung im gesamten Ökosystem gefördert. Der bereits erwähnte rust-analyzer moniert Abweichungen zu Namenskonventionen bereits während der Eingabe.

Innovate Your Software – for a Smarter Future

Deutschlands Leitkongress der Embedded-Softwarebranche

Embedded Software Engineering Kongress

Das Programm des ESE Kongress umfasst 96 Vorträge, 21 Seminare und 3 Keynotes. Seien Sie dabei, wenn sich die Embedded-Software-Community trifft, und nutzen Sie Diskussionen und Expertengespräche für einen ergiebigen Wissenstransfer und erfolgreiches Networken. Während der vier Kongresstage erwartet Sie zudem eine große Fachausstellung mit den führenden Firmen der Branche. Erfahren Sie alles über die neuesten Trends, Herausforderungen und Lösungen im Embedded Software Engineering, von KI, Safety und Security bis hin zu Management und Innovation.

Code-Abdeckung – Die größte Lücke

Ein wichtiger Indikator für die Testgüte ist die Testabdeckung. Im Fall von Software wird sehr oft eine Code-Abdeckung genutzt. Eine Reihe von Standards für kritische Anwendungen sowie Qualitätsanforderungen bedeutender Automobilhersteller definieren strenge Vorgaben hinsichtlich der zu erreichenden Testabdeckung. Bisher ist es in Rust lediglich möglich, mittels llvm-cov, der in das LLVM-Compiler-Framework eingebetteten Code-Coverage-Instrumentierung, eine sogenannte Statement-Coverage zu ermitteln. Allerdings haben Studien gezeigt, dass dies ein zu schwacher Indikator für eine hinreichende Testtiefe ist. Für striktere Abdeckungsmetriken, wie beispielsweise MC/DC, sind auch Änderungen am zugrunde liegenden LLVM-Compiler-Framework erforderlich. Diese Anpassungen wurden bereits begonnen. Allerdings lassen sich Definitionen aus der Luftfahrtindustrie nicht einfach auf Rust übertragen. So müssen noch Lösungen für die sogenannten Kombinatoren (and_then, or_else) gefunden werden, da hier der Kontrollfluss für die Instrumentierung nicht sichtbar ist. Kombinatoren werden oft idiomatisch genutzt. Es existieren zwar keine Makros wie in C++, dennoch bietet Rust unverzichtbare, sogenannte deklarative und prozedurale Makros. Mit deren Hilfe lässt sich der abstrakte Syntaxbaum verändern und erweitern. Es sei jedoch angemerkt, dass auch in diesem Fall eine Code-Abdeckung gemessen werden muss.

Debugger und Profiler zur Leistungsanalyse von Programmen sind in der Regel unabhängig von der genutzten Programmiersprache. Daher ist bereits eine große Auswahl an ausgereiften Werkzeugen verfügbar. Auch die für die Entwicklung von Embedded-Systemen erforderlichen Hardware-Probes und zugehörige Software unterstützen in vielen Fällen die Neuerungen, die sich aus der Nutzung von Rust ergeben haben.

Code-Metriken zur Messung der Komplexität von Software sind noch nicht im Ökosystem von Rust etabliert. Es existieren zwar Werkzeuge wie tokei zur Größenmessung oder auch rust-code-analysis. Allerdings erreichen diese noch nicht das Niveau, das für etablierte Embedded-Programmierung typisch ist.

Kodierrichtlinien bereits in Arbeit

Im Umfeld von C und C++ hat sich MISRA als Instanz für einen sinnvollen Regelsatz etabliert, um ein Subset der jeweiligen Programmiersprachen zu definieren, der in kritischen Projekten zum Einsatz kommen kann. Für Rust existiert derzeit noch keine solche anerkannte Richtlinie, jedoch steht ihre Veröffentlichung unmittelbar bevor. Der Standard JA-1020 der SAE wird ein erster Schritt in diese Richtung sein. Gleichzeitig hat sich unter der Rust Foundation das Safety-Critical Rust Consortium formiert, um ebendiese Richtlinien in einem offeneren Verfahren zu erzeugen. Im Vergleich zu C und C++ ergibt sich für Rust ein signifikanter Vorteil, da durch die Verwendung der Programmiersprache bereits bestimmte Regeln obsolet werden.

Viele Argumente sprechen dafür, dass Rust die optimale Programmiersprache für das Software-Defined Vehicle ist. Der entscheidende Vorteil besteht demnach nicht nur in der Tatsache, dass durch Rust eine robustere Software entsteht, sondern darin, dass sich die Effizient der gesamten Softwareentwicklung erhöht. Derzeit bestehen noch Lücken im Ökosystem von Rust (siehe Tabelle). Diese sollten aber in absehbarer Zeit geschlossen werden können.

Ökosystem-Komponente Konkretes Werkzeug Reife
Compiler Rust-Compiler Produktiv nutzbar, Safety-qualifiziert
Standard-Bibliothek std, core Safety-Qualifizierung in Arbeit
IDE Bsp.: Visual Studio Code
mit Rust-Analyzer
Produktiv nutzbar
Test-Framework In Sprache eingebettet Produktiv nutzbar
Code Coverage Analyse Aktuell: llvm-cov Lücken in Auswertung
und Qualifizierung
Debugger gdb, iSystem,... Produktiv nutzbar
Profiler flamegraph
(basierend auf perf)
Produktiv nutzbar
Statische Code Analyse clippy, miri Produktiv nutzbar
Code-Formatierung cargo-rustfmt Produktiv nutzbar
Build System cargo Produktiv nutzbar
Paket-Management cargo Produktiv nutzbar
Metrik-Erhebung rust-code-analysis, tokei
(nur Code-Größe)
Lücken in Auswertung
Lizenzverwaltung cargo-deny Juristische Prüfung der
Lizenzkompatibilität weiter notwendig
SBOMs cargo-sbom
(SPDX und CycloneDX unterstützt)
Produktiv nutzbar

Spätestens wenn das erfolgt ist, hat Rust das Potential, sich auch im Automobilbereich zu etablieren. Und dies nicht nur wegen des robusteren Codes, sondern auch wegen der zu erwartenden Kosteneffizienz. (sg)

* Dipl.-Ing. Jonas Wolf ist seit 2012 bei Vector Informatik GmbH in verschiedenen Rollen mit dem Thema Funktionale Sicherheit beschäftigt. Er ist Mitglied des Safety-Critical Rust Consortiums und hat zur SAE JA-1020 beigetragen. Auch privat beschäftigt er sich gerne mit Rust.

* Lukas Wirth war bis Juli 2025 als Software-Engineer bei der Ferrous Systems GmbH beschäftigt. Er ist seit vier Jahren Mitglied im Rust-Projekt des Rust-Analyzer-Teams, Mitglied des Coding-Guildeline-Subcommittees des Safety-Critical Rust Consortiums und ist außerdem Co-Autor der Ferrocene-Language-Specification.

(ID:50452618)