Die Sensors Hardware Abstraction Layer (HAL) ist die Schnittstelle zwischen dem Android-Sensor-Framework und den Sensoren eines Geräts, z. B. einem Beschleunigungsmesser oder Gyroskop. Die Sensors HAL definiert die Funktionen, die implementiert werden müssen, damit das Framework die Sensoren steuern kann.
Sensors HAL 2.0 ist in Android 10 und höher für neue und aktualisierte Geräte verfügbar. Sensors HAL 2.0 basiert auf Sensors HAL 1.0, weist aber einige wichtige Unterschiede auf, die eine Abwärtskompatibilität verhindern. Sensors HAL 2.0 verwendet Fast Message Queues (FMQs), um Sensorereignisse vom HAL in das Android-Sensor-Framework zu senden.
Sensors HAL 2.1 ist in Android 11 und höher für neue und aktualisierte Geräte verfügbar. Sensors HAL 2.1 ist eine Iteration von Sensors HAL 2.0, die den Sensortyp HINGE_ANGLE verfügbar macht und verschiedene Methoden aktualisiert, um den Typ HINGE_ANGLE
zu akzeptieren.
HAL 2.1-Schnittstelle
Die Hauptquelle für die Dokumentation zu Sensors HAL 2.1 ist die HAL-Definition unter hardware/interfaces/sensors/2.1/ISensors.hal.
Wenn es einen Konflikt zwischen den Anforderungen auf dieser Seite und ISensors.hal
gibt, verwenden Sie die Anforderung in ISensors.hal
.
HAL 2.0-Schnittstelle
Die Hauptquelle für die Dokumentation zu Sensors HAL 2.0 ist die HAL-Definition unter hardware/interfaces/sensors/2.0/ISensors.hal.
Wenn es einen Konflikt zwischen den Anforderungen auf dieser Seite und ISensors.hal
gibt, verwenden Sie die Anforderung in ISensors.hal
.
Sensors HAL 2.0 und HAL 2.1 implementieren
Um Sensors HAL 2.0 oder 2.1 zu implementieren, muss ein Objekt die ISensors
-Schnittstelle erweitern und alle in 2.0/ISensors.hal
oder 2.1/ISensors.hal
definierten Funktionen implementieren.
HAL initialisieren
Das Sensors HAL muss vom Android-Sensor-Framework initialisiert werden, bevor es verwendet werden kann. Das Framework ruft die Funktion initialize()
für HAL 2.0 und die Funktion initialize_2_1()
für HAL 2.1 auf, um drei Parameter für die Sensors-HAL bereitzustellen: zwei FMQ-Deskriptoren und einen Zeiger auf ein ISensorsCallback
-Objekt.
Das HAL verwendet den ersten Deskriptor, um den Event-FMQ zu erstellen, mit dem Sensorereignisse in das Framework geschrieben werden. Das HAL verwendet den zweiten Deskriptor, um das Wake Lock-FMQ zu erstellen, das zur Synchronisierung verwendet wird, wenn das HAL sein Wake Lock für WAKE_UP
-Sensorereignisse freigibt. Das HAL muss einen Zeiger auf das ISensorsCallback
-Objekt speichern, damit alle erforderlichen Callback-Funktionen aufgerufen werden können.
Die Funktion initialize()
oder initialize_2_1()
muss die erste Funktion sein, die beim Initialisieren des Sensors HAL aufgerufen wird.
Verfügbare Sensoren bereitstellen
Wenn Sie eine Liste aller verfügbaren statischen Sensoren auf dem Gerät abrufen möchten, verwenden Sie die Funktion getSensorsList()
in HAL 2.0 und die Funktion getSensorsList_2_1()
in HAL 2.1. Diese Funktion gibt eine Liste von Sensoren zurück, die jeweils durch ihr Handle eindeutig identifiziert werden. Der Handle für einen bestimmten Sensor darf sich nicht ändern, wenn der Prozess, in dem die Sensors HAL gehostet wird, neu gestartet wird. Aliasse können sich bei Geräte- und Systemserverneustarts ändern.
Wenn mehrere Sensoren denselben Sensortyp und dieselbe Wake-up-Eigenschaft haben, wird der erste Sensor in der Liste als Standardsensor bezeichnet und an Apps zurückgegeben, die die Funktion getDefaultSensor(int sensorType, bool wakeUp)
verwenden.
Stabilität der Sensorliste
Wenn die von getSensorsList()
oder getSensorsList_2_1()
zurückgegebenen Daten nach einem Neustart des Sensors HAL eine erhebliche Änderung im Vergleich zur vor dem Neustart abgerufenen Sensorliste aufweisen, löst das Framework einen Neustart der Android-Laufzeit aus. Zu den wesentlichen Änderungen an der Sensorliste gehören Fälle, in denen ein Sensor mit einem bestimmten Handle fehlt oder sich seine Attribute geändert haben oder in denen neue Sensoren eingeführt werden. Das Neustarten der Android-Laufzeit ist zwar störend für den Nutzer, aber erforderlich, da das Android-Framework den Android-API-Vertrag nicht mehr erfüllen kann, der besagt, dass sich statische (nicht dynamische) Sensoren während der Lebensdauer einer App nicht ändern. Dies kann auch verhindern, dass das Framework aktive Sensoranfragen von Apps wiederherstellt. Daher wird HAL-Anbietern empfohlen, vermeidbare Änderungen an der Sensorliste zu verhindern.
Damit die Sensor-Handles stabil sind, muss das HAL einen bestimmten physischen Sensor im Gerät deterministisch seinem Handle zuordnen. Obwohl die Sensors HAL-Schnittstelle keine bestimmte Implementierung vorschreibt, haben Entwickler mehrere Optionen, um diese Anforderung zu erfüllen.
Die Sensorliste kann beispielsweise anhand einer Kombination der festen Attribute jedes Sensors sortiert werden, z. B. Anbieter, Modell und Sensortyp. Eine weitere Option beruht auf der Tatsache, dass die statischen Sensoren des Geräts in der Hardware festgelegt sind. Daher muss die HAL wissen, wann alle erwarteten Sensoren initialisiert wurden, bevor sie von getSensorsList()
oder getSensorsList_2_1()
zurückkehrt. Diese Liste der erwarteten Sensoren kann in die HAL-Binärdatei kompiliert oder in einer Konfigurationsdatei im Dateisystem gespeichert werden. Die Reihenfolge des Auftretens kann verwendet werden, um stabile Handles abzuleiten. Die beste Lösung hängt von den spezifischen Implementierungsdetails Ihres HAL ab. Die wichtigste Anforderung ist jedoch, dass sich die Sensor-Handles bei HAL-Neustarts nicht ändern.
Sensoren konfigurieren
Bevor ein Sensor aktiviert wird, muss er mit einem Erfassungszeitraum und einer maximalen Meldeverzögerung konfiguriert werden. Verwenden Sie dazu die Funktion batch()
.
Ein Sensor muss jederzeit über batch()
neu konfiguriert werden können, ohne dass Sensordaten verloren gehen.
Stichprobenzeitraum
Der Erfassungszeitraum hat je nach konfiguriertem Sensortyp eine andere Bedeutung:
- Kontinuierlich: Sensorereignisse werden kontinuierlich generiert.
- Bei Änderung: Ereignisse werden nicht schneller als im Stichprobenzeitraum generiert. Wenn sich der gemessene Wert nicht ändert, kann die Rate, mit der Ereignisse generiert werden, auch langsamer als im Stichprobenzeitraum sein.
- Einmalig: Der Stichprobenzeitraum wird ignoriert.
- Spezial: Weitere Informationen finden Sie unter Sensortypen.
Weitere Informationen zur Interaktion zwischen einem Erfassungszeitraum und den Berichtsmodi eines Sensors finden Sie unter Berichtsmodi.
Maximale Latenz bei der Berichterstellung
Die maximale Meldeverzögerung gibt die maximale Zeit in Nanosekunden an, um die Ereignisse verzögert und im Hardware-FIFO gespeichert werden können, bevor sie über das HAL in den Event-FMQ geschrieben werden, während der SoC aktiv ist.
Ein Wert von null bedeutet, dass die Ereignisse gemeldet werden müssen, sobald sie erfasst werden. Das FIFO wird entweder ganz übersprungen oder geleert, sobald ein Ereignis vom Sensor im FIFO vorhanden ist.
Ein Beschleunigungsmesser, der mit 50 Hz aktiviert ist und eine maximale Meldeverzögerung von null hat, löst beispielsweise 50 Unterbrechungen pro Sekunde aus, wenn der SoC aktiv ist.
Wenn die maximale Meldeverzögerung größer als null ist, müssen Sensorereignisse nicht sofort nach der Erkennung gemeldet werden. Ereignisse können vorübergehend im Hardware-FIFO gespeichert und in Batches gemeldet werden, sofern kein Ereignis um mehr als die maximale Meldeverzögerung verzögert wird. Alle Ereignisse seit dem vorherigen Batch werden aufgezeichnet und gleichzeitig zurückgegeben. Dadurch wird die Anzahl der an den SoC gesendeten Interrupts reduziert und der SoC kann in einen Energiesparmodus wechseln, während der Sensor Daten erfasst und in Batches zusammenfasst.
Jedem Ereignis ist ein Zeitstempel zugeordnet. Das Verzögern des Zeitpunkts, zu dem ein Ereignis gemeldet wird, darf sich nicht auf den Zeitstempel des Ereignisses auswirken. Der Zeitstempel muss korrekt sein und dem Zeitpunkt entsprechen, zu dem das Ereignis tatsächlich stattgefunden hat, nicht dem Zeitpunkt, zu dem es gemeldet wurde.
Weitere Informationen und Anforderungen zum Melden von Sensorereignissen mit einer maximalen Meldeverzögerung ungleich null finden Sie unter Batching.
Sensoren aktivieren
Das Framework aktiviert und deaktiviert Sensoren mit der Funktion activate()
.
Bevor ein Sensor aktiviert werden kann, muss das Framework ihn zuerst mit batch()
konfigurieren.
Nachdem ein Sensor deaktiviert wurde, dürfen keine zusätzlichen Sensorereignisse von diesem Sensor in die Event FMQ geschrieben werden.
Unterputzsensoren
Wenn ein Sensor so konfiguriert ist, dass Sensordaten in Batches verarbeitet werden, kann das Framework durch Aufrufen von flush()
ein sofortiges Leeren der Batch-Sensorereignisse erzwingen. Dadurch werden die Batch-Sensorereignisse für das angegebene Sensor-Handle sofort in die Event-FMQ geschrieben. Die Sensors HAL muss am Ende der Sensorereignisse, die als Ergebnis eines Aufrufs von flush()
geschrieben werden, ein Flush-Complete-Ereignis anhängen.
Das Leeren erfolgt asynchron. Das bedeutet, dass diese Funktion sofort zurückgegeben werden muss. Wenn in der Implementierung ein einzelner FIFO für mehrere Sensoren verwendet wird, wird dieser FIFO geleert und das Ereignis „Flush abgeschlossen“ wird nur für den angegebenen Sensor hinzugefügt.
Wenn der angegebene Sensor keinen FIFO-Speicher hat (keine Pufferung möglich) oder der FIFO-Speicher zum Zeitpunkt des Aufrufs leer war, muss flush()
trotzdem erfolgreich ausgeführt werden und ein Ereignis für das Abschließen des Flush-Vorgangs für diesen Sensor gesendet werden. Das gilt für alle Sensoren außer One-Shot-Sensoren.
Wenn flush()
für einen One-Shot-Sensor aufgerufen wird, muss flush()
BAD_VALUE
zurückgeben und kein Flush-Complete-Ereignis generieren.
Sensorereignisse in die FMQ schreiben
Die Event-FMQ wird von der Sensors HAL verwendet, um Sensorereignisse in das Android-Sensor-Framework zu übertragen.
Die Event-FMQ ist eine synchronisierte FMQ. Das bedeutet, dass jeder Versuch, mehr Ereignisse in die FMQ zu schreiben, als der verfügbare Speicherplatz zulässt, zu einem fehlgeschlagenen Schreibvorgang führt. In diesem Fall sollte das HAL entscheiden, ob der aktuelle Satz von Ereignissen als zwei kleinere Gruppen von Ereignissen oder als alle Ereignisse zusammen geschrieben werden soll, wenn genügend Speicherplatz verfügbar ist.
Wenn die Sensors HAL die gewünschte Anzahl von Sensorereignissen in die Event-FMQ geschrieben hat, muss sie das Framework benachrichtigen, dass die Ereignisse bereit sind. Dazu muss sie das EventQueueFlagBits::READ_AND_PROCESS
-Bit in die EventFlag::wake
-Funktion der Event-FMQ schreiben. Das EventFlag kann aus dem Event FMQ mit EventFlag::createEventFlag
und der getEventFlagWord()
-Funktion des Event FMQ erstellt werden.
Sensors HAL 2.0/2.1 unterstützt sowohl write
als auch writeBlocking
im Event-FMQ.
Die Standardimplementierung bietet eine Referenz für die Verwendung von write
. Wenn die Funktion writeBlocking
verwendet wird, muss das Flag readNotification
auf EventQueueFlagBits::EVENTS_READ
gesetzt sein. Das Framework legt diesen Wert fest, wenn es Ereignisse aus der Event FMQ liest. Das Flag für Schreibbenachrichtigungen muss auf EventQueueFlagBits::READ_AND_PROCESS
gesetzt sein. Dadurch wird das Framework darüber informiert, dass Ereignisse in die Event FMQ geschrieben wurden.
WAKE_UP-Ereignisse
WAKE_UP
-Ereignisse sind Sensorereignisse, die dazu führen, dass der Anwendungsprozessor (AP) aktiviert wird und das Ereignis sofort verarbeitet. Immer wenn ein WAKE_UP
-Ereignis in die Event-FMQ geschrieben wird, muss die Sensors-HAL ein Wake Lock sichern, damit das System so lange aktiv bleibt, bis das Framework das Ereignis verarbeiten kann. Beim Empfang eines WAKE_UP
-Ereignisses sichert das Framework seinen eigenen Wake Lock, sodass das Sensors HAL seinen Wake Lock freigeben kann. Verwenden Sie das Wake Lock FMQ, um die Synchronisierung zu starten, wenn das Sensors HAL sein Wake Lock freigibt.
Die Sensors HAL muss das Wake Lock FMQ lesen, um die Anzahl der WAKE_UP
-Ereignisse zu ermitteln, die vom Framework verarbeitet wurden. Das HAL sollte sein Wake Lock für WAKE_UP
-Ereignisse nur freigeben, wenn die Gesamtzahl der nicht verarbeiteten WAKE_UP
-Ereignisse null ist.
Nach der Verarbeitung von Sensorereignissen zählt das Framework die Anzahl der Ereignisse, die als WAKE_UP
-Ereignisse gekennzeichnet sind, und schreibt diese Zahl zurück in die Wake Lock FMQ.
Das Framework legt die WakeLockQueueFlagBits::DATA_WRITTEN
-Schreibbenachrichtigung für die Wake Lock-FMQ fest, wenn Daten in die Wake Lock-FMQ geschrieben werden.
Dynamische Sensoren
Dynamische Sensoren sind Sensoren, die nicht physisch Teil des Geräts sind, aber als Eingabe für das Gerät verwendet werden können, z. B. ein Gamepad mit einem Beschleunigungsmesser.
Wenn ein dynamischer Sensor verbunden ist, muss die Funktion onDynamicSensorConnected
in ISensorsCallback
über die Sensors HAL aufgerufen werden. Dadurch wird das Framework über den neuen dynamischen Sensor informiert und der Sensor kann über das Framework gesteuert werden. Außerdem können die Ereignisse des Sensors von Clients genutzt werden.
Wenn ein dynamischer Sensor getrennt wird, muss die Funktion onDynamicSensorDisconnected
in ISensorsCallback
aufgerufen werden, damit das Framework alle Sensoren entfernen kann, die nicht mehr verfügbar sind.
Direkter Channel
Der direkte Kanal ist eine Betriebsmethode, bei der Sensorereignisse in einen bestimmten Speicher geschrieben werden, anstatt in die Event FMQ. Dabei wird das Android Sensors Framework umgangen. Ein Client, der einen direkten Kanal registriert, muss die Sensorereignisse direkt aus dem Speicher lesen, der zum Erstellen des direkten Kanals verwendet wurde. Er empfängt die Sensorereignisse nicht über das Framework. Die Funktion configDirectReport()
ähnelt batch()
für den normalen Betrieb und konfiguriert den direkten Meldekanal.
Mit den Funktionen registerDirectChannel()
und unregisterDirectChannel()
wird ein neuer direkter Kanal erstellt oder gelöscht.
Betriebsmodi
Mit der Funktion setOperationMode()
kann das Framework einen Sensor so konfigurieren, dass Sensordaten in den Sensor eingefügt werden können. Das ist nützlich für Tests, insbesondere für Algorithmen, die unter dem Framework liegen.
Die Funktion injectSensorData()
in HAL 2.0 und die Funktion injectSensorsData_2_1()
in HAL 2.0 werden normalerweise verwendet, um Betriebsparameter in das Sensors-HAL zu übertragen. Die Funktion kann auch verwendet werden, um Sensorereignisse in einen bestimmten Sensor einzufügen.
Zertifizierungsstufe
Führen Sie die Sensor-CTS- und VTS-Tests aus, um Ihre Implementierung des Sensors HAL zu validieren.
CTS-Tests
Sensor-CTS-Tests sind sowohl in automatisierten CTS-Tests als auch in der manuellen CTS-Verifier-App verfügbar.
Die automatisierten Tests befinden sich unter cts/tests/sensor/src/android/hardware/cts. Mit diesen Tests wird die Standardfunktionalität von Sensoren überprüft, z. B. das Aktivieren von Sensoren, das Batching und die Raten von Sensorereignissen.
Die CTS Verifier-Tests befinden sich unter cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors. Für diese Tests ist eine manuelle Eingabe durch den Tester erforderlich. Sie sorgen dafür, dass die Sensoren genaue Werte liefern.
Das Bestehen der CTS-Tests ist entscheidend, um sicherzustellen, dass das zu testende Gerät alle CDD-Anforderungen erfüllt.
VTS-Tests
VTS-Tests für Sensors HAL 2.0 befinden sich in hardware/interfaces/sensors/2.0/vts.
VTS-Tests für Sensors HAL 2.1 befinden sich in hardware/interfaces/sensors/2.1/vts.
Mit diesen Tests wird sichergestellt, dass das Sensors HAL richtig implementiert ist und alle Anforderungen in ISensors.hal
und ISensorsCallback.hal
ordnungsgemäß erfüllt werden.
Upgrade von Sensors HAL 2.0 auf 2.1
Wenn Sie ein Upgrade von Sensors HAL 2.0 auf 2.1 durchführen, muss Ihre HAL-Implementierung die Methoden initialize_2_1()
, getSensorsList_2_1()
und injectSensorsData_2_1()
sowie die HAL 2.1-Typen enthalten. Diese Methoden müssen dieselben Anforderungen erfüllen, die oben für HAL 2.0 beschrieben wurden.
Da Nebenversions-HALs alle Funktionen der vorherigen HALs unterstützen müssen, müssen 2.1-HALs als 2.0-HALs initialisiert werden können. Um die Komplexität der Unterstützung beider HAL-Versionen zu vermeiden, wird dringend empfohlen, Multi-HAL 2.1 zu verwenden.
Ein Beispiel für die Implementierung einer eigenen Sensors 2.1-HAL finden Sie unter Sensors.h.
Upgrade von Sensors HAL 1.0 auf 2.0
Wenn Sie von Sensors HAL 1.0 auf 2.0 aktualisieren, muss Ihre HAL-Implementierung die folgenden Anforderungen erfüllen.
HAL initialisieren
Die Funktion initialize()
muss unterstützt werden, um FMQs zwischen dem Framework und der HAL einzurichten.
Verfügbare Sensoren bereitstellen
In Sensors HAL 2.0 muss die Funktion getSensorsList()
während eines einzelnen Gerätestarts denselben Wert zurückgeben, auch wenn Sensors HAL neu gestartet wird. Eine neue Anforderung der Funktion getSensorsList()
ist, dass sie während eines einzelnen Geräteboots denselben Wert zurückgeben muss, auch bei Neustarts des Sensors HAL. Dadurch kann das Framework versuchen, Sensorverbindungen wiederherzustellen, wenn der Systemserver neu gestartet wird. Der von getSensorsList()
zurückgegebene Wert kann sich nach einem Neustart des Geräts ändern.
Sensorereignisse in die FMQ schreiben
Anstatt darauf zu warten, dass poll()
aufgerufen wird, muss die Sensors HAL in Sensors HAL 2.0 proaktiv Sensorereignisse in die Event-FMQ schreiben, sobald Sensorereignisse verfügbar sind. Das HAL ist auch dafür verantwortlich, die richtigen Bits in EventFlag
zu schreiben, um einen FMQ-Lesevorgang im Framework auszulösen.
WAKE_UP-Ereignisse
In Sensors HAL 1.0 konnte die HAL ihr Wake Lock für jedes WAKE_UP
-Ereignis bei jedem nachfolgenden Aufruf von poll()
freigeben, nachdem ein WAKE_UP
an poll()
gesendet wurde. Dies wies darauf hin, dass das Framework alle Sensorereignisse verarbeitet und bei Bedarf ein Wake Lock abgerufen hatte. Da die HAL in Sensors HAL 2.0 nicht mehr weiß, wann das Framework Ereignisse verarbeitet hat, die in die FMQ geschrieben wurden, kann das Framework über die Wake Lock FMQ der HAL mitteilen, wann es WAKE_UP
-Ereignisse verarbeitet hat.
In der Sensors HAL 2.0 muss das von der Sensors HAL für WAKE_UP
-Ereignisse gesicherte Wake Lock mit SensorsHAL_WAKEUP
beginnen.
Dynamische Sensoren
Dynamische Sensoren wurden mit der Funktion poll()
in Sensors HAL 1.0 zurückgegeben.
Für Sensors HAL 2.0 müssen onDynamicSensorsConnected
und onDynamicSensorsDisconnected
in ISensorsCallback
aufgerufen werden, wenn sich dynamische Sensorverbindungen ändern. Diese Callbacks sind als Teil des ISensorsCallback
-Zeigers verfügbar, der über die Funktion initialize()
bereitgestellt wird.
Betriebsmodi
Der DATA_INJECTION
-Modus für WAKE_UP
-Sensoren muss in Sensors HAL 2.0 unterstützt werden.
Unterstützung mehrerer HALs
Sensors HAL 2.0 und 2.1 unterstützen Multi-HAL mit dem Sensors Multi-HAL-Framework. Implementierungsdetails finden Sie unter Von Sensors HAL 1.0 portieren.