Czujniki HAL 1.0

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

Interfejs Sensors HAL, zadeklarowany w sensorach.h , reprezentuje interfejs między platformą Android a oprogramowaniem specyficznym dla sprzętu. Implementacja HAL musi definiować każdą funkcję zadeklarowaną w sensorach.h. Główne funkcje to:

  • get_sensors_list - Zwraca listę wszystkich czujników.
  • activate - Uruchamia lub zatrzymuje czujnik.
  • batch — Ustawia parametry czujnika, takie jak częstotliwość próbkowania i maksymalne opóźnienie raportowania.
  • setDelay — używany tylko w wersji HAL 1.0. Ustawia częstotliwość próbkowania dla danego czujnika.
  • flush — opróżnia FIFO określonego czujnika i zgłasza zdarzenie zakończenia płukania po wykonaniu tej czynności.
  • poll - Zwraca dostępne zdarzenia czujnika.

Implementacja musi być bezpieczna dla wątków i umożliwiać wywoływanie tych funkcji z różnych wątków.

Interfejs definiuje również kilka typów używanych przez te funkcje. Główne typy to:

  • sensors_module_t
  • sensors_poll_device_t
  • sensor_t
  • sensors_event_t

Oprócz sekcji poniżej, patrz sensors.h , aby uzyskać więcej informacji na temat tych typów.

get_sensors_list(lista)

int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t
  const** list);

Udostępnia listę czujników zaimplementowanych przez HAL. Zobacz sensor_t, aby uzyskać szczegółowe informacje na temat definiowania czujników.

Kolejność, w jakiej czujniki pojawiają się na liście, to kolejność, w jakiej czujniki będą raportowane do aplikacji. Zwykle jako pierwsze pojawiają się czujniki podstawowe, a następnie czujniki kompozytowe.

Jeśli kilka czujników współdzieli ten sam typ czujnika i właściwość budzenia, pierwszy na liście jest nazywany czujnikiem „domyślnym”. Jest to ten zwrócony przez getDefaultSensor(int sensorType, bool wakeUp) .

Ta funkcja zwraca liczbę czujników na liście.

aktywuj(czujnik, prawda/fałsz)

int (*activate)(struct sensors_poll_device_t *dev, int sensor_handle, int
  enabled);

Aktywuje lub dezaktywuje czujnik.

sensor_handle to uchwyt czujnika do aktywacji/dezaktywacji. Uchwyt czujnika jest zdefiniowany przez pole handle jego struktury sensor_t .

enabled jest ustawiony na 1, aby włączyć lub 0, aby wyłączyć czujnik.

Czujniki one-shot dezaktywują się automatycznie po otrzymaniu zdarzenia i nadal muszą zaakceptować dezaktywację poprzez wezwanie do activate(..., enabled=0) .

Czujniki niewybudzone nigdy nie zapobiegają przejściu SoC w tryb wstrzymania; oznacza to, że warstwa HAL nie może blokować częściowego wybudzenia w imieniu aplikacji.

Czujniki wybudzania, gdy dostarczają zdarzenia w sposób ciągły, mogą uniemożliwić SoC przejście w tryb wstrzymania, ale jeśli żadne zdarzenie nie musi być dostarczane, częściowa blokada wybudzenia musi zostać zwolniona.

Jeśli enabled jest 1, a czujnik jest już aktywowany, ta funkcja jest nieaktywna i się powiedzie.

Jeśli enabled ma wartość 0, a czujnik jest już dezaktywowany, ta funkcja nie działa i się powiedzie.

Ta funkcja zwraca 0 w przypadku powodzenia, aw przeciwnym razie ujemną liczbę błędów.

partia (czujnik, flagi, okres próbkowania, maksymalne opóźnienie raportu)

int (*batch)(
     struct sensors_poll_device_1* dev,
     int sensor_handle,
     int flags,
     int64_t sampling_period_ns,
     int64_t max_report_latency_ns);

Ustawia parametry czujnika, w tym częstotliwość próbkowania i maksymalne opóźnienie raportu . Ta funkcja może być wywołana, gdy czujnik jest aktywny, w którym to przypadku nie może spowodować utraty jakichkolwiek pomiarów czujnika: Przejście z jednej częstotliwości próbkowania na drugą nie może spowodować utraty zdarzeń, ani przejście z wysokiego maksymalnego opóźnienia raportu do niskiego maksymalne opóźnienie raportu.

sensor_handle to uchwyt czujnika do skonfigurowania.

flags nie są obecnie używane.

sampling_period_ns to okres próbkowania, w którym czujnik powinien działać, w nanosekundach. Zobacz sampling_period_ns , aby uzyskać więcej informacji.

max_report_latency_ns to maksymalny czas, o który zdarzenia mogą być opóźnione przed zgłoszeniem przez warstwę HAL, w nanosekundach. Zobacz paragraf max_report_latency_ns , aby uzyskać więcej informacji.

Ta funkcja zwraca 0 w przypadku powodzenia, aw przeciwnym razie ujemną liczbę błędów.

setDelay(czujnik, okres próbkowania)

int (*setDelay)(
     struct sensors_poll_device_t *dev,
     int sensor_handle,
     int64_t sampling_period_ns);

Po wersji HAL 1.0 ta funkcja jest przestarzała i nigdy nie jest wywoływana. Zamiast tego wywoływana jest funkcja batch w celu ustawienia parametru sampling_period_ns .

W HAL w wersji 1.0, setDelay został użyty zamiast wsadu do ustawienia sampling_period_ns .

spłukiwanie (czujnik)

int (*flush)(struct sensors_poll_device_1* dev, int sensor_handle);

Dodaj zdarzenie zakończenia płukania na końcu sprzętowej FIFO dla określonego czujnika i opróżnij FIFO; te zdarzenia są dostarczane jak zwykle (tzn. tak, jakby wygasł maksymalny czas oczekiwania na raportowanie) i usuwane z FIFO.

Opróżnianie odbywa się asynchronicznie (tzn. ta funkcja musi natychmiast powrócić). Jeśli implementacja używa pojedynczego FIFO dla kilku czujników, to FIFO jest opróżniane, a zdarzenie opróżniania zakończone jest dodawane tylko dla określonego czujnika.

Jeśli określony czujnik nie ma FIFO (brak możliwości buforowania) lub jeśli FIFO była pusta w czasie wywołania, flush nadal musi się powieść i wysłać zdarzenie zakończenia opróżniania dla tego czujnika. Dotyczy to wszystkich czujników innych niż czujniki jednorazowe.

Gdy wywoływane jest flush , nawet jeśli zdarzenie opróżniania jest już w FIFO dla tego czujnika, należy utworzyć dodatkowe i dodać na końcu FIFO, a FIFO musi zostać opróżnione. Liczba wywołań flush musi być równa liczbie utworzonych zdarzeń zakończenia płukania.

flush nie dotyczy czujników jednorazowych ; jeśli sensor_handle odnosi się do czujnika jednorazowego, flush musi zwrócić -EINVAL i nie generować żadnego zdarzenia pełnych metadanych spłukiwania.

Ta funkcja zwraca 0 w przypadku powodzenia, -EINVAL , jeśli określony czujnik jest czujnikiem jednorazowym lub nie był włączony, aw przeciwnym razie ujemną liczbę błędów.

głosowanie()

int (*poll)(struct sensors_poll_device_t *dev, sensors_event_t* data, int
  count);

Zwraca tablicę danych czujnika, wypełniając argument data . Ta funkcja musi być blokowana, dopóki zdarzenia nie będą dostępne. Zwróci liczbę zdarzeń odczytanych w przypadku powodzenia lub ujemną liczbę błędów w przypadku błędu.

Liczba zdarzeń zwracanych w data musi być mniejsza lub równa argumentowi count . Ta funkcja nigdy nie zwraca 0 (brak zdarzenia).

Sekwencja połączeń

Po uruchomieniu urządzenia wywoływana jest get_sensors_list .

Gdy czujnik zostanie aktywowany, funkcja batch zostanie wywołana z żądanymi parametrami, a następnie activate(..., enable=1) .

Zwróć uwagę, że w wersji HAL 1_0 kolejność była odwrotna: najpierw wywołano activate , a następnie set_delay .

Gdy żądana charakterystyka czujnika zmienia się podczas jego aktywacji, wywoływana jest funkcja batch .

flush można wywołać w dowolnym momencie, nawet na nieaktywowanych czujnikach (w takim przypadku musi zwrócić -EINVAL )

Gdy czujnik zostanie dezaktywowany, zostanie wywołane activate(..., enable=0) .

Równolegle do tych wywołań funkcja poll będzie wywoływana wielokrotnie, aby zażądać danych. poll może zostać wywołana nawet wtedy, gdy żadne czujniki nie są aktywne.

sensor_moduł_t

sensors_module_t to typ używany do tworzenia modułu sprzętowego Androida dla czujników. Implementacja warstwy HAL musi zdefiniować obiekt HAL_MODULE_INFO_SYM tego typu, aby udostępnić funkcję get_sensors_list . Zobacz definicję sensors_module_t w hw_module_t , aby uzyskać więcej informacji.

sensory_poll_device_t / sensors_poll_device_1_t

sensors_poll_device_1_t zawiera pozostałe metody zdefiniowane powyżej: activate , batch , flush i poll . Jego common pole (typu hw_device_t ) definiuje numer wersji warstwy HAL.

czujnik_t

sensor_t reprezentuje czujnik Androida . Oto niektóre z jego ważnych dziedzin:

nazwa: widoczny dla użytkownika ciąg znaków reprezentujący czujnik. Ten ciąg często zawiera nazwę części podstawowego czujnika, typ czujnika oraz informację, czy jest to czujnik budzenia. Na przykład „akcelerometr LIS2HH12”, „nieskalibrowany żyroskop MAX21000”, „barometr budzenia BMP280”, „wektor obrotu gry MPU6515”

uchwyt: Liczba całkowita używana do odwoływania się do czujnika podczas rejestrowania do niego lub generowania z niego zdarzeń.

type: typ czujnika. Zobacz wyjaśnienie typu czujnika w Czym są czujniki Androida? Aby uzyskać więcej informacji, zobacz Typy czujników dla oficjalnych typów czujników. W przypadku nieoficjalnych typów czujników type musi zaczynać się od SENSOR_TYPE_DEVICE_PRIVATE_BASE

stringType: Typ czujnika w postaci ciągu. Gdy czujnik ma oficjalny typ, ustaw SENSOR_STRING_TYPE_* . Gdy czujnik ma typ specyficzny dla producenta, stringType musi zaczynać się od nazwy domeny odwrotnej producenta. Na przykład czujnik (powiedzmy detektor jednorożca) zdefiniowany przez zespół Cool-product w Fictional-Company może używać stringType=”com.fictional_company.cool_product.unicorn_detector” . stringType służy do jednoznacznej identyfikacji nieoficjalnych typów czujników. Więcej informacji na temat typów i typów łańcuchów można znaleźć w pliku sensors.h .

requiredPermission: ciąg znaków reprezentujący uprawnienia, które muszą posiadać aplikacje, aby zobaczyć czujnik, zarejestrować się w nim i otrzymywać jego dane. Pusty ciąg oznacza, że ​​aplikacje nie wymagają żadnego pozwolenia na dostęp do tego czujnika. Niektóre typy czujników, takie jak czujnik tętna , wymagają obowiązkowego requiredPermission . Wszystkie czujniki dostarczające poufnych informacji użytkownika (takich jak tętno) muszą być chronione zezwoleniem.

flags: flagi dla tego czujnika, określające tryb raportowania czujnika oraz czy czujnik jest czujnikiem wybudzania, czy nie. Na przykład jednorazowy czujnik budzenia będzie miał flags = SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP . Bity flagi, które nie są używane w bieżącej wersji warstwy HAL, muszą pozostać równe 0.

maxRange: maksymalna wartość, jaką czujnik może zgłosić, w tej samej jednostce, co wartości raportowane. Czujnik musi mieć możliwość zgłaszania wartości bez nasycenia w [-maxRange; maxRange] . Zauważ, że oznacza to, że całkowity zasięg czujnika w sensie ogólnym wynosi 2*maxRange . Gdy czujnik zgłasza wartości w kilku osiach, zakres dotyczy każdej osi. Na przykład akcelerometr „+/- 2g” wyśle ​​raport maxRange = 2*9.81 = 2g .

rozdzielczość: najmniejsza różnica wartości, jaką czujnik może zmierzyć. Zwykle obliczana na podstawie maxRange i liczby bitów w pomiarze.

power: Koszt energii włączenia czujnika w miliamperach. Prawie zawsze jest to więcej niż zużycie energii podane w arkuszu danych odpowiedniego czujnika. Zobacz Czujniki podstawowe != czujniki fizyczne , aby uzyskać więcej informacji i zobacz Proces pomiaru mocy, aby uzyskać szczegółowe informacje na temat pomiaru zużycia energii przez czujnik. Jeśli pobór mocy czujnika zależy od tego, czy urządzenie się porusza, pobór mocy podczas ruchu jest taki sam jak w polu power .

minDelay: W przypadku czujników ciągłych okres próbkowania w mikrosekundach, odpowiadający najszybszej obsługiwanej przez czujnik szybkości. Zobacz sampling_period_ns , aby uzyskać szczegółowe informacje na temat używania tej wartości. Pamiętaj, że minDelay jest wyrażane w mikrosekundach, podczas gdy sampling_period_ns jest w nanosekundach. O ile nie określono inaczej, dla czujników przy zmianie i w trybie raportowania specjalnego, minDelay musi wynosić 0. W przypadku czujników jednorazowych musi wynosić -1.

maxDelay: dla czujników ciągłych i na zmianę, okres próbkowania w mikrosekundach, odpowiadający najwolniejszej częstotliwości obsługiwanej przez czujnik. Zobacz sampling_period_ns , aby uzyskać szczegółowe informacje na temat używania tej wartości. Pamiętaj, że maxDelay jest wyrażane w mikrosekundach, podczas gdy sampling_period_ns jest w nanosekundach. W przypadku czujników specjalnych i jednorazowych maxDelay musi wynosić 0.

fifoReservedEventCount: liczba zdarzeń zarezerwowanych dla tego czujnika w sprzętowym FIFO. Jeśli istnieje dedykowana FIFO dla tego czujnika, wtedy fifoReservedEventCount jest wielkością tego dedykowanego FIFO. Jeśli FIFO jest współdzielona z innymi czujnikami, fifoReservedEventCount jest rozmiarem części FIFO, która jest zarezerwowana dla tego czujnika. W większości systemów współużytkowanych FIFO oraz w systemach, które nie mają sprzętowego FIFO, ta wartość wynosi 0.

fifoMaxEventCount: maksymalna liczba zdarzeń, które mogą być przechowywane w FIFO dla tego czujnika. Jest to zawsze większe lub równe fifoReservedEventCount . Wartość ta jest używana do oszacowania, jak szybko FIFO zapełni się podczas rejestracji do czujnika z określoną szybkością, zakładając, że żadne inne czujniki nie są aktywowane. W systemach, które nie mają sprzętowego FIFO, fifoMaxEventCount ma wartość 0. Zobacz Batching , aby uzyskać więcej informacji.

W przypadku czujników z oficjalnym typem czujnika niektóre pola są nadpisywane przez framework. Na przykład czujniki akcelerometru muszą mieć tryb ciągłego raportowania, a czujniki tętna muszą być chronione przez uprawnienie SENSOR_PERMISSION_BODY_SENSORS .

sensory_event_t

Zdarzenia czujnika generowane przez czujniki systemu Android i zgłaszane przez funkcję odpytywaniatype sensors_event_t . Oto kilka ważnych pól sensors_event_t :

wersja: musi być sizeof(struct sensors_event_t)

sensor: uchwyt czujnika, który wygenerował zdarzenie, zdefiniowany przez sensor_t.handle .

type: typ czujnika, który wygenerował zdarzenie, zdefiniowany przez sensor_t.type .

znacznik czasu: znacznik czasu zdarzenia w nanosekundach. Jest to czas, w którym wydarzyło się zdarzenie (wykonano krok lub dokonano pomiaru akcelerometrem), a nie czas zgłoszenia zdarzenia. timestamp musi być zsynchronizowany z zegarem elapsedRealtimeNano , a w przypadku czujników ciągłych jitter musi być niewielki. Filtrowanie znaczników czasowych jest czasami konieczne, aby spełnić wymagania CDD, ponieważ użycie tylko czasu przerwania SoC do ustawienia znaczników czasowych powoduje zbyt duże jitter, a użycie tylko czasu chipu czujnika do ustawienia znaczników czasowych może spowodować desynchronizację z zegara elapsedRealtimeNano , ponieważ zegar czujnika dryfuje.

dane i nakładające się pola: wartości zmierzone przez czujnik. Znaczenie i jednostki tych pól są specyficzne dla każdego typu czujnika. Aby zapoznać się z opisem pól danych, zapoznaj się z plikami sensory.h i definicjami różnych typów czujników . W przypadku niektórych czujników dokładność odczytów jest również raportowana jako część danych za pośrednictwem pola status . To pole jest przesyłane potokiem tylko w przypadku wybranych typów czujników i pojawia się w warstwie SDK jako wartość dokładności. W przypadku tych czujników fakt, że pole stanu musi być ustawione, jest podany w ich definicji typu czujnika .

Metadane opróżniają kompletne zdarzenia

Zdarzenia metadanych mają ten sam typ, co zwykłe zdarzenia czujnika: sensors_event_meta_data_t = sensors_event_t . Są one zwracane wraz z innymi zdarzeniami czujnika poprzez ankietę. Posiadają następujące pola:

wersja: musi być META_DATA_VERSION

typ: musi być SENSOR_TYPE_META_DATA

czujnik, zarezerwowany i znacznik czasu : Musi wynosić 0

meta_data.what: zawiera typ metadanych dla tego zdarzenia. Obecnie istnieje jeden prawidłowy typ metadanych: META_DATA_FLUSH_COMPLETE .

Zdarzenia META_DATA_FLUSH_COMPLETE reprezentują zakończenie opróżniania czujnika FIFO. Gdy meta_data.what=META_DATA_FLUSH_COMPLETE , meta_data.sensor musi być ustawiony na uchwyt czujnika, który został opróżniony. Są one generowane tylko wtedy, gdy na czujniku zostanie wywołane flush . Więcej informacji można znaleźć w rozdziale dotyczącym funkcji spłukiwania .