Sensoren HAL 2.0

Die Hardware-Abstraktionsschicht (Sensors Hardware Abstraktionsschicht, 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.

Die Sensoren HAL 2.0 sind ab Android 10 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 schnelle Nachrichtenwarteschlangen (Fast Message Queues, FMQs), um Sensorereignisse von der HAL an 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 freigibt und verschiedene Methoden aktualisiert, um den Typ HINGE_ANGLE zu akzeptieren.

HAL 2.1-Schnittstelle

Die Hauptdokumentation für Sensoren HAL 2.1 befindet sich in der HAL-Definition unter hardware/interfaces/sensors/2.1/ISensors.hal. Wenn die Anforderungen auf dieser Seite und in ISensors.hal nicht übereinstimmen, verwenden Sie die Anforderungen in ISensors.hal.

HAL 2.0-Schnittstelle

Die Hauptquelle für die Dokumentation von Sensors HAL 2.0 befindet sich in der HAL-Definition unter hardware/interfaces/sensors/2.0/ISensors.hal. Wenn zwischen dieser Seite und ISensors.hal ein Anforderungskonflikt besteht, verwende 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

Die Sensors HAL muss vom Android-Sensor-Framework initialisiert werden, bevor sie verwendet werden kann. Das Framework ruft die initialize()-Funktion für HAL 2.0 und die initialize_2_1()-Funktion für HAL 2.1 auf, um drei Parameter an die Sensors HAL zu übergeben: zwei FMQ-Beschreibungen und einen Verweis auf ein ISensorsCallback-Objekt.

Die HAL verwendet den ersten Descriptor, um die Ereignis-FMQ zu erstellen, mit der Sensorereignisse in das Framework geschrieben werden. Die HAL verwendet den zweiten Deskriptor, um die Wake Lock-FMQ zu erstellen, die zum Synchronisieren verwendet wird, wenn die HAL die Wake Lock für WAKE_UP-Sensorereignisse freigibt. Die HAL muss einen Verweis 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 bei der Initialisierung der Sensors HAL aufgerufen wird.

Verfügbare Sensoren freigeben

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 ihren eindeutigen Handle identifiziert werden. Der Handle für einen bestimmten Sensor darf sich nicht ändern, wenn der Prozess, der die HAL des Sensors hostet, neu gestartet wird. Aliasse können sich bei Geräteneustarts und Systemserver-Neustarts ändern.

Wenn mehrere Sensoren denselben Sensortyp und dieselbe Aufwacheigenschaft haben, wird der erste Sensor in der Liste als Standardsensor bezeichnet und an Anwendungen zurückgegeben, die die Funktion getDefaultSensor(int sensorType, bool wakeUp) verwenden.

Stabilität der Liste der Sensoren

Wenn nach einem Neustart der HAL für Sensoren die von getSensorsList() oder getSensorsList_2_1() zurückgegebenen Daten eine erhebliche Änderung im Vergleich zur Sensorliste anzeigen, die vor dem Neustart abgerufen wurde, 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 seine Attribute geändert wurden, oder in denen neue Sensoren eingeführt werden. Der Neustart der Android-Laufzeit hat zwar eine Störung für den Nutzer, ist aber erforderlich, weil das Android-Framework den Android API-Vertrag nicht mehr erfüllen kann, sodass sich statische (nicht dynamische) Sensoren während der Lebensdauer einer App nicht ändern. Dadurch kann das Framework unter Umständen auch keine aktiven Sensoranfragen von Apps neu einrichten. Daher wird HAL-Anbietern empfohlen, vermeidbare Änderungen an der Sensorliste zu vermeiden.

Um stabile Sensor-Handles zu gewährleisten, muss die HAL einen bestimmten physischen Sensor auf dem Gerät deterministisch seinem Handle zuordnen. Die HAL-Schnittstelle für Sensoren schreibt zwar keine bestimmte Implementierung vor, Entwickler haben aber eine Reihe von Möglichkeiten, diese Anforderung zu erfüllen.

Die Sensorliste kann beispielsweise anhand einer Kombination der festen Attribute der einzelnen Sensoren wie Anbieter, Modell und Sensortyp sortiert werden. Eine weitere Option basiert darauf, dass die statischen Sensoren des Geräts in der Hardware festgelegt sind. Daher muss die HAL wissen, wann die Initialisierung aller erwarteten Sensoren abgeschlossen ist, 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 der Darstellung kann verwendet werden, um stabile Handles abzuleiten. Obwohl die beste Lösung von den spezifischen Implementierungsdetails Ihres HAL abhängig ist, besteht die Hauptanforderung darin, dass sich die Sensor-Handles bei HAL-Neustarts nicht ändern.

Sensoren konfigurieren

Bevor ein Sensor aktiviert wird, muss er mit einer Stichprobenzeit und einer maximalen Berichtslatenz mithilfe der Funktion batch() konfiguriert werden.

Ein Sensor muss ohne den Verlust von Sensordaten jederzeit mit batch() neu konfiguriert werden können.

Stichprobenzeiträume

Der Stichprobenzeitraum hat je nach konfiguriertem Sensortyp eine andere Bedeutung:

  • Kontinuierlich: Sensorereignisse werden kontinuierlich generiert.
  • Bei Änderung: Ereignisse werden nicht schneller als in der Stichprobenzeit generiert. Wenn sich der Messwert nicht ändert, kann die Rate auch langsamer sein.
  • Einmalig: Der Stichprobenzeitraum wird ignoriert.
  • Speziell: Weitere Informationen finden Sie unter Sensortypen.

Weitere Informationen zur Interaktion zwischen einem Messzeitraum und den Berichtsmodi eines Sensors finden Sie unter Berichtsmodi.

Maximale Berichtslatenz

Mit der maximalen Berichtslatenz wird die maximale Zeit in Nanosekunden festgelegt, um die Ereignisse verzögert und im Hardware-FIFO gespeichert werden können, bevor sie über die HAL in die Ereignis-FMQ geschrieben werden, während das SoC aktiv ist.

Ein Wert von null bedeutet, dass die Ereignisse sobald sie gemessen werden, gemeldet werden müssen. Dabei wird der FIFO entweder komplett übersprungen oder geleert, sobald ein Ereignis vom Sensor im FIFO vorhanden ist.

Ein Beschleunigungsmesser, der mit 50 Hz aktiviert ist und eine maximale Berichtslatenz von null hat, löst beispielsweise 50 Mal pro Sekunde Unterbrechungen aus, wenn das SoC aktiv ist.

Wenn die maximale Berichtslatenz 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, solange kein Ereignis um mehr als die maximale Berichtslatenz verzögert wird. Alle Ereignisse seit dem letzten Batch werden auf einmal erfasst und zurückgegeben. Dadurch wird die Anzahl der Unterbrechungen reduziert, die an das SoC gesendet werden, und das SoC kann in einen niedrigeren Energiesparmodus wechseln, während der Sensor Daten erfasst und bündelt.

Jedem Ereignis ist ein Zeitstempel zugeordnet. Eine Verzögerung bei der Meldung eines Ereignisses darf sich nicht auf den Zeitstempel des Ereignisses auswirken. Der Zeitstempel muss korrekt sein und dem Zeitpunkt entsprechen, zu dem das Ereignis tatsächlich aufgetreten ist, nicht dem Zeitpunkt, zu dem es gemeldet wurde.

Weitere Informationen und Anforderungen zum Melden von Sensorereignissen mit einer nicht nullwertigen maximalen Meldelatenz finden Sie unter Batchverarbeitung.

Sensoren aktivieren

Das Framework aktiviert und deaktiviert Sensoren mithilfe 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 weiteren Sensorereignisse von diesem Sensor in die Ereignis-FMQ geschrieben werden.

Spülsensoren

Wenn ein Sensor für Batch-Sensordaten konfiguriert ist, kann das Framework durch Aufrufen von flush() ein sofortiges Ausgeben der Batch-Sensorereignisse erzwingen. Dadurch werden die gebatchten Sensorereignisse für den angegebenen Sensor-Handle sofort in die Ereignis-FMQ geschrieben. Die Sensors HAL muss am Ende der Sensorereignisse, die als Ergebnis eines Aufrufs von flush() geschrieben werden, ein Ereignis vom Typ „Flush complete“ anhängen.

Das Leeren erfolgt asynchron, d. h., diese Funktion muss sofort zurückgeben. Wenn die Implementierung einen einzelnen FIFO für mehrere Sensoren verwendet, wird dieser FIFO geleert und das Ereignis für abgeschlossene Leerung nur für den angegebenen Sensor hinzugefügt.

Wenn der angegebene Sensor keinen FIFO hat (keine Pufferung möglich) oder der FIFO zum Zeitpunkt des Aufrufs leer war, muss flush() trotzdem erfolgreich sein und ein Ereignis vom Typ „Flush complete“ für diesen Sensor senden. Das gilt für alle Sensoren mit Ausnahme von Einmalsensoren.

Wenn flush() für einen One-Shot-Sensor aufgerufen wird, muss flush() BAD_VALUE zurückgeben und kein Ereignis des abgeschlossenen Leerens erzeugen.

Sensorereignisse in die FMQ schreiben

Die Event-FMQ wird von der Sensors HAL verwendet, um Sensorereignisse an das Android-Sensor-Framework zu senden.

Das Ereignis-FMQ ist ein synchronisiertes FMQ. Das bedeutet, dass jeder Versuch, mehr Ereignisse in das FMQ zu schreiben, als der verfügbare Speicherplatz zulässt, zu einem fehlgeschlagenen Schreibvorgang führt. In diesem Fall sollte der HAL entscheiden, ob die aktuellen Ereignisse als zwei kleinere Ereignisgruppen oder alle Ereignisse zusammen geschrieben werden sollen, wenn genügend Speicherplatz verfügbar ist.

Wenn die Sensors HAL die gewünschte Anzahl von Sensorereignissen in die Ereignis-FMQ geschrieben hat, muss sie das Framework darüber informieren, dass Ereignisse verfügbar sind, indem sie das EventQueueFlagBits::READ_AND_PROCESS-Bit in die EventFlag::wake-Funktion der Ereignis-FMQ schreibt. Die EventFlag kann über die EventFlag::createEventFlag-Funktion und die getEventFlagWord()-Funktion der Event-FMQ erstellt werden.

HAL 2.0/2.1 der Sensoren unterstützt sowohl write als auch writeBlocking in Event-FMQ. Die Standardimplementierung dient als Referenz für die Verwendung von write. Wenn die Funktion writeBlocking verwendet wird, muss das Flag readNotification auf EventQueueFlagBits::EVENTS_READ gesetzt sein. Dieser Wert wird vom Framework festgelegt, wenn Ereignisse aus dem Ereignis-FMQ gelesen werden. Das Flag für die Schreibbenachrichtigung muss auf EventQueueFlagBits::READ_AND_PROCESS gesetzt sein. Dadurch wird das Framework benachrichtigt, dass Ereignisse in die Ereignis-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. Jedes Mal, wenn ein WAKE_UP-Ereignis in die Ereignis-FMQ geschrieben wird, muss die Sensors HAL eine Wake-Lock sichern, damit das System aktiv bleibt, bis das Framework das Ereignis verarbeiten kann. Wenn ein WAKE_UP-Ereignis empfangen wird, sichert das Framework seine eigene Wake-Lock, sodass die Sensors HAL ihre Wake-Lock freigeben kann. Verwenden Sie die Wake Lock FMQ, um zu synchronisieren, wenn der Sensors-HAL seinen Wakelock freigibt.

Die Sensors HAL muss die Wake Lock-FMQ lesen, um die Anzahl der WAKE_UP-Ereignisse zu ermitteln, die vom Framework verarbeitet wurden. Die HAL sollte die Wake-Locks für WAKE_UP-Ereignisse nur dann 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 das Wake Lock-FMQ.

Das Framework setzt die WakeLockQueueFlagBits::DATA_WRITTEN-Schreibbenachrichtigung im Wake Lock-FMQ, wenn es Daten in das Wake Lock-FMQ schreibt.

Dynamische Sensoren

Dynamische Sensoren sind Sensoren, die physisch nicht Teil des Geräts sind, aber als Eingabe für das Gerät verwendet werden können, z. B. ein Gamepad mit Beschleunigungsmesser.

Wenn ein dynamischer Sensor verbunden ist, muss die onDynamicSensorConnected-Funktion in ISensorsCallback von der Sensors HAL aufgerufen werden. Dadurch wird das Framework des neuen dynamischen Sensors informiert und der Sensor kann über das Framework gesteuert werden und die Ereignisse des Sensors können von Clients verarbeitet werden.

Wenn ein dynamischer Sensor getrennt wird, muss die Funktion onDynamicSensorDisconnected in ISensorsCallback aufgerufen werden, damit das Framework alle nicht mehr verfügbaren Sensoren entfernen kann.

Direkter Kanal

Ein direkter Kanal ist eine Betriebsmethode, bei der Sensorereignisse in einen bestimmten Speicher geschrieben werden, anstatt sie über das Android Sensors Framework an die Ereignis-FMQ zu senden. Ein Client, der einen direkten Kanal registriert, muss die Sensorereignisse direkt aus dem Arbeitsspeicher lesen, der zum Erstellen des direkten Kanals verwendet wurde. Er erhält die Sensorereignisse nicht über das Framework. Die Funktion configDirectReport() ähnelt batch() für den normalen Betrieb und konfiguriert den Kanal für direkte Berichte.

Mit den Funktionen registerDirectChannel() und unregisterDirectChannel() können Sie einen neuen Direktkanal erstellen oder löschen.

Betriebsmodi

Mit der Funktion setOperationMode() kann das Framework einen Sensor so konfigurieren, dass es Sensordaten in den Sensor einschleusen kann. Das ist für Tests nützlich, insbesondere für Algorithmen, die unterhalb des Frameworks liegen.

Die injectSensorData()-Funktion in HAL 2.0 und die injectSensorsData_2_1()-Funktion in HAL 2.0 werden normalerweise verwendet, um Betriebsparameter in die HAL für Sensoren zu übergeben. Die Funktion kann auch verwendet werden, um Sensorereignisse in einen bestimmten Sensor einzuschleusen.

Zertifizierungsstufe

Führen Sie die CTS- und VTS-Tests für Sensoren aus, um Ihre Implementierung der Sensors HAL zu validieren.

CTS-Tests

Sensor-CTS-Tests gibt es sowohl in automatisierten CTS-Tests als auch in der manuellen CTS Verifier App.

Die automatisierten Tests befinden sich unter cts/tests/sensor/src/android/hardware/cts. Bei diesen Tests werden die Standardfunktionen von Sensoren überprüft, z. B. die Aktivierung von Sensoren, Batching und Sensorereignisraten.

Die CTS Verifier-Tests befinden sich unter cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors. Diese Tests erfordern eine manuelle Eingabe durch den Testoperator und sorgen dafür, dass die Sensoren korrekte Werte melden.

Das Bestehen der CTS-Tests ist entscheidend, um sicherzustellen, dass das getestete Gerät alle CDD-Anforderungen erfüllt.

VTS-Tests

VTS-Tests für Sensors HAL 2.0 befinden sich unter hardware/interfaces/sensors/2.0/vts. VTS-Tests für Sensors HAL 2.1 befinden sich unter hardware/interfaces/sensors/2.1/vts. Mit diesen Tests wird sichergestellt, dass die Sensors HAL richtig implementiert ist und alle Anforderungen in ISensors.hal und ISensorsCallback.hal erfüllt werden.

Upgrade von Sensors HAL 2.0 auf 2.1

Wenn Sie von Sensors HAL 2.0 auf 2.1 umstellen, 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 HALs mit Nebenversionen alle Funktionen der vorherigen HALs unterstützen müssen, müssen HALs der Version 2.1 auch als HALs der Version 2.0 initialisiert werden können. Um die Komplexität der Unterstützung beider HAL-Versionen zu vermeiden, wird die Verwendung von Multi-HAL 2.1 dringend empfohlen.

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

Achten Sie beim Upgrade von Sensors HAL 1.0 auf Sensors HAL 2.0 darauf, dass Ihre HAL-Implementierung die folgenden Anforderungen erfüllt.

HAL initialisieren

Die Funktion initialize() muss unterstützt werden, um FMQs zwischen dem Framework und HAL einzurichten.

Verfügbare Sensoren bereitstellen

In Sensors HAL 2.0 muss die Funktion getSensorsList() bei einem einzelnen Gerätestart denselben Wert zurückgeben, auch bei Neustarts von Sensors HAL. Eine neue Anforderung an die Funktion getSensorsList() ist, dass sie beim Starten eines Geräts immer denselben Wert zurückgeben muss, auch bei Neustarts der Sensors HAL. So 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 der HAL der Sensoren in HAL 2.0 von Sensoren proaktiv Sensorereignisse in die Ereignis-FMQ schreiben, wenn Sensorereignisse verfügbar sind. Die HAL ist auch dafür verantwortlich, die richtigen Bits in EventFlag zu schreiben, um eine FMQ-Lesevorgänge im Framework auszulösen.

WAKE_UP-Ereignisse

In Sensors HAL 1.0 konnte die HAL bei jedem nachfolgenden Aufruf von poll() nach dem Posten eines WAKE_UP-Ereignisses an poll() die Wake-Lock für jedes WAKE_UP-Ereignis freigeben, da dies darauf hindeutete, dass das Framework alle Sensorereignisse verarbeitet und bei Bedarf eine Wake-Lock erhalten 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 mit der HAL kommunizieren, wenn es WAKE_UP-Ereignisse verarbeitet hat.

In Sensors HAL 2.0 muss die Wake-Lock, die von der Sensors HAL für WAKE_UP-Ereignisse gesichert wird, mit SensorsHAL_WAKEUP beginnen.

Dynamische Sensoren

Dynamische Sensoren wurden mit der Funktion poll() in Sensoren 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 über den ISensorsCallback-Zeiger 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 mehrere HALs mit dem Sensors Multi-HAL Framework. Implementierungsdetails finden Sie unter Portierung von Sensors HAL 1.0.