HAL 1.0 de sensores

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 do HAL precisa definir cada função declarada em sensors.h. As funções principais são:

  • get_sensors_list: retorna a lista de todos os sensores.
  • activate: inicia ou para um sensor.
  • batch: define os parâmetros de um sensor, como a frequência de amostragem e a latência máxima de relatórios.
  • setDelay: usado apenas na versão 1.0 do HAL. Define a frequência de amostragem para um determinado sensor.
  • flush: limpa o 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 diferentes linhas de execução.

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 pelo 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 a mesma propriedade de ativação, o primeiro na lista será chamado de sensor "padrão". É o valor 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 são desativados automaticamente ao receber um evento e ainda precisam aceitar a desativação por uma chamada para activate(..., enabled=0).

Sensores que não ativam nunca impedem que o SoC entre no modo de suspensão. Ou seja, o HAL não pode manter um wake lock parcial em nome de aplicativos.

Os sensores de ativação, ao transmitir eventos continuamente, podem impedir que o SoC entre no modo de suspensão, mas, se nenhum evento precisar ser transmitido, o bloqueio de ativação parcial precisa ser liberado.

Se enabled for 1 e o sensor já estiver ativado, essa função não fará nada e terá sucesso.

Se enabled for 0 e o sensor já estiver desativado, essa função não vai fazer nada e terá sucesso.

Essa função retorna 0 em caso de sucesso e um número de erro negativo, caso contrário.

lote(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 a frequência de amostragem e a latência máxima de relatórios. Essa função pode ser chamada enquanto o sensor está ativado. Nesse caso, ele não pode causar a perda de nenhuma medição do sensor: a transição de uma taxa de amostragem para outra não pode causar a perda de eventos, nem a transição de uma latência máxima 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 pelo 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, sampling period)

int (*setDelay)(
     struct sensors_poll_device_t *dev,
     int sensor_handle,
     int64_t sampling_period_ns);

Depois da 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 do HAL, setDelay foi 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 limpeza completa ao final da FIFO de hardware do sensor especificado e limpe a FIFO. Esses eventos são enviados normalmente (ou seja, como se a latência máxima de relatórios tivesse expirado) e removidos da FIFO.

A limpeza acontece de forma assíncrona (ou seja, essa função precisa retornar imediatamente). Se a implementação usar um único FIFO para vários sensores, esse FIFO será apagado e o evento de conclusão de limpeza 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 terá sucesso e enviará um evento de limpeza completa para esse sensor. Isso se aplica a todos os sensores, exceto os de disparo único.

Quando flush é chamado, mesmo que um evento de limpeza já esteja na FIFO do sensor, outro evento precisa ser criado e adicionado ao final da FIFO, e a FIFO precisa ser limpa. O número de chamadas flush precisa ser igual ao número de eventos de flush completos criados.

flush não se aplica a sensores one-shot. Se sensor_handle se referir a um sensor one-shot, flush precisará retornar -EINVAL e não gerar nenhum evento de limpeza de metadados completo.

Essa função retorna 0 em caso de sucesso, -EINVAL se o sensor especificado for ú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 do sensor preenchendo o argumento data. Essa função precisa ser bloqueada 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 erro.

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, seguidos por activate(..., enable=1).

Na versão 1_0 do HAL, a ordem era oposta: activate era chamado primeiro, seguido por set_delay.

Quando as características solicitadas de um sensor estão mudando 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. O poll pode ser chamado mesmo quando nenhum sensor é 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 do 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 do HAL.

sensor_t

sensor_t representa um sensor Android. Estes são alguns dos campos importantes:

name:uma string visível para o usuário que representa o sensor. Essa string geralmente contém o nome da parte do sensor subjacente, o tipo do sensor e se ele é um sensor de ativação. Por exemplo, "Acelerômetro LIS2HH12", "Giroscópio MAX21000 não calibrado", "Barômetro de ativação BMP280", "Vetor de rotação do jogo MPU6515"

handle:o número inteiro usado para se referir ao sensor ao se registrar nele ou gerar eventos dele.

type:o tipo do 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 tipos de sensores 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 tiver 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 reverso do fabricante. Por exemplo, um sensor (por exemplo, um detector de unicórnios) definido pela equipe do Cool-product na Fictional-Company pode usar stringType=”com.fictional_company.cool_product.unicorn_detector”. O stringType é usado para identificar exclusivamente os 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 apps precisam ter para acessar o sensor, se registrar nele e receber os dados. Uma string vazia significa que os aplicativos não precisam de nenhuma 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 esse sensor, que definem o modo de relatório do sensor e se ele é um sensor de ativação ou não. Por exemplo, um sensor de ativação único 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 do HAL precisam ser iguais a 0.

maxRange:o valor máximo que o sensor pode informar, na mesma unidade dos valores informados. O sensor precisa informar valores sem saturar dentro de [-maxRange; maxRange]. Isso significa que o alcance total do sensor no sentido genérico é 2*maxRange. Quando o sensor informa valores em vários eixos, o intervalo se aplica a cada eixo. 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 é maior que o consumo de energia informado na folha de dados do sensor. 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 de se o dispositivo está em movimento, o consumo de energia em movimento será o informado no campo power.

minDelay:para sensores contínuos, o período de amostragem, em microssegundos, corresponde à taxa mais rápida com suporte do sensor. Consulte sampling_period_ns para saber como esse valor é usado. minDelay é expresso em microssegundos, enquanto sampling_period_ns está em nanossegundos. Para sensores de mudança e do modo de relatório especial, a menos que seja 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, corresponde à taxa mais lenta com suporte do sensor. Consulte sampling_period_ns para saber como esse valor é usado. maxDelay é expresso em microssegundos, enquanto sampling_period_ns está em nanossegundos. Para sensores especiais e únicos, maxDelay precisa ser 0.

fifoReservedEventCount:o número de eventos reservados para esse sensor na FIFO de hardware. Se houver um FIFO dedicado para esse sensor, fifoReservedEventCount será o tamanho desse FIFO dedicado. Se a FIFO for compartilhada com outros sensores, fifoReservedEventCount será o tamanho da parte da FIFO reservada para esse sensor. Na maioria dos sistemas FIFO compartilhados e nos sistemas 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 seja ativado. Em sistemas que não têm um FIFO de hardware, fifoMaxEventCount é 0. Consulte Como fazer o agrupamento 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 forçados a ter um modo de relatório contínuo, e os monitores de frequência cardíaca são forçados a serem 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 de 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 do sensor que gerou o evento, conforme definido por sensor_t.type.

carimbo de data/hora:o carimbo de data/hora do evento em nanossegundos. É a hora em que o evento ocorreu (uma etapa foi realizada ou uma medição do acelerômetro foi feita), não o horário em que o evento foi informado. O timestamp precisa ser sincronizado com o relógio elapsedRealtimeNano e, no caso de sensores contínuos, o jitter precisa ser pequeno. Às vezes, a filtragem de carimbos de data/hora é necessária para atender aos requisitos do CDD, já que o uso apenas do tempo de interrupção do SoC para definir os carimbos de data/hora causa um jitter muito alto. Além disso, o uso apenas do tempo do sensor para definir os carimbos de data/hora pode causar a desincronização do relógio elapsedRealtimeNano, já que o relógio do sensor se desloca.

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, usando um campo status. Esse campo é transmitido apenas para esses tipos de sensores selecionados, aparecendo na camada do SDK como um valor de precisão. Para esses sensores, o fato de que o campo de status precisa ser definido é mencionado na definição do tipo de sensor.

Eventos de conclusão de limpeza de metadados

Os eventos de metadados têm o mesmo tipo que os eventos de sensor normais: sensors_event_meta_data_t = sensors_event_t. Eles são retornados com outros eventos do sensor por meio de pesquisa. Eles têm os seguintes campos:

version:precisa ser META_DATA_VERSION.

type:precisa ser SENSOR_TYPE_META_DATA

sensor, reservado e carimbo de data/hora: 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 do flush de um FIFO do sensor. Quando meta_data.what=META_DATA_FLUSH_COMPLETE, meta_data.sensor precisa ser definido como o identificador do sensor que foi limpo. 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.