La capa de abstracción de hardware de sensores (HAL) es la interfaz entre el marco del sensor de Android y los sensores de un dispositivo, como un acelerómetro o un giroscopio. Sensors HAL define las funciones que deben implementarse para permitir que el marco controle los sensores.
Sensors HAL 2.0 está disponible en Android 10 y superior para dispositivos nuevos y actualizados. Sensors HAL 2.0 se basa en Sensors HAL 1.0 , pero tiene varias diferencias clave que impiden que sea compatible con versiones anteriores. Sensores HAL 2.0 utiliza colas de mensajes rápidos (FMQ) para enviar eventos de sensores desde HAL al marco de trabajo de sensores de Android.
Sensors HAL 2.1 está disponible en Android 11 y superior para dispositivos nuevos y actualizados. Sensors HAL 2.1 es una iteración de Sensors HAL 2.0 que expone el tipo de sensor HINGE_ANGLE y actualiza varios métodos para aceptar el tipo HINGE_ANGLE
.
Interfaz HAL 2.1
La principal fuente de documentación para sensores HAL 2.1 se encuentra dentro de la definición de HAL en hardware/interfaces/sensors/2.1/ISensors.hal . Si hay un conflicto de requisitos entre esta página e ISensors.hal
, use el requisito en ISensors.hal
.
Interfaz HAL 2.0
La principal fuente de documentación para Sensores HAL 2.0 se encuentra dentro de la definición de HAL en hardware/interfaces/sensors/2.0/ISensors.hal . Si hay un conflicto de requisitos entre esta página e ISensors.hal
, use el requisito en ISensors.hal
.
Implementando Sensores HAL 2.0 y HAL 2.1
Para implementar Sensors HAL 2.0 o 2.1, un objeto debe ampliar la interfaz ISensors
e implementar todas las funciones definidas en 2.0/ISensors.hal
o 2.1/ISensors.hal
.
Inicializar la HAL
La HAL de sensores debe ser inicializada por el marco de trabajo del sensor de Android antes de que se pueda usar. El marco llama a la función initialize()
para HAL 2.0 y la función initialize_2_1()
para HAL 2.1 para proporcionar tres parámetros a los sensores HAL: dos descriptores FMQ y un puntero a un objeto ISensorsCallback
.
HAL usa el primer descriptor para crear el evento FMQ que se usa para escribir eventos de sensor en el marco. HAL usa el segundo descriptor para crear Wake Lock FMQ que se usa para sincronizar cuando HAL libera su wake lock para eventos de sensor WAKE_UP
. La HAL debe guardar un puntero al objeto ISensorsCallback
para poder invocar cualquier función de devolución de llamada necesaria.
La función initialize()
o initialize_2_1()
debe ser la primera función llamada al inicializar los sensores HAL.
Exponer los sensores disponibles
Para obtener una lista de todos los sensores estáticos disponibles en el dispositivo, utilice la función getSensorsList()
en HAL 2.0 y la función getSensorsList_2_1()
en HAL 2.1. Esta función devuelve 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 los sensores HAL. Los identificadores pueden cambiar entre los reinicios del dispositivo y entre 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 aplicaciones que utilizan la getDefaultSensor(int sensorType, bool wakeUp)
.
Estabilidad de la lista de sensores
Después de un reinicio HAL de Sensores, si los datos devueltos por getSensorsList()
o getSensorsList_2_1()
indican un cambio significativo en comparación con la lista de sensores recuperada antes del reinicio, el marco desencadena 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 identificador determinado o ha cambiado sus atributos, o en los que se introducen nuevos sensores. Si bien reiniciar el tiempo de ejecución de Android es perjudicial para el usuario, es necesario porque el marco de trabajo de Android ya no puede cumplir con el contrato de la API de Android de que los sensores estáticos (no dinámicos) no cambian durante la vida útil de una aplicación. Esto también puede evitar que el marco restablezca las solicitudes de sensores activos realizadas por las aplicaciones. Por lo tanto, se recomienda a los proveedores de HAL que eviten los cambios evitables en la lista de sensores.
Para garantizar que los identificadores de sensores sean estables, la HAL debe asignar de manera determinista un sensor físico dado en el dispositivo a su identificador. Aunque la interfaz HAL de sensores no exige una implementación específica, los desarrolladores tienen varias opciones disponibles para cumplir con este requisito.
Por ejemplo, la lista de sensores se puede ordenar mediante una combinación de los atributos fijos de cada sensor, como proveedor, modelo y 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 HAL necesita 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 puede compilarse en el binario HAL o almacenarse en un archivo de configuración en el sistema de archivos, y el orden de aparición puede usarse para derivar identificadores estables. Aunque la mejor solución depende de los detalles de implementación específicos de su HAL, el requisito clave es que los identificadores de los sensores no cambien entre los reinicios de HAL.
Configuración de sensores
Antes de que se active un sensor, el sensor debe configurarse con un período de muestreo y una latencia de informe máxima mediante la función batch()
.
Un sensor debe poder reconfigurarse en cualquier momento usando batch()
sin la pérdida de datos del sensor.
Periodo de muestreo
El período de muestreo tiene un significado diferente según el tipo de sensor que se esté configurando:
- Continuo: los eventos del sensor se generan a un ritmo continuo.
- Al cambiar: los eventos no se generan más rápido que el período de muestreo y pueden generarse a un ritmo más lento que el período de muestreo si el valor medido no cambia.
- One-shot: Se ignora el período de muestreo.
- Especial: para obtener más detalles, consulte Tipos de sensores .
Para obtener información sobre la interacción entre un período de muestreo y los modos de informe de un sensor, consulte Modos de informe .
Latencia máxima de informes
La latencia máxima de informes establece el tiempo máximo en nanosegundos que los eventos pueden retrasarse y almacenarse en el FIFO del hardware antes de escribirse en Event FMQ a través de HAL mientras el SoC está activo.
Un valor de cero significa que los eventos deben informarse tan pronto como se miden, ya sea omitiendo el FIFO por completo o vaciando el FIFO tan pronto como un evento del sensor esté presente en el FIFO.
Por ejemplo, un acelerómetro activado a 50 Hz con una latencia de informe máxima de cero activaciones interrumpe 50 veces por segundo cuando el SoC está activo.
Cuando la latencia máxima de informes es superior a cero, no es necesario informar los eventos del sensor tan pronto como se detectan. Los eventos se pueden almacenar temporalmente en el FIFO del 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 devuelven 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 procesa datos por lotes.
Cada evento tiene una marca de tiempo asociada a él. 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 a la hora en que ocurrió físicamente el evento, no a la hora en que se informó.
Para obtener información adicional y requisitos sobre los eventos de sensores de informes con una latencia máxima de informes distinta de cero, consulte Procesamiento por lotes .
Activación de sensores
El marco habilita y deshabilita los sensores usando la función activate()
. Antes de activar un sensor, el marco primero debe configurar el sensor usando batch()
.
Después de que se desactiva un sensor, los eventos de sensor adicionales de ese sensor no deben escribirse en Event FMQ.
Sensores de lavado
Si un sensor está configurado para procesar datos de sensor por lotes, el marco puede forzar una descarga inmediata de eventos de sensor por lotes llamando a flush()
. Esto hace que los eventos de sensor por lotes para el identificador de sensor especificado se escriban inmediatamente en Event FMQ. La HAL de sensores debe agregar un evento de descarga completa al final de los eventos de sensor que se escriben como resultado de una llamada a flush()
.
El vaciado ocurre de forma asincrónica (es decir, esta función debe regresar de inmediato). Si la implementación utiliza un solo FIFO para varios sensores, ese FIFO se descarga y el evento de descarga 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 el FIFO estaba vacío en el momento de la llamada, flush()
aún debe tener éxito y enviar un evento de descarga completa para ese sensor. Esto se aplica a todos los sensores que no sean sensores de disparo único.
Si se llama a flush()
para un sensor de disparo único, entonces flush()
debe devolver BAD_VALUE
y no generar un evento de descarga completa.
Escribir eventos de sensores en el FMQ
El Event FMQ es utilizado por Sensors HAL para insertar eventos de sensores en el marco de sensores de Android.
El evento FMQ es un FMQ sincronizado, lo que significa que cualquier intento de escribir más eventos en el FMQ que el espacio disponible da como resultado una escritura fallida. En tal caso, el HAL debe determinar si escribe el conjunto actual de eventos como dos grupos de eventos más pequeños o escribe todos los eventos juntos cuando hay suficiente espacio disponible.
Cuando Sensors HAL ha escrito el número deseado de eventos de sensor en Event FMQ, Sensors HAL debe notificar al marco que los eventos están listos escribiendo el EventQueueFlagBits::READ_AND_PROCESS
en EventFlag EventFlag::wake
wake de Event FMQ. EventFlag se puede crear desde Event FMQ usando EventFlag::createEventFlag
y la función getEventFlagWord()
de Event FMQ.
Los sensores HAL 2.0/2.1 admiten write
y bloqueo de escritura en Event writeBlocking
. La implementación predeterminada proporciona una referencia para usar write
. Si se usa la función writeBlocking
, el indicador readNotification
debe establecerse en EventQueueFlagBits::EVENTS_READ
, que establece el marco cuando lee eventos de Event FMQ. El indicador de notificación de escritura debe establecerse en EventQueueFlagBits::READ_AND_PROCESS
, que notifica al marco que los eventos se han escrito en Event FMQ.
Eventos WAKE_UP
Los eventos WAKE_UP
son eventos de sensor que hacen que el procesador de aplicaciones (AP) se despierte y maneje el evento de inmediato. Cada vez que se escribe un evento WAKE_UP
en Event FMQ, los sensores HAL deben asegurar un wake lock para garantizar que el sistema permanezca despierto hasta que el marco pueda manejar el evento. Al recibir un evento WAKE_UP
, el marco asegura su propio bloqueo de activación, lo que permite que Sensors HAL libere su bloqueo de activación. Para sincronizar cuando los sensores HAL liberan su bloqueo de activación, utilice Wake Lock FMQ.
Los sensores HAL deben leer Wake Lock FMQ para determinar la cantidad de eventos WAKE_UP
que ha manejado el marco. La HAL solo debe liberar su bloqueo de activación para eventos WAKE_UP
si el número total de eventos WAKE_UP
no manejados es cero. Después de manejar los eventos del sensor, el marco cuenta la cantidad de eventos que están marcados como eventos WAKE_UP
y vuelve a escribir este número en Wake Lock FMQ.
El marco establece la notificación de escritura WakeLockQueueFlagBits::DATA_WRITTEN
en Wake Lock FMQ cada vez que escribe datos en Wake Lock FMQ.
Sensores dinámicos
Los sensores dinámicos son sensores que no forman parte físicamente del dispositivo, pero que se pueden usar como entrada para el dispositivo, como un gamepad con un acelerómetro.
Cuando se conecta un sensor dinámico, la función onDynamicSensorConnected
en ISensorsCallback
debe llamarse desde Sensors HAL. Esto notifica al marco del nuevo sensor dinámico y permite controlar el sensor a través del marco y hacer 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 marco pueda eliminar 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 los sensores se escriben en una memoria específica en lugar de en Event FMQ sin pasar por Android Sensors Framework. 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 marco. La función configDirectReport()
es similar a batch()
para el funcionamiento normal y configura el canal de informe directo.
Las funciones registerDirectChannel()
y unregisterDirectChannel()
crean o destruyen un nuevo canal directo.
Modos de operación
La función setOperationMode()
permite que el marco configure un sensor para que el marco pueda inyectar datos del sensor en el sensor. Esto es útil para realizar pruebas, especialmente para algoritmos que existen debajo del marco.
La función injectSensorData()
en HAL 2.0 y la función injectSensorsData_2_1()
en HAL 2.0 se usan normalmente para insertar parámetros operativos en Sensores HAL. La función también se puede utilizar para inyectar eventos de sensor en un sensor específico.
Validación
Para validar su implementación de Sensores HAL, ejecute las pruebas de sensor CTS y VTS.
Pruebas CTS
Las pruebas CTS del sensor existen tanto en las pruebas CTS automatizadas como en la aplicación CTS Verifier manual.
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, el procesamiento por lotes y las tasas de eventos del sensor.
Las pruebas de CTS Verifier 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.
Pasar las pruebas CTS es fundamental para garantizar que el dispositivo bajo prueba cumpla con todos los requisitos de CDD.
pruebas VTS
Las pruebas VTS para sensores HAL 2.0 se encuentran en hardware/interfaces/sensors/2.0/vts . Las pruebas de VTS para sensores HAL 2.1 se encuentran en hardware/interfaces/sensors/2.1/vts . Estas pruebas aseguran que Sensors HAL se implemente correctamente y que todos los requisitos dentro de ISensors.hal
y ISensorsCallback.hal
se cumplan correctamente.
Actualización a Sensores HAL 2.1 desde 2.0
Al actualizar Sensors HAL 2.1 desde 2.0, su implementación HAL debe incluir los métodos initialize_2_1()
, getSensorsList_2_1()
e injectSensorsData_2_1()
, junto con los tipos HAL 2.1. Estos métodos deben cumplir los mismos requisitos descritos anteriormente para HAL 2.0.
Debido a 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 utilizar Multi-HAL 2.1.
Para ver un ejemplo de cómo implementar su propia HAL Sensors 2.1, consulte Sensors.h .
Actualización a Sensores HAL 2.0 desde 1.0
Al actualizar a Sensors HAL 2.0 desde 1.0, asegúrese de que su implementación de HAL cumpla con los siguientes requisitos.
Inicializar la HAL
La función initialize()
debe admitirse para establecer FMQ entre el marco y HAL.
Exponer los sensores disponibles
En Sensors HAL 2.0, la función getSensorsList()
debe devolver el mismo valor durante el arranque de un solo dispositivo, incluso entre reinicios de Sensors HAL. Un nuevo requisito de la función getSensorsList()
es que debe devolver el mismo valor durante el arranque de un solo dispositivo, incluso entre los reinicios de Sensores HAL. Esto permite que el marco intente restablecer las conexiones del sensor si el servidor del sistema se reinicia. El valor devuelto por getSensorsList()
puede cambiar después de que el dispositivo se reinicia.
Escribir eventos de sensores en el FMQ
En lugar de esperar a que se llame a poll()
, en Sensors HAL 2.0, Sensors HAL debe escribir eventos de sensor de manera proactiva en Event FMQ siempre que haya eventos de sensor disponibles. HAL también es responsable de escribir los bits correctos en EventFlag
para provocar una lectura de FMQ dentro del marco.
Eventos WAKE_UP
En Sensors HAL 1.0, HAL pudo liberar su bloqueo de activación para cualquier evento WAKE_UP
en cualquier llamada posterior a poll()
después de que se envió un WAKE_UP
a poll()
porque esto indicaba que el marco había procesado todos los eventos del sensor y había obtenido un bloqueo de activación, si es necesario. Debido a que, en Sensors HAL 2.0, HAL ya no sabe cuándo el marco ha procesado eventos escritos en FMQ, Wake Lock FMQ permite que el marco se comunique con HAL cuando ha manejado eventos WAKE_UP
.
En Sensors HAL 2.0, el wake lock asegurado por Sensors HAL para eventos WAKE_UP
debe comenzar con SensorsHAL_WAKEUP
.
Sensores dinámicos
Los sensores dinámicos se devolvieron usando la función poll()
en Sensors HAL 1.0. Sensors HAL 2.0 requiere que onDynamicSensorsConnected
y onDynamicSensorsDisconnected
en ISensorsCallback
se llamen 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 sensores WAKE_UP
debe ser compatible con Sensors HAL 2.0.
Compatibilidad con múltiples HAL
Sensors HAL 2.0 y 2.1 admite multi-HAL utilizando el marco Sensors Multi-HAL . Para obtener detalles sobre la implementación, consulte Portabilidad desde sensores HAL 1.0 .