Interfejs Sensors HAL, zadeklarowany w pliku sensors.h, stanowi interfejs między frameworkem Androida a oprogramowaniem przeznaczonym do konkretnego sprzętu. Implementacja HAL musi definiować każdą funkcję zadeklarowane w sensors.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 1.0 interfejsu HAL. Ustawia częstotliwość próbkowania dla danego czujnika.flush
– opróżnia kolejkę FIFO określonego czujnika i zgłasza zdarzenie flush complete, gdy to zrobi.poll
– zwraca dostępne zdarzenia czujnika.
Implementacja musi być bezpieczna w zasobie wątków i umożliwiać wywoływanie tych funkcji z różnych wątków.
Interfejs definiuje też kilka typów używanych przez te funkcje. Główny typy:
sensors_module_t
sensors_poll_device_t
sensor_t
sensors_event_t
Więcej informacji o tych typach znajdziesz w pliku sensors.h, a nie tylko w sekcjach poniżej.
get_sensors_list(list)
int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t const** list);
Udostępnia listę czujników wdrożonych przez HAL. Szczegółowe informacje o definiowaniu czujników znajdziesz w sekcji sensor_t.
Kolejność, w jakiej czujniki są widoczne na liście, to kolejność, w jakiej będą one raportowane aplikacjom. Zwykle najpierw pojawiają się czujniki podstawowe, a potem złożone.
Jeśli kilka czujników ma ten sam typ i właściwości wybudzania, pierwszy
czujnik na liście jest nazywany „domyślnym”. Jest to wartość zwrócona 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 służący do aktywacji lub dezaktywacji. Czujnik
uchwyt jest zdefiniowany przez pole handle
jego struktury sensor_t.
Wartość enabled
1 włącza czujnik, a 0 – wyłącza.
Czujniki jednego uderzenia dezaktywują się automatycznie po otrzymaniu informacji o zdarzeniu.
i muszą je zaakceptować, aby można było dezaktywować, używając wywołania activate(...,
enabled=0)
.
Czujniki niewybudzające nigdy nie uniemożliwiają SoC przejścia w tryb zawieszenia. Oznacza to, że interfejs HAL nie może blokować częściowego wybudzania w imieniu aplikacji.
Ciągłe wysyłanie zdarzeń przez czujniki aktywujące może uniemożliwić SoC przejście w tryb zawieszenia, ale jeśli nie trzeba wysyłać żadnych zdarzeń, należy zwolnić blokadę częściowego budzenia.
Jeśli enabled
= 1, a czujnik jest już aktywny, ta funkcja nie wykonuje żadnej operacji i kończy się sukcesem.
Jeśli enabled
= 0 i czujnik jest już dezaktywowany, ta funkcja nie wykonuje żadnej operacji i kończy się sukcesem.
Ta funkcja zwraca 0 w przypadku powodzenia, a w przeciwnym razie zwraca ujemną liczbę błędów.
wsad(czujnik, flagi, okres próbkowania, maksymalny czas oczekiwania na raport)
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 oraz Raport o maksymalnej liczbie wyświetleń Funkcję tę można wywołać podczas aktywacji czujnika. W tym przypadku nie może ona spowodować utraty pomiarów czujnika. Przejście z jednego współczynnika próbkowania na inny nie może spowodować utraty zdarzeń. Nie może też nastąpić przejście z wysokiej maksymalnej latencji raportu na niską maksymalną latencję raportu.
sensor_handle
to uchwyt czujnika do skonfigurowania.
Konto flags
nie jest obecnie używane.
sampling_period_ns
to okres próbkowania, w którym powinien działać czujnik (w nanosekundach). Zobacz sampling_period_ns dla
.
max_report_latency_ns
to maksymalny czas, do którego mogą być rejestrowane zdarzenia
jest opóźniony przed zgłoszeniem przez HAL, w nanosekundach. Zobacz max_report_latency_ns
.
Ta funkcja zwraca 0 w przypadku powodzenia, a w przeciwnym razie zwraca 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 została wycofana i nigdy nie jest wywoływana.
Zamiast tego funkcja batch
jest wywoływana w celu ustawienia atrybutu
sampling_period_ns
.
W wersji HAL 1.0 do ustawienia parametru sampling_period_ns używana była funkcja setDelay zamiast batch.
flush(sensor)
int (*flush)(struct sensors_poll_device_1* dev, int sensor_handle);
Dodaj zgłoszenie całkowitego opróżnienia bufora FIFO na końcu bufora FIFO sprzętowego dla określonego czujnika i opróżnij bufor FIFO. Te zdarzenia są dostarczane jak zwykle (czyli tak, jakby upłynął maksymalny czas oczekiwania na raportowanie) i usuwane z bufora FIFO.
Usuwanie danych odbywa się asynchronicznie (tj. ta funkcja musi wrócić natychmiast). Jeśli implementacja używa jednego kolejki FIFO dla kilku czujników, ta kolej jest opróżniana, a zdarzenie o ukończeniu opróżniania jest dodawane tylko w przypadku określonego czujnika.
Jeśli wskazany czujnik nie ma kolejki FIFO (nie można przeprowadzić buforowania) lub jeśli kolejka FIFO była pusta w momencie wywołania, funkcja flush
musi się zakończyć sukcesem i wysłać zdarzenie flush complete dla tego czujnika. Dotyczy to wszystkich czujników oprócz czujników jednorazowych.
Gdy wywołanie flush
jest wywoływane, nawet jeśli zdarzenie flush jest już w
FIFO dla tego czujnika, należy utworzyć dodatkowy i dodać go na końcu
a FIFO i FIFO muszą być usunięte. Liczba wywołań funkcji flush
musi być równa liczbie utworzonych zdarzeń Flush Complete.
flush
nie dotyczy one-shot
czujniki; jeśli sensor_handle
odnosi się do czujnika pojedynczego,
Funkcja flush
musi zwrócić wartość -EINVAL
i nie może generować żadnych
flush pełne zdarzenie metadanych.
Ta funkcja zwraca 0 w przypadku powodzenia, -EINVAL
, jeśli podany czujnik jest
z czujnikiem jednorazowym lub nie został włączony, a w przeciwnym razie wartość błędu była ujemna.
ankieta()
int (*poll)(struct sensors_poll_device_t *dev, sensors_event_t* data, int
count);
Zwraca tablicę danych czujnika przez wypełnienie argumentu data
. Ta funkcja musi blokować do czasu, gdy wydarzenia będą dostępne. Zwraca liczbę przeczytanych zdarzeń
w przypadku powodzenia, a ujemna – w przypadku błędu.
Liczba zdarzeń zwracanych w wartości data
musi być mniejsza lub równa argumentowi count
. Ta funkcja nigdy nie zwraca 0 (brak zdarzenia).
Kolejność połączeń
Gdy urządzenie się uruchamia, wywoływana jest funkcja get_sensors_list
.
Po aktywowaniu czujnika funkcja batch
jest wywoływana za pomocą
żądane parametry, po których następuje znak activate(..., enable=1)
.
W wersji HAL 1_0 kolejność była odwrotna: najpierw wywoływana była funkcja activate
, a potem set_delay
.
Gdy żądane parametry czujnika zmieniają się, gdy jest włączony
aktywowany, zostaje wywołana funkcja batch
.
flush
może być wywoływany w dowolnym momencie, nawet w przypadku nieaktywnych czujników (w takim przypadku musi zwracać -EINVAL
).
Gdy czujnik zostanie wyłączony, wywołana jest funkcja activate(..., enable=0)
.
Równolegle do tych wywołań funkcja poll
będzie wielokrotnie wywoływana w celu
żądania danych. poll
może być wywoływany nawet wtedy, gdy nie są aktywne żadne czujniki.
czujniki_moduł_t
sensors_module_t
to typ używany do tworzenia modułu sprzętowego Androida dla czujników. Implementacja HAL musi definiować obiekt
HAL_MODULE_INFO_SYM
tego typu do udostępniania funkcji get_sensors_list. Więcej informacji znajdziesz w definicji sensors_module_t
w pliku sensors.h oraz w definicji hw_module_t
.
czujniki_poll_device_t / czujniki_poll_device_1_t
sensors_poll_device_1_t
zawiera pozostałe zdefiniowane powyżej metody: activate
, batch
, flush
i poll
. Jego pole common
(typu hw_device_t)
określa numer wersji HAL.
czujnik_t
sensor_t
odpowiada czujnikowi w Androidzie. Oto kilka jego ważnych pól:
name: widoczny dla użytkownika ciąg znaków reprezentujący czujnik. Ciąg ten często zawiera nazwę części czujnika, typ czujnika oraz informację, czy jest to czujnik budzenia. Przykłady: „LIS2HH12 Accelerometer”, „MAX21000 Uncalibrated Gyroscope”, „BMP280 Wake-up Barometer”, „MPU6515 Game Rotation Vector”.
handle:liczba całkowita używana do odwoływania się do czujnika podczas rejestracji lub i generowanie z niego zdarzeń.
type:typ czujnika. Więcej informacji o typach czujników znajdziesz w artykule Czym są czujniki Androida?, a o oficjalnych typach czujników – w artykule Typy czujników. W przypadku nieoficjalnych typów czujników type
musi zaczynać się od SENSOR_TYPE_DEVICE_PRIVATE_BASE
stringType: typ czujnika określony za pomocą ciągu znaków. Jeśli czujnik ma oficjalny typ, ustaw wartość SENSOR_STRING_TYPE_*
. Jeśli czujnik ma typ określony przez producenta, stringType
musi zaczynać się od nazwy domeny odwróconej producenta. Na przykład czujnik (np. detektor jednorożców) zdefiniowany przez zespół Cool-product w firmie Fictional-Company może używać stringType=”com.fictional_company.cool_product.unicorn_detector”
.
Wartość stringType
służy do jednoznacznej identyfikacji nieoficjalnych typów czujników. Więcej informacji na temat typów i ciągów znajdziesz na stronie sensors.h.
.
requiredPermission: ciąg znaków reprezentujący uprawnienie
które aplikacje muszą mieć, aby mieć dostęp do czujnika, zarejestrować się w nim i odbierać
swoje dane. Pusty ciąg znaków oznacza, że aplikacje nie wymagają żadnych uprawnień do dostępu do tego czujnika. Niektóre typy czujników, np. pulsometr, mają
obowiązkowo requiredPermission
. Wszystkie czujniki dostarczające informacje o użytkowniku o charakterze wrażliwym (takie jak tętno) muszą być chronione przez uprawnienia.
flagi: flagi tego czujnika określające tryb raportowania i to, czy jest to czujnik aktywacji. Na przykład czujnik pojedynczego pobudzenia będzie miał wartość flags = SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP
. Fragmenty
flaga, która nie jest używana w bieżącej wersji HAL, musi mieć wartość 0.
maxRange: maksymalna wartość, jaką może podać czujnik, w tych samych jednostkach co wartości zgłoszone. Sensor musi być w stanie raportować wartości bez nasycenia w zakresie [-maxRange; maxRange]
. Oznacza to, że całkowity zakres czujnika w ogólnym znaczeniu to 2*maxRange
. Gdy czujnik wskaże wartości przekraczające
kilku osi, zakres odnosi się do każdej z nich. Na przykład: „+/- 2g”
akcelerometr wskaże maxRange = 2*9.81 = 2g
.
resolution: najmniejsza różnica w wartości, jaką może mierzyć czujnik.
Zwykle jest obliczany na podstawie parametru maxRange
i liczby bitów w pomiarze.
power: koszt zasilania czujnika (miliAmp).
To prawie zawsze większe niż zużycie energii podawane w
danych czujnika. Sprawdź czujniki podstawowe != fizyczne
, aby dowiedzieć się więcej, i przeczytaj artykuł na temat pomiaru mocy).
, aby dowiedzieć się, jak zmierzyć zużycie energii przez czujnik.
Jeśli zużycie energii przez czujnik zależy od tego, czy urządzenie się porusza,
zużycie energii podczas ruchu jest zgodne z zużyciem energii w aplikacji power
.
minDelay: w przypadku ciągłych czujników okres próbkowania w mikrosekundach odpowiadający najszybszej częstotliwości obsługiwanej przez czujnik. Zobacz sampling_period_ns dla
o sposobie wykorzystania tej wartości. Pamiętaj, że minDelay
jest wyrażona w mikrosekundach, a sampling_period_ns
– w nanosekundach. W przypadku czujników w trybie raportowania zmian i trybie specjalnym (chyba że określono inaczej) wartość minDelay
musi wynosić 0. W przypadku czujników jednorazowych musi ona mieć wartość -1.
maxDelay: w przypadku ciągłych i zmiennych czujników okres próbkowania w mikrosekundach odpowiadający najwolniejszej częstotliwości obsługiwanej przez czujnik. Szczegółowe informacje o użyciu tej wartości znajdziesz w sekcji sampling_period_ns. Pamiętaj, że maxDelay
wyrażony w mikrosekundach, podczas gdy sampling_period_ns
jest w
nanosekund. Czujniki specjalne i jednorazowe muszą mieć parametr maxDelay
0.
fifoReserveEventCount: liczba zdarzeń zarezerwowanych dla tego czujnika w
sprzętowy FIFO. Jeśli dla tego czujnika istnieje dedykowany FIFO,
fifoReservedEventCount
to rozmiar tego dedykowanego FIFO. Jeśli FIFO jest
udostępniane innym czujnikom, fifoReservedEventCount
to rozmiar części
FIFO, który jest zarezerwowany dla tego czujnika. W większości systemów FIFO oraz wł.
w systemach bez sprzętowego FIFO ta wartość wynosi 0.
fifoMaxEventCount: maksymalna liczba zdarzeń, które mogą
będą przechowywane w FIFO dla tego czujnika. Jest to zawsze większe lub równe
fifoReservedEventCount
Ta wartość służy do oszacowania,
FIFO będzie się zapełniać po zarejestrowaniu na czujniku
jeśli żadne inne czujniki nie zostały aktywowane. W systemach, które nie mają FIFO sprzętowego, fifoMaxEventCount
ma wartość 0. Więcej informacji znajdziesz w sekcji przetwarzanie zbiorcze.
W przypadku czujników z oficjalnym typem niektóre pola są zastępowane przez platformę. Na przykład czujniki akcelerometru muszą mieć tryb ciągłego raportowania, a monitory tętna muszą być chronione przez uprawnienie SENSOR_PERMISSION_BODY_SENSORS
.
czujniki_zdarzenie_t
Zdarzenia z czujników generowane przez czujniki Androida i zgłaszane za pomocą funkcji ankiety mają wartość type sensors_event_t
. Oto niektóre ważne pola w sensors_event_t
:
wersja: wymagana to sizeof(struct sensors_event_t)
sensor: uchwyt czujnika, który wygenerował zdarzenie, zgodnie z definicją w sensor_t.handle
.
type:typ czujnika czujnika, który wywołał zdarzenie, określony za pomocą funkcji
sensor_t.type
timestamp: sygnatura czasowa zdarzenia w nanosekundach. Jest to czas wystąpienia zdarzenia (krok lub pomiar przyspieszenia), a nie czas zgłoszenia zdarzenia. Pole timestamp
musi być zsynchronizowane z
zegara elapsedRealtimeNano
, a w przypadku czujników ciągłych zakłócenia.
muszą być małe. Filtrowanie sygnatur czasowych jest czasami konieczne, aby spełnić wymagania dotyczące CDD, ponieważ użycie tylko czasu przerwania SoC do ustawienia sygnatur czasowych powoduje zbyt duży jitter, a użycie tylko czasu z układu scalonego czujnika do ustawienia sygnatur czasowych może spowodować brak synchronizacji z zegarem elapsedRealtimeNano
, ponieważ zegar czujnika może się przesuwać.
danych i nakładających się pól: wartości mierzone przez parametr
. Ich znaczenie i jednostki zależą od typu czujnika. Opis pól danych znajdziesz w pliku sensors.h oraz w definicji różnych typów czujników. W przypadku niektórych czujników dokładność odczytów jest również raportowana jako część danych w polu status
. To pole jest przekazywane tylko w przypadku wybranych typów czujników i wyświetlane na poziomie SDK jako wartość dokładności. W przypadku tych czujników fakt, że pole stanu musi być ustawione, jest wspomniany w definicji typu czujnika.
Zdarzenia zakończenia usuwania metadanych
Zdarzenia metadanych mają ten sam typ co zwykłe zdarzenia czujnika:
sensors_event_meta_data_t = sensors_event_t
. Zwracane są razem z:
innych zdarzeń z czujników. Zawierają te pola:
wersja: wymagana to META_DATA_VERSION
type:musi mieć wartość SENSOR_TYPE_META_DATA
.
sensor, zarezerwowane i timestamp: musi mieć wartość 0.
meta_data.what: zawiera typ metadanych tego zdarzenia. Obecnie istnieje
jeden prawidłowy typ metadanych: META_DATA_FLUSH_COMPLETE
.
Zdarzenia META_DATA_FLUSH_COMPLETE
wskazują na zakończenie czyszczenia kolejki FIFO czujnika. Gdy meta_data.what=META_DATA_FLUSH_COMPLETE
, meta_data.sensor
musi być ustawiona na uchwyt czujnika, który został opróżniony. Są one generowane tylko wtedy, gdy funkcja flush
jest wywoływana w przypadku czujnika. Zapoznaj się z sekcją na temat:
użyj funkcji flush.