Sensores HAL 2.0

La capa de abstracción de hardware (HAL) de sensores es la interfaz entre el framework de sensores de Android y los sensores de un dispositivo, como un acelerómetro o un giroscopio. La HAL de sensores define las funciones que se deben implementar para permitir que el framework controle los sensores.

La HAL de sensores 2.0 está disponible en Android 10 y versiones posteriores para dispositivos nuevos y actualizados. La HAL de sensores 2.0 se basa en Sensors HAL 1.0, pero tiene varias diferencias clave que impiden que sea compatible con versiones anteriores. La HAL de sensores 2.0 usa colas de mensajes rápidos (FMQ) para enviar eventos de sensores desde la HAL al framework de sensores de Android.

La HAL de sensores 2.1 está disponible en Android 11 y versiones posteriores para dispositivos nuevos y actualizados. La HAL de sensores 2.1 es una iteración de la HAL de sensores 2.0 que expone el tipo de sensor HINGE_ANGLE y actualiza varios métodos para aceptar el tipo HINGE_ANGLE.

Interfaz de HAL 2.1

La principal fuente de documentación para la HAL de sensores 2.1 se encuentra en la HAL definición en hardware/interfaces/sensors/2.1/ISensors.hal. Si hay un conflicto de requisitos entre esta página y ISensors.hal, usa el requisito en ISensors.hal.

Interfaz de HAL 2.0

La principal fuente de documentación para la HAL de sensores 2.0 se encuentra en la definición de HAL en hardware/interfaces/sensors/2.0/ISensors.hal. Si hay un conflicto de requisitos entre esta página y ISensors.hal, usa el requisito en ISensors.hal.

Implementa la HAL de sensores 2.0 y la HAL de sensores 2.1

Para implementar la HAL de sensores 2.0 o 2.1, un objeto debe extender la ISensors interfaz e implementar todas las funciones definidas en 2.0/ISensors.hal o 2.1/ISensors.hal.

Inicializa la HAL

El framework de sensores de Android debe inicializar la HAL de sensores antes de que se pueda usar. El framework llama a la función initialize() para la HAL 2.0 y a la función initialize_2_1() para la HAL 2.1 para proporcionar tres parámetros a la HAL de sensores: dos descriptores de FMQ y un puntero a un objeto ISensorsCallback.

La HAL usa el primer descriptor para crear la FMQ de eventos que se usa para escribir eventos de sensores en el framework. La HAL usa el segundo descriptor para crear la FMQ de bloqueo de activación que se usa para sincronizar cuando la HAL libera su bloqueo de activación para eventos de sensores WAKE_UP. La HAL debe guardar un puntero al objeto ISensorsCallback para que se puedan invocar las funciones de devolución de llamada necesarias.

La función initialize() o initialize_2_1() debe ser la primera función a la que se llame cuando se inicializa la HAL de sensores.

Expón los sensores disponibles

Para obtener una lista de todos los sensores estáticos disponibles en el dispositivo, usa la función getSensorsList() en la HAL 2.0 y la función getSensorsList_2_1() en la HAL 2.1. Esta función muestra una lista de sensores, cada uno identificado de forma única por su controlador. El controlador de un sensor determinado no debe cambiar cuando se reinicia el proceso que aloja la HAL de sensores. Los controladores pueden cambiar en los reinicios del dispositivo y en los reinicios del servidor del sistema.

Si varios sensores comparten el mismo tipo de sensor y la misma propiedad de activación, el primer sensor de la lista se denomina sensor predeterminado y se muestra a las apps que utilizan la función getDefaultSensor(int sensorType, bool wakeUp).

Estabilidad de la lista de sensores

Después de un reinicio de la HAL de sensores, si los datos que muestra getSensorsList() o getSensorsList_2_1() indican un cambio significativo en comparación con la lista de sensores recuperada antes del reinicio, el framework activa un reinicio del tiempo de ejecución de Android. Los cambios significativos en la lista de sensores incluyen casos en los que falta un sensor con un controlador determinado o tiene atributos modificados, o bien cuando se introducen sensores nuevos. Aunque reiniciar el tiempo de ejecución de Android es perjudicial para el usuario, es necesario porque el framework de Android ya no puede cumplir con el contrato de la API de Android que indica que los sensores estáticos (no dinámicos) no cambian durante la vida útil de una app. Esto también puede impedir que el framework restablezca las solicitudes de sensores activos realizadas por las apps. Por lo tanto, se recomienda a los proveedores de HAL que eviten los cambios innecesarios en la lista de sensores.

Para garantizar controladores de sensores estables, la HAL debe asignar de forma determinista un sensor físico determinado en el dispositivo a su controlador. Aunque la interfaz de la HAL de sensores no exige ninguna implementación específica, los desarrolladores tienen varias opciones disponibles para cumplir con este requisito.

Por ejemplo, la lista de sensores se puede ordenar con una combinación de los atributos fijos de cada sensor, como el proveedor, el modelo y el tipo de sensor. Otra opción se basa en el hecho de que el conjunto de sensores estáticos del dispositivo está fijo en el hardware, por lo que la HAL debe saber cuándo todos los sensores esperados completaron la inicialización antes de mostrar getSensorsList() o getSensorsList_2_1(). Esta lista de sensores esperados se puede compilar en el objeto binario de la HAL o almacenarse en un archivo de configuración en el sistema de archivos, y el orden de aparición se puede usar para derivar controladores estables. Aunque la mejor solución depende de los detalles de implementación específicos de tu HAL, el requisito clave es que los controladores de sensores no cambien en los reinicios de la HAL.

Configura los sensores

Antes de activar un sensor, se debe configurar con un período de muestreo y una latencia máxima de informes mediante la función batch().

Un sensor debe poder reconfigurarse en cualquier momento con batch() sin perder datos del sensor.

Período de muestreo

El período de muestreo tiene un significado diferente según el tipo de sensor que se esté configurando:

  • Continuo: Los eventos de sensores se generan a una velocidad continua.
  • En el cambio: Los eventos no se generan más rápido que el período de muestreo y pueden generarse a una velocidad más lenta que el período de muestreo si el valor medido no cambia.
  • Único: Se ignora el período de muestreo.
  • Especial: Para obtener más detalles, consulta Tipos de sensores.

Para obtener información sobre la interacción entre un período de muestreo y los modos de informes de un sensor, consulta Modos de informes.

Latencia máxima de informes

La latencia máxima de informes establece el tiempo máximo en nanosegundos que se pueden retrasar y almacenar los eventos en la FIFO de hardware antes de escribirse en la FMQ de eventos a través de la HAL mientras el SoC está activo.

Un valor de cero indica que los eventos se deben informar en cuanto se midan, ya sea omitiendo la FIFO por completo o vaciándola en cuanto un evento del sensor esté presente en la FIFO.

Por ejemplo, un acelerómetro activado a 50 Hz con una latencia máxima de informes de cero activa interrupciones 50 veces por segundo cuando el SoC está activo.

Cuando la latencia máxima de informes es mayor que cero, no es necesario informar los eventos de sensores en cuanto se detectan. Los eventos se pueden almacenar temporalmente en la FIFO de hardware y se pueden informar en lotes, siempre que ningún evento se retrase más que la latencia máxima de informes. Todos los eventos desde el lote anterior se registran y se muestran a la vez. Esto reduce la cantidad de interrupciones enviadas al SoC y permite que el SoC cambie a un modo de menor consumo de energía mientras el sensor captura y agrupa datos en lotes.

Cada evento tiene una marca de tiempo asociada. Retrasar el momento en que se informa un evento no debe afectar la marca de tiempo del evento. La marca de tiempo debe ser precisa y corresponder al momento en que ocurrió el evento físicamente, no al momento en que se informó.

Para obtener información y requisitos adicionales sobre cómo informar eventos de sensores con una latencia máxima de informes distinta de cero, consulta Agrupación en lotes.

Activa los sensores

El framework habilita y deshabilita los sensores con la función activate(). Antes de activar un sensor, el framework primero debe configurarlo con batch().

Después de desactivar un sensor, no se deben escribir eventos de sensores adicionales de ese sensor en la FMQ de eventos.

Vaciar los sensores

Si un sensor está configurado para agrupar datos de sensores en lotes, el framework puede forzar una limpieza inmediata de los eventos de sensores agrupados en lotes llamando a flush(). Esto hace que los eventos de sensores agrupados en lotes para el controlador de sensor especificado se escriban de inmediato en la FMQ de eventos. La HAL de sensores debe agregar un evento de limpieza completa al final de los eventos de sensores que se escriben como resultado de una llamada a flush().

La limpieza ocurre de forma asíncrona (es decir, esta función debe mostrarse de inmediato). Si la implementación usa una sola FIFO para varios sensores, se limpia esa FIFO y el evento de limpieza completa se agrega solo para el sensor especificado.

Si el sensor especificado no tiene FIFO (no es posible el almacenamiento en búfer) o si la FIFO estaba vacía en el momento de la llamada, flush() debe tener éxito y enviar un evento de limpieza completa para ese sensor. Esto se aplica a todos los sensores que no sean de un solo disparo.

Si se llama a flush() para un sensor de un solo disparo, flush() debe mostrar BAD_VALUE y no generar un evento de limpieza completa.

Escribe eventos de sensores en la FMQ

La HAL de sensores usa la FMQ de eventos para enviar eventos de sensores al framework de sensores de Android.

La FMQ de eventos es una FMQ sincronizada, lo que significa que cualquier intento de escribir más eventos en la FMQ que el espacio disponible permite que se produzca una escritura fallida. En ese caso, la HAL debe determinar si escribir el conjunto actual de eventos como dos grupos de eventos más pequeños o escribir todos los eventos juntos cuando haya suficiente espacio disponible.

Cuando la HAL de sensores haya escrito la cantidad deseada de eventos de sensores en la FMQ de eventos, la HAL de sensores debe notificar al framework que los eventos están listos escribiendo el bit EventQueueFlagBits::READ_AND_PROCESS en la función EventFlag::wake de la FMQ de eventos. El EventFlag se puede crear desde la FMQ de eventos con EventFlag::createEventFlag y la función getEventFlagWord() de la FMQ de eventos.

La HAL de sensores 2.0/2.1 admite write y writeBlocking en la FMQ de eventos. La implementación predeterminada proporciona una referencia para usar write. Si se usa la función writeBlocking, la marca readNotification debe establecerse en EventQueueFlagBits::EVENTS_READ, que establece el framework cuando lee eventos de la FMQ de eventos. La marca de notificación de escritura debe establecerse en EventQueueFlagBits::READ_AND_PROCESS, que notifica al framework que se escribieron eventos en la FMQ de eventos.

Eventos WAKE_UP

Los eventos WAKE_UP son eventos de sensores que hacen que el procesador de aplicaciones (AP) se active y controle el evento de inmediato. Cada vez que se escribe un evento WAKE_UP en la FMQ de eventos, la HAL de sensores debe proteger un bloqueo de activación para garantizar que el sistema permanezca activo hasta que el framework pueda controlar el evento. Cuando recibe un evento WAKE_UP, el framework protege su propio bloqueo de activación, lo que permite que la HAL de sensores libere su bloqueo de activación. Para sincronizar cuando la HAL de sensores libera su bloqueo de activación, usa la FMQ de bloqueo de activación.

La HAL de sensores debe leer la FMQ de bloqueo de activación para determinar la cantidad de eventos WAKE_UP que controló el framework. La HAL solo debe liberar su bloqueo de activación para eventos WAKE_UP si la cantidad total de eventos WAKE_UP no controlados es cero. Después de controlar los eventos de sensores, el framework cuenta la cantidad de eventos marcados como eventos WAKE_UP y vuelve a escribir este número en la FMQ de bloqueo de activación.

El framework establece la notificación de escritura WakeLockQueueFlagBits::DATA_WRITTEN en la FMQ de bloqueo de activación cada vez que escribe datos en la FMQ de bloqueo de activación.

Sensores dinámicos

Los sensores dinámicos son sensores que no forman parte física del dispositivo, pero se pueden usar como entrada para el dispositivo, como un gamepad con un acelerómetro.

Cuando se conecta un sensor dinámico, se debe llamar a la función onDynamicSensorConnected en ISensorsCallback desde la HAL de sensores. Esto notifica al framework sobre el nuevo sensor dinámico y permite que el sensor se controle a través del framework y que los clientes consuman los eventos del sensor.

Del mismo modo, cuando se desconecta un sensor dinámico, se debe llamar a la función onDynamicSensorDisconnected en ISensorsCallback para que el framework pueda quitar cualquier sensor que ya no esté disponible.

Canal directo

El canal directo es un método de operación en el que los eventos de sensores se escriben en una memoria específica en lugar de en la FMQ de eventos, lo que omite el framework de sensores de Android. Un cliente que registra un canal directo debe leer los eventos de sensores directamente desde la memoria que se usó para crear el canal directo y no recibirá los eventos de sensores a través del framework. La función configDirectReport() es similar a batch() para el funcionamiento normal y configura el canal de informes directos.

Las funciones registerDirectChannel() y unregisterDirectChannel() crean o destruyen un nuevo canal directo.

Modos de operación

La función setOperationMode() permite que el framework configure un sensor para que el framework pueda insertar datos de sensores en el sensor. Esto es útil para las pruebas, en especial para los algoritmos que existen debajo del framework.

Por lo general, la función injectSensorData() en la HAL 2.0 y la función injectSensorsData_2_1() en la HAL 2.0 se usan para enviar parámetros operativos a la HAL de sensores. La función también se puede usar para insertar eventos de sensores en un sensor específico.

Validación

Para validar tu implementación de la HAL de sensores, ejecuta las pruebas de CTS y VTS de sensores.

Pruebas de CTS

Las pruebas de CTS de sensores existen en las pruebas de CTS automatizadas y en la app manual del verificador de CTS.

Las pruebas automatizadas se encuentran en cts/tests/sensor/src/android/hardware/cts. Estas pruebas verifican la funcionalidad estándar de los sensores, como la activación de sensores, la agrupación en lotes y las tasas de eventos de sensores.

Las pruebas del verificador de CTS se encuentran en cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors. Estas pruebas requieren la entrada manual del operador de prueba y garantizan que los sensores informen valores precisos.

Aprobar las pruebas de CTS es fundamental para garantizar que el dispositivo en prueba cumpla con todos los requisitos del CDD.

Pruebas de VTS

Las pruebas de VTS para la HAL de sensores 2.0 se encuentran en hardware/interfaces/sensors/2.0/vts. Las pruebas de VTS para la HAL de sensores 2.1 se encuentran en hardware/interfaces/sensors/2.1/vts. Estas pruebas garantizan que la HAL de sensores se implemente correctamente y que se cumplan todos los requisitos dentro de ISensors.hal y ISensorsCallback.hal.

Actualiza a la HAL de sensores 2.1 desde la 2.0

Cuando actualices a la HAL de sensores 2.1 desde la 2.0, tu implementación de HAL debe incluir los métodos initialize_2_1(), getSensorsList_2_1() y injectSensorsData_2_1(), junto con los tipos de HAL 2.1. Estos métodos deben cumplir con los mismos requisitos que se describen para la HAL 2.0 más arriba.

Dado que las HAL de versiones secundarias deben admitir todas las funciones de las HAL anteriores, las HAL 2.1 deben admitir la inicialización como HAL 2.0. Para evitar la complejidad de admitir ambas versiones de HAL, se recomienda usar Multi-HAL 2.1.

Para ver un ejemplo de cómo implementar tu propia HAL de sensores 2.1, consulta Sensors.h.

Actualiza a la HAL de sensores 2.0 desde la 1.0

Cuando actualices a la HAL de sensores 2.0 desde la 1.0, asegúrate de que tu implementación de HAL cumpla con los siguientes requisitos.

Inicializa la HAL

Se debe admitir la función initialize() para establecer FMQ entre el framework y la HAL.

Expón los sensores disponibles

En la HAL de sensores 2.0, la función getSensorsList() debe mostrar el mismo valor durante un solo inicio del dispositivo, incluso en los reinicios de la HAL de sensores. Un nuevo requisito de la función getSensorsList() es que debe mostrar el mismo valor durante un solo inicio del dispositivo, incluso en los reinicios de la HAL de sensores. Esto permite que el framework intente restablecer las conexiones de sensores si se reinicia el servidor del sistema. El valor que muestra getSensorsList() puede cambiar después de que el dispositivo realice un reinicio.

Escribe eventos de sensores en la FMQ

En lugar de esperar a que se llame a poll(), en la HAL de sensores 2.0, la HAL de sensores debe escribir de forma proactiva eventos de sensores en la FMQ de eventos cada vez que estén disponibles. La HAL también es responsable de escribir los bits correctos en EventFlag para provocar una lectura de FMQ dentro del framework.

Eventos WAKE_UP

En la HAL de sensores 1.0, la HAL podía liberar su bloqueo de activación para cualquier evento WAKE_UP en cualquier llamada posterior a poll() después de que se publicara un WAKE_UP en poll(), ya que esto indicaba que el framework había procesado todos los eventos de sensores y había obtenido un bloqueo de activación, si era necesario. Debido a que, en la HAL de sensores 2.0, la HAL ya no sabe cuándo el framework procesó los eventos escritos en la FMQ, la FMQ de bloqueo de activación permite que el framework se comunique con la HAL cuando controla eventos WAKE_UP.

En la HAL de sensores 2.0, el bloqueo de activación protegido por la HAL de sensores para eventos WAKE_UP debe comenzar con SensorsHAL_WAKEUP.

Sensores dinámicos

Los sensores dinámicos se mostraban con la función poll() en la HAL de sensores 1.0. La HAL de sensores 2.0 requiere que se llame a onDynamicSensorsConnected y onDynamicSensorsDisconnected en ISensorsCallback cada vez que cambien las conexiones de sensores dinámicos. Estas devoluciones de llamada están disponibles como parte del puntero ISensorsCallback que se proporciona a través de la función initialize().

Modos de operación

Se debe admitir el modo DATA_INJECTION para los sensores WAKE_UP en la HAL de sensores 2.0.

Compatibilidad con Multi-HAL

La HAL de sensores 2.0 y 2.1 admite Multi-HAL con el framework de sensores Multi-HAL. Para obtener detalles de la implementación, consulta Cómo realizar la portabilidad desde la HAL de sensores 1.0.