Sensoren HAL 2.0

Der Sensors Hardware Abstraction Layer (HAL) ist die Schnittstelle zwischen dem Android-Sensor-Framework und den Sensoren eines Geräts, beispielsweise einem Beschleunigungsmesser oder einem Gyroskop. Der Sensor-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 jedoch mehrere wesentliche Unterschiede auf, die eine Abwärtskompatibilität verhindern. Sensors HAL 2.0 verwendet Fast Message Queues (FMQs) , um Sensorereignisse vom 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 verfügbar macht und verschiedene Methoden aktualisiert, um den Typ HINGE_ANGLE zu akzeptieren.

HAL 2.1-Schnittstelle

Die Hauptdokumentationsquelle für Sensors HAL 2.1 ist die HAL-Definition unter hardware/interfaces/sensors/2.1/ISensors.hal . Wenn zwischen dieser Seite und ISensors.hal ein Anforderungskonflikt besteht, verwenden Sie die Anforderung in ISensors.hal .

HAL 2.0-Schnittstelle

Die Hauptdokumentationsquelle für Sensors HAL 2.0 ist die HAL-Definition unter hardware/interfaces/sensors/2.0/ISensors.hal . Wenn zwischen dieser Seite und ISensors.hal ein Anforderungskonflikt besteht, verwenden Sie die Anforderung in ISensors.hal .

Implementieren Sie die Sensoren HAL 2.0 und HAL 2.1

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.

Initialisieren Sie die HAL

Der Sensor-HAL muss vom Android-Sensor-Framework initialisiert werden, bevor er 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 Sensor-HAL bereitzustellen: zwei FMQ-Deskriptoren und einen Zeiger auf ein ISensorsCallback Objekt.

Der HAL verwendet den ersten Deskriptor, um den Event FMQ zu erstellen, der zum Schreiben von Sensorereignissen in das Framework verwendet wird. Der HAL verwendet den zweiten Deskriptor, um die Wake-Lock-FMQ zu erstellen, die zur Synchronisierung verwendet wird, wenn der HAL seinen Wake-Lock für WAKE_UP Sensorereignisse freigibt. Der HAL muss einen Zeiger auf das ISensorsCallback Objekt speichern, damit alle erforderlichen Rückruffunktionen aufgerufen werden können.

Die Funktion initialize() oder initialize_2_1() muss die erste Funktion sein, die beim Initialisieren der Sensor-HAL aufgerufen wird.

Verfügbare Sensoren freilegen

Um eine Liste aller verfügbaren statischen Sensoren im Gerät zu erhalten, verwenden Sie die Funktion getSensorsList() auf HAL 2.0 und die Funktion getSensorsList_2_1() auf HAL 2.1. Diese Funktion gibt eine Liste von Sensoren zurück, die jeweils durch ihr Handle eindeutig identifiziert werden. Das Handle für einen bestimmten Sensor darf sich nicht ändern, wenn der Prozess, der die Sensor-HAL hostet, neu gestartet wird. Handles können sich bei Geräteneustarts und Systemserverneustarts ändern.

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

Liste der Stabilität der Sensoren

Wenn die von getSensorsList() oder getSensorsList_2_1() zurückgegebenen Daten nach einem Sensors-HAL-Neustart eine wesentliche Änderung im Vergleich zur vor dem Neustart abgerufenen Sensorliste anzeigen, löst das Framework einen Neustart der Android-Laufzeitumgebung aus. Wesentliche Änderungen an der Sensorliste umfassen Fälle, in denen ein Sensor mit einem bestimmten Handle fehlt oder geänderte Attribute aufweist oder in denen neue Sensoren eingeführt werden. Obwohl ein Neustart der Android-Laufzeit für den Benutzer störend ist, ist er erforderlich, da das Android-Framework den Android-API-Vertrag nicht mehr erfüllen kann, 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.

Um stabile Sensorhandles zu gewährleisten, muss der HAL einen bestimmten physischen Sensor im Gerät deterministisch seinem Handle zuordnen. Obwohl die HAL-Schnittstelle von Sensors keine spezifische Implementierung vorschreibt, stehen Entwicklern eine Reihe von Optionen zur Verfügung, um diese Anforderung zu erfüllen.

Beispielsweise kann die Sensorliste anhand einer Kombination der festen Attribute jedes Sensors sortiert werden, z. B. Hersteller, Modell und Sensortyp. Eine weitere Option basiert auf der Tatsache, dass der Satz statischer Sensoren des Geräts in der Hardware festgelegt ist. Daher muss die HAL wissen, wann alle erwarteten Sensoren die Initialisierung abgeschlossen haben, 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, und die Reihenfolge des Erscheinens kann zum Ableiten stabiler Handles verwendet werden. Obwohl die beste Lösung von den spezifischen Implementierungsdetails Ihres HAL abhängt, besteht die wichtigste Anforderung darin, dass sich die Sensorhandles bei HAL-Neustarts nicht ändern.

Sensoren konfigurieren

Bevor ein Sensor aktiviert wird, muss der Sensor mithilfe der Funktion batch() mit einem Abtastzeitraum und einer maximalen Meldelatenz konfiguriert werden.

Ein Sensor muss jederzeit über die Funktion batch() ohne Verlust von Sensordaten neu konfiguriert werden können.

Testphase

Der Abtastzeitraum hat je nach konfiguriertem Sensortyp eine unterschiedliche Bedeutung:

  • Kontinuierlich: Sensorereignisse werden kontinuierlich generiert.
  • Bei Änderung: Ereignisse werden nicht schneller als der Abtastzeitraum generiert und können langsamer als der Abtastzeitraum generiert werden, wenn sich der Messwert nicht ändert.
  • One-Shot: Der Abtastzeitraum wird ignoriert.
  • Besonderheit: Weitere Details finden Sie unter Sensortypen .

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

Maximale Berichtslatenz

Die maximale Berichtslatenz legt die maximale Zeit in Nanosekunden fest, die Ereignisse verzögert und im Hardware-FIFO gespeichert werden können, bevor sie über die 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 gemessen werden, wobei entweder der FIFO ganz übersprungen wird oder der FIFO geleert wird, sobald ein Ereignis vom Sensor im FIFO vorhanden ist.

Beispielsweise löst ein bei 50 Hz aktivierter Beschleunigungsmesser mit einer maximalen Meldelatenz von Null 50 Mal pro Sekunde Interrupts aus, wenn der SoC aktiv ist.

Wenn die maximale Meldelatenz größer als Null ist, müssen Sensorereignisse nicht sofort nach ihrer Erkennung gemeldet werden. Ereignisse können vorübergehend im Hardware-FIFO gespeichert und stapelweise gemeldet werden, solange kein Ereignis um mehr als die maximale Meldelatenz verzögert wird. Alle Ereignisse seit der vorherigen Charge werden aufgezeichnet und sofort zurückgegeben. Dies reduziert die Anzahl der an den SoC gesendeten Interrupts und ermöglicht es dem SoC, in einen Modus mit geringerem Stromverbrauch zu wechseln, während der Sensor Daten erfasst und stapelt.

Jedem Ereignis ist ein Zeitstempel zugeordnet. Eine Verzögerung 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 physisch stattgefunden hat, nicht dem Zeitpunkt, zu dem es gemeldet wurde.

Weitere Informationen und Anforderungen zum Melden von Sensorereignissen mit einer maximalen Meldelatenz ungleich Null finden Sie unter Stapelverarbeitung .

Sensoren aktivieren

Das Framework aktiviert und deaktiviert Sensoren mithilfe der Funktion activate() . Vor der Aktivierung eines Sensors muss das Framework den Sensor zunächst 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 die Stapelverarbeitung von Sensordaten konfiguriert ist, kann das Framework durch den Aufruf von flush() eine sofortige Löschung der gestapelten Sensorereignisse erzwingen. Dadurch werden die gestapelten Sensorereignisse für das angegebene Sensorhandle sofort in die Ereignis-FMQ geschrieben. Der Sensor-HAL muss ein Ereignis „Flush Complete“ an das Ende der Sensorereignisse anhängen, die als Ergebnis eines Aufrufs von flush() geschrieben werden.

Der Flush erfolgt asynchron (d. h. diese Funktion muss sofort zurückkehren). Wenn die Implementierung einen einzelnen FIFO für mehrere Sensoren verwendet, wird dieser FIFO geleert und das Ereignis „Flush Complete“ wird nur für den angegebenen Sensor hinzugefügt.

Wenn der angegebene Sensor keinen FIFO hat (keine Pufferung möglich) oder wenn der FIFO zum Zeitpunkt des Aufrufs leer war, muss flush() trotzdem erfolgreich sein und ein Flush-Complete-Ereignis für diesen Sensor senden. Dies 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 darf kein Flush-Complete-Ereignis generieren.

Schreiben Sie Sensorereignisse in den FMQ

Der Event FMQ wird vom Sensors HAL verwendet, um Sensorereignisse in das Android-Sensor-Framework zu übertragen.

Die Ereignis-FMQ ist eine synchronisierte FMQ, was 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 einem solchen Fall sollte die HAL entscheiden, ob der aktuelle Satz von Ereignissen als zwei kleinere Gruppen von Ereignissen geschrieben werden soll oder ob alle Ereignisse zusammen geschrieben werden sollen, wenn genügend Platz verfügbar ist.

Wenn die Sensor-HAL die gewünschte Anzahl von Sensorereignissen in die Event-FMQ geschrieben hat, muss die Sensor-HAL das Framework darüber informieren, dass Ereignisse bereit sind, indem sie das EventQueueFlagBits::READ_AND_PROCESS Bit in die EventFlag::wake Funktion der Event-FMQ schreibt. Das EventFlag kann aus dem Event FMQ mithilfe von EventFlag::createEventFlag und der Funktion getEventFlagWord() 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 write . Wenn die writeBlocking Funktion verwendet wird, muss das readNotification Flag auf EventQueueFlagBits::EVENTS_READ gesetzt werden, das vom Framework gesetzt wird, wenn es Ereignisse aus dem Event FMQ liest. Das Schreibbenachrichtigungsflag muss auf EventQueueFlagBits::READ_AND_PROCESS gesetzt werden, wodurch das Framework benachrichtigt wird, dass Ereignisse in den Event FMQ geschrieben wurden.

WAKE_UP-Ereignisse

WAKE_UP Ereignisse sind Sensorereignisse, die dazu führen, dass der Anwendungsprozessor (AP) aufwacht und das Ereignis sofort verarbeitet. Immer wenn ein WAKE_UP Ereignis in die Ereignis-FMQ geschrieben wird, muss die Sensor-HAL eine Wecksperre sichern, um sicherzustellen, dass das System wach bleibt, bis das Framework das Ereignis verarbeiten kann. Beim Empfang eines WAKE_UP Ereignisses sichert das Framework seine eigene Wake-Sperre, sodass die Sensor-HAL ihre Wake-Sperre freigeben kann. Um zu synchronisieren, wann die Sensor-HAL ihre Wake-Lock-Funktion aufhebt, verwenden Sie die Wake-Lock-FMQ.

Die Sensor-HAL muss die Wake-Lock-FMQ lesen, um die Anzahl der WAKE_UP Ereignisse zu ermitteln, die das Framework verarbeitet hat. Die HAL sollte ihre Wecksperre für WAKE_UP Ereignisse nur dann freigeben, wenn die Gesamtzahl der nicht behandelten WAKE_UP Ereignisse Null ist. Nach der Verarbeitung von Sensorereignissen zählt das Framework die Anzahl der Ereignisse, die als WAKE_UP Ereignisse markiert sind, und schreibt diese Zahl zurück in die Wake Lock FMQ.

Das Framework legt die Schreibbenachrichtigung WakeLockQueueFlagBits::DATA_WRITTEN auf dem Wake Lock FMQ fest, wann immer es Daten in den Wake Lock FMQ schreibt.

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 angeschlossen ist, muss die Funktion onDynamicSensorConnected in ISensorsCallback von der Sensor-HAL aufgerufen werden. Dies benachrichtigt das Framework über den neuen dynamischen Sensor und ermöglicht die Steuerung des Sensors über das Framework und die Nutzung der Sensorereignisse durch Clients.

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

Direkter Kanal

Direkter Kanal ist eine Betriebsmethode, bei der Sensorereignisse unter Umgehung des Android Sensors Framework in einen bestimmten Speicher statt in den Event FMQ geschrieben werden. Ein Client, der einen direkten Kanal registriert, muss die Sensorereignisse direkt aus dem Speicher lesen, der zum Erstellen des direkten Kanals verwendet wurde, und empfängt die Sensorereignisse nicht über das Framework. Die Funktion configDirectReport() ähnelt batch() für den Normalbetrieb und konfiguriert den direkten Berichtskanal.

Die Funktionen registerDirectChannel() und unregisterDirectChannel() erstellen oder zerstören einen neuen direkten Kanal.

Betriebsarten

Mit der Funktion setOperationMode() kann das Framework einen Sensor so konfigurieren, dass das Framework Sensordaten in den Sensor einspeisen kann. Dies ist zum Testen nützlich, insbesondere für Algorithmen, die unterhalb des Frameworks vorhanden sind.

Die Funktion injectSensorData() in HAL 2.0 und die Funktion injectSensorsData_2_1() in HAL 2.0 werden normalerweise verwendet, um Betriebsparameter in die Sensor-HAL zu übertragen. Die Funktion kann auch verwendet werden, um Sensorereignisse in einen bestimmten Sensor einzuspeisen.

Validierung

Um Ihre Implementierung des Sensors HAL zu validieren, führen Sie die Sensor-CTS- und VTS-Tests aus.

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 in cts/tests/sensor/src/android/hardware/cts . Diese Tests überprüfen die Standardfunktionalität von Sensoren, wie z. B. die Aktivierung von Sensoren, die Stapelverarbeitung und die Sensorereignisraten.

Die CTS Verifier-Tests befinden sich in cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors . Diese Tests erfordern eine manuelle Eingabe durch den Prüfer und stellen sicher, dass die Sensoren genaue Werte melden.

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 Sensoren HAL 2.0 befinden sich in hardware/interfaces/sensors/2.0/vts . VTS-Tests für Sensoren HAL 2.1 befinden sich in hardware/interfaces/sensors/2.1/vts . Diese Tests stellen sicher, dass die Sensors HAL ordnungsgemäß implementiert wird und alle Anforderungen in ISensors.hal und ISensorsCallback.hal ordnungsgemäß erfüllt werden.

Upgrade auf Sensoren HAL 2.1 von 2.0

Wenn Sie von 2.0 auf Sensors HAL 2.1 aktualisieren, muss Ihre HAL-Implementierung die Methoden initialize_2_1() , getSensorsList_2_1() und injectSensorsData_2_1() zusammen mit den HAL 2.1-Typen enthalten. Diese Methoden müssen die gleichen Anforderungen erfüllen, die oben für HAL 2.0 beschrieben wurden.

Da Nebenversions-HALs alle Funktionen früherer HALs unterstützen müssen, müssen 2.1-HALs die Initialisierung als 2.0-HALs unterstützen. 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 Ihres eigenen Sensors 2.1 HAL finden Sie unter Sensors.h .

Upgrade auf Sensoren HAL 2.0 von 1.0

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

Initialisieren Sie die HAL

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

Verfügbare Sensoren freilegen

In Sensors HAL 2.0 muss die Funktion getSensorsList() während eines einzelnen Gerätestarts denselben Wert zurückgeben, auch über mehrere Sensors HAL-Neustarts hinweg. Eine neue Anforderung an die Funktion getSensorsList() besteht darin, dass sie während eines einzelnen Gerätestarts denselben Wert zurückgeben muss, auch über mehrere Sensor-HAL-Neustarts hinweg. Dadurch kann das Framework versuchen, Sensorverbindungen wiederherzustellen, wenn der Systemserver neu startet. Der von getSensorsList() zurückgegebene Wert kann sich ändern, nachdem das Gerät einen Neustart durchführt.

Schreiben Sie Sensorereignisse in den FMQ

Anstatt auf den Aufruf von poll() zu warten, muss der Sensors HAL in Sensors HAL 2.0 proaktiv Sensorereignisse in die Event FMQ schreiben, wann immer Sensorereignisse verfügbar sind. Der HAL ist auch dafür verantwortlich, die richtigen Bits in EventFlag zu schreiben, um einen FMQ-Lesevorgang innerhalb des Frameworks zu veranlassen.

WAKE_UP-Ereignisse

In Sensors HAL 1.0 konnte die HAL ihre Wake-Sperre für jedes WAKE_UP Ereignis bei jedem nachfolgenden Aufruf von poll() freigeben, nachdem ein WAKE_UP an poll() gesendet wurde, da dies anzeigte, dass das Framework alle Sensorereignisse verarbeitet und ein erhalten hatte Wakelock, ggf. Da der HAL in Sensors HAL 2.0 nicht mehr weiß, wann das Framework in den FMQ geschriebene Ereignisse verarbeitet hat, ermöglicht der Wake Lock FMQ dem Framework, mit dem HAL zu kommunizieren, wenn es WAKE_UP Ereignisse verarbeitet hat.

In Sensors HAL 2.0 muss die durch die Sensors HAL für WAKE_UP Ereignisse gesicherte Wecksperre mit SensorsHAL_WAKEUP beginnen.

Dynamische Sensoren

Dynamische Sensoren wurden mit der Funktion poll() in Sensors HAL 1.0 zurückgegeben. Sensoren HAL 2.0 erfordert, dass onDynamicSensorsConnected und onDynamicSensorsDisconnected in ISensorsCallback immer dann aufgerufen werden, wenn sich dynamische Sensorverbindungen ändern. Diese Rückrufe sind als Teil des ISensorsCallback -Zeigers verfügbar, der über die Funktion initialize() bereitgestellt wird.

Betriebsarten

Der DATA_INJECTION Modus für WAKE_UP Sensoren muss in Sensors HAL 2.0 unterstützt werden.

Multi-HAL-Unterstützung

Sensors HAL 2.0 und 2.1 unterstützen Multi-HAL mithilfe des Sensors Multi-HAL-Frameworks . Einzelheiten zur Implementierung finden Sie unter Portierung von Sensoren HAL 1.0 .