Czujniki wielofunkcyjne HAL

Multi-HAL czujników to framework, który umożliwia uruchamianie HAL-i czujników wraz z innymi HAL-ami czujników. Interfejs wielopoziomowych czujników dynamicznie wczytuje podinterfejsy czujników przechowywane jako dynamiczne biblioteki w partycji dostawcy i przekazuje im obiekt wywołania, który może obsługiwać publikowanie zdarzeń oraz uzyskiwanie i zwalnianie blokady aktywacji. Podsystem HAL czujników to interfejs HAL czujników wbudowany w wspólny obiekt w partycji dostawcy, który jest używany przez interfejs wielopoziomowego interfejsu HAL. Te podrzędne konta HAL nie zależą od siebie lub od kodu HAL zawierającego funkcję główną na temat całego procesu.

Interfejs Sensors Multi-HAL 2.1, dostępny na urządzeniach z Androidem 11 lub nowszym, to wersja interfejsu Sensors Multi-HAL 2.0, która obsługuje wczytywanie podinterfejsów HAL, które mogą udostępniać typ czujnika kąt zawiasu. Aby obsługiwać ten typ czujnika, podrzędne interfejsy HAL muszą używać interfejsów API podrzędnych HAL. zdefiniowane w 2.1 Nagłówek SubHal.

W przypadku urządzeń z Androidem 13 lub nowszym, które korzystają z interfejsu sterownika HAL interfejsu AIDL dla czujników, możesz użyć warstwy shim dla wielu interfejsów HAL, aby umożliwić obsługę wielu interfejsów HAL. Szczegółowe informacje o wdrożeniu znajdziesz w artykule Korzystanie z Sensors Multi-HAL z Sensors AIDL HAL.

Różnica między czujnikami Multi-HAL 2 a czujnikami HAL 2

Czujniki Multi-HAL 2, dostępne na urządzeniach z Androidem 10 lub więcej, wprowadza kilka abstrakcji oprócz HAL Sensors, 2, aby ułatwić do interakcji z interfejsami HAL API. Interfejs Sensors Multi-HAL 2 wprowadza klasę HalProxy, która obsługuje implementację interfejsu Sensors HAL 2 oraz interfejs V2_1/SubHal (lub V2_0/SubHal), aby umożliwić HalProxy interakcję z podrzędnymi interfejsami HAL.

Interfejs ISensorsSubHal różni się od interfejsu 2.1/ISensors.hal (lub 2.0/ISensors.hal). w następujący sposób:

  • Metoda initialize przekazuje klasę IHalProxyCallback zamiast 2 elementów FMQ i ISensorsCallback.
  • Sub-HALs musi implementować funkcję debugowania, aby dostarczać informacje o debugowaniu w raportach o błędach.
  • Sub-HAL musi obsługiwać funkcję nazw, odróżniać się od innych subkont HAL.

Główna różnica między Czujnikami Multi-HAL 2 a Czujnikami HAL 2 polega na tym, zainicjuj funkcje. Zamiast wprowadzenia FMQ, IHalProxyCallback udostępnia 2 metody – jedną z nich do wysyłania zdarzeń z czujników do czujników. oraz jedną metodę tworzenia blokad uśpienia. W ramach tej usługi zarządza się wszystkimi interakcjami z interfejsami FMQ, aby zapewnić terminowe dostarczanie zdarzeń czujników do wszystkich podrzędnych interfejsów HAL. Zdecydowanie zalecamy, aby interfejsy HAL podrzędnych używały metody createScopedWakelock, aby przekazać obciążenie związane z wygaszaniem blokady na czas trwania blokady na rzecz interfejsu Sensors Multi-HAL i zcentralizować używanie blokady na rzecz całego interfejsu Sensors Multi-HAL, co zminimalizuje wywołania blokady i odblokowania.

Sensory Multi-HAL 2 mają też wbudowane funkcje bezpieczeństwa. Obsługuje on sytuacje, w których kolejka FMQ czujnika jest pełna lub w których framework czujnika Androida jest ponownie uruchamiany i konieczne jest zresetowanie stanu czujnika. Dodatkowo, gdy zdarzenia są publikowane w klasie HalProxy, ale framework czujnika nie może ich od razu zaakceptować, czujniki Multi-HAL mogą przenieść te zdarzenia do wątku w tle, aby umożliwić kontynuowanie pracy we wszystkich podrzędnych HAL-ach w czasie oczekiwania na opublikowanie zdarzeń.

Implementacja kodu źródłowego i referencyjnego

Kod HAL wszystkich czujników jest dostępny w hardware/interfaces/sensors/common/default/2.X/multihal/ Oto kilka wskazówek dotyczących przydatnych materiałów.

  • HalProxy.h: Wystąpienie obiektu HalProxy jest tworzone przez Sensors Multi-HAL i obsługuje przekazywanie danych z Sub-HAL do platformy czujnika.
  • HalProxy.cpp: Implementacja HalProxy zawiera wszystkie funkcje logiczne niezbędne do komunikacji Multiplex między podrzędnymi produktami HAL a platformą czujnika.
  • SubHal.h: Interfejs ISensorsSubHal definiuje interfejs, w którym podrzędne produkty HAL muszą , aby były zgodne z HalProxy. Sub-HAL implementuje metodę initialize, aby obiekt HalProxyCallback można było używać w przypadku postEventscreateScopedWakelock.

    W przypadku implementacji Multi-HAL 2.0 użyj wersji 2.0 pliku SubHal.h.

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/: te testy jednostkowe sprawdzają implementację HalProxy.

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/: Ta przykładowa implementacja sub-HAL wykorzystuje fałszywe czujniki, aby wygenerować fałszywe i skalowalnych danych. Ta opcja jest przydatna do sprawdzania, jak różne części podrzędne HAL współdziałają na urządzeniu.

Implementacja

W tej sekcji opisano, jak zaimplementować interfejs Multi-HAL czujników w tych sytuacjach:

Używanie wieloplatformowego interfejsu HAL dla czujników z interfejsem HAL AIDL dla czujników

Aby umożliwić obsługę wielu HAL za pomocą interfejsu HAL Sensors AIDL, zaimportuj AIDL Moduł warstwowej podkładki HAL, który znajduje się w sprzęt/interfejsy/czujniki/aidl/default/multihal/. Moduł obsługuje konwersję między czujnikami AIDL i HIDL i definiuje otokę wokół interfejsu HAL opisanego w Implementacja czujników Multi-HAL 2.1. Warstwę shimu wielopoziomowego AIDL można stosować na urządzeniach, które implementują interfejs Sensors Multi-HAL 2.1.

Warstwa podkładek AIDL multi-HAL pozwala odsłonić tracker na głowie Ograniczone typy czujników IMU w interfejsie Sensors AIDL HAL. Aby używać tych typów czujników zdefiniowanych przez interfejs AIDL HAL, ustaw pole type w strukturze SensorInfo w implementacji getSensorsList_2_1(). To jest bezpieczne ponieważ pola typu czujnika z wspieranym liczbą całkowitą w czujnikach AIDL i HIDL nie nakładają się na siebie.

Zastosuj czujniki Multi-HAL 2.1

Aby wdrożyć Sensors Multi-HAL 2.1 na nowym urządzeniu, wykonaj te czynności:

  1. Zaimplementuj interfejs ISensorsSubHal, tak jak to opisano w SubHal.h
  2. Zaimplementuj metodę sensorsHalGetSubHal_2_1SubHal.h.
  3. Dodaj cel cc_library_shared, aby utworzyć nowo wdrożony podsystem HAL. Podczas dodawania celu:

    1. Upewnij się, że docelowy element jest przesyłany do jakiegoś miejsca na partycji dostawcy na urządzeniu.
    2. W pliku konfiguracyjnym znajdującym się w lokalizacji /vendor/etc/sensors/hals.conf dodaj ścieżkę do biblioteki w nowym wierszu. W razie potrzeby utwórz hals.conf.

    Przykładowy wpis Android.bp dotyczący tworzenia biblioteki podrzędnej HAL znajdziesz tutaj hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp

  4. Usuń wszystkie wpisy android.hardware.sensors z pliku manifest.xml, który zawiera listę obsługiwanych interfejsów HAL na urządzeniu.

  5. Usuń wszystkie pliki usługi android.hardware.sensors i pliki service.rc z pliku device.mk, a potem dodaj pliki android.hardware.sensors@2.1-service.multihalandroid.hardware.sensors@2.1-service.multihal.rc do pliku PRODUCT_PACKAGES.

Podczas uruchamiania HalProxy szuka nowo zaimplementowanego podsystemu HAL i inicjuje go, wywołując sensorsHalGetSubHal_2_1.

Przenoszenie z Sensors Multi-HAL 2.0 do Multi-HAL 2.1

Aby zmienić protokół Multi-HAL 2.0 na Multi-HAL 2.1, zaimplementuj klucz SubHal i ponownie skompilować sub-HAL.

Różnice między interfejsami SubHal w wersjach 2.0 i 2.1:

  • Funkcja IHalProxyCallback używa typów utworzonych w wersji 2.1 specyfikacji ISensors.hal.
  • Funkcja initialize() przekazuje nowy IHalProxyCallback zamiast interfejsu 2.0 SubHal.
  • Podsystemy HAL muszą implementować metody getSensorsList_2_1injectSensorData_2_1 zamiast getSensorsListinjectSensorData, ponieważ te metody używają nowych typów dodanych w wersji 2.1 specyfikacji ISensors.hal.
  • Aby Multi-HAL traktował je jako podzbiory HAL w wersji 2.1, podzbiory muszą udostępniać sensorsHalGetSubHal_2_1, a nie sensorsHalGetSubHal.

Port z Czujnika HAL 2.0

Uaktualnienie do systemu Sensors Multi-HAL 2.0 z modelu Sensors HAL 2.0, sprawdź, czy HAL spełnia poniższe wymagania.

Inicjowanie HAL

HAL 2.0 ma funkcję inicjowania, która umożliwia usłudze czujnika przekazywać sygnały FMQ i dynamiczne wywołanie zwrotne czujnika. W interfejsie Sensors Multi-HAL 2.0 Funkcja initialize() przekazuje jedno wywołanie zwrotne, które musi zostać użyte do opublikowania zdarzeń z czujników, uzyskiwanie blokad uśpienia oraz powiadamianie o dynamicznym połączeniu z czujnikiem oraz odłączania kont.

Przesyłanie zdarzeń czujnika do implementacji Multi-HAL

Zamiast publikować zdarzenia z czujników przez FMQ, interfejs podrzędny HAL musi zapisywać dane czujnika wydarzeń na IHalProxyCallback gdy dostępne są zdarzenia z czujnika.

Zdarzenia WAKE_UP

W przypadku interfejsu Sensors HAL 2.0 HAL może zarządzać blokadą uśpienia w ramach implementacji. W Czujniki Multi-HAL 2.0, podrzędne karty HAL umożliwiają implementację Multi-HAL zarządzać blokadami uśpienia i może zażądać uzyskania blokady uśpienia przez wywołanie createScopedWakelock Blokada uśpienia o zakresie zablokowanym musi zostać uzyskana i przekazana do postEvents, gdy publikowanie zdarzeń wybudzenia w implementacji Multi-HAL.

Czujniki dynamiczne

Interfejs Sensors Multi-HAL 2.0 wymaga, aby funkcje onDynamicSensorsConnectedonDynamicSensorsDisconnectedIHalProxyCallback były wywoływane za każdym razem, gdy zmieniają się dynamiczne połączenia czujników. Te wywołania zwrotne są dostępne w ramach wskaźnika IHalProxyCallback dostarczanego przez funkcji initialize().

Port z Sensors HAL 1.0

Podczas przejścia z wersji Sensors HAL 1.0 na wersję 2.0 interfejsu HAL dla czujników upewnij się, że implementacja HAL spełnia te wymagania.

Inicjowanie HAL

W celu ustanowienia wywołania zwrotnego między funkcją initialize() musi być obsługiwana zarówno w przypadku treści podrzędnych, jak i multi-HAL.

Udostępnianie dostępnych czujników

W przypadku Sensors Multi-HAL 2.0 funkcja getSensorsList() musi zwracać tę samą wartość podczas jednego rozruchu urządzenia, nawet wtedy, gdy HAL uruchamia się ponownie. Dzięki temu platformy do podejmowania prób ponownego nawiązania połączeń z czujnikiem, jeśli serwer systemu uruchomi się ponownie. Wartość zwracana przez getSensorsList() może się zmienić po ponownym uruchomieniu urządzenia.

Publikuj zdarzenia z czujników w implementacji Multi-HAL

W usłudze Sensors HAL 2.0 zamiast czekać na wywołanie funkcji poll(), można użyć jej musi aktywnie zapisywać zdarzenia czujnika w IHalProxyCallback .

Zdarzenia WAKE_UP

W interfejsie HAL czujników 1.0 interfejs HAL może zarządzać blokadą aktywacji w ramach swojej implementacji. W Interfejsy Sensors Multi-HAL 2.0, podrzędne listy HAL umożliwiają implementację Multi-HAL zarządzać blokadami uśpienia i może zażądać uzyskania blokady uśpienia przez wywołanie createScopedWakelock Blokada uśpienia o zakresie zablokowanym musi zostać uzyskana i przekazana do postEvents, gdy publikowanie zdarzeń wybudzenia w implementacji Multi-HAL.

Czujniki dynamiczne

W komponencie HAL czujników w wersji 1.0 czujniki dynamiczne są zwracane za pomocą funkcji poll(). Czujniki Multi-HAL 2.0 wymagają tych elementów: onDynamicSensorsConnected i onDynamicSensorsDisconnected in IHalProxyCallback są wywoływane zawsze, gdy zmienią się dynamiczne połączenia czujnika. Te funkcje wywołania zwrotnego są dostępne w ramach wskaźnika IHalProxyCallback, który jest udostępniany przez funkcję initialize().

Port z Czujnika Multi-HAL 1.0

Aby przenieść istniejące rozwiązanie z Sensors Multi-HAL 1.0, wykonaj te czynności.

  1. Sprawdź, czy konfiguracja HAL czujników znajduje się w /vendor/etc/sensors/hals.conf Może to wymagać przeniesienia pliku o /system/etc/sensors/hals.conf.
  2. Usuń wszystkie odwołania do hardware/hardware.h i hardware/sensors.h, ponieważ nie są one obsługiwane w HAL 2.0.
  3. Przenoś podsystemy HAL zgodnie z opisem w artykule Przenoszenie z Sensors HAL 1.0.
  4. Ustaw Sensors Multi-HAL 2.0 jako wyznaczoną HAL, wykonując kroki 3 i 4 w sekcji Implementowanie czujników Mutli-HAL 2.0.

Weryfikacja

Uruchamianie VTS

Po zintegrowaniu co najmniej 1 interfejsu HAL podrzędnego z interfejsem Sensors Multi-HAL 2.1 użyj pakietu testów dostawcy (VTS), aby sprawdzić, czy implementacje interfejsu HAL podrzędnego spełniają wszystkie wymagania określone przez interfejs HAL Sensors.

Aby uruchomić tylko testy VTS czujników po skonfigurowaniu VTS na hoście, wykonaj te polecenia:

vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsHalSensorsV2_0Target && \
  vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsHalSensorsV2_1Target

Jeśli używasz warstwy podkładowej AIDL Multi-HAL, uruchom VtsAidlHalSensorsTargetTest.

vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsAidlHalSensorsTargetTest

Przeprowadzanie testów jednostkowych

Testy jednostkowe w HalProxy_test.cpp test HalProxy korzystają z fałszywych podsystemów HAL, które są tworzone w teście jednostkowym i nie są ładowane dynamicznie. Podczas tworzenia nowego podsystemu HAL te testy powinny służyć jako wskazówka, jak dodawać testy jednostkowe, które weryfikują, czy nowy podsystem HAL jest prawidłowo zaimplementowany.

Aby uruchomić testy, wykonaj te polecenia:

cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest

Testowanie z wykorzystaniem fałszywych sub-HAL

Fałszywe sub-HAL to fikcyjne implementacje interfejsu ISensorsSubHal. Podsystemy HAL udostępniają różne listy czujników. Gdy czujniki są aktywne, okresowo publikują automatycznie wygenerowane zdarzenia dotyczące czujnika w usłudze HalProxy na podstawie odstępów określonych w danym żądaniu czujnika.

Fałszywe sub-HAL można wykorzystać do przetestowania działania pełnego kodu Multi-HAL części składowych HAL wczytywanych do systemu i podkreślania różnych aspektów Kod HAL czujnika.

2 fałszywe sub-HAL są dostępne na hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/

Aby utworzyć i przekazać fałszywe podsystemy HAL na urządzenie, wykonaj te czynności:

  1. Uruchom następujące polecenia, aby utworzyć i przekazać 3 różne fałszywe na urządzeniu:

    $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests/
    mma
    adb push \
      $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so \
      /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so
    adb push \
      $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so \
      /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so
    adb push \
      $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so \
      /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
    
  2. Zaktualizuj konfigurację HAL czujników w pliku /vendor/etc/sensors/hals.conf, podając ścieżki do fałszywych pod-HAL-i.

    /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so
    /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so
    /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
    
  3. Uruchom ponownie HalProxy i załaduj nowe podsystemy HAL wymienione w konfiguracji.

    adb shell stop
    adb shell start
    

Debugowanie

Deweloperzy mogą debugować platformę za pomocą polecenia lshal. Aby uzyskać dane debugowania interfejsu HAL czujników, uruchom to polecenie:

adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default

Informacje o bieżącym stanie klienta HalProxy i jego podrzędnych kont HAL będą dane wyjściowe do terminala. Poniżej przedstawiono przykładowe dane wyjściowe poleceń dla polecenia HalProxy obiekt i fałszywe sub-HAL.

Internal values:
  Threads are running: true
  Wakelock timeout start time: 200 ms ago
  Wakelock timeout reset time: 73208 ms ago
  Wakelock ref count: 0
  # of events on pending write queue: 0
  # of non-dynamic sensors across all subhals: 8
  # of dynamic sensors across all subhals: 0
SubHals (2):
  Name: FakeSubHal-OnChange
  Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2
  Name: FakeSubHal-OnChange
  Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2

Jeśli wartość podana w polu # of events on pending write queue to duża liczba (1000 lub więcej), oznacza to, że istnieje wiele zdarzeń oczekujących na zapisanie w czujnikach. platformy. Wskazuje to, że usługa czujnika jest zablokowana lub uległa awarii i nie przetwarza zdarzeń czujnika albo że z poziomu podrzędnego HAL niedawno opublikowano dużą partię zdarzeń czujnika.

Jeśli liczba referencji blokady uśpienia jest większa niż 0, oznacza to, że HalProxy ma następuje blokada uśpienia. Wartość ta powinna być większa od 0 tylko wtedy, gdy ScopedWakelock jest celowo wstrzymywany lub gdy zdarzenia aktywacji zostały wysłane do HalProxy i nie zostały przetworzone przez interfejs sensora.

Deskryptor pliku przekazany metodzie debugowania w HalProxy jest przekazywany do każdego podinterfejsu HAL, więc deweloperzy muszą zaimplementować metodę debugowania w ramach interfejsu ISensorsSubHal.