Safety und Zuverlässigkeit erhöhen Acht Schritte zu besserer ADAS-Software

Das Entwickeln von ADAS-Software kann viel Zeit in Anspruch nehmen. Safety ist dabei ein vorrangiges Kriterium, und die Zuverlässigkeit hat denselben Stellenwert. Im Beitrag wird gezeigt, wie sich in acht Schritten Entwicklungszeiten beschleunigen sowie Safety und Zuverlässigkeit verbessern lassen.

Nachdem ein bestimmter Baustein für ein Projekt ausgewählt wurde, muss man sich für den Anbieter einer Compiler-Werkzeugkette entscheiden und eine Version wählen, die kompatibel zu den Treibern, Bibliotheken und Versionen des Echtzeit-Betriebssystems (Real Time Operation System, RTOS) für den Zielbaustein ist. Dabei handelt es sich meist um den Microcontroller Abstraction Layer (MCAL) für die AUTomotive Open System ARchitecture (AUTOSAR), SafeTLib und Secure Hardware Extension (SHE) für Safety-Anwendungen sowie potenziell weitere Bib­liotheken für Verschlüsselung, lineare Algebra-Manipulationen usw.

1. Schritt: Treiber- und RTOS-Unterstützung

Wie Bild 1 zeigt, erfordert der MCAL sorgfältige Überlegungen bezüglich der Abhängigkeiten. In der Regel bieten der Anbieter des Zielbausteins und der Anbieter des Echtzeit-Betriebssystems Unterstützung für die im Einzelfall gewählte Compiler-Version. Allerdings ist die Zertifizierung aller notwendigen Treiber und Konfigurationsdateien mit einem erheblichen Arbeits- und Zeitaufwand verbunden. Bei Zeitknappheit kann es deshalb auch sinnvoll sein, sich für eine fertig lieferbare Kombination aus Treibern und einer Compilerversion zu entscheiden.

Cross Linking

Cross Linking gibt die Möglichkeit zum sicheren Mischen von Binärdateien, die mit älteren Compiler-Versionen erstellt wurden, und Binärdateien, die mit neueren Versionen kompiliert wurden. Das Wiederverwenden bestehender Programme und Binärdateien kann Zeit und Geld sparen, während die Nutzung aktueller Compiler-Optimierungen für neue Anwendungen die Leistungsfähigkeit zu steigern vermag, sodass die Applikation in einen kleineren und kostengünstigeren Baustein passt oder mehr Funktionen liefern kann.

Abgesehen vom Kompilieren der MCAL-Treiber mit einem älteren Compiler-Release lässt sich auch älterer und bereits zertifizierter Code ohne Änderungen wiederverwenden. Aktuelle Applikationen und neuer Code, der nicht an eine alte Compiler-Version gebunden ist, können damit umgehend von den Performance-Steigerungen und Verbesserungen profitieren, die mit
der aktuellen Compiler-Technologie verfügbar werden.

2. Schritt: Betriebssicherheit und Leistungsfähigkeit

Die Betriebssicherheit und Leistungsfähigkeit der Werkzeuge und ihrer Resultate werden häufig als separate Themen behandelt. Einige Entwickler benchmarken unter Umständen verschiedene Compiler-Versionen, um das beste Werkzeug für eine bestimmte Anwendung herauszufinden, und bewerten anschließend separat die Informationen über die gebotenen Safety-Features. Was aber nutzen die attraktivsten Benchmark-Resultate, wenn viele der besten Features und Optimierungen deaktiviert werden müssen, weil sie in Grenzsituationen möglicherweise versagen?

Safety

Die Norm ISO-26262-6 enthält Richtlinien für die Entwicklung von Automotive-Produkten auf Software-Ebene (Bild 2). Zur Einhaltung dieser Richtlinien müssen Safety-zertifizierte Software-Tools zum Einsatz kommen. Hier einige wichtige Überlegungen, die bei der Auswahl der Software-Werkzeuge anzustellen sind:

  • Die Entwicklung gemäß ASPICE CL2 bietet aufgrund zertifizierter Entwicklungsprozesse und Qualitätssicherung für sämtliche Prozess- und Entwicklungsschritte die Gewähr für hohe Software-Qualität.
  • Garantierte, qualitativ hochwertige und latenzarme Unterstützung auf aktuellen und alten Compiler-Ver­sionen, damit die Entwicklung niemals blockiert wird.
  • Kein Code von Drittanbietern in der C-Compiler-Werkzeugkette, sodass alle etwaigen Probleme schnell im eigenen Haus bearbeitet werden können.
  • Verfügbarkeit eines Compiler-Toolchain-Safety-Kits, mit dem es einfach ist, die Compiler-Werkzeugkette für das Safety-Projekt zu qua­lifizieren und zu zertifizieren.
  • Tools zur Optimierung der Leistungsfähigkeit bezogen auf den Code-Umfang.
  • Werkzeug zur Realisierung der Freedom From Interference (FFI) zwischen Software-Komponenten mit verschiedenen ASIL-Werten gemäß Kapitel 7 der Norm ISO 26262.

Leistungsfähigkeit

Ein Compiler sollte nicht nur einfach funktionieren, sondern die ungeteilte Aufmerksamkeit seines Anbieters besit­zen. Viele Embedded-Compiler basieren auf Open-Source-Technologie wie gcc oder LLVM, was ein Vorteil sein kann, wenn es um High-End-Cores von Intel, Cortex-A oder ähnliche Familien geht. Aus der Sicht des Compilers sind die Performance-relevanten Merkmale dieser Architekturen ähnlich. Die Geschwindigkeit wird in der Regel von folgenden Kriterien bestimmt:

  • Cache-Hierarchie. Der Speicher ist deutlich langsamer als der Kern, und Cache-Speicher verhindern, dass der Core ständig auf den Speicher warten muss.
  • Effiziente Nutzung der SIMD- (Single Instruction, Multiple Data) oder Gleitkomma-Einheiten (Floating-Point Units, FPUs).
  • Weitere Anweisungen für spezielle Zwecke.

Diese High-End-Cores nutzen Techniken wie die Out-of-Order-Verarbeitung, Advanced Branch Prediction, Register-Umbenennung und zahlreiche weitere Tricks zur Steigerung des Durchsatzes, was den Druck auf den Compiler hinsichtlich der Pipeline-Optimierungen deutlich mindert. Viele Optimierungen im Front-End und Back-End von LLVM sind auf High-End-Cores dieser Art zugeschnitten. Das Portieren von Code auf einen neuen Kern mit ähnlichen Eigenschaften kann sich auf das Anpassen einiger weniger Schlüsselwerte wie etwa der Cache-Größe beschränken, während der Befehlssatz unverändert bleibt.

Grundlegend anders liegen die Verhältnisse, wenn es um komplexe Embedded-Multicore-Prozessoren wie Infineon Aurix TriCore geht, die sich radikal von den High-End-Cores unterscheiden. Oftmals kombinieren diese Embedded-Cores Merkmale aus der digitalen Signalverarbeitung (Digital Signal Processing, DSP), dem Reduced Instruction Set Computing (RISC), dem Very Long Instruction Word-Konzept (VLIW) sowie spezieller Beschleuniger-Hardware wie etwa der FFT-Einheit.

Viele Algorithmen aus den bestehenden LLVM-Back-Ends lassen sich nicht einfach an komplexe Embedded-Bausteine dieser Art anpassen, sodass das Back-End in diesem Fall nahezu ganz neu geschrieben werden muss. Viele der für die Performance entscheidenden Optimierungen für derartig komplexe Embedded-Cores erfolgen jedoch nicht im Front-End, sondern im Back-End. Daher bringt es nur wenige Vorteile mit sich, wenn das LLVM-Framework zum Entwickeln von Hochleistungs-Code für einen Aurix-Baustein zum Einsatz kommt. Das heißt im Klartext: Wird mit einem komplett neuen Compiler und einem beliebigen Front-End begonnen, ist man nicht schlechter dran.

3. Schritt: Konfigurieren des Bausteins

Multicore-Prozessoren sind extrem leistungsfähige Bauelemente, und
es gibt Hunderte von Varianten mit verschiedenen funktionalen Konfigurationen. Zum Beispiel kann ein einziger Aurix-Baustein bis zu sechs TriCore-Cores, ein Hardware Security Module (HSM), ein Generic Timer Module (GTM) und eine Vielzahl von Peripheriefunk­tionen enthalten.

Zu schreiben ist der Start-up-Code, welcher die Takte, den Speicher und die Peripherie korrekt konfiguriert. Zu jedem Core gibt es ein umfangreiches Handbuch, das die Pin-Beschränkungen und die Optionen zum Konfigurieren der Peripherie skizziert. Alle diese Vorgaben müssen beachtet werden, um ein gültiges Pin-Mapping zu erhalten (Bild 3).