Rust w AUTOSAR Classic: od teorii do praktycznej implementacji w ekosystemie SDV

dou.eu 16 godzin temu

Branża motoryzacyjna przechodzi fundamentalną transformację. W modelu Software-Defined Vehicle (SDV) to oprogramowanie w coraz większym stopniu definiuje funkcje pojazdu i staje się jednym z głównych motorów innowacji.

Równolegle z innymi istotnymi zmianami sektor zmierza dziś w kierunku zonal architectures oraz konsolidacji mocy obliczeniowej wokół platform obliczeniowych wysokiej wydajności (HPC).

Centralizacja nie eliminuje jednak luk w zabezpieczeniach występujących w komponentach oprogramowania. W miarę przenoszenia kolejnych funkcji pojazdu do warstwy software’owej coraz większego znaczenia nabiera nie tylko architektura systemu, ale także sposób, w jaki tworzony jest sam kod. W pojeździe błąd systemu może potencjalnie przełożyć się na bezpieczeństwo fizyczne.

Bezpieczeństwo pamięci staje się elementem bezpieczeństwa w motoryzacji

Przez dziesięciolecia języki C i C++ stanowiły fundament systemu motoryzacyjnego. Jednym z głównych wyzwań związanych z ich wykorzystaniem w środowiskach krytycznych jest ryzyko wynikające z manualnego zarządzania pamięcią.

Odwołania do wskaźnika o wartości null, przepełnienia bufora, błędy typu use-after-free oraz wyścigi danych mogą prowadzić do awarii systemu i powstawania luk w zabezpieczeniach. W systemach krytycznych takie defekty generują dodatkowe ryzyka, które muszą być odpowiednio zarządzane w ramach procesów bezpieczeństwa funkcjonalnego (Functional Safety) oraz cyberbezpieczeństwa, w tym procesów określonych przez normy ISO 26262 i ISO/SAE 21434.

Zainteresowanie językami wyposażonymi we wbudowane mechanizmy bezpieczeństwa pamięci (memory safety) wykraczarównież poza branżą motoryzacyjną. Raport „Back to the Building Blocks” opublikowany przez amerykańskie Biuro Krajowego Dyrektora ds. Cyberbezpieczeństwa (Office of the National Cyber Director)oraz inicjatywy DARPA, w tym program TRACTOR, wskazują na potrzebę szerszego wykorzystania języków zapewniających bezpieczeństwo pamięci, takich jak Rust.

W branży motoryzacyjnej wartość języka Rust nie wynika jedynie z faktu, iż stanowi on alternatywę dla języków C lub C++. Znacznie istotniejsze jest to, iż część gwarancji bezpieczeństwa jest egzekwowana już na poziomie samego języka i kompilatora.

Co zmienia Rust na poziomie kodu

Główną zaletą języka Rust w systemach krytycznych jest możliwość zwiększenia niezawodności systemu bez utraty wydajności.

Kilka cech jest szczególnie istotnych dla systemu motoryzacyjnego:

  • Wbudowane bezpieczeństwo pamięci (memory safety) na etapie kompilacji. Tak zwany Safe Rust eliminuje całe klasy podatności jeszcze przed uruchomieniem systemu na rzeczywistym mikrokontrolerze. Obejmuje to między innymi dereferencję wskaźników null (null-pointer dereference), przepełnienia buforów (buffer overflows) oraz błędy typu use-after-free.
  • Wydajność porównywalna z C/C++ bez wykorzystania Garbage Collectora. Dzięki abstrakcjom o zerowym koszcie wykonania (zero-cost abstractions) oraz niskopoziomowej kontroli nad zasobami, Rust może dostarczać wydajność wymaganą przez systemy czasu rzeczywistego oraz sterowniki ECU dysponujące ograniczonymi zasobami obliczeniowymi.
  • Przydatność w systemach wbudowanych (embedded). Rust może pracować w trybie #![no_std], bez standardowej biblioteki, co pozwala zachować pełną kontrolę nad zasobami i środowiskiem wykonawczym w aplikacjach wbudowanych.
  • Bezpieczniejsza współbieżność (concurrency). Safe Rust zapobiega występowaniu wyścigów danych, (data races) w sytuacjach, gdy wiele wątków lub rdzeni jednocześnie korzysta ze współdzielonych zasobów. Ma to szczególne znaczenie w przypadku wielordzeniowych mikrokontrolerów, procesorów samochodowych oraz platform HPC (High-Performance Computing) stosowanych w architekturach SDV.

To prowadzi do naturalnego pytania: o ile Rust oferuje tak znaczące korzyści, dlaczego branża motoryzacyjna nie przechodzi na niego całkowicie?

Przyszłość to nie „Rust zamiast C”

Dla producentów OEM i dostawców Tier 1 całkowite porzucenie istniejących systemów i przepisanie systemu motoryzacyjnego od podstaw byłoby nie tylko nieopłacalne ekonomicznie, ale również obarczone znacznym ryzykiem technicznym i projektowym.

Przez dekady branża zbudowała rozbudowaną bazę sprawdzonych komponentów systemu napisanych w języku C, procesów, narzędzi i infrastruktury wokół AUTOSAR Classic. Z tego względu bardziej realistycznym podejściem jest stopniowa, ewolucyjna integracja języka Rust w istniejącym środowisku, czyli podejście hybrydowe.

W takim modelu Rust nie musi zastępować C w całym stosie programowym pojazdu. Może być wykorzystywany w wybranych komponentach programowych (SWC, Software Components), szczególnie tam, gdzie jego mechanizmy bezpieczeństwa przynoszą największe korzyści pod względem niezawodności, bezpieczeństwa funkcjonalnego oraz cyberbezpieczeństwa.

W konsekwencji kluczowym pytaniem nie jest już, czy branża motoryzacyjna powinna przejść z języka C na Rust, ale gdzie i w jaki sposób Rust może zostać zintegrowany z istniejącym ekosystemem AUTOSAR, bez konieczności rezygnacji z dotychczasowych rozwiązań, procesów oraz wieloletnich inwestycji.

Jak działa hybrydowa integracja w AUTOSAR Classic

W praktyce może to wymagać połączenia dwóch zestawów narzędzi kompilacyjnych w jednym procesie budowania — choć jest to wybór specyficzny dla projektu, a nie nieodłączny wymóg hybrydowej integracji Rust/C. W tym PoC zestawiliśmy dwa oddzielne zestawy narzędzi kompilacyjnych różnych dostawców. Możliwą alternatywą jest zestaw narzędzi jednego dostawcy, umożliwiający kompilację obu języków, taki jak zunifikowane rozwiązanie Rust/C firmy HighTec oparte na wspólnym backendzie LLVM. W tym projekcie wybraliśmy jednak wariant wykorzystujący dwa zestawy narzędzi, ponieważ odpowiadał istniejącemu środowisku budowania opartemu na TASKING.

  • Kompilacja komponentu Rust przy użyciu HighTec Rust. Narzędzie to posiada kwalifikację do zastosowań zgodnych z ISO 26262 aż do poziomu ASIL D dla platform Infineon AURIX. Warto zauważyć, iż HighTec nie jest jedynym kwalifikowanym rozwiązaniem dla Rust. Dostępny jest również kompilator Ferrocene, posiadający kwalifikację ISO 26262. W analizowanym projekcie kluczowym czynnikiem decydującym było jednak wsparcie dla architektury AURIX.
  • Hybrydowe linkowanie w środowisku TASKING. Utworzona biblioteka statyczna Rusta jest przekazywana do zestawu narzędzi TASKING, który kompiluje pozostałe moduły AUTOSAR w C, w tym oprogramowanie bazowe Vector MICROSAR Classic oraz RTE, a następnie wykonuje końcowe linkowanie.

Połączenie dwóch różnych toolchainów w jednym obrazie wykonywalnym wymaga spełnienia dodatkowych warunków technicznych. Obiekty wygenerowane przez kompilator Rust muszą być zgodne z TriCore ABI oczekiwanym przez środowisko TASKING. Ponadto argumentacja dotycząca kwalifikacji narzędzi (tool qualification argument) musi obejmować:

  • kompilator Rust,
  • kompilator C,
  • proces linkowania,
  • końcowy artefakt wykonywalny.

W opisywanym przypadku wymagania te zostały spełnione, jednak nie należy traktować tego jako uniwersalnego wyniku. Każdy projekt wymaga własnej analizy zgodności, kwalifikacji narzędzi oraz oceny wpływu na bezpieczeństwo funkcjonalne.

Alternatywą jest zastosowanie rozwiązania jednego dostawcy, w którym zarówno kod C, jak i Rust są kompilowane przez wspólny backend LLVM, przy użyciu jednego linkera i wspólnej infrastruktury buildowej. Takie podejście może znacząco uprościć argumentację dotyczącą kwalifikacji narzędzi i zredukować ryzyko na granicy integracji, choć wiąże projekt z jednym dostawcą technologii.

Kluczowy wniosek dla branży motoryzacyjnej

Podejście hybrydowe pozwala stopniowo wprowadzać Rust do istniejących projektów bez konieczności rezygnacji z infrastruktury AUTOSAR Classic, sprawdzonych komponentów C oraz dotychczasowych inwestycji technologicznych.

Z perspektywy OEM-ów, dostawców Tier 1 oraz zespołów odpowiedzialnych za Functional Safety i Cybersecurity, najważniejszą zaletą może być nie całkowite zastąpienie języka C, ale możliwość bezpiecznego współistnienia obu technologii. Dzięki temu Rust może być wdrażany tam, gdzie przynosi największą wartość, szczególnie w nowych lub krytycznych komponentach związanych z bezpieczeństwem funkcjonalnym, cyberbezpieczeństwem oraz platformami SDV.

Więcej niż bezpieczeństwo pamięci

Zgodność na poziomie procesu budowania jest jedynie fundamentem. Rust może również zmienić sposób rozwiązywania niektórych wyzwań inżynieryjnych charakterystycznych dla AUTOSAR, zwłaszcza w obszarach przetwarzania wielordzeniowego oraz obsługi błędów.

W wielordzeniowych mikrokontrolerach, takich jak Infineon AURIX, wiele zadań może jednocześnie uzyskiwać dostęp do stanu wewnętrznego komponentu lub pamięci PerInstanceMemory (PIM).) W tradycyjnym C programista zarządza tym procesem manualnie dzięki Rte_Enter_EA() i Rte_Exit_EA(). Pominięcie któregoś z tych wywołań lub nieprawidłowe ich użycie może prowadzić do wystąpienia wyścigu danych (data race), którego kompilator nie jest w stanie wykryć.

Proponowany wzorzec PimGuard przenosi tę ochronę do systemu typów języka Rust: dostęp do danych przechowywanych w PIM jest możliwy wyłącznie wtedy, gdy odpowiednia blokada została uzyskana i jest potwierdzona przez kompilator na etapie kompilacji.

Należy jednak podkreślić, iż gwarancja ta dotyczy wyłącznie części napisanej w Rust. Komponenty AUTOSAR RTE oraz pozostałe moduły napisane w C mogą przez cały czas posiadać dostęp do tej samej pamięci PerInstanceMemory, a kompilator Rust nie ma wglądu w takie operacje. Oznacza to, iż wzorzec PimGuard podnosi poziom bezpieczeństwa wewnątrz komponentu SWC zaimplementowanego w Rust, ale nie eliminuje konieczności przeprowadzania klasycznej analizy współbieżności na granicy komponentów i języków programowania.

Podobna zasada dotyczy obsługi błędów. Rust wykorzystuje jawny typ Result wraz z mechanizmem pattern matching. Result sprawia, iż scenariusz błędu jest jawnie reprezentowany w systemie typów, a kompilator domyślnie ostrzega, jeżeli wynik zostanie zignorowany. W praktyce zmniejsza to ryzyko sytuacji, w których błędy są przypadkowo pomijane lub niewłaściwie obsługiwane, co ma szczególne znaczenie w systemach związanych z bezpieczeństwem funkcjonalnym.

Patrząc szerzej, jest to jeden z najważniejszych aspektów wykorzystania Rust w motoryzacji. Część mechanizmów kontrolnych, które dotychczas opierały się głównie na: doświadczeniu programisty, stosowaniu wytycznych kodowania (np. MISRA), przeglądach kodu, działaniach weryfikacyjnych i testowych, może zostać przeniesiona na poziom języka programowania i kompilatora.

Nie oznacza to zastąpienia procesów wymaganych przez ISO 26262, ISO/SAE 21434 czy ASPICE, ale pozwala ograniczyć liczbę potencjalnych błędów już na etapie tworzenia kodu. W rezultacie część wymagań dotyczących niezawodności, bezpieczeństwa funkcjonalnego i cyberbezpieczeństwa może być wspierana przez samą technologię, a nie wyłącznie przez procesy inżynierskie stosowane po napisaniu oprogramowania.

Od koncepcji do rzeczywistego sprzętu

Aby zweryfikować to podejście w rzeczywistym środowisku AUTOSAR Classic, nasz zespół opracował i i przeprowadził walidację praktycznego demonstratora technologii (Proof of Concept, PoC).

W ramach migracji z języka C do Rust wybrano moduł obsługi czujników ultradźwiękowych dla systemu wspomagania parkowania (Park Assist SWC), który przetwarza dane o wysokiej częstotliwości w czasie rzeczywistym. Oprogramowanie działa na fizycznym mikrokontrolerze Infineon AURIX TriCore TC375 z wykorzystaniem Vector MICROSAR Classic BSW oraz narzędzi DaVinci.

Moduł zaimplementowany w Rust został zintegrowany z platformą Intellias ECU Kit, połączoną magistralą CAN z platformą sprzętowo-programową IntelliKit. IntelliKit symuluje parametry pojazdu, takie jak: prędkość pojazdu, stan naładowania akumulatora, zmiany biegów, hamowanie rekuperacyjne. Przetworzone dane z czujników są następnie przesyłane za pośrednictwem magistrali CAN do cyfrowego kokpitu pojazdu (digital cockpit).

Takie środowisko umożliwia testowanie komponentu Rust w pełnym łańcuchu komunikacyjnym i wykonawczym, obejmującym: AUTOSAR Classic → ECU → CAN → HMI. Dzięki temu można ocenić nie tylko poprawność działania samego komponentu, ale również jego integrację z istniejącym ekosystemem motoryzacyjnym.

Procesy opracowania i walidacji demonstratora zostały poddane niezależnej ocenie przez zewnętrznych audytorów. Realizacja PoC była zgodna z wymaganiami: ASPICE CL2, ISO 26262, ISO/SAE 21434.

Spełnienie wymagań zostało potwierdzone oficjalnymi raportami audytowymi VDA oraz TÜV.

Obszary, które przez cały czas stanowią wyzwanie:

  • Zachowanie w przypadku panic: w środowisku no_std obsługa panic należy do programisty, a jej działanie trzeba zdefiniować z uwzględnieniem wymagań dotyczących Freedom from Interference (FFI). To, jak wystąpienie panic w funkcji runnable napisanej w języku Rust wpływa na pozostałą część ECU, jest kwestią koncepcji bezpieczeństwa, a nie samego języka.
  • Standardy kodowania: obecnie nie istnieje odpowiednik MISRA C dla języka Rust. Prace w ramach Safety-Critical Rust Consortium trwają, dlatego projekty definiują dziś własny podzbiór języka i uzasadniają jego zastosowanie.
  • Debugowanie i narzędzia: przechodzenie podczas debugowania przez granicę C/Rust, obsługa symboli i analiza śladów w istniejących debuggerach motoryzacyjnych są możliwe, ale wyraźnie mniej dojrzałe niż w środowisku opartym wyłącznie na C. Jest to często praktyczny koszt, który zespoły niedoszacowują.

Co dalej

Doświadczenia zdobyte podczas wykorzystania Rust w środowisku AUTOSAR Classic pokazują, iż transformacja nie musi oznaczać wyboru między starym a nowym stosem technologicznym. Podejście hybrydowe pozwala zachować sprawdzone komponenty i istniejącą infrastrukturę, a jednocześnie stopniowo wprowadzać technologie zapewniające bezpieczeństwo pamięci tam, gdzie przynoszą one największą wartość.

Warto również zauważyć, iż Rust zaczyna pojawiać się bezpośrednio w pracach organizacji AUTOSAR. W materiałach dotyczących wydania R25-11 wykorzystanie Rust w Classic Platform zostało wskazane jako jeden z kierunków dalszego rozwoju w obszarze Rust in CP Outlook

Równocześnie AUTOSAR Adaptive Platform posiada wsparcie dla Rust już od wydania R23-11. To właśnie Classic Platform pozostaje trudniejszym przypadkiem ze względu na:

  • generowany kod RTE,
  • ograniczenia toolchainów,
  • wymagania kwalifikacyjne narzędzi,
  • konieczność zachowania kompatybilności z istniejącym ekosystemem.

Rust nie przekreśla dekad rozwoju systemu w języku C ani dorobku AUTOSAR Classic i nie powinien tego robić. Jego rzeczywista wartość leży gdzie indziej. Zamiast polegać wyłącznie na procesach, przeglądach kodu, testach i działaniach weryfikacyjnych, niektóre klasy błędów mogą zostać wyeliminowane już na etapie kompilacji. Z perspektywy bezpieczeństwa funkcjonalnego (ISO 26262) oraz cyberbezpieczeństwa (ISO/SAE 21434) oznacza to stopniowe przesuwanie części mechanizmów bezpieczeństwa: od bezpieczeństwa zapewnianego głównie przez procesy i weryfikację do bezpieczeństwa częściowo wymuszanego przez sam język programowania i narzędzia deweloperskie.

Nie stanie się to wszędzie i nie nastąpi automatycznie. Jednak w przypadku komponentów, dla których dominującym źródłem defektów są błędy zarządzania pamięcią, współbieżności lub obsługi błędów, jest to kierunek wart wdrażania krok po kroku i warto rozpocząć ten proces już dziś.

Autor

Abdelrahman Mabrouk

Automotive Architect, Functional Safety Engineer w Intellias Abdelrahman Mabrouk

Abdelrahman ma ponad osiem lat doświadczenia w branży motoryzacyjnej. Jako Automotive Software Architect w Intellias specjalizuje się w cyberbezpieczeństwie, bezpieczeństwie funkcjonalnym oraz technologiach SDV. Posiada certyfikaty z zakresu ISO 21434 i TÜV Functional Safety oraz tytuł licencjata w dziedzinie mechatroniki, robotyki i automatyki. Koncentruje się na tworzeniu bezpiecznych i niezawodnych systemów motoryzacyjnych, a szczególnie interesują go Software-Defined Vehicles oraz przyszłość mobilności.


Idź do oryginalnego materiału