L'interfaccia HAL Sensors, dichiarata in sensors.h, rappresenta l'interfaccia tra il framework Android e il software specifico per l'hardware. Un'implementazione HAL deve definire ogni funzione dichiarata in sensors.h. Le funzioni principali sono:
get_sensors_list
: restituisce l'elenco di tutti i sensori.activate
- Avvia o arresta un sensore.batch
: imposta i parametri di un sensore, ad esempio la frequenza di campionamento e la latenza massima dei report.setDelay
: utilizzata solo nella versione 1.0 dell'HAL. Imposta la frequenza di campionamento per un determinato sensore.flush
: svuota la coda FIFO del sensore specificato e genera un evento di completamento dello svuotamento al termine dell'operazione.poll
: restituisce gli eventi del sensore disponibili.
L'implementazione deve essere sicura per i thread e consentire di chiamare queste funzioni da thread diversi.
L'interfaccia definisce anche diversi tipi utilizzati da queste funzioni. I tipi principali sono:
sensors_module_t
sensors_poll_device_t
sensor_t
sensors_event_t
Oltre alle sezioni riportate di seguito, consulta sensors.h per ulteriori informazioni su questi tipi.
get_sensors_list(elenco)
int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t const** list);
Fornisce l'elenco dei sensori implementati dall'HAL. Consulta sensor_t per informazioni dettagliate su come vengono definiti i sensori.
L'ordine in cui i sensori vengono visualizzati nell'elenco è l'ordine in cui verranno segnalati alle applicazioni. In genere, i sensori di base vengono visualizzati per primi, seguiti dai sensori compositi.
Se più sensori condividono lo stesso tipo di sensore e la stessa proprietà di risveglio, il primo nell'elenco è chiamato sensore "predefinito". È quello restituito da
getDefaultSensor(int sensorType, bool wakeUp)
.
Questa funzione restituisce il numero di sensori nell'elenco.
attiva(sensore, true/false)
int (*activate)(struct sensors_poll_device_t *dev, int sensor_handle, int enabled);
Attiva o disattiva un sensore.
sensor_handle
è il manico del sensore per l'attivazione/disattivazione. L'handle di un sensore è definito dal campo handle
della sua struttura sensor_t.
Il valore enabled
è impostato su 1 per attivare o su 0 per disattivare il sensore.
I sensori una tantum si disattivano automaticamente alla ricezione di un evento e devono comunque accettare di essere disattivati tramite una chiamata a activate(...,
enabled=0)
.
I sensori non di riattivazione non impediscono mai al SoC di entrare in modalità di sospensione; in altre parole, l'HAL non deve mantenere un wakelock parziale per conto delle applicazioni.
I sensori di risveglio, quando inviano eventi continuamente, possono impedire al SoC di entrare in modalità di sospensione, ma se non è necessario inviare alcun evento, il blocco parziale del risveglio deve essere rilasciato.
Se enabled
è 1 e il sensore è già attivato, questa funzione è autonoma e riesce.
Se enabled
è 0 e il sensore è già disattivato, questa funzione è autonoma e riesce.
Questa funzione restituisce 0 in caso di esito positivo e un numero di errore negativo in caso contrario.
batch(sensor, flags, sampling period, maximum report latency)
int (*batch)( struct sensors_poll_device_1* dev, int sensor_handle, int flags, int64_t sampling_period_ns, int64_t max_report_latency_ns);
Imposta i parametri di un sensore, tra cui la frequenza di campionamento e la latenza massima dei report. Questa funzione può essere chiamata quando il sensore è attivato, nel qual caso non deve causare la perdita di misurazioni del sensore: il passaggio da una frequenza di campionamento all'altra non può causare la perdita di eventi, né il passaggio da una latenza massima del report elevata a una minima.
sensor_handle
è il punto di manipolazione del sensore da configurare.
flags
al momento non è utilizzato.
sampling_period_ns
è il periodo di campionamento a cui deve funzionare il sensore, in nanosecondi. Per maggiori dettagli, consulta sampling_period_ns.
max_report_latency_ns
è il tempo massimo di ritardo degli eventi prima che vengano registrati tramite l'HAL, in nanosecondi. Per ulteriori dettagli, consulta il paragrafo max_report_latency_ns.
Questa funzione restituisce 0 in caso di esito positivo, mentre in caso contrario restituisce un numero di errore negativo.
setDelay(sensore, periodo di campionamento)
int (*setDelay)( struct sensors_poll_device_t *dev, int sensor_handle, int64_t sampling_period_ns);
Dopo la versione 1.0 dell'HAL, questa funzione è deprecata e non viene mai chiamata.
Viene invece chiamata la funzione batch
per impostare il parametro sampling_period_ns
.
Nella versione 1.0 di HAL, veniva utilizzato setDelay anziché batch per impostare sampling_period_ns.
flush(sensor)
int (*flush)(struct sensors_poll_device_1* dev, int sensor_handle);
Aggiungi un evento di aggiornamento completo alla fine della coda FIFO hardware per il sensore specificato ed esegui l'aggiornamento della coda FIFO. Questi eventi vengono inviati come di consueto (ovvero come se la latenza massima dei report fosse scaduta) e rimossi dalla coda FIFO.
Lo svuotamento avviene in modo asincrono (ovvero questa funzione deve restituire immediatamente). Se l'implementazione utilizza una singola coda FIFO per più sensori, la coda viene svuotata e l'evento di completamento dello svuotamento viene aggiunto solo per il sensore specificato.
Se il sensore specificato non ha un FIFO (nessun buffering possibile) o se il FIFO era vuoto al momento della chiamata, flush
deve comunque riuscire e inviare un evento di svuotamento completo per quel sensore. Questo vale per tutti i sensori diversi da quelli one-shot.
Quando viene chiamato flush
, anche se un evento di svuotamento è già presente nella FIFO per quel sensore, deve essere creato e aggiunto un altro evento alla fine della FIFO, che deve essere svuotata. Il numero di chiamate flush
deve essere uguale al numero di eventi di aggiornamento completo creati.
flush
non si applica ai sensori una tantum. Se sensor_handle
si riferisce a un sensore una tantum, flush
deve restituire -EINVAL
e non generare alcun evento di aggiornamento completo dei metadati.
Questa funzione restituisce 0 in caso di esito positivo, -EINVAL
se il sensore specificato è un
sensore one-shot o non è stato abilitato, e un numero di errore negativo negli altri casi.
poll()
int (*poll)(struct sensors_poll_device_t *dev, sensors_event_t* data, int count);
Restituisce un array di dati del sensore compilando l'argomento data
. Questa funzione deve bloccare fino a quando gli eventi non sono disponibili. Restituisce il numero di eventi letti
in caso di esito positivo o un numero di errore negativo in caso di errore.
Il numero di eventi restituiti in data
deve essere minore o uguale all'argomento count
. Questa funzione non deve mai restituire 0 (nessun evento).
Sequenza di chiamate
Quando il dispositivo si avvia, viene chiamato get_sensors_list
.
Quando un sensore viene attivato, la funzione batch
viene chiamata con i parametri richiesti, seguita da activate(..., enable=1)
.
Tieni presente che nella versione 1_0 dell'HAL l'ordine era il contrario: activate
è stato chiamato per primo, seguito da set_delay
.
Quando le caratteristiche richieste di un sensore cambiano mentre è
attivato, viene chiamata la funzione batch
.
flush
può essere chiamato in qualsiasi momento, anche su sensori non attivati (in questo caso deve restituire -EINVAL
)
Quando un sensore viene disattivato, viene chiamato activate(..., enable=0)
.
In parallelo a queste chiamate, la funzione poll
verrà chiamata ripetutamente per richiedere i dati. poll
può essere chiamato anche quando non sono attivi sensori.
sensors_module_t
sensors_module_t
è il tipo utilizzato per creare il modulo hardware Android per i sensori. L'implementazione dell'HAL deve definire un oggetto
HAL_MODULE_INFO_SYM
di questo tipo per esporre la funzione get_sensors_list. Per ulteriori informazioni, consulta la definizione di sensors_module_t
in sensors.h e la definizione di hw_module_t
.
sensor_poll_device_t / sensori_poll_device_1_t
sensors_poll_device_1_t
contiene i restanti metodi definiti sopra:
activate
, batch
, flush
e
poll
. Il campo common
(di tipo hw_device_t)
definisce il numero di versione dell'HAL.
sensor_t
sensor_t
rappresenta un sensore
Android. Ecco alcuni dei suoi campi importanti:
name: una stringa visibile all'utente che rappresenta il sensore. Spesso questa stringa contiene il nome della parte del sensore sottostante, il tipo di sensore e se si tratta di un sensore di attivazione. Ad esempio, "LIS2HH12 Accelerometer", "MAX21000 Uncalibrated Gyroscope", "BMP280 Wake-up Barometer", "MPU6515 Game Rotation Vector"
handle: il numero intero utilizzato per fare riferimento al sensore quando ti registri o generi eventi dal sensore.
type: il tipo di sensore. Per ulteriori dettagli, consulta la spiegazione del tipo di sensore in Che cosa sono i sensori Android? e la sezione Tipi di sensori per i tipi di sensori ufficiali. Per i tipi di sensori non ufficiali, type
deve iniziare con SENSOR_TYPE_DEVICE_PRIVATE_BASE
stringType: il tipo di sensore come stringa. Se il sensore ha un tipo ufficiale, impostalo su SENSOR_STRING_TYPE_*
. Quando il sensore ha un tipo specifico del produttore, stringType
deve iniziare con il nome di dominio inverso del produttore. Ad esempio, un sensore (ad esempio un
rilevatore unicorno) definito dal team di Cool-product di
Narrativaal-Company potrebbe utilizzare
stringType=”com.fictional_company.cool_product.unicorn_detector”
.
stringType
viene utilizzato per identificare in modo univoco i tipi di sensori non ufficiali. Per ulteriori informazioni sui tipi e sui tipi di stringa, consulta sensors.h.
requiredPermission: una stringa che rappresenta l'autorizzazione
che le applicazioni devono disporre per vedere il sensore, registrarsi e ricevere
i relativi dati. Una stringa vuota indica che le applicazioni non richiedono alcuna autorizzazione per accedere a questo sensore. Alcuni tipi di sensori, come il rilevatore del battito cardiaco, hanno un requiredPermission
obbligatorio. Tutti i sensori che forniscono informazioni sensibili dell'utente (come la frequenza cardiaca) devono essere protetti da un'autorizzazione.
flag: segnalazioni per questo sensore, che definiscono la modalità di segnalazione del sensore e se il sensore è un sensore di riattivazione o meno. Ad esempio, un sensore di attivazione one-shot
avrà flags = SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP
. I bit del flag non utilizzati nella versione HAL corrente devono essere lasciati uguali a 0.
maxRange: il valore massimo che il sensore può segnalare, nella stessa unità dei valori registrati. Il sensore deve essere in grado di registrare valori senza saturare
entro [-maxRange; maxRange]
. Tieni presente che questo significa che l'intervallo totale del
sensore in senso generico è 2*maxRange
. Quando il sensore registra valori su più assi, l'intervallo si applica a ciascun asse. Ad esempio, un accelerometro "+/- 2 g" registrerà maxRange = 2*9.81 = 2g
.
risoluzione:la differenza minima di valore che il sensore è in grado di misurare.
In genere viene calcolato in base a maxRange
e al numero di bit nella misurazione.
power (alimentazione): il costo dell'alimentazione per l'attivazione del sensore, espresso in milliA.
Questo valore è quasi sempre superiore al consumo di energia indicato nella scheda tecnica del sensore sottostante. Per ulteriori dettagli, consulta la sezione Sensori di base != sensori fisici e la sezione Procedura di misurazione della potenza per informazioni su come misurare il consumo di energia di un sensore.
Se il consumo energetico del sensore dipende dal fatto che il dispositivo sia in movimento, il consumo durante il movimento è quello riportato nel campo power
.
minDelay: per i sensori continui, il periodo di campionamento, in microsecondi, corrispondente alla frequenza più veloce supportata dal sensore. Consulta sampling_period_ns per dettagli su come viene utilizzato questo valore. Tieni presente che minDelay
è expressed in microseconds mentre sampling_period_ns
è in
nanoseconds. Per i sensori con modalità di generazione di report speciali e al cambio, se non diversamente specificato, minDelay
deve essere 0. Per i sensori una tantum, deve essere -1.
maxDelay: per i sensori continui e con variazioni, il periodo di campionamento in microsecondi corrispondente alla frequenza più lenta supportata dal sensore. Consulta sampling_period_ns per dettagli su come viene utilizzato questo valore. Tieni presente che maxDelay
è expressed in microseconds mentre sampling_period_ns
è in
nanoseconds. Per i sensori speciali e una tantum, maxDelay
deve essere equale a 0.
fifoReservedEventCount: il numero di eventi riservati per questo sensore nella FIFO hardware. Se è presente un FIFO dedicato per questo sensore, le dimensioni di questo sensore FIFO sono fifoReservedEventCount
. Se la coda FIFO è condivisa con altri sensori, fifoReservedEventCount
è la dimensione della parte della coda FIFO riservata a quel sensore. Nella maggior parte dei sistemi FIFO condivisi e su quelli che non hanno un FIFO hardware questo valore è 0.
fifoMaxEventCount: il numero massimo di eventi che possono essere memorizzati nelle code FIFO per questo sensore. Questo valore è sempre maggiore o uguale a
fifoReservedEventCount
. Questo valore viene utilizzato per stimare la rapidità con cui la coda FIFO si riempie quando la registrazione al sensore avviene a una frequenza specifica, supponendo che non siano attivati altri sensori. Sui sistemi che non dispongono di una FIFO hardware, fifoMaxEventCount
è 0. Per ulteriori dettagli, consulta Raggruppamento in batch.
Per i sensori con un tipo di sensore ufficiale, alcuni campi vengono sovrascritti
dal framework. Ad esempio, i sensori di accelerometro devono avere obbligatoriamente una modalità di generazione di report continua e i monitor della frequenza cardiaca devono essere obbligatoriamente protetti dall'autorizzazione SENSOR_PERMISSION_BODY_SENSORS
.
evento_t_sensori
Gli eventi dei sensori generati dai sensori Android e segnalati tramite la funzione poll sono di tipo type sensors_event_t
. Ecco alcuni
campi importanti di sensors_event_t
:
version: deve essere sizeof(struct sensors_event_t)
sensor: l'handle del sensore che ha generato l'evento, come definito da
sensor_t.handle
.
type: il tipo di sensore che ha generato l'evento, come definito da
sensor_t.type
.
timestamp: il timestamp dell'evento in nanosecondi. Si tratta dell'ora in cui si è verificato l'evento (è stato fatto un passo o è stata eseguita una misurazione dell'accelerometro), non dell'ora in cui è stato registrato. timestamp
deve essere sincronizzato con il clock elapsedRealtimeNano
e, nel caso di sensori continui, il jitter deve essere ridotto. A volte il filtro dei timestamp è necessario per soddisfare i requisiti
CDD, poiché utilizzare solo il tempo di interruzione del SoC per impostare i timestamp
causa un jitter troppo elevato, mentre utilizzare solo il tempo del chip del sensore per impostare i
timestamp può causare la desincronizzazione dall'orologio
elapsedRealtimeNano
, mentre l'orologio del sensore cambia.
Dati e campi sovrapposti: i valori misurati dal sensore. Il significato e le unità di questi campi sono specifici per ogni tipo di sensore. Per una descrizione dei campi di dati, consulta sensors.h e la definizione dei diversi tipi di sensori. Per alcuni sensori, l'accuratezza delle letture viene riportata anche come parte dei dati, tramite un campo status
. Questo campo viene comunicato solo per i tipi di sensori selezionati e visualizzato a livello di SDK come valore di accuratezza. Per questi sensori, il fatto che il campo dello stato debba essere impostato è indicato nella definizione del tipo di sensore.
Eventi completati per lo svuotamento dei metadati
Gli eventi dei metadati hanno lo stesso tipo dei normali eventi del sensore:
sensors_event_meta_data_t = sensors_event_t
. Vengono restituiti insieme ad altri eventi del sensore tramite il sondaggio. Sono presenti i seguenti campi:
version: deve essere META_DATA_VERSION
type: deve essere SENSOR_TYPE_META_DATA
sensore, riservato e timestamp: deve essere 0
meta_data.what: contiene il tipo di metadati per questo evento. Al momento è disponibile un singolo tipo di metadati valido: META_DATA_FLUSH_COMPLETE
.
Gli eventi META_DATA_FLUSH_COMPLETE
rappresentano il completamento dello svuotamento di un FIFO del sensore. Quando meta_data.what=META_DATA_FLUSH_COMPLETE
, meta_data.sensor
deve essere impostato sull'handle del sensore che è stato svuotato. Vengono
generati quando e solo quando viene chiamato flush
su un sensore. Per ulteriori informazioni, consulta la sezione sulla funzione flush.