Sensori HAL 2.0

L'HAL (Hardware Abstraction Layer) dei sensori è l'interfaccia tra il framework dei sensori Android e i sensori di un dispositivo, come un accelerometro o un giroscopio. L'HAL dei sensori definisce le funzioni che devono essere implementate per consentire al framework di controllare i sensori.

L'HAL dei sensori 2.0 è disponibile in Android 10 e versioni successive per i dispositivi nuovi e aggiornati. L'HAL dei sensori 2.0 si basa su Sensors HAL 1.0, ma presenta diverse differenze fondamentali che ne impediscono la retrocompatibilità. L'HAL dei sensori 2.0 utilizza le FMQ (Fast Message Queues) per inviare gli eventi dei sensori dall'HAL al framework dei sensori Android.

L'HAL dei sensori 2.1 è disponibile in Android 11 e versioni successive per i dispositivi nuovi e aggiornati. L'HAL dei sensori 2.1 è un'iterazione dell'HAL dei sensori 2.0 che espone il HINGE_ANGLE tipo di sensore e aggiorna vari metodi per accettare il HINGE_ANGLE tipo.

Interfaccia HAL 2.1

La fonte principale di documentazione per l'HAL dei sensori 2.1 si trova nella definizione HAL in hardware/interfaces/sensors/2.1/ISensors.hal. In caso di conflitto di requisiti tra questa pagina e ISensors.hal, utilizza il requisito in ISensors.hal.

Interfaccia HAL 2.0

La fonte principale di documentazione per l'HAL dei sensori 2.0 si trova nella definizione HAL in hardware/interfaces/sensors/2.0/ISensors.hal. In caso di conflitto di requisiti tra questa pagina e ISensors.hal, utilizza il requisito in ISensors.hal.

Implementare l'HAL dei sensori 2.0 e 2.1

Per implementare l'HAL dei sensori 2.0 o 2.1, un oggetto deve estendere l'ISensors interfaccia e implementare tutte le funzioni definite in 2.0/ISensors.hal o 2.1/ISensors.hal.

Inizializzare l'HAL

L'HAL dei sensori deve essere inizializzato dal framework dei sensori Android prima di poter essere utilizzato. Il framework chiama la funzione initialize() per l'HAL 2.0 e la funzione initialize_2_1() per l'HAL 2.1 per fornire tre parametri all'HAL dei sensori: due descrittori FMQ e un puntatore a un oggetto ISensorsCallback.

L'HAL utilizza il primo descrittore per creare l'FMQ eventi utilizzato per scrivere gli eventi dei sensori nel framework. L'HAL utilizza il secondo descrittore per creare l'FMQ di wakelock utilizzato per sincronizzare il momento in cui l'HAL rilascia il wakelock per gli eventi dei sensori WAKE_UP. L'HAL deve salvare un puntatore all'oggetto ISensorsCallback in modo che possano essere richiamate le funzioni di callback necessarie.

La funzione initialize() o initialize_2_1() deve essere la prima funzione chiamata durante l'inizializzazione dell'HAL dei sensori.

Esporre i sensori disponibili

Per ottenere un elenco di tutti i sensori statici disponibili sul dispositivo, utilizza la funzione getSensorsList() sull'HAL 2.0 e la funzione getSensorsList_2_1() sull'HAL 2.1. Questa funzione restituisce un elenco di sensori, ognuno identificato in modo univoco dal proprio handle. L'handle di un determinato sensore non deve cambiare quando il processo che ospita l'HAL dei sensori viene riavviato. Gli handle possono cambiare in caso di riavvio del dispositivo e del server di sistema.

Se più sensori condividono lo stesso tipo di sensore e la stessa proprietà di riattivazione, il primo sensore dell'elenco viene chiamato sensore predefinito e viene restituito alle app che utilizzano la funzione getDefaultSensor(int sensorType, bool wakeUp).

Stabilità dell'elenco dei sensori

Dopo il riavvio dell'HAL dei sensori, se i dati restituiti da getSensorsList() o getSensorsList_2_1() indicano una modifica significativa rispetto all'elenco dei sensori recuperato prima del riavvio, il framework attiva il riavvio del runtime Android. Le modifiche significative all'elenco dei sensori includono i casi in cui manca un sensore con un determinato handle o i relativi attributi sono stati modificati oppure sono stati introdotti nuovi sensori. Sebbene il riavvio del runtime Android sia dirompente per l'utente, è necessario perché il framework Android non può più rispettare il contratto dell'API Android secondo cui i sensori statici (non dinamici) non cambiano durante il ciclo di vita di un'app. Ciò potrebbe anche impedire al framework di ristabilire le richieste di sensori attivi effettuate dalle app. Pertanto, i fornitori di HAL sono invitati a evitare modifiche evitabili all'elenco dei sensori.

Per garantire handle dei sensori stabili, l'HAL deve mappare in modo deterministico un determinato sensore fisico del dispositivo al relativo handle. Sebbene l'interfaccia HAL dei sensori non imponga un'implementazione specifica, gli sviluppatori hanno a disposizione diverse opzioni per soddisfare questo requisito.

Ad esempio, l'elenco dei sensori può essere ordinato utilizzando una combinazione degli attributi fissi di ogni sensore, come fornitore, modello e tipo di sensore. Un'altra opzione si basa sul fatto che l'insieme di sensori statici del dispositivo è fisso nell'hardware, quindi l'HAL deve sapere quando tutti i sensori previsti hanno completato l'inizializzazione prima di restituire da getSensorsList() o getSensorsList_2_1(). Questo elenco di sensori previsti può essere compilato nel file binario HAL o memorizzato in un file di configurazione nel file system e l'ordine di visualizzazione può essere utilizzato per derivare handle stabili. Sebbene la soluzione migliore dipenda dai dettagli di implementazione specifici dell'HAL, il requisito fondamentale è che gli handle dei sensori non cambino in caso di riavvio dell'HAL.

Configurare i sensori

Prima di attivare un sensore, è necessario configurarlo con un periodo di campionamento e una latenza di reporting massima utilizzando la funzione batch().

Un sensore deve poter essere riconfigurato in qualsiasi momento utilizzando batch() senza perdita di dati dei sensori.

Periodo di campionamento

Il periodo di campionamento ha un significato diverso a seconda del tipo di sensore configurato:

  • Continuo: gli eventi dei sensori vengono generati a una velocità continua.
  • Al cambio: gli eventi vengono generati a una velocità non superiore al periodo di campionamento e possono essere generati a una velocità inferiore al periodo di campionamento se il valore misurato non cambia.
  • Una tantum: il periodo di campionamento viene ignorato.
  • Speciale: per maggiori dettagli, vedi Tipi di sensori.

Per scoprire di più sull'interazione tra un periodo di campionamento e le modalità di reporting di un sensore, vedi Modalità di reporting.

Latenza di reporting massima

La latenza di reporting massima imposta il tempo massimo in nanosecondi in cui gli eventi possono essere ritardati e memorizzati nella FIFO hardware prima di essere scritti nell'FMQ eventi tramite l'HAL mentre il SoC è attivo.

Un valore pari a zero indica che gli eventi devono essere segnalati non appena vengono misurati, saltando completamente la FIFO o svuotando la FIFO non appena è presente un evento del sensore nella FIFO.

Ad esempio, un accelerometro attivato a 50 Hz con una latenza di reporting massima pari a zero attiva interruzioni 50 volte al secondo quando il SoC è attivo.

Quando la latenza di reporting massima è maggiore di zero, gli eventi dei sensori non devono essere segnalati non appena vengono rilevati. Gli eventi possono essere memorizzati temporaneamente nella FIFO hardware e segnalati in batch, purché nessun evento venga ritardato di più della latenza di reporting massima. Tutti gli eventi dall'ultimo batch vengono registrati e restituiti contemporaneamente. In questo modo si riduce il numero di interruzioni inviate al SoC e si consente al SoC di passare a una modalità di risparmio energetico mentre il sensore acquisisce e raggruppa i dati.

A ogni evento è associato un timestamp. Il ritardo dell'ora in cui viene segnalato un evento non deve influire sul timestamp dell'evento. Il timestamp deve essere preciso e corrispondere all'ora in cui l'evento si è verificato fisicamente, non all'ora in cui è stato segnalato.

Per ulteriori informazioni e requisiti sulla segnalazione degli eventi dei sensori con latenza di reporting massima diversa da zero, vedi Batch.

Attivare i sensori

Il framework attiva e disattiva i sensori utilizzando la funzione activate(). Prima di attivare un sensore, il framework deve prima configurarlo utilizzando batch().

Dopo la disattivazione di un sensore, non è necessario scrivere ulteriori eventi dei sensori da quel sensore nell'FMQ eventi.

Svuotare i sensori

Se un sensore è configurato per raggruppare i dati, il framework può forzare uno svuotamento immediato degli eventi dei sensori raggruppati chiamando flush(). In questo modo, gli eventi dei sensori raggruppati per l'handle del sensore specificato vengono scritti immediatamente nell'FMQ eventi. L'HAL dei sensori deve aggiungere un evento di completamento dello svuotamento alla fine degli eventi dei sensori scritti in seguito a una chiamata a flush().

Lo svuotamento avviene in modo asincrono, ovvero questa funzione deve essere restituita immediatamente. Se l'implementazione utilizza una singola FIFO per più sensori, la FIFO viene svuotata e l'evento di completamento dello svuotamento viene aggiunto solo per il sensore specificato.

Se il sensore specificato non ha una FIFO (nessun buffering possibile) o se la FIFO era vuota al momento della chiamata, flush() deve comunque riuscire e inviare un evento di completamento dello svuotamento per quel sensore. Questo vale per tutti i sensori tranne i sensori una tantum.

Se flush() viene chiamato per un sensore una tantum, flush() deve restituire BAD_VALUE e non generare un evento di completamento dello svuotamento.

Scrivere gli eventi dei sensori nell'FMQ

L'FMQ eventi viene utilizzato dall'HAL dei sensori per inserire gli eventi dei sensori nel framework dei sensori Android.

L'FMQ eventi è un FMQ sincronizzato, il che significa che qualsiasi tentativo di scrivere più eventi nell'FMQ rispetto allo spazio disponibile comporta una scrittura non riuscita. In questo caso, l'HAL deve determinare se scrivere l'insieme corrente di eventi come due gruppi di eventi più piccoli o scrivere tutti gli eventi insieme quando è disponibile spazio sufficiente.

Quando l'HAL dei sensori ha scritto il numero desiderato di eventi dei sensori nell'FMQ eventi, deve notificare al framework che gli eventi sono pronti scrivendo il bit EventQueueFlagBits::READ_AND_PROCESS nella funzione EventFlag::wake dell'FMQ eventi. L'EventFlag può essere creato dall'FMQ eventi utilizzando EventFlag::createEventFlag e la funzione getEventFlagWord() dell'FMQ eventi.

L'HAL dei sensori 2.0/2.1 supporta sia write sia writeBlocking sull'FMQ eventi. L'implementazione predefinita fornisce un riferimento per l'utilizzo di write. Se viene utilizzata la funzione writeBlocking, il flag readNotification deve essere impostato su EventQueueFlagBits::EVENTS_READ, che viene impostato dal framework quando legge gli eventi dall'FMQ eventi. Il flag di notifica di scrittura deve essere impostato su EventQueueFlagBits::READ_AND_PROCESS, che notifica al framework che gli eventi sono stati scritti nell'FMQ eventi.

Eventi WAKE_UP

Gli eventi WAKE_UP sono eventi dei sensori che causano la riattivazione del processore dell'applicazione (AP) e la gestione immediata dell'evento. Ogni volta che un evento WAKE_UP viene scritto nell'FMQ eventi, l'HAL dei sensori deve acquisire un wakelock per garantire che il sistema rimanga attivo finché il framework non è in grado di gestire l'evento. Dopo aver ricevuto un evento WAKE_UP, il framework protegge il proprio wakelock, consentendo all'HAL dei sensori di rilasciare il proprio wakelock. Per sincronizzare il momento in cui l'HAL dei sensori rilascia il wakelock, utilizza l'FMQ di wakelock.

L'HAL dei sensori deve leggere l'FMQ di blocco di riattivazione per determinare il numero di eventi WAKE_UP gestiti dal framework. L'HAL deve rilasciare il wakelock per gli eventi WAKE_UP solo se il numero totale di eventi WAKE_UP non gestiti è zero. Dopo aver gestito gli eventi dei sensori, il framework conta il numero di eventi contrassegnati come eventi WAKE_UP e scrive questo numero nell'FMQ di blocco di riattivazione.

Il framework imposta la notifica di scrittura WakeLockQueueFlagBits::DATA_WRITTEN sull'FMQ di blocco di riattivazione ogni volta che scrive dati nell'FMQ di blocco di riattivazione.

Sensori dinamici

I sensori dinamici sono sensori che non fanno fisicamente parte del dispositivo, ma possono essere utilizzati come input per il dispositivo, ad esempio un gamepad con un accelerometro.

Quando viene collegato un sensore dinamico, è necessario chiamare la funzione onDynamicSensorConnected in ISensorsCallback dall'HAL dei sensori. In questo modo il framework viene informato del nuovo sensore dinamico e il sensore può essere controllato tramite il framework e gli eventi del sensore possono essere utilizzati dai client.

Allo stesso modo, quando un sensore dinamico viene scollegato, è necessario chiamare la funzione onDynamicSensorDisconnected in ISensorsCallback in modo che il framework possa rimuovere qualsiasi sensore non più disponibile.

Canale diretto

Il canale diretto è una modalità di funzionamento in cui gli eventi dei sensori vengono scritti in una memoria specifica anziché nell'FMQ eventi, bypassando il framework dei sensori Android. Un client che registra un canale diretto deve leggere gli eventi dei sensori direttamente dalla memoria utilizzata per creare il canale diretto e non riceverà gli eventi dei sensori tramite il framework. La funzione configDirectReport() è simile a batch() per il funzionamento normale e configura il canale di report diretto.

Le funzioni registerDirectChannel() e unregisterDirectChannel() creano o eliminano un nuovo canale diretto.

Modalità operative

La funzione setOperationMode() consente al framework di configurare un sensore in modo che possa inserire i dati dei sensori nel sensore. Questa funzionalità è utile per i test, in particolare per gli algoritmi che si trovano sotto il framework.

La funzione injectSensorData() nell'HAL 2.0 e la funzione injectSensorsData_2_1() nell'HAL 2.0 vengono normalmente utilizzate per inserire i parametri operativi nell'HAL dei sensori. La funzione può essere utilizzata anche per inserire eventi dei sensori in un sensore specifico.

Convalida

Per convalidare l'implementazione dell'HAL dei sensori, esegui i test CTS e VTS dei sensori.

Test CTS

I test CTS dei sensori sono presenti sia nei test CTS automatici sia nell'app manuale CTS Verifier.

I test automatici si trovano in cts/tests/sensor/src/android/hardware/cts. Questi test verificano la funzionalità standard dei sensori, come l'attivazione dei sensori, il raggruppamento e le frequenze degli eventi dei sensori.

I test CTS Verifier si trovano in cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors. Questi test richiedono l'input manuale dell'operatore di test e garantiscono che i sensori segnalino valori precisi.

Il superamento dei test CTS è fondamentale per garantire che il dispositivo in fase di test soddisfi tutti i requisiti CDD.

Test VTS

I test VTS per l'HAL dei sensori 2.0 si trovano in hardware/interfaces/sensors/2.0/vts. I test VTS per l'HAL dei sensori 2.1 si trovano in hardware/interfaces/sensors/2.1/vts. Questi test garantiscono che l'HAL dei sensori sia implementato correttamente e che tutti i requisiti in ISensors.hal e ISensorsCallback.hal siano soddisfatti correttamente.

Eseguire l'upgrade all'HAL dei sensori 2.1 dalla versione 2.0

Quando esegui l'upgrade all'HAL dei sensori 2.1 dalla versione 2.0, l'implementazione dell'HAL deve includere i metodi initialize_2_1(), getSensorsList_2_1() e injectSensorsData_2_1(), insieme ai tipi HAL 2.1. Questi metodi devono soddisfare gli stessi requisiti descritti sopra per l'HAL 2.0.

Poiché gli HAL delle versioni secondarie devono supportare tutte le funzioni degli HAL precedenti, gli HAL 2.1 devono supportare l'inizializzazione come HAL 2.0. Per evitare la complessità del supporto di entrambe le versioni HAL, è vivamente consigliato di utilizzare Multi-HAL 2.1.

Per un esempio di come implementare il tuo HAL dei sensori 2.1, vedi Sensors.h.

Eseguire l'upgrade all'HAL dei sensori 2.0 dalla versione 1.0

Quando esegui l'upgrade all'HAL dei sensori 2.0 dalla versione 1.0, assicurati che l'implementazione dell'HAL soddisfi i seguenti requisiti.

Inizializzare l'HAL

La funzione initialize() deve essere supportata per stabilire le FMQ tra il framework e l'HAL.

Esporre i sensori disponibili

Nell'HAL dei sensori 2.0, la funzione getSensorsList() deve restituire lo stesso valore durante un singolo avvio del dispositivo, anche in caso di riavvio dell'HAL dei sensori. Un nuovo requisito della funzione getSensorsList() è che deve restituire lo stesso valore durante un singolo avvio del dispositivo, anche in caso di riavvio dell'HAL dei sensori. In questo modo, il framework può tentare di ristabilire le connessioni dei sensori se il server di sistema viene riavviato. Il valore restituito da getSensorsList() può cambiare dopo il riavvio del dispositivo.

Scrivere gli eventi dei sensori nell'FMQ

Anziché attendere la chiamata di poll(), nell'HAL dei sensori 2.0, l'HAL dei sensori deve scrivere in modo proattivo gli eventi dei sensori nell'FMQ eventi ogni volta che sono disponibili. L'HAL è anche responsabile della scrittura dei bit corretti in EventFlag per causare una lettura FMQ all'interno del framework.

Eventi WAKE_UP

Nell'HAL dei sensori 1.0, l'HAL era in grado di rilasciare il suo wakelock per qualsiasi evento WAKE_UP in qualsiasi chiamata successiva a poll() dopo la pubblicazione di un evento WAKE_UP in poll(), perché ciò indicava che il framework aveva elaborato tutti gli eventi dei sensori e aveva ottenuto un wakelock, se necessario. Poiché, nell'HAL dei sensori 2.0, l'HAL non sa più quando il framework ha elaborato gli eventi scritti nell'FMQ, l'FMQ di blocco di riattivazione consente al framework di comunicare all'HAL quando ha gestito gli eventi WAKE_UP.

Nell'HAL dei sensori 2.0, il wakelock protetto dall'HAL dei sensori per gli eventi WAKE_UP deve iniziare con SensorsHAL_WAKEUP.

Sensori dinamici

I sensori dinamici venivano restituiti utilizzando la funzione poll() nell'HAL dei sensori 1.0. L'HAL dei sensori 2.0 richiede che onDynamicSensorsConnected e onDynamicSensorsDisconnected in ISensorsCallback vengano chiamati ogni volta che le connessioni dei sensori dinamici cambiano. Questi callback sono disponibili come parte del puntatore ISensorsCallback fornito tramite la funzione initialize().

Modalità operative

La modalità DATA_INJECTION per i sensori WAKE_UP deve essere supportata nell'HAL dei sensori 2.0.

Supporto Multi-HAL

L'HAL dei sensori 2.0 e 2.1 supporta Multi-HAL utilizzando il framework Multi-HAL dei sensori. Per i dettagli sull'implementazione, vedi Eseguire il porting dall'HAL dei sensori 1.0.