Die Anzahl der Steuergeräte sowie die benötigte Rechenleistung im Fahrzeug nimmt durch die steigende Anzahl an Elektronik im Fahrzeug weiter zu. Stand der Technik ist daher der Einsatz von Multicore-Prozessoren. Damit lässt sich je nach Einsatzgebiet entweder durch Konsolidierung die Anzahl der Steuergeräte verringern oder zusätzliche Rechenleistung bereitstellen, beispielsweise für ADAS-Funktionen. Damit einher geht jedoch eine höhere Komplexität im Bereich funktionale Sicherheit sowie die vollständige Unterstützung seitens der verwendeten Entwicklungswerkzeuge.

Eckdaten

Bei Functional-Safety-Analysen auf Multicore-Systemen stoßen traditionelle statische Analysetools an ihre Grenzen. Tasking bietet eine Lösung, die auf der statischen Analyse von Objektcode basiert, um den Code bereits vor der Ausführung auf Rückwirkungsfreiheit zu überprüfen. Da das Entwicklungswerkzeug detaillierte Kenntnis über die Prozessoren, Busse, Speicher, verwendete Variablen und den Datenfluss besitzt, ist es möglich, fehlerhafte Speicherzugriffe innerhalb des kompletten Adressraums festzustellen, auch auf Multicore-Systemen.

Insbesondere die Tatsache, dass oft eine heterogene Multicore-Architektur, also unterschiedliche Prozessorarchitekturen auf einem Chip, zum Einsatz kommen, stellt Entwickler vor neue Herausforderungen. Beispielsweise enthält Infineons Aurix neben den Tricore-Kernen je nach Variante zusätzlich Kerne basierend auf der GTM-IP, ARM-Cortex oder der XC800-Architektur. Stammen die für die Architekturen benötigten Softwareentwicklungswerkzeuge zusätzlich von unterschiedlichen Anbietern, entstehen weitere Abhängigkeiten – und zwar sowohl technischer als auch finanzieller Natur. Insbesondere die Langzeitverfügbarkeit ist nicht gegeben, da jeder Versionssprung eine erneute Kompatibilitätsprüfung seitens der Anbieter in der verwendeten Werkzeugkombination erfordern würde. Dies ist in der Praxis durch die große Anzahl an Kombinationsmöglichkeiten nicht umsetzbar.

Um diese Herausforderungen zu meistern, sollte ein zertifiziertes Softwareentwicklungswerkzeug wie die Tasking-Produktreihe mit einheitlichem Ansatz gewählt werden. Das bedeutet im Falle eines Compilers konkret, dass für sämtliche innerhalb des Prozessors verwendeten Architekturen die gleichen Schlüsselwörter, die gleiche Linker-Syntax, die gleiche IDE und der gleiche Debugger zum Einsatz kommen sollten, wobei das Ergebnis in einer gemeinsamen Binärdatei zusammengefasst wird. Dies hat neben einer Zertifizierung der kompletten Entwicklungsumgebung den unmittelbaren Vorteil, dass eine Komplettlösung meist günstiger ist und Entwickler sich nur einmalig einarbeiten müssen. Weiterhin können im Falle von Tasking auf diesem Wege mit Features wie MISRA-C- oder CERT-C-Support sowie Proven-in-Use-Erfahrungen in Compiler für Architekturen einfließen, die neu auf dem Markt sind oder die nur wenige Kunden als Spezialcore nutzen.

Bild 1: Beispielhafte Softwarekomponenten in einem heterogenen Multicore-System.

Bild 1: Beispielhafte Softwarekomponenten in einem heterogenen Multicore-System.Altium/Tasking

Softwarepartitionierung

Ein viel behandeltes Thema ist die sichere Aufteilung der Softwarekomponenten auf die Prozessorkerne. Dies setzt voraus, dass bereits vor der Ausführung eine Zuordnung auf die Speicherbereiche mittels Compiler oder Linker erfolgt. Im Gegensatz zu Singlecore-Architekturen besteht die Herausforderung in der Tatsache, dass beispielsweise im Falle des Aurix-Prozessors von Infineon je nach Speichertyp auch unterschiedliche Möglichkeiten bestehen. Eine Softwarekomponente lässt sich gemeinsam genutztem Speicher zuordnen. Alle Cores können daher auf die Komponente zugreifen. Erhält die Softwarekomponente allerdings eine Zuordnung zu lokalem Speicher auf einem Core, dann lässt sich dieser entweder ebenfalls im Sharing-Betrieb von allen Kernen verwenden; im Private-Betrieb hat nur der lokale Core Zugriff, und im Clone-Betrieb legt das System jeweils eine lokale Kopie an und verwendet diese.

Durch diese Komplexität ist eine umfassende Unterstützung seitens der Entwicklungsumgebung notwendig. Mit der Tasking-Toolchain kann diese Zuordnung sowohl durch Schlüsselwörter innerhalb des Quellcodes erfolgen als auch nachträglich durch den Linker. Die nachträgliche Zuordnung ist insbesondere für Softwarekomponenten wichtig, die sich durch eine Zertifizierung oder mangels Quellcode nicht verändern lassen. Trotz der Aufteilung auf verschiedene Prozessorkerne und Architekturen ist es im Sinne einer einheitlichen Entwicklungsumgebung weiterhin möglich, eine gemeinsame Binärdatei für das komplette System zu erzeugen.

Functional Safety auf Multicore-Systemen

Die Firmware eines Steuergerätes besteht aus einer Vielzahl einzelner Softwarekomponenten, die jeweils in ASIL (Automotive Safety Integrity Level) genannte Sicherheitsstufen eingeteilt sind. Der im Kraftfahrzeug übliche Standard ISO 26262 („Road Vehicles – Functional Safety“) erfordert „Freedom of Interference“, also eine Rückwirkungsfreiheit zwischen den Softwarekomponenten. Andernfalls könnte ein Fehlverhalten einer als nicht sicherheitskritisch eingestuften QM-Komponente auf sicherheitskritische ASIL-Komponenten Einfluss nehmen. Dieser Beweis erfordert bereits auf einem klassischen Singlecore-Prozessor weitreichende Analysen und Tests. Wenn bereits vor der Ausführung auf potenzielle Verletzungen der Rückwirkungsfreiheit ein Test möglich ist, verringert sich der spätere Aufwand, sodass sich Fehler bereits im Vorfeld beheben lassen.

Bild 2: Beispiel für das Linkerkonzept des Tricore VX Toolsets von Tasking.

Bild 2: Beispiel für das Linkerkonzept des Tricore VX Toolsets von Tasking.Altium/Tasking

Ein Multicore-Prozessor wie der Aurix verfügt je nach Modell über bis zu fünf Cores im gleichen Adressraum. Mithilfe der MPU (Memory Protection Unit) ist es hardwareseitig möglich, zur Laufzeit Speicherzugriffe zu überwachen und eine Fehlerbehandlung auszulösen. Weiterhin bietet auch eine Implementierung gemäß dem Autosar-Standard bereits einen Ansatz, um Rückwirkungsfreiheit zu gewährleisten. Die technisch begrenzte Anzahl an MPU-Bereichen und insbesondere die Tatsache, dass Fehler erst zur Laufzeit und damit möglicherweise erst nach Auslieferung entdeckt und behandelt werden, disqualifizieren diese Methode jedoch als alleinigen Ansatz.

Der gängige Ansatz einer statischen Analyse besteht darin, den Quelltext der Komponenten auf Fehler und gefährliche Code-Konstrukte zu überprüfen, die der Compiler nicht erkennt oder anmerkt. Marktübliche Werkzeuge arbeiten überwiegend generisch ohne Kenntnisse über den Prozessor, das Speicherlayout und die Aufteilung der Komponenten auf die Kerne. Daher detektieren sie einige Probleme nicht, die durch die Verwendung von Multicore-Prozessoren auftreten können.

Statische Analyse

Tasking bietet eine Lösung, die auf der statischen Analyse von Objektcode basiert, um den Code bereits vor der Ausführung auf Rückwirkungsfreiheit zu überprüfen. Da das Entwicklungswerkzeug detaillierte Kenntnis über die Prozessoren, Busse, Speicher, verwendete Variablen und den Datenfluss besitzt, ist es möglich, fehlerhafte Speicherzugriffe innerhalb des kompletten Adressraums festzustellen. Damit lassen sich bestehende Softwarekomponenten aber auch komplette Systeme, sowohl Single- als auch Multicore, auf potenzielle Verletzungen der Rückwirkungsfreiheit testen. Der Nutzer kann festlegen, welche Zugriffe innerhalb der Komponenten erlaubt oder verboten sind, dass beispielsweise eine ASIL-3-Komponente Daten einer Komponente mit ASIL-4-Level zwar lesen aber nicht schreiben darf. Dies verhindert, dass Softwarekomponenten gemäß einer höheren ASIL-Einstufung verifiziert werden müssen und verringert den Testaufwand sowie die Kosten für eine ISO-26262-Zertifizierung.