L'interfaccia HAL dei sensori, dichiarata in sensors.h, rappresenta l'interfaccia tra il framework Android e il software specifico dell'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, come la frequenza di campionamento e la latenza massima di reporting.setDelay
- Utilizzato 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 segnala un evento di completamento dello svuotamento al termine dell'operazione.poll
- Restituisce gli eventi del sensore disponibili.
L'implementazione deve essere thread-safe e consentire la chiamata di 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 seguenti, consulta sensors.h per ulteriori informazioni su questi tipi.
get_sensors_list(list)
int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t const** list);
Fornisce l'elenco dei sensori implementati dall'HAL. Per maggiori dettagli su come vengono definiti i sensori, consulta sensor_t.
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 riattivazione, il primo
nell'elenco viene chiamato sensore "predefinito". È quello restituito da
getDefaultSensor(int sensorType, bool wakeUp)
.
Questa funzione restituisce il numero di sensori nell'elenco.
activate(sensor, true/false)
int (*activate)(struct sensors_poll_device_t *dev, int sensor_handle, int enabled);
Attiva o disattiva un sensore.
sensor_handle
è l'handle del sensore da attivare/disattivare. L'handle di un sensore
è definito dal campo handle
della relativa struttura sensor_t.
enabled
è impostato su 1 per attivare o su 0 per disattivare il sensore.
I sensori one-shot 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, ovvero l'HAL non deve mantenere un wake lock parziale per conto delle applicazioni.
I sensori di riattivazione, quando inviano eventi in modo continuo, possono impedire al SoC di entrare in modalità di sospensione, ma se non è necessario inviare alcun evento, il wake lock parziale deve essere rilasciato.
Se enabled
è 1 e il sensore è già attivato, questa funzione non ha effetto
e viene eseguita correttamente.
Se enabled
è 0 e il sensore è già disattivato, questa funzione non ha effetto
e viene eseguita correttamente.
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 del report. Questa funzione può essere chiamata mentre il sensore è attivato, nel qual caso non deve causare la perdita di alcuna misurazione del sensore: la transizione da una frequenza di campionamento all'altra non può causare la perdita di eventi, né la transizione da una latenza massima di report elevata a una latenza massima di report bassa.
sensor_handle
è l'handle del sensore da configurare.
flags
non è attualmente utilizzato.
sampling_period_ns
è il periodo di campionamento in cui il sensore
deve essere eseguito, in nanosecondi. Per maggiori dettagli, consulta sampling_period_ns.
max_report_latency_ns
è il tempo massimo entro il quale gli eventi possono essere
ritardati prima di essere segnalati tramite l'HAL, in nanosecondi. Per ulteriori dettagli, consulta il paragrafo max_report_latency_ns.
Questa funzione restituisce 0 in caso di esito positivo e un numero di errore negativo in caso contrario.
setDelay(sensor, sampling period)
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, per impostare sampling_period_ns veniva utilizzato setDelay anziché batch.
flush(sensor)
int (*flush)(struct sensors_poll_device_1* dev, int sensor_handle);
Aggiungi un evento di svuotamento completato alla fine della coda FIFO hardware per il sensore specificato e svuota la coda FIFO; questi eventi vengono inviati come di consueto (ovvero come se fosse scaduta la latenza di reporting massima) 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, questa viene svuotata e l'evento di completamento dello svuotamento viene aggiunto solo per il sensore specificato.
Se il sensore specificato non ha FIFO (nessun buffering possibile) o se FIFO era vuoto al momento della chiamata, flush
deve comunque riuscire e inviare un evento di svuotamento completato per quel sensore. Questo vale per tutti i sensori diversi
da quelli monouso.
Quando viene chiamato flush
, anche se è già presente un evento di svuotamento nella
FIFO per quel sensore, deve essere creato un evento aggiuntivo e aggiunto alla fine
della FIFO, che deve essere svuotata. Il numero di chiamate flush
deve essere uguale al numero di eventi di completamento dello svuotamento creati.
flush
non si applica ai sensori
one-shot; se sensor_handle
si riferisce a un sensore one-shot,
flush
deve restituire -EINVAL
e non generare alcun
evento di metadati di completamento dello svuotamento.
Questa funzione restituisce 0 in caso di esito positivo, -EINVAL
se il sensore specificato è un
sensore one-shot o non è stato attivato e un numero di errore negativo in caso contrario.
poll()
int (*poll)(struct sensors_poll_device_t *dev, sensors_event_t* data, int
count);
Restituisce un array di dati dei sensori compilando l'argomento data
. Questa funzione
deve bloccarsi finché non sono disponibili eventi. 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 restituirà mai 0 (nessun evento).
Sequenza di chiamate
All'avvio del dispositivo, 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 di HAL l'ordine era inverso: activate
veniva 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 (nel qual caso
deve restituire -EINVAL
)
Quando un sensore viene disattivato, viene chiamato activate(..., enable=0)
.
Parallelamente a queste chiamate, la funzione poll
verrà chiamata ripetutamente per
richiedere i dati. poll
può essere chiamato anche quando non sono attivati 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 saperne di più, consulta la definizione di sensors_module_t
in sensors.h e la definizione di hw_module_t
.
sensors_poll_device_t / sensors_poll_device_1_t
sensors_poll_device_1_t
contiene il resto dei 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. Questa stringa spesso contiene il nome della parte del sensore sottostante, il tipo di sensore e se si tratta di un sensore di riattivazione. Ad esempio, "LIS2HH12 Accelerometer", "MAX21000 Uncalibrated Gyroscope", "BMP280 Wake-up Barometer", "MPU6515 Game Rotation Vector"
handle: l'intero utilizzato per fare riferimento al sensore durante la registrazione o la generazione di eventi.
type: il tipo di sensore. Per maggiori dettagli, consulta la spiegazione del tipo di sensore nella sezione Cosa sono i sensori Android? e la sezione Tipi di sensori per i tipi di sensori ufficiali. Per i tipi di sensore non ufficiali, type
deve iniziare con SENSOR_TYPE_DEVICE_PRIVATE_BASE
stringType: il tipo di sensore come stringa. Quando 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 di unicorni) definito dal team Cool-product di
Fictional-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 possedere per visualizzare 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 cardiofrequenzimetro, hanno un
requiredPermission
obbligatorio. Tutti i sensori che forniscono informazioni utente sensibili (come la frequenza cardiaca) devono essere protetti da un'autorizzazione.
flags: Flag 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 riattivazione one-shot
avrà flags = SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP
. I bit del flag che non vengono 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 segnalati. Il sensore deve essere in grado di segnalare valori senza saturarsi
entro [-maxRange; maxRange]
. Tieni presente che ciò significa che l'intervallo totale del sensore in senso generico è 2*maxRange
. Quando il sensore segnala valori su
più assi, l'intervallo si applica a ciascun asse. Ad esempio, un accelerometro
"+/- 2 g" segnalerà maxRange = 2*9.81 = 2g
.
Risoluzione:la più piccola differenza di valore che il sensore può misurare.
Di solito viene calcolato in base a maxRange
e al numero di bit nella misurazione.
power: il costo energetico dell'attivazione del sensore, in milliampere.
Questo valore è quasi sempre superiore al consumo energetico riportato nella
scheda tecnica del sensore sottostante. Per ulteriori dettagli, consulta la sezione Sensori di base ≠ sensori fisici e la sezione Procedura di misurazione del consumo energetico per informazioni dettagliate su come misurare il consumo energetico di un sensore.
Se il consumo energetico del sensore dipende dal movimento del dispositivo, il
consumo energetico durante il movimento è quello riportato nel campo power
.
minDelay: per i sensori continui, il periodo di campionamento, in
microsecondi, corrispondente alla velocità più elevata supportata dal sensore. Per informazioni dettagliate su come viene utilizzato questo valore, consulta sampling_period_ns. Tieni presente che minDelay
è
espresso in microsecondi, mentre sampling_period_ns
è in
nanosecondi. Per i sensori in modalità di segnalazione speciale e di modifica, a meno che
non sia specificato diversamente, minDelay
deve essere 0. Per i sensori one-shot, deve
essere -1.
maxDelay: per i sensori continui e on-change, il periodo di campionamento, in microsecondi, corrispondente alla velocità più bassa supportata dal sensore. Per informazioni dettagliate su come viene utilizzato questo valore, consulta sampling_period_ns. Tieni presente che maxDelay
è
espresso in microsecondi, mentre sampling_period_ns
è in
nanosecondi. Per i sensori speciali e monouso, maxDelay
deve essere
0.
fifoReservedEventCount: il numero di eventi riservati a questo sensore nella FIFO hardware. Se esiste una FIFO dedicata per questo sensore, allora
fifoReservedEventCount
è la dimensione di questa FIFO dedicata. Se la FIFO è
condivisa con altri sensori, fifoReservedEventCount
è la dimensione della parte
della FIFO riservata a quel sensore. Nella maggior parte dei sistemi FIFO condivisi e nei sistemi che non dispongono di una FIFO hardware, questo valore è 0.
fifoMaxEventCount: il numero massimo di eventi che potrebbero
essere memorizzati nelle FIFO per questo sensore. Questo valore è sempre maggiore o uguale a
fifoReservedEventCount
. Questo valore viene utilizzato per stimare la velocità con cui la coda FIFO si riempirà durante la registrazione al sensore a una velocità specifica, supponendo che non siano attivati altri sensori. Sui sistemi che non hanno un
FIFO hardware, fifoMaxEventCount
è 0. Per ulteriori dettagli, consulta la sezione Batching.
Per i sensori con un tipo di sensore ufficiale, alcuni campi vengono sovrascritti
dal framework. Ad esempio, i sensori accelerometro
sono costretti ad avere una modalità di segnalazione continua e i monitor della frequenza cardiaca
sono costretti a essere protetti dall'autorizzazione SENSOR_PERMISSION_BODY_SENSORS
.
sensors_event_t
Gli eventi dei sensori generati dai sensori Android e segnalati tramite la funzione poll sono di 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 l'ora in cui è stato segnalato l'evento. timestamp
deve essere sincronizzato con l'orologio elapsedRealtimeNano
e, nel caso di sensori continui, il jitter deve essere ridotto. Il filtro dei timestamp è a volte necessario per soddisfare i requisiti CDD, in quanto l'utilizzo solo dell'ora di interruzione del SoC per impostare i timestamp causa un jitter troppo elevato e l'utilizzo solo dell'ora del chip del sensore per impostare i timestamp può causare la desincronizzazione dall'orologio elapsedRealtimeNano
, poiché l'orologio del sensore si sposta.
Dati e campi sovrapposti:i valori misurati dal sensore. Il significato e le unità di questi campi sono specifici per ogni tipo di sensore. Consulta sensors.h e la definizione dei diversi tipi di sensori per una descrizione dei campi di dati. Per alcuni sensori, l'accuratezza delle letture viene segnalata anche
come parte dei dati, tramite un campo status
. Questo campo viene
trasmesso solo per i tipi di sensore selezionati e viene visualizzato a livello di SDK come
valore di precisione. Per questi sensori, il fatto che il campo dello stato debba essere impostato
è menzionato nella definizione del tipo di sensore.
Eventi di svuotamento dei metadati completati
Gli eventi di metadati hanno lo stesso tipo degli eventi dei sensori normali:
sensors_event_meta_data_t = sensors_event_t
. Vengono restituiti insieme ad
altri eventi dei sensori tramite polling. Contengono 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 esiste un solo tipo di metadati valido: META_DATA_FLUSH_COMPLETE
.
Gli eventi META_DATA_FLUSH_COMPLETE
rappresentano il completamento dello svuotamento di una
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
generate quando e solo quando viene chiamato flush
su un sensore. Per saperne di più, consulta la sezione
sulla funzione flush.