Sensoren AIDL HAL

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.

Der Sensors AIDL HAL ist in Android 13 und höher für neue und aktualisierte Geräte verfügbar. Der Sensors AIDL HAL, der auf Sensors HAL 2.1 basiert, nutzt die AIDL HAL-Schnittstelle und stellt die Sensortypen Headtracker und Limited-Axis-IMU zur Verfügung.

AIDL HAL-Schnittstelle

Die Hauptdokumentationsquelle für die Sensors AIDL HAL ist die HAL-Definition unter hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl .

Implementieren Sie die Sensoren AIDL HAL

Um den Sensors AIDL HAL zu implementieren, muss ein Objekt die ISensors Schnittstelle erweitern und alle in hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl 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() auf, um dem Sensors HAL drei Parameter 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. Die HAL muss einen Zeiger auf das ISensorsCallback Objekt speichern, damit alle erforderlichen Rückruffunktionen aufgerufen werden können.

Die Funktion initialize() 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() . 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() zurückgegebenen Daten nach einem Sensors-HAL-Neustart eine signifikante Ä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() 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.

Der AIDL HAL des Sensors 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, um das Framework darüber zu informieren, 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 freigibt, verwenden Sie den 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, wenn Daten in den 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 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 konfigurieren, sodass 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() wird normalerweise verwendet, um Betriebsparameter in den 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 die Sensoren AIDL HAL befinden sich in hardware/interfaces/sensors/aidl/vts/ . Diese Tests stellen sicher, dass die Sensor-HAL ordnungsgemäß implementiert wird und alle Anforderungen in ISensors.aidl und ISensorsCallback.aidl ordnungsgemäß erfüllt werden.

Initialisieren Sie die HAL

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

Verfügbare Sensoren freilegen

Im Sensors AIDL HAL 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 darauf zu warten, dass poll() aufgerufen wird, muss die Sensor-HAL in der Sensor-AIDL-HAL proaktiv Sensorereignisse in die Ereignis-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 in der Sensors AIDL HAL die HAL nicht mehr benachrichtigt wird, wenn das Framework in die FMQ geschriebene Ereignisse verarbeitet hat, ermöglicht die Wake Lock FMQ dem Framework, mit der HAL zu kommunizieren, wenn es WAKE_UP Ereignisse verarbeitet hat.

Im Sensors AIDL HAL muss die durch den 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. Der Sensors AIDL HAL 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 unterstützt werden.

Multi-HAL-Unterstützung

Der Sensors AIDL HAL unterstützt Multi-HAL mithilfe des Sensors Multi-HAL-Frameworks . Einzelheiten zur Implementierung finden Sie unter Portierung von Sensoren HAL 2.1 .