Środowisko wykonawcze centrum kontekstu (CHRE)

Smartfony zawierają wiele procesorów, z których każdy jest zoptymalizowany pod kątem wykonywania różnych zadań. Android działa jednak tylko na jednym procesorze: procesorze aplikacji (AP). Procesor aplikacji jest dostosowany do zapewniania wysokiej wydajności w przypadku korzystania z urządzenia przy włączonym ekranie, np. podczas grania, ale zużywa zbyt dużo energii, aby obsługiwać funkcje, które wymagają częstych, krótkich serii przetwarzania przez cały czas, nawet gdy ekran jest wyłączony. Mniejsze procesory mogą wydajniej obsługiwać te obciążenia, wykonując zadania bez zauważalnego wpływu na baterię. Środowiska oprogramowania w tych procesorach o niskim poborze mocy są jednak bardziej ograniczone i mogą się znacznie różnić, co utrudnia tworzenie aplikacji na wielu platformach.

Środowisko wykonawcze Context Hub (CHRE) to wspólna platforma do uruchamiania aplikacji na procesorze o niskim poborze mocy, z prostym, standardowym interfejsem API, który jest łatwy do osadzenia. CHRE ułatwia producentom OEM urządzeń i ich zaufanym partnerom odciążanie przetwarzania z procesora aplikacji, aby oszczędzać baterię i ulepszać różne aspekty działania urządzenia, a także umożliwia korzystanie z funkcji działających w trybie ciągłym i dopasowanych kontekstowo, zwłaszcza tych, które wykorzystują uczenie maszynowe do wykrywania otoczenia.

Kluczowych pojęć

CHRE to środowisko oprogramowania, w którym małe aplikacje natywne, zwane nanoaplikacjami, działają na procesorze o niskim poborze mocy i wchodzą w interakcje z systemem bazowym za pomocą wspólnego interfejsu CHRE API. Aby przyspieszyć prawidłowe wdrożenie interfejsów API CHRE, w AOSP znajduje się referencyjna implementacja CHRE na wielu platformach. Implementacja referencyjna zawiera wspólny kod i abstrakcje dotyczące sprzętu i oprogramowania bazowego w postaci serii warstw abstrakcji platformy (PAL). Nanoaplikacje są prawie zawsze powiązane z co najmniej jedną aplikacją kliencką działającą na Androidzie, która wchodzi w interakcję z CHRE i nanoaplikacjami za pomocą interfejsów API systemu o ograniczonym dostępie ContextHubManager.

Ogólnie rzecz biorąc, można znaleźć podobieństwa między architekturą CHRE a Androidem jako całością. Istnieje jednak kilka ważnych różnic:

  • CHRE obsługuje tylko nanoaplikacje opracowane w kodzie natywnym (C lub C++); Java nie jest obsługiwana.
  • Ze względu na ograniczenia zasobów i bezpieczeństwa CHRE nie jest dostępny dla dowolnych aplikacji na Androida innych firm. Dostęp do niego mają tylko aplikacje zaufane przez system.

Ważne jest też rozróżnienie między koncepcją CHRE a centrum czujników. Chociaż często używa się tego samego sprzętu do implementacji koncentratora czujników i CHRE, CHRE samo w sobie nie zapewnia możliwości czujników wymaganych przez HAL czujników Androida. CHRE jest powiązany z HAL Centrum kontekstowego i działa jako klient platformy czujników specyficznych dla urządzenia, aby odbierać dane z czujników bez angażowania procesora aplikacji.

Architektura platformy CHRE

Rysunek 1. Architektura platformy CHRE

Context Hub HAL

Warstwa abstrakcji sprzętowej (HAL) Centrum kontekstowego to interfejs między platformą Android a implementacją CHRE na urządzeniu. Jest on zdefiniowany w hardware/interfaces/contexthub. Warstwa HAL Centrum kontekstowego definiuje interfejsy API, za pomocą których framework Androida wykrywa dostępne centra kontekstowe i ich nanoaplikacje, wchodzi z nimi w interakcje za pomocą przekazywania wiadomości oraz umożliwia wczytywanie i zwalnianie nanoaplikacji. Implementacja referencyjna HAL Context Hub, która działa z implementacją referencyjną CHRE, jest dostępna pod adresem system/chre/host.

W przypadku sprzeczności między tą dokumentacją a definicją HAL pierwszeństwo ma definicja HAL.

Inicjowanie

Gdy Android się uruchamia, usługa ContextHubService wywołuje funkcję HAL getHubs(), aby sprawdzić, czy na urządzeniu są dostępne jakiekolwiek koncentratory kontekstowe. Jest to blokujące wywołanie jednorazowe, więc musi się szybko zakończyć, aby nie opóźniać uruchamiania, i musi zwracać dokładny wynik, ponieważ później nie można wprowadzać nowych centrów kontekstowych.

Wczytywanie i zwalnianie nanoaplikacji

Centrum kontekstowe może zawierać zestaw nanoaplikacji, które są uwzględnione w obrazie urządzenia i ładowane po uruchomieniu CHRE. Są one nazywane wstępnie załadowanymi nanoaplikacjami i powinny być uwzględnione w pierwszej możliwej odpowiedzi na queryApps().

HAL Centrum kontekstowego obsługuje też dynamiczne wczytywanie i zwalnianie nanoaplikacji w czasie działania za pomocą funkcji loadNanoApp()unloadNanoApp(). Nanoaplikacje są dostarczane do HAL w formacie binarnym specyficznym dla sprzętu CHRE i implementacji oprogramowania urządzenia.

Jeśli implementacja wczytywania nanoaplikacji obejmuje zapisywanie jej w pamięci nietrwałej, np. w pamięci flash podłączonej do procesora, na którym działa CHRE, implementacja CHRE musi zawsze uruchamiać się z tymi dynamicznymi nanoaplikacjami w stanie wyłączonym. Oznacza to, że żaden kod nanoaplikacji nie jest wykonywany, dopóki przez HAL nie zostanie odebrane enableNanoapp()żądanie. Wstępnie wczytane nanoaplikacje mogą się inicjować w stanie włączonym.

Ponowne uruchomienia centrum kontekstowego

CHRE nie powinien się ponownie uruchamiać podczas normalnego działania, ale może to być konieczne w przypadku nieoczekiwanych sytuacji, takich jak próba uzyskania dostępu do niezmapowanego adresu pamięci. W takich sytuacjach CHRE uruchamia się ponownie niezależnie od Androida. HAL powiadamia o tym system Android za pomocą zdarzenia RESTARTED, które musi wysłać dopiero po ponownym zainicjowaniu CHRE do momentu, w którym może ono akceptować nowe żądania, takie jak queryApps().

Omówienie systemu CHRE

CHRE ma architekturę opartą na zdarzeniach, w której podstawową jednostką obliczeniową jest zdarzenie przekazywane do punktu wejścia obsługi zdarzeń w aplikacji nano. Platforma CHRE może być wielowątkowa, ale dana nanoaplikacja nigdy nie jest wykonywana równolegle w wielu wątkach. Platforma CHRE wchodzi w interakcję z daną nanoaplikacją za pomocą jednego z 3 punktów wejścia nanoaplikacji (nanoappStart(), nanoappHandleEvent()nanoappEnd()) lub za pomocą wywołania zwrotnego podanego w poprzednim wywołaniu interfejsu CHRE API. Nanoaplikacje wchodzą w interakcję z platformą CHRE i systemem bazowym za pomocą interfejsu CHRE API. Interfejs CHRE API udostępnia zestaw podstawowych funkcji oraz narzędzia do uzyskiwania dostępu do sygnałów kontekstowych, w tym czujników, GNSS, Wi-Fi, WWAN i dźwięku. Można go rozszerzyć o dodatkowe funkcje specyficzne dla dostawcy, które będą używane przez specyficzne dla dostawcy nanoaplikacje.

System kompilacji

Chociaż HAL Context Hub i inne niezbędne komponenty po stronie AP są tworzone razem z Androidem, kod działający w CHRE może mieć wymagania, które sprawiają, że jest on niezgodny z systemem kompilacji Androida, np. potrzebę specjalistycznego łańcucha narzędzi. Dlatego projekt CHRE w AOSP udostępnia uproszczony system kompilacji oparty na GNU Make, który umożliwia kompilowanie nanoaplikacji i opcjonalnie platformy CHRE do bibliotek, które można zintegrować z systemem. Producenci urządzeń dodający obsługę CHRE powinni zintegrować z AOSP obsługę systemu kompilacji dla swoich urządzeń docelowych.

Interfejs CHRE API jest napisany w standardzie języka C99, a implementacja referencyjna korzysta z ograniczonego podzbioru C++11 odpowiedniego dla aplikacji o ograniczonych zasobach.

CHRE API

CHRE API to zbiór plików nagłówkowych C, które definiują interfejs oprogramowania między nanoaplikacją a systemem. Został on zaprojektowany tak, aby kod nanoaplikacji był zgodny ze wszystkimi urządzeniami obsługującymi CHRE. Oznacza to, że kod źródłowy nanoaplikacji nie musi być modyfikowany w celu obsługi nowego typu urządzenia, chociaż może wymagać ponownej kompilacji specjalnie dla zestawu instrukcji procesora urządzenia docelowego lub interfejsu ABI. Architektura CHRE i projekt interfejsu API zapewniają też binarną zgodność aplikacji w różnych wersjach interfejsu CHRE API, co oznacza, że nie trzeba ponownie kompilować aplikacji, aby uruchomić ją w systemie, który implementuje inną wersję interfejsu CHRE API niż docelowy interfejs API, z którym jest skompilowana. Innymi słowy, jeśli binarna wersja nanoaplikacji działa na urządzeniu, które obsługuje interfejs CHRE API w wersji 1.3, a to urządzenie zostanie uaktualnione do obsługi interfejsu CHRE API w wersji 1.4, ta sama binarna wersja nanoaplikacji będzie nadal działać. Podobnie nanoaplikacja może działać w interfejsie CHRE API w wersji 1.2 i określać w czasie działania, czy do osiągnięcia zamierzonego celu potrzebuje funkcji z interfejsu API w wersji 1.3, czy też może działać z potencjalnym ograniczeniem funkcji.

Nowe wersje interfejsu CHRE API są udostępniane wraz z Androidem, ale ponieważ implementacja CHRE jest częścią implementacji dostawcy, wersja interfejsu CHRE API obsługiwana na urządzeniu nie musi być powiązana z wersją Androida.

Podsumowanie wersji

Podobnie jak schemat wersji HIDL Androida, interfejs CHRE API jest zgodny z wersjonowaniem semantycznym. Wersja główna wskazuje zgodność binarną, a wersja podrzędna jest zwiększana, gdy wprowadzane są funkcje zgodne wstecz. Interfejs CHRE API zawiera adnotacje w kodzie źródłowym, które wskazują, w której wersji wprowadzono funkcję lub parametr, np. @since v1.1.

Implementacja CHRE udostępnia też wersję poprawki specyficzną dla platformy za pomocą interfejsu chreGetVersion(), który wskazuje, kiedy w implementacji wprowadzono poprawki błędów lub drobne aktualizacje.

Podsumowania poszczególnych wersji znajdziesz w sekcji version.h.

Obowiązkowe funkcje systemowe

Źródła sygnałów kontekstowych, takie jak czujniki, są podzielone na opcjonalne obszary funkcji, ale kilka podstawowych funkcji jest wymaganych we wszystkich implementacjach CHRE. Obejmuje to podstawowe interfejsy API systemu, takie jak interfejsy do ustawiania timerów, wysyłania i odbierania wiadomości do klientów na procesorze aplikacji, rejestrowania zdarzeń i inne. Szczegółowe informacje znajdziesz w artykule Nagłówki interfejsu API.

Oprócz podstawowych funkcji systemowych skodyfikowanych w interfejsie CHRE API istnieją też obowiązkowe funkcje systemowe CHRE na poziomie HAL centrum kontekstowego. Najważniejszą z nich jest możliwość dynamicznego wczytywania i zwalniania nanoaplikacji.

Biblioteka standardowa C/C++

Aby zminimalizować wykorzystanie pamięci i złożoność systemu, implementacje CHRE muszą obsługiwać tylko podzbiór standardowych bibliotek C i C++ oraz funkcji językowych wymagających obsługi w czasie działania. Zgodnie z tymi zasadami niektóre funkcje są wyraźnie wykluczone ze względu na ich wymagania dotyczące pamięci i rozbudowane zależności na poziomie systemu operacyjnego, a inne dlatego, że zostały zastąpione bardziej odpowiednimi interfejsami API specyficznymi dla CHRE. Poniższa lista nie jest wyczerpująca, ale te funkcje nie są przeznaczone dla nanoaplikacji:

  • Wyjątki C++ i informacje o typie w czasie działania (RTTI)
  • Standardowa biblioteka obsługuje wielowątkowość, w tym nagłówki C++11. <thread>, <mutex>, <atomic>, <future>
  • Biblioteki standardowych wejść/wyjść w językach C i C++
  • Biblioteka szablonów standardowych C++ (STL)
  • Biblioteka wyrażeń regularnych w C++
  • dynamiczna alokacja pamięci za pomocą standardowych funkcji (np. malloc, calloc, realloc, free, operator new) i innych standardowych funkcji biblioteki, które z natury wykorzystują dynamiczną alokację pamięci, takich jak std::unique_ptr;
  • Obsługa lokalizacji i znaków Unicode
  • Biblioteki daty i godziny
  • Funkcje, które modyfikują normalny przepływ programu, w tym <setjmp.h>,<signal.h>, abort, std::terminate
  • Dostęp do środowiska hosta, w tym system, getenv
  • Biblioteki POSIX i inne biblioteki, które nie są uwzględnione w standardach języka C99 ani C++11

W wielu przypadkach równoważne funkcje są dostępne w funkcjach interfejsu CHRE API i bibliotekach narzędziowych. Na przykład chreLog może służyć do rejestrowania informacji debugowania przeznaczonych dla systemu logcat Androida, podczas gdy bardziej tradycyjny program może używać printf lub std::cout.

Z kolei niektóre funkcje biblioteki standardowej są wymagane. To implementacja platformy decyduje o tym, czy udostępniać je za pomocą bibliotek statycznych do włączenia do pliku binarnego nanoaplikacji, czy przez dynamiczne łączenie nanoaplikacji z systemem. Obejmuje to m.in.:

  • Narzędzia do obsługi ciągów znaków i tablic: memcmp, memcpy, memmove, memset,strlen
  • Biblioteka matematyczna: powszechnie używane funkcje zmiennoprzecinkowe pojedynczej precyzji:

    • Podstawowe operacje: ceilf, fabsf, floorf, fmaxf, fminf, fmodf, roundf, lroundf, remainderf
    • Funkcje wykładnicze i potęgowe: expf, log2f, powf, sqrtf
    • Funkcje trygonometryczne i hiperboliczne: sinf, cosf, tanf, asinf,acosf, atan2f, tanhf

Chociaż niektóre platformy bazowe obsługują dodatkowe funkcje, nanoaplikacja nie jest uznawana za przenośną w różnych implementacjach CHRE, chyba że ogranicza swoje zależności zewnętrzne do funkcji interfejsu CHRE API i zatwierdzonych funkcji biblioteki standardowej.

Funkcje opcjonalne

Aby promować sprzęt i oprogramowanie, interfejs CHRE API jest podzielony na obszary funkcji, które z perspektywy interfejsu API są opcjonalne. Chociaż te funkcje mogą nie być wymagane do obsługi zgodnej implementacji CHRE, mogą być niezbędne do obsługi konkretnej nanoaplikacji. Nawet jeśli platforma nie obsługuje danego zestawu interfejsów API, nanoaplikacje, które odwołują się do tych funkcji, muszą być w stanie się skompilować i wczytać.

Czujniki

Interfejs CHRE API umożliwia wysyłanie zapytań o dane z czujników, w tym akcelerometru, żyroskopu, magnetometru, czujnika jasności otoczenia i czujnika zbliżeniowego. Te interfejsy API mają zapewniać zestaw funkcji podobny do interfejsów API czujników Androida, w tym obsługę grupowania próbek z czujników w celu zmniejszenia zużycia energii. Przetwarzanie danych z czujników w CHRE umożliwia znacznie mniejsze zużycie energii i krótszy czas oczekiwania w przypadku przetwarzania sygnałów ruchu w porównaniu z przetwarzaniem na procesorze aplikacji.

GNSS

CHRE udostępnia interfejsy API do wysyłania żądań dotyczących danych o lokalizacji z globalnego systemu nawigacji satelitarnej (GNSS), w tym GPS i innych konstelacji satelitarnych. Obejmuje to żądania okresowych poprawek pozycji, a także surowe dane pomiarowe, choć obie te funkcje są niezależne. CHRE ma bezpośrednie połączenie z podsystemem GNSS, więc zużycie energii jest mniejsze niż w przypadku żądań GNSS opartych na AP, ponieważ AP może pozostawać w stanie uśpienia przez cały cykl życia sesji lokalizacji.

Wi-Fi

CHRE umożliwia interakcję z chipem Wi-Fi, głównie na potrzeby lokalizacji. GNSS dobrze sprawdza się w przypadku lokalizacji na zewnątrz, ale wyniki skanowania Wi-Fi mogą dostarczać dokładnych informacji o lokalizacji w pomieszczeniach i na obszarach zabudowanych. Oprócz uniknięcia kosztów wybudzania procesora aplikacji na potrzeby skanowania CHRE może nasłuchiwać wyników skanowania Wi-Fi wykonywanego przez oprogramowanie sprzętowe Wi-Fi na potrzeby łączności, które zwykle nie są dostarczane do procesora aplikacji ze względu na oszczędność energii. Wykorzystywanie skanowania połączeń do celów kontekstowych pomaga zmniejszyć łączną liczbę skanowań Wi-Fi, co pozwala oszczędzać energię.

Obsługa Wi-Fi została dodana w interfejsie CHRE API w wersji 1.1. Obejmuje ona możliwość monitorowania wyników skanowania i wywoływania skanowania na żądanie. W wersji 1.2 te możliwości zostały rozszerzone o pomiar czasu błądzenia (RTT) w przypadku punktów dostępu, które obsługują tę funkcję, co umożliwia dokładne określanie pozycji względnej.

WWAN

Interfejs CHRE API umożliwia pobieranie informacji o identyfikatorze komórki obsługującej i jej sąsiadów, które są zwykle używane do określania przybliżonej lokalizacji.

Audio

CHRE może przetwarzać partie danych audio z mikrofonu o niskim poborze mocy, który zwykle korzysta ze sprzętu używanego do implementacji warstwy HAL SoundTrigger. Przetwarzanie danych audio w CHRE może umożliwić ich łączenie z innymi danymi, np. z czujników ruchu.

Bluetooth

CHRE udostępnia interfejsy API obsługujące podzbiór funkcji Bluetooth, które korzystają z przenoszenia obliczeń na urządzenie o niskim poborze mocy. CHRE umożliwia nanoaplikacjom przeprowadzanie skanowania BLE, monitorowanie RSSI i przetwarzanie danych reklamowych BLE bez wybudzania procesora aplikacji. Dodatkowo własność ustalonego połączenia gniazda Bluetooth można przenieść do domeny odciążonej, co wymaga mniej energii na utrzymanie i umożliwia nanoaplikacjom komunikację za pomocą odciążonego połączenia gniazda BLE.

Implementacja referencyjna

Kod referencyjny platformy CHRE jest zawarty w AOSP w system/chreprojekcie i został zaimplementowany w C++11. Chociaż nie jest to bezwzględnie wymagane, zalecamy, aby wszystkie implementacje CHRE były oparte na tej bazie kodu, co pomoże zapewnić spójność i przyspieszyć wdrażanie nowych funkcji. Ten kod można traktować jako analogię do podstawowej platformy Androida, ponieważ jest to implementacja interfejsów API typu open source, z których korzystają aplikacje. Stanowi on podstawę i standard zgodności. Można go dostosowywać i rozszerzać o funkcje specyficzne dla dostawcy, ale zalecamy, aby wspólny kod był jak najbardziej zbliżony do kodu referencyjnego. Podobnie jak w przypadku warstw HAL w Androidzie, referencyjna implementacja CHRE korzysta z różnych abstrakcji platformy, aby można było ją dostosować do dowolnego urządzenia spełniającego minimalne wymagania.

Szczegóły techniczne i przewodnik przenoszenia znajdziesz w pliku README dołączonym do projektu system/chre.