A interface HAL de sensores, declarada em sensors.h, representa a interface entre o framework do Android e o software específico do hardware. Uma implementação de HAL precisa definir cada função declarada em sensors.h. As principais funções são:
get_sensors_list
: retorna a lista de todos os sensores.activate
: inicia ou interrompe um sensor.batch
: define os parâmetros de um sensor, como frequência de amostragem e latência máxima de relatório.setDelay
: usado apenas na versão 1.0 da HAL. Define a frequência de amostragem para um determinado sensor.flush
- Limpa a FIFO do sensor especificado e informa um evento de limpeza concluída quando isso é feito.poll
: retorna os eventos de sensor disponíveis.
A implementação precisa ser segura para linhas de execução e permitir que essas funções sejam chamadas de linhas de execução diferentes.
A interface também define vários tipos usados por essas funções. Os principais tipos são:
sensors_module_t
sensors_poll_device_t
sensor_t
sensors_event_t
Além das seções abaixo, consulte sensors.h para mais informações sobre esses tipos.
get_sensors_list(list)
int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t const** list);
Fornece a lista de sensores implementados pela HAL. Consulte sensor_t para saber como os sensores são definidos.
A ordem em que os sensores aparecem na lista é a ordem em que eles serão informados aos aplicativos. Normalmente, os sensores básicos aparecem primeiro, seguidos pelos sensores compostos.
Se vários sensores compartilharem o mesmo tipo e propriedade de despertar, o primeiro na lista será chamado de sensor "padrão". É o mesmo retornado por
getDefaultSensor(int sensorType, bool wakeUp)
.
Essa função retorna o número de sensores na lista.
activate(sensor, true/false)
int (*activate)(struct sensors_poll_device_t *dev, int sensor_handle, int enabled);
Ativa ou desativa um sensor.
sensor_handle
é o identificador do sensor a ser ativado/desativado. O identificador de um sensor é definido pelo campo handle
da estrutura sensor_t.
enabled
é definido como 1 para ativar ou 0 para desativar o sensor.
Os sensores únicos se desativam automaticamente ao receber um evento,
mas ainda precisam aceitar a desativação por uma chamada para activate(...,
enabled=0)
.
Os sensores que não ativam o dispositivo nunca impedem que o SoC entre no modo de suspensão. Ou seja, a HAL não pode manter um wake lock parcial em nome dos aplicativos.
Os sensores de despertar, ao fornecer eventos continuamente, podem impedir que o SoC entre no modo de suspensão. No entanto, se nenhum evento precisar ser entregue, o bloqueio de despertar parcial deverá ser liberado.
Se enabled
for 1 e o sensor já estiver ativado, essa função não fará nada e será concluída.
Se enabled
for 0 e o sensor já estiver desativado, essa função não fará nada e será concluída.
Essa função retorna 0 em caso de sucesso e um número de erro negativo caso contrário.
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);
Define os parâmetros de um sensor, incluindo frequência de amostragem e latência máxima de relatório. Essa função pode ser chamada enquanto o sensor está ativado. Nesse caso, ela não pode causar a perda de medições do sensor: a transição de uma taxa de amostragem para outra não pode causar eventos perdidos, nem a transição de uma latência máxima de relatório alta para uma baixa.
sensor_handle
é o identificador do sensor a ser configurado.
flags
não é usado no momento.
sampling_period_ns
é o período de amostragem em que o sensor precisa ser executado, em nanossegundos. Consulte sampling_period_ns para mais detalhes.
max_report_latency_ns
é o tempo máximo em que os eventos podem ser
atrasados antes de serem informados pela HAL, em nanossegundos. Consulte o parágrafo max_report_latency_ns para mais detalhes.
Essa função retorna 0 em caso de sucesso e um número de erro negativo caso contrário.
setDelay(sensor, período de amostragem)
int (*setDelay)( struct sensors_poll_device_t *dev, int sensor_handle, int64_t sampling_period_ns);
Após a versão 1.0 do HAL, essa função foi descontinuada e nunca é chamada.
Em vez disso, a função batch
é chamada para definir o parâmetro sampling_period_ns
.
Na versão 1.0 da HAL, "setDelay" era usado em vez de "batch" para definir sampling_period_ns.
flush(sensor)
int (*flush)(struct sensors_poll_device_1* dev, int sensor_handle);
Adicione um evento de conclusão de limpeza ao final do FIFO de hardware para o sensor especificado e limpe o FIFO. Esses eventos são entregues como de costume (ou seja, como se a latência máxima de relatório tivesse expirado) e removidos do FIFO.
A limpeza é feita de forma assíncrona. Ou seja, essa função precisa retornar imediatamente. Se a implementação usar uma única FIFO para vários sensores, ela será limpa, e o evento de limpeza concluída será adicionado apenas para o sensor especificado.
Se o sensor especificado não tiver FIFO (nenhum buffer possível) ou se o FIFO
estiver vazio no momento da chamada, flush
ainda precisará ser bem-sucedido e
enviar um evento de conclusão de limpeza para esse sensor. Isso se aplica a todos os sensores, exceto os únicos.
Quando flush
é chamado, mesmo que um evento de limpeza já esteja na
PEPS desse sensor, outro precisa ser criado e adicionado ao final
da PEPS, que precisa ser limpa. O número de chamadas de flush
precisa ser igual ao número de eventos de conclusão de limpeza criados.
flush
não se aplica a sensores únicos. Se sensor_handle
se referir a um sensor único, flush
vai retornar -EINVAL
e não vai gerar um evento de metadados de conclusão de limpeza.
Essa função retorna 0 em caso de sucesso, -EINVAL
se o sensor especificado for de
uso único ou não estiver ativado e um número de erro negativo caso contrário.
poll()
int (*poll)(struct sensors_poll_device_t *dev, sensors_event_t* data, int
count);
Retorna uma matriz de dados de sensores preenchendo o argumento data
. Essa função
precisa bloquear até que os eventos estejam disponíveis. Ele vai retornar o número de eventos lidos
em caso de sucesso ou um número de erro negativo em caso de falha.
O número de eventos retornados em data
precisa ser menor ou igual ao argumento count
. Essa função nunca vai retornar 0 (nenhum evento).
Sequência de chamadas
Quando o dispositivo é inicializado, get_sensors_list
é chamado.
Quando um sensor é ativado, a função batch
é chamada com os parâmetros solicitados, seguida por activate(..., enable=1)
.
Na versão 1_0 da HAL, a ordem era oposta: activate
era chamado primeiro, seguido por set_delay
.
Quando as características solicitadas de um sensor mudam enquanto ele está ativado, a função batch
é chamada.
flush
pode ser chamado a qualquer momento, mesmo em sensores não ativados. Nesse caso, ele precisa retornar -EINVAL
.
Quando um sensor é desativado, activate(..., enable=0)
é chamado.
Paralelamente a essas chamadas, a função poll
será chamada repetidamente para
solicitar dados. poll
pode ser chamado mesmo quando nenhum sensor está ativado.
sensors_module_t
sensors_module_t
é o tipo usado para criar o módulo de hardware do Android
para os sensores. A implementação da HAL precisa definir um objeto HAL_MODULE_INFO_SYM
desse tipo para expor a função get_sensors_list. Consulte a definição de sensors_module_t
em sensors.h e a definição de hw_module_t
para mais informações.
sensors_poll_device_t / sensors_poll_device_1_t
sensors_poll_device_1_t
contém o restante dos métodos definidos acima: activate
, batch
, flush
e poll
. O campo common
(do tipo hw_device_t)
define o número da versão da HAL.
sensor_t
sensor_t
representa um sensor do Android. Confira alguns dos campos importantes:
name:uma string visível ao usuário que representa o sensor. Essa string geralmente contém o nome da peça do sensor subjacente, o tipo do sensor e se ele é um sensor de despertar. Por exemplo, "LIS2HH12 Accelerometer", "MAX21000 Uncalibrated Gyroscope", "BMP280 Wake-up Barometer", "MPU6515 Game Rotation Vector"
handle:o número inteiro usado para se referir ao sensor ao registrar ou gerar eventos dele.
type:o tipo de sensor. Consulte a explicação do tipo de sensor em O que são sensores do Android? para mais detalhes e Tipos de sensores para conferir os tipos oficiais. Para
tipos de sensores não oficiais, type
precisa começar com SENSOR_TYPE_DEVICE_PRIVATE_BASE
stringType:o tipo do sensor como uma string. Quando o sensor tem um tipo oficial, defina como SENSOR_STRING_TYPE_*
. Quando o sensor tem um tipo específico do fabricante, stringType
precisa começar com o nome de domínio invertido do fabricante. Por exemplo, um sensor (digamos, um detector de unicórnios) definido pela equipe Cool-product da Fictional-Company pode usar stringType=”com.fictional_company.cool_product.unicorn_detector”
.
O stringType
é usado para identificar exclusivamente tipos de sensores não oficiais. Consulte sensors.h para mais informações sobre tipos e tipos de
string.
requiredPermission:uma string que representa a permissão
que os aplicativos precisam ter para ver o sensor, se registrar nele e receber
os dados dele. Uma string vazia significa que os aplicativos não exigem permissão para acessar esse sensor. Alguns tipos de sensores, como o monitor de frequência cardíaca, têm um requiredPermission
obrigatório. Todos os sensores que fornecem informações sensíveis do usuário (como a frequência cardíaca) precisam ser protegidos por uma permissão.
flags:flags para este sensor, definindo o modo de relatório do sensor e se ele é um sensor de despertar ou não. Por exemplo, um sensor de ativação única
terá flags = SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP
. Os bits da flag que não são usados na versão atual da HAL precisam ser deixados iguais a 0.
maxRange:o valor máximo que o sensor pode informar, na mesma unidade dos valores informados. O sensor precisa ser capaz de informar valores sem saturação em [-maxRange; maxRange]
. Isso significa que o intervalo total do sensor no sentido genérico é 2*maxRange
. Quando o sensor informa valores em vários eixos, o intervalo se aplica a cada um deles. Por exemplo, um acelerômetro "+/- 2g" vai informar maxRange = 2*9.81 = 2g
.
Resolução:a menor diferença de valor que o sensor pode medir.
Geralmente calculado com base em maxRange
e no número de bits na medição.
power:o custo de energia para ativar o sensor, em miliampères.
Isso é quase sempre mais do que o consumo de energia informado na
folha de dados do sensor subjacente. Consulte Sensores básicos != sensores físicos para mais detalhes e Processo de medição de energia para saber como medir o consumo de energia de um sensor.
Se o consumo de energia do sensor depender da movimentação do dispositivo, o consumo de energia durante o movimento será o informado no campo power
.
minDelay:para sensores contínuos, o período de amostragem, em microssegundos, correspondente à taxa mais rápida que o sensor aceita. Consulte sampling_period_ns para detalhes sobre como esse valor é usado. minDelay
é expresso em microssegundos, enquanto sampling_period_ns
é em nanossegundos. Para sensores de modo de relatórios especiais e de mudança, a menos que especificado de outra forma, minDelay
precisa ser 0. Para sensores únicos, ele
precisa ser -1.
maxDelay:para sensores contínuos e de mudança, o período de amostragem, em microssegundos, correspondente à taxa mais lenta que o sensor aceita. Consulte sampling_period_ns para detalhes sobre como esse valor é usado. maxDelay
é expresso em microssegundos, enquanto sampling_period_ns
é em nanossegundos. Para sensores especiais e únicos, maxDelay
precisa ser 0.
fifoReservedEventCount:o número de eventos reservados para esse sensor no
FIFO de hardware. Se houver um FIFO dedicado para esse sensor, fifoReservedEventCount
será o tamanho dele. Se a PEPS for compartilhada com outros sensores, fifoReservedEventCount
será o tamanho da parte da PEPS reservada para esse sensor. Na maioria dos sistemas FIFO compartilhados e naqueles que não têm um FIFO de hardware, esse valor é 0.
fifoMaxEventCount:o número máximo de eventos que podem ser armazenados nos FIFOs para esse sensor. Esse valor é sempre maior ou igual a fifoReservedEventCount
. Esse valor é usado para estimar a rapidez com que a FIFO vai ficar cheia ao se registrar no sensor a uma taxa específica, supondo que nenhum outro sensor esteja ativado. Em sistemas sem um FIFO de hardware, fifoMaxEventCount
é 0. Consulte Lotes para mais detalhes.
Para sensores com um tipo oficial, alguns campos são substituídos
pelo framework. Por exemplo, os sensores de acelerômetro são obrigados a ter um modo de relatório contínuo, e os monitores de frequência cardíaca precisam ser protegidos pela permissão SENSOR_PERMISSION_BODY_SENSORS
.
sensors_event_t
Os eventos de sensor gerados por sensores do Android e informados pela função poll são do tipo type sensors_event_t
. Confira alguns campos importantes de sensors_event_t
:
version:precisa ser sizeof(struct sensors_event_t)
sensor:o identificador do sensor que gerou o evento, conforme definido por
sensor_t.handle
.
type:o tipo de sensor que gerou o evento, conforme definido por
sensor_t.type
.
timestamp:o carimbo de data/hora do evento em nanossegundos. É o momento em que o evento aconteceu (uma etapa foi realizada ou uma medição do acelerômetro foi feita), e não o momento em que ele foi informado. timestamp
precisa estar sincronizado com o relógio elapsedRealtimeNano
e, no caso de sensores contínuos, o jitter precisa ser pequeno. Às vezes, é necessário filtrar os carimbos de data/hora para atender aos requisitos do CDD. Isso porque usar apenas o tempo de interrupção do SoC para definir os carimbos causa jitter muito alto, e usar apenas o tempo do chip do sensor pode causar dessincronização do relógio elapsedRealtimeNano
, já que o relógio do sensor sofre desvios.
Dados e campos sobrepostos:os valores medidos pelo sensor. O significado e as unidades desses campos são específicos para cada tipo de sensor. Consulte sensors.h e a definição dos diferentes Tipos de sensores para uma descrição dos campos de dados. Para alguns sensores, a precisão das leituras também é informada como parte dos dados, em um campo status
. Esse campo só é transmitido para esses tipos de sensores selecionados, aparecendo na camada do SDK como um valor de acurácia. Para esses sensores, o fato de o campo de status precisar ser definido é mencionado na definição do tipo de sensor.
Eventos de conclusão da limpeza de metadados
Os eventos de metadados têm o mesmo tipo dos eventos normais de sensor: sensors_event_meta_data_t = sensors_event_t
. Eles são retornados junto com outros eventos de sensor por polling. Elas têm os seguintes campos:
version:precisa ser META_DATA_VERSION
type:precisa ser SENSOR_TYPE_META_DATA
sensor, reserved e timestamp: precisa ser 0
meta_data.what:contém o tipo de metadados para este evento. No momento, há um único tipo de metadados válido: META_DATA_FLUSH_COMPLETE
.
Os eventos META_DATA_FLUSH_COMPLETE
representam a conclusão da limpeza de uma
FIFO do sensor. Quando meta_data.what=META_DATA_FLUSH_COMPLETE
, meta_data.sensor
precisa ser definido como o identificador do sensor que foi liberado. Elas são geradas quando e somente quando flush
é chamado em um sensor. Consulte a seção sobre a função flush para mais informações.