Sensores AIDL HAL

A camada de abstração de hardware de sensores (HAL) é a interface entre a estrutura do sensor Android e os sensores de um dispositivo, como um acelerômetro ou giroscópio. O Sensors HAL define as funções que devem ser implementadas para permitir que a estrutura controle os sensores.

O Sensors AIDL HAL está disponível no Android 13 e superior para dispositivos novos e atualizados. O Sensors AIDL HAL, que é baseado no Sensors HAL 2.1 , usa a interface AIDL HAL e expõe o rastreador de cabeça e os tipos de sensores IMU de eixo limitado.

Interface AIDL-HAL

A principal fonte de documentação para o Sensors AIDL HAL está dentro da definição HAL em hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl .

Implementando os Sensores AIDL HAL

Para implementar o Sensors AIDL HAL, um objeto deve estender a interface ISensors e implementar todas as funções definidas em hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl .

Inicializando o HAL

O Sensors HAL deve ser inicializado pela estrutura do sensor Android antes de poder ser usado. A estrutura chama a função initialize() para fornecer três parâmetros para o Sensors HAL: dois descritores FMQ e um ponteiro para um objeto ISensorsCallback .

O HAL usa o primeiro descritor para criar o Event FMQ usado para gravar eventos de sensor na estrutura. O HAL usa o segundo descritor para criar o Wake Lock FMQ usado para sincronizar quando o HAL libera seu wake lock para eventos do sensor WAKE_UP . O HAL deve salvar um ponteiro para o objeto ISensorsCallback para que quaisquer funções de retorno de chamada necessárias possam ser invocadas.

A função initialize() deve ser a primeira função chamada ao inicializar o HAL dos Sensores.

Expondo sensores disponíveis

Para obter uma lista de todos os sensores estáticos disponíveis no dispositivo, use a função getSensorsList() . Esta função retorna uma lista de sensores, cada um identificado exclusivamente por seu identificador. O identificador de um determinado sensor não deve mudar quando o processo que hospeda o HAL dos Sensores for reiniciado. Os identificadores podem mudar nas reinicializações do dispositivo e nas reinicializações do servidor do sistema.

Se vários sensores compartilharem o mesmo tipo de sensor e propriedade de ativação, o primeiro sensor da lista será chamado de sensor padrão e será retornado aos aplicativos que utilizam a função getDefaultSensor(int sensorType, bool wakeUp) .

Estabilidade da lista de sensores

Após a reinicialização do Sensors HAL, se os dados retornados por getSensorsList() indicarem uma alteração significativa em comparação com a lista de sensores recuperada antes da reinicialização, a estrutura acionará uma reinicialização do tempo de execução do Android. Mudanças significativas na lista de sensores incluem casos em que um sensor com uma determinada alça está faltando ou possui atributos alterados, ou onde novos sensores são introduzidos. Embora reiniciar o tempo de execução do Android seja prejudicial para o usuário, ele é necessário porque a estrutura do Android não pode mais atender ao contrato da API do Android de que os sensores estáticos (não dinâmicos) não mudam durante a vida útil de um aplicativo. Isso também pode impedir que a estrutura restabeleça solicitações de sensores ativos feitas por aplicativos. Portanto, os fornecedores de HAL são aconselhados a evitar alterações evitáveis ​​na lista de sensores.

Para garantir alças de sensor estáveis, o HAL deve mapear deterministicamente um determinado sensor físico no dispositivo para sua alça. Embora nenhuma implementação específica seja exigida pela interface HAL dos Sensores, os desenvolvedores têm diversas opções disponíveis para atender a esse requisito.

Por exemplo, a lista de sensores pode ser classificada usando uma combinação dos atributos fixos de cada sensor, como fornecedor, modelo e tipo de sensor. Outra opção depende do fato de que o conjunto de sensores estáticos do dispositivo é fixo em hardware, portanto, o HAL precisa saber quando todos os sensores esperados concluíram a inicialização antes de retornar de getSensorsList() . Esta lista de sensores esperados pode ser compilada no binário HAL ou armazenada em um arquivo de configuração no sistema de arquivos, e a ordem de aparecimento pode ser usada para derivar identificadores estáveis. Embora a melhor solução dependa dos detalhes específicos de implementação do seu HAL, o principal requisito é que os identificadores do sensor não mudem nas reinicializações do HAL.

Configurando sensores

Antes de um sensor ser ativado, ele deve ser configurado com um período de amostragem e latência máxima de relatório usando a função batch() .

Um sensor deve poder ser reconfigurado a qualquer momento usando batch() sem perda de dados do sensor.

Período de amostragem

O período de amostragem tem um significado diferente dependendo do tipo de sensor que está sendo configurado:

  • Contínuo: Os eventos do sensor são gerados em uma taxa contínua.
  • On-change: Os eventos não são gerados mais rapidamente que o período de amostragem e podem ser gerados a uma taxa mais lenta que o período de amostragem se o valor medido não mudar.
  • One-shot: O período de amostragem é ignorado.
  • Especial: Para obter mais detalhes, consulte Tipos de sensores .

Para saber mais sobre a interação entre um período de amostragem e os modos de relatório de um sensor, consulte Modos de relatório .

Latência máxima de relatórios

A latência máxima de relatório define o tempo máximo em nanossegundos que os eventos podem ser atrasados ​​e armazenados no FIFO de hardware antes de serem gravados no Event FMQ por meio do HAL enquanto o SoC está ativo.

Um valor zero significa que os eventos devem ser relatados assim que forem medidos, ignorando completamente o FIFO ou esvaziando o FIFO assim que um evento do sensor estiver presente no FIFO.

Por exemplo, um acelerômetro ativado a 50 Hz com latência máxima de relatório de zero gatilhos interrompe 50 vezes por segundo quando o SoC está ativo.

Quando a latência máxima de relatório é superior a zero, os eventos do sensor não precisam de ser comunicados assim que são detetados. Os eventos podem ser armazenados temporariamente no hardware FIFO e relatados em lotes, desde que nenhum evento seja atrasado mais do que a latência máxima de relatório. Todos os eventos desde o lote anterior são registrados e retornados de uma só vez. Isso reduz o número de interrupções enviadas ao SoC e permite que o SoC mude para um modo de menor consumo de energia enquanto o sensor captura e agrupa dados em lote.

Cada evento tem um carimbo de data/hora associado a ele. Atrasar o horário em que um evento é relatado não deve afetar o carimbo de data/hora do evento. O carimbo de data/hora deve ser preciso e corresponder ao horário em que o evento ocorreu fisicamente, e não ao horário em que foi relatado.

Para obter informações e requisitos adicionais sobre como relatar eventos de sensor com latência máxima de relatório diferente de zero, consulte Lote .

Ativando sensores

A estrutura habilita e desabilita sensores usando a função activate() . Antes de ativar um sensor, a estrutura deve primeiro configurar o sensor usando batch() .

Depois que um sensor for desativado, eventos de sensor adicionais desse sensor não deverão ser gravados no Event FMQ.

Sensores de lavagem

Se um sensor estiver configurado para armazenar dados do sensor em lote, a estrutura poderá forçar uma liberação imediata de eventos de sensor em lote chamando flush() . Isso faz com que os eventos de sensor em lote para o identificador de sensor especificado sejam imediatamente gravados no Event FMQ. O Sensors HAL deve anexar um evento flush complete ao final dos eventos do sensor que são gravados como resultado de uma chamada para flush() .

A liberação acontece de forma assíncrona (ou seja, esta função deve retornar imediatamente). Se a implementação usar um único FIFO para vários sensores, esse FIFO será liberado e o evento flush complete será adicionado apenas para o sensor especificado.

Se o sensor especificado não tiver FIFO (sem buffer possível) ou se o FIFO estiver vazio no momento da chamada, flush() ainda deverá ser bem-sucedido e enviar um evento de liberação completa para esse sensor. Isto se aplica a todos os sensores, exceto sensores de disparo único.

Se flush() for chamado para um sensor único, então flush() deverá retornar BAD_VALUE e não gerar um evento de liberação completa.

Gravando eventos de sensor no FMQ

O Event FMQ é usado pelo Sensors HAL para enviar eventos de sensor para a estrutura de sensor Android.

O Event FMQ é um FMQ sincronizado, o que significa que qualquer tentativa de gravar mais eventos no FMQ do que o espaço disponível permite resulta em falha na gravação. Nesse caso, o HAL deve determinar se deve escrever o conjunto atual de eventos como dois grupos menores de eventos ou escrever todos os eventos juntos quando houver espaço suficiente disponível.

Quando o Sensors HAL gravou o número desejado de eventos de sensor no Event FMQ, o Sensors HAL deve notificar a estrutura de que os eventos estão prontos gravando o bit EventQueueFlagBits::READ_AND_PROCESS na função EventFlag::wake do Event FMQ. O EventFlag pode ser criado a partir do Event FMQ usando EventFlag::createEventFlag e a função getEventFlagWord() do Event FMQ.

O Sensors AIDL HAL suporta write e writeBlocking no Event FMQ. A implementação padrão fornece uma referência para usar write . Se a função writeBlocking for usada, o sinalizador readNotification deverá ser definido como EventQueueFlagBits::EVENTS_READ , que é definido pela estrutura quando ela lê eventos do Event FMQ. O sinalizador de notificação de gravação deve ser definido como EventQueueFlagBits::READ_AND_PROCESS , que notifica a estrutura de que eventos foram gravados no Event FMQ.

Eventos WAKE_UP

Eventos WAKE_UP são eventos de sensor que fazem com que o processador de aplicativos (AP) seja ativado e manipule o evento imediatamente. Sempre que um evento WAKE_UP é gravado no Event FMQ, o Sensors HAL deve proteger um wake lock para garantir que o sistema permaneça ativo até que a estrutura possa lidar com o evento. Ao receber um evento WAKE_UP , a estrutura protege seu próprio wake lock, permitindo que o Sensors HAL libere seu wake lock. Para sincronizar quando o Sensors HAL libera seu wake lock, use o Wake Lock FMQ.

O Sensors HAL deve ler o Wake Lock FMQ para determinar o número de eventos WAKE_UP que a estrutura manipulou. O HAL só deverá liberar seu wake lock para eventos WAKE_UP se o número total de eventos WAKE_UP não tratados for zero. Depois de tratar os eventos do sensor, a estrutura conta o número de eventos marcados como eventos WAKE_UP e grava esse número de volta no Wake Lock FMQ.

A estrutura define a notificação de gravação WakeLockQueueFlagBits::DATA_WRITTEN no Wake Lock FMQ sempre que grava dados no Wake Lock FMQ.

Sensores dinâmicos

Sensores dinâmicos são sensores que não fazem parte fisicamente do dispositivo, mas podem ser usados ​​como entrada para o dispositivo, como um gamepad com acelerômetro.

Quando um sensor dinâmico é conectado, a função onDynamicSensorConnected em ISensorsCallback deve ser chamada a partir do Sensors HAL. Isso notifica a estrutura do novo sensor dinâmico e permite que o sensor seja controlado através da estrutura e que os eventos do sensor sejam consumidos pelos clientes.

Da mesma forma, quando um sensor dinâmico é desconectado, a função onDynamicSensorDisconnected em ISensorsCallback deve ser chamada para que a estrutura possa remover qualquer sensor que não esteja mais disponível.

Canal direto

Canal direto é um método de operação em que os eventos do sensor são gravados em uma memória específica, em vez de no Event FMQ, ignorando o Android Sensors Framework. Um cliente que registra um canal direto deve ler os eventos do sensor diretamente da memória que foi utilizada para criar o canal direto e não receberá os eventos do sensor através do framework. A função configDirectReport() é semelhante a batch() para operação normal e configura o canal de reporte direto.

As funções registerDirectChannel() e unregisterDirectChannel() criam ou destroem um novo canal direto.

Modos de operação

A função setOperationMode() permite que a estrutura configure um sensor para que a estrutura possa injetar dados do sensor no sensor. Isto é útil para testes, especialmente para algoritmos que existem abaixo da estrutura.

A função injectSensorData() normalmente é usada para enviar parâmetros operacionais para o HAL dos sensores. A função também pode ser usada para injetar eventos de sensor em um sensor específico.

Validação

Para validar sua implementação dos Sensores HAL, execute os testes CTS e VTS do sensor.

Testes CTS

Os testes Sensor CTS existem em testes CTS automatizados e no aplicativo CTS Verifier manual.

Os testes automatizados estão localizados em cts/tests/sensor/src/android/hardware/cts . Esses testes verificam a funcionalidade padrão dos sensores, como ativação de sensores, lotes e taxas de eventos de sensores.

Os testes do CTS Verifier estão localizados em cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors . Esses testes exigem entrada manual do operador de teste e garantem que os sensores relatem valores precisos.

Passar nos testes CTS é fundamental para garantir que o dispositivo em teste atenda a todos os requisitos do CDD.

Testes VTS

Os testes VTS para os Sensores AIDL HAL estão localizados em hardware/interfaces/sensors/aidl/vts/ . Esses testes garantem que o Sensors HAL seja implementado corretamente e que todos os requisitos de ISensors.aidl e ISensorsCallback.aidl sejam atendidos adequadamente.

Inicializando o HAL

A função initialize() deve ser suportada para estabelecer FMQs entre a estrutura e o HAL.

Expondo sensores disponíveis

No Sensors AIDL HAL, a função getSensorsList() deve retornar o mesmo valor durante a inicialização de um único dispositivo, mesmo durante as reinicializações do Sensors HAL. Um novo requisito da função getSensorsList() é que ela deve retornar o mesmo valor durante a inicialização de um único dispositivo, mesmo durante as reinicializações do Sensors HAL. Isso permite que a estrutura tente restabelecer as conexões dos sensores se o servidor do sistema for reiniciado. O valor retornado por getSensorsList() pode mudar após a reinicialização do dispositivo.

Gravando eventos de sensor no FMQ

Em vez de esperar que poll() seja chamado, no Sensors AIDL HAL, o Sensors HAL deve gravar proativamente eventos de sensor no Event FMQ sempre que eventos de sensor estiverem disponíveis. O HAL também é responsável por escrever os bits corretos no EventFlag para causar uma leitura do FMQ dentro da estrutura.

Eventos WAKE_UP

No Sensors HAL 1.0, o HAL foi capaz de liberar seu wake lock para qualquer evento WAKE_UP em qualquer chamada subsequente para poll() depois que um WAKE_UP foi postado em poll() porque isso indicava que a estrutura havia processado todos os eventos do sensor e obtido um wake lock, se necessário. Como, no Sensors AIDL HAL, o HAL não é mais notificado quando a estrutura processa eventos gravados no FMQ, o Wake Lock FMQ permite que a estrutura se comunique com o HAL quando ela tiver manipulado eventos WAKE_UP .

No Sensors AIDL HAL, o wake lock protegido pelo Sensors HAL para eventos WAKE_UP deve começar com SensorsHAL_WAKEUP .

Sensores dinâmicos

Os sensores dinâmicos foram retornados usando a função poll() no Sensors HAL 1.0. O Sensors AIDL HAL exige que onDynamicSensorsConnected e onDynamicSensorsDisconnected em ISensorsCallback sejam chamados sempre que as conexões de sensores dinâmicos mudarem. Esses retornos de chamada estão disponíveis como parte do ponteiro ISensorsCallback fornecido por meio da função initialize() .

Modos de operação

O modo DATA_INJECTION para sensores WAKE_UP deve ser suportado.

Suporte multi-HAL

O Sensors AIDL HAL suporta multi-HAL usando a estrutura Sensors Multi-HAL . Para obter detalhes de implementação, consulte Portando de Sensores HAL 2.1 .