[VYBRID] Realizacja systemów czasu rzeczywistego pod Linuksem
Podział systemu
Wybór rozwiązania hybrydowego zazwyczaj oznacza wymagania na wydajność, których nie jest w stanie spełnić pojedynczy CPU. Po decyzji o użyciu systemu hybrydowego projektant musi się zastanowić, jak podzielić aplikację na części i jak wykorzystać zasoby. Choć nie ma niezawodnych wytycznych, jak tego dokonać, następujące podejście okazuje się zazwyczaj skuteczne:
Podzielimy specyfikację systemu na fragmenty o różnych wymaganiach na moc obliczeniową. Te fragmenty w przykładowym systemie mogą wyglądać tak:
- Akwizycja danych
- Kontrola PWM i układów wykonawczych
- Obliczanie FFT
- Transformacja Clarka
- Interakcja z użytkownikiem za pośrednictwem GUI
- Monitorowanie systemu i logi
- Narysuj schemat systemu, z częściami oznaczającymi fragmenty i strzałkami oznaczającymi ilość danych, które muszą zostać przesłane między nimi. Oznacz wymagania na przepustowość między częściami za pomocą wartości absolutnych lub przynajmniej względnych wielkości.
- Przypisz każdą część systemu do najbardziej odpowiedniego rdzenia procesora lub mikrokontrolera (nie jest to decyzja ostateczna) i wybierz odpowiedni system operacyjny dla tego procesora.
- Korzystając z tego schematu, zoptymalizuj system pod kątem następujących kryteriów:
- Narzut powodowany przez kanał komunikacji może łatwo przewyższyć zysk z przeniesienia zadania na szybszy układ. W wielu wypadkach lepiej jest połączyć dwa intensywnie komunikujące się ze sobą układy w jednym miejscu i korzystać z pamięci współdzielonej zamiast rozdzielać je na dwa rdzenie.
- Proste jest piękne, a w dodatku stabilne. Jeśli zadanie może zrealizować każdy z procesorów, a wybór jednego pomaga uprościć i zrozumieć system, wybierz to rozwiązanie – nawet, jeśli drugi procesor mógłby zaoferować wyższą wydajność.
- Komunikacja o dużym opóźnieniu może być tunelowana kanałami o niskim opóźnieniu. Im mniej kanałów istnieje w systemie, tym mniejszy narzut na całość komunikacji. Na przykład jeśli istnieje wydajne połączenie między A oraz B i B oraz C, komunikację między A oraz C należy tunelować przy użyciu istniejących kanałów, aby poprawić wydajność.
- Połącz wszystkie części związane z jednym rdzeniem w jedną i usuń wszystkie wewnętrzne kanały komunikacji. Pozostaw tylko te, które służą do komunikacji z układami na zewnątrz rdzenia. Ponownie warto jest rozważyć możliwości tunelowania.
- Aby dowiedzieć się, czy wszystkie wymagania na komunikację oraz wydajność mogą zostać spełnione, warto utworzyć abstrakcyjny model systemu w języku Matlab lub SystemC. SystemC zawiera zbudowane pojęcie kanału. Kanały te można skonfigurować, aby odtworzyć dowolny kanał komunikacyjny systemu docelowego. Niewielkim nakładem pracy da się stworzyć dokładny model systemu wysokiego poziomu, który można poddać dalszej optymalizacji.
- Ustal, czy kod mikrokontrolera może zostać efektywnie zrealizowany przy użyciu systemu operacyjnego, takiego jak MQX lub FreeRTOS, czy też zadanie to należy zaimplementować bezpośrednio w języku niskiego poziomu.
Istnieje wiele systemów, w których funkcje czasu rzeczywistego muszą być obsługiwane oddzielnie, niż pozostała część aplikacji Linuksa – w podobnej architekturze, jak opisana powyżej. W systemach z interfejsem użytkownika GUI wykorzystuje cała dostępna moc procesora wraz z akceleracją grafiki i złożonym interfejsem, na przykład wykorzystującym QT. Wymaganie stawiane GUI to efektowny wygląd oraz szybka reakcja na działania użytkownika. To zadanie może zrealizować najprostsze jądro Linuxa uruchomione na rdzeniu ARM Cortex-A5.
GUI pracuje równolegle z zasadniczą częścią systemu, którą są krytyczne czasowo pomiary lub sterowanie, na przykład kontrola silników wielu płaszczyznach czy komunikacja systemów przemysłowych. Te funkcje najlepiej zaimplementować na rdzeniu mikrokontrolera ARM Cortex-M4 układu Vybrid i uruchomić na nim niskopoziomowy kod lub lekki, wydajny system czasu rzeczywistego.
Interfejs komunikacyjny między oboma rdzeniami musi spełniać wymagania na przepustowość i opóźnienie. Przepustowość jest potrzebna na przykład do wyświetlania wyników pomiarów i analiz w czasie rzeczywistym, niskie opóźnienie jest wymagane, aby system sprawnie reagował na komendy użytkownika.
Nie tylko systemy czasu rzeczywistego mogą wykorzystać hybrydową architekturę. Systemy wysokiej klasy bezpieczeństwa również stawiają takie wymagania, choć z innych przyczyn. Głównym powodem jest konieczność uzyskania certyfikatów, takich jak ISO26262 czy IEC 61518 – można je spełnić niezależnie od niepodlegających zabezpieczeniu funkcji jądra Linuksa.
Podstawowym wymaganiem stawianym systemowi jest pewność, że krytyczny fragment może zawsze przejść w bezpieczny tryb pracy, niezależnie od działania reszty systemu. Przy użyciu lekkiego systemu czasu rzeczywistego lub kodu niskopoziomowego łatwo jest spełnić to wymaganie i uzyskać certyfikat. Natomiast duże i często zmieniające się jądro Linuksa, pracujące na rdzeniu procesora, nie podlega certyfikacji.
System-On-Chip – proste rozwiązanie dla inżyniera
W artykule pokazano różne zastosowania, w których dodanie małego rdzenia mikrokontrolera do procesora obsługującego aplikację jest korzystne, a w innych – wręcz konieczne. System zrealizowany jako hybryda procesora i mikrokontrolera jest najprostszą i najtańszą implementacją tej architektury.
Układ Vybrid typu System-On-Chip firmy Freescale oferuje wszystkie zalety systemu hybrydowego, ale ukrywa przed użytkownikiem złożoność projektu i oprogramowania. Ponadto jednordzeniowe obudowy ARM Cortex-A5 firmy Freescale mają ten sam układ wyprowadzeń, jak układy hybrydowe. Dzięki temu użytkownik może rozpocząć projektowanie z użyciem układu jednordzeniowego, na w przyszłości dokonać migracji na architekturę hybrydową.