La capa de abstracción de hardware de sensores (HAL) es la interfaz entre el framework de sensores de Android y los sensores de un dispositivo, como un acelerómetro o un giroscopio. El HAL de sensores define las funciones que se deben implementar para permitir que el framework controle los sensores.
El 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 la HAL de sensores 1.0, pero tiene varias diferencias clave que impiden la retrocompatibilidad. La HAL de sensores 2.0 usa colas de mensajes rápidos (FMQ) para enviar eventos de sensores desde la HAL al marco de trabajo del sensor 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 fuente principal de documentación para la HAL de sensores 2.1 se encuentra dentro de la definición de HAL en hardware/interfaces/sensors/2.1/ISensors.hal.
Si existe un conflicto de requisitos entre esta página y ISensors.hal
, usa el requisito de ISensors.hal
.
Interfaz de HAL 2.0
La fuente principal de documentación para la HAL de sensores 2.0 se encuentra dentro de la definición de la 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 de ISensors.hal
.
Implementa los HAL de sensores 2.0 y 2.1
Para implementar la HAL de sensores 2.0 o 2.1, un objeto debe extender la interfaz ISensors
y, luego, implementar todas las funciones definidas en 2.0/ISensors.hal
o 2.1/ISensors.hal
.
Inicializa el sistema 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 HAL 2.0 y a la función initialize_2_1()
para 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 sensor en el framework. El sistema HAL usa el segundo descriptor para crear la FMQ de bloqueo de activación que se usa para sincronizar cuando el sistema HAL libera su bloqueo de activación para los eventos del sensor WAKE_UP
. El 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 llama cuando se inicializa el HAL de sensores.
Expone los sensores disponibles
Para obtener una lista de todos los sensores estáticos disponibles en el dispositivo, usa la función getSensorsList()
en HAL 2.0 y la función getSensorsList_2_1()
en HAL 2.1. Esta función muestra una lista de sensores, cada uno identificado de forma única por su identificador. El identificador de un sensor determinado no debe cambiar cuando se reinicia el proceso que aloja el HAL de los sensores. Los identificadores pueden cambiar entre los reinicios del dispositivo y los reinicios del servidor del sistema.
Si varios sensores comparten el mismo tipo de sensor y propiedad de activación, el primer sensor de la lista se denomina sensor predeterminado y se devuelve a las apps que usan la función getDefaultSensor(int sensorType, bool wakeUp)
.
Estabilidad de la lista de sensores
Después de un reinicio del sistema 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 entorno de ejecución de Android. Los cambios significativos en la lista de sensores incluyen casos en los que falta un sensor con un identificador determinado o se cambiaron sus atributos, o bien cuando se introducen sensores nuevos. Si bien reiniciar el entorno de ejecución de Android es disruptivo para el usuario, es necesario porque el framework de Android ya no puede cumplir con el contrato de la API de Android que establece que los sensores estáticos (no dinámicos) no cambian durante el ciclo de vida de una app. Esto también puede impedir que el framework restablezca las solicitudes de sensores activos que realizan las apps. Por lo tanto, se recomienda a los proveedores de HAL que eviten cambios evitables en la lista de sensores.
Para garantizar controladores de sensores estables, el sistema HAL debe asignar de forma determinista un sensor físico determinado en el dispositivo a su controlador. Si bien la interfaz de 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 el HAL debe saber cuándo todos los sensores esperados completaron la inicialización antes de regresar de getSensorsList()
o getSensorsList_2_1()
. Esta lista de sensores esperados se puede compilar en el objeto binario 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. Si bien 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 durante los reinicios de HAL.
Configura sensores
Antes de que se active un sensor, se debe configurar con un período de muestreo y la latencia de informe máxima 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 configura:
- Continuo: Los eventos del sensor se generan a una velocidad continua.
- Al cambiar: 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 más información sobre la interacción entre un período de muestreo y los modos de informe de un sensor, consulta Modos de generación de informes.
Latencia máxima de los informes
La latencia máxima de informes establece el tiempo máximo en nanosegundos que los eventos pueden retrasarse y almacenarse en la FIFO de hardware antes de escribirse en la FMQ de eventos a través del HAL mientras el SoC está activo.
Un valor de cero significa que los eventos se deben informar en cuanto se miden, ya sea omitiendo la fila FIFO por completo o vaciándola en cuanto haya un evento del sensor en la fila FIFO.
Por ejemplo, un acelerómetro activado a 50 Hz con una latencia de informe máxima de cero activadores interrumpe 50 veces por segundo cuando el SoC está activo.
Cuando la latencia máxima de informe es mayor que cero, los eventos del sensor no necesitan informarse en cuanto se detectan. Los eventos se pueden almacenar de forma temporal en el FIFO de hardware y se pueden informar por lotes, siempre que no se retrase ningún evento que supere la latencia máxima de informe. Todos los eventos desde el lote anterior se registran y se muestran en una sola acción. Esto reduce la cantidad de interrupciones enviadas al SoC y permite que este cambie a un modo de menor consumo mientras el sensor captura y procesa los datos en lotes.
Cada evento tiene una marca de tiempo asociada. Retrasar el momento en el que se informa un evento no debe afectar la marca de tiempo del evento. La marca de tiempo debe ser precisa y corresponder a la hora a la que ocurrió físicamente el evento, no a la hora en la 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.
Cómo activar los sensores
El framework habilita e inhabilita los sensores con la función activate()
.
Antes de activar un sensor, el framework debe configurarlo con batch()
.
Después de desactivar un sensor, los eventos de sensor adicionales de ese sensor no se deben escribir en el evento FMQ.
Sensores empotrables
Si un sensor está configurado para procesar datos por lotes, el framework puede forzar una limpieza inmediata de los eventos de sensor por lotes llamando a flush()
. Esto hace que los eventos de sensores por lotes del controlador de sensores especificado se escriban de inmediato en la FMQ de eventos. La HAL de sensores debe agregar un evento de vaciado completo al final de los eventos de sensores que se escriben como resultado de una llamada a flush()
.
La limpieza se realiza de forma asíncrona (es decir, esta función debe mostrarse de inmediato). Si la implementación usa un solo FIFO para varios sensores, se borra ese FIFO y se agrega el evento de limpieza completa solo para el sensor especificado.
Si el sensor especificado no tiene FIFO (no se puede almacenar en búfer) o si el FIFO estaba vacío en el momento de la llamada, flush()
aún debe tener éxito y enviar un evento de limpieza completa para ese sensor. Esto se aplica a todos los sensores, excepto a los de un solo disparo.
Si se llama a flush()
para un sensor único, flush()
debe mostrar BAD_VALUE
y no generar un evento de vaciado completo.
Cómo escribir 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 operación de escritura fallida. En ese caso, el sistema HAL debe determinar si escribir el conjunto actual de eventos como dos grupos más pequeños de eventos o escribir todos los eventos juntos cuando haya suficiente espacio disponible.
Cuando la HAL de sensores escribió la cantidad deseada de eventos del sensor 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. Se puede crear el objeto EventFlag 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 el framework establece cuando lee eventos del FMQ del evento. La marca de notificación de escritura se debe establecer 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 la aplicación (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 el HAL de sensores libere su bloqueo de activación. Para sincronizar cuándo la HAL de sensores libera su bloqueo de activación, usa la FMQ de bloqueo de activación.
El HAL de sensores debe leer el FMQ de bloqueo de activación para determinar la cantidad de eventos WAKE_UP
que manejó el framework. El sistema 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 del sensor, el framework cuenta la cantidad de eventos que se marcan como eventos WAKE_UP
y vuelve a escribir este número en la FMQ de Wake Lock.
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 ella.
Sensores dinámicos
Los sensores dinámicos son sensores que no forman parte física del dispositivo, pero que se pueden usar como entrada para el dispositivo, como un control de juegos con un acelerómetro.
Cuando se conecta un sensor dinámico, se debe llamar a la función onDynamicSensorConnected
en ISensorsCallback
desde el HAL de sensores. Esto notifica al framework del nuevo sensor dinámico y permite que se controle a través del framework y que los clientes consuman los eventos del sensor.
De manera similar, 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 del sensor se escriben en una memoria específica en lugar de la FMQ de eventos, lo que evita el framework de sensores de Android. Un cliente que registra un canal directo debe leer los eventos del sensor directamente desde la memoria que se usó para crear el canal directo y no recibirá los eventos del sensor a través del framework. La función configDirectReport()
es similar a batch()
para el funcionamiento normal y configura el canal de informes directo.
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 pueda insertar datos en él. 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 usa para enviar parámetros operativos a la HAL de sensores. La función también se puede usar para insertar eventos del sensor en un sensor específico.
Validación
Para validar tu implementación del HAL de sensores, ejecuta las pruebas de CTS y VTS del sensor.
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 los sensores, el procesamiento por lotes y las tasas de eventos de los sensores.
Las pruebas del verificador del CTS se encuentran en cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors. Estas pruebas requieren entradas manuales del operador de prueba y garantizan que los sensores informen valores precisos.
Pasar 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 esté implementada correctamente y que se cumplan correctamente todos los requisitos de ISensors.hal
y ISensorsCallback.hal
.
Actualiza a la HAL de sensores 2.1 desde la versión 2.0
Cuando actualizas a la HAL de sensores 2.1 desde la versión 2.0, la implementación de la 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 describieron para HAL 2.0 anteriormente.
Debido a que las HAL de versiones secundarias deben admitir todas las funciones de las HAL anteriores, las HAL 2.1 deben admitir que se inicialicen 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 propio HAL de sensores 2.1, consulta Sensors.h.
Actualiza de la HAL de sensores 1.0 a la 2.0
Cuando actualices la HAL de sensores 2.0 desde la versión 1.0, asegúrate de que la implementación de la HAL cumpla con los siguientes requisitos.
Inicializa el sistema HAL
La función initialize()
debe admitirse para establecer FMQ entre el framework y HAL.
Cómo exponer los sensores disponibles
En el HAL de sensores 2.0, la función getSensorsList()
debe mostrar el mismo valor durante el inicio de un solo dispositivo, incluso en los reinicios del HAL de sensores. Un nuevo requisito de la función getSensorsList()
es que debe mostrar el mismo valor durante el inicio de un solo dispositivo, incluso en los reinicios de HAL de los sensores. Esto permite que el framework intente restablecer las conexiones de los sensores si se reinicia el servidor del sistema. El valor que muestra getSensorsList()
puede cambiar después de que el dispositivo se reinicie.
Cómo escribir 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 los eventos de sensores en la FMQ del evento siempre 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 pudo liberar su bloqueo de activación para cualquier evento WAKE_UP
en cualquier llamada posterior a poll()
después de que se publicara una WAKE_UP
en poll()
, ya que esto indicaba que el framework había procesado todos los eventos del sensor y obtuvo un bloqueo de activación, si fuera necesario. Debido a que, en la HAL de sensores 2.0, la HAL ya no sabe cuándo el framework procesó eventos escritos en la FMQ, la FMQ de bloqueo de activación permite que el framework se comunique con la HAL cuando haya controlado eventos WAKE_UP
.
En el HAL de sensores 2.0, el bloqueo de activación que protege el HAL de sensores para los 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.
El 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
El modo DATA_INJECTION
para los sensores WAKE_UP
debe ser compatible con la HAL de sensores 2.0.
Compatibilidad con varios HAL
La HAL de sensores 2.0 y 2.1 admite varias HAL usando el framework de Multi-HAL de sensores. Para obtener detalles sobre la implementación, consulta Portabilidad de la HAL de sensores 1.0.