HAL de sensores 1.0

La interfaz de la HAL de sensores, declarada en sensors.h, representa la interfaz entre el framework de Android y el software específico del hardware. Una implementación de HAL debe definir cada función declarada en sensors.h. Las funciones principales son las siguientes:

  • get_sensors_list: Muestra la lista de todos los sensores.
  • activate: Inicia o detiene un sensor.
  • batch: Establece los parámetros de un sensor, como la frecuencia de muestreo y la latencia máxima de informes.
  • setDelay: Se usa solo en la versión 1.0 del HAL. Establece la frecuencia de muestreo para un sensor determinado.
  • flush: Vacía la FIFO del sensor especificado y registra un evento de vaciado completo cuando se realiza esta acción.
  • poll: Devuelve los eventos del sensor disponibles.

La implementación debe ser segura para subprocesos y permitir que se llamen a estas funciones desde diferentes subprocesos.

La interfaz también define varios tipos que usan esas funciones. Los tipos principales son los siguientes:

  • sensors_module_t
  • sensors_poll_device_t
  • sensor_t
  • sensors_event_t

Además de las secciones que se muestran a continuación, consulta sensors.h para obtener más información sobre esos tipos.

get_sensors_list(list)

int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t
  const** list);

Proporciona la lista de sensores implementados por el HAL. Consulta sensor_t para obtener detalles sobre cómo se definen los sensores.

El orden en que aparecen los sensores en la lista es el orden en que se informarán a las aplicaciones. Por lo general, los sensores básicos aparecen primero, seguidos de los sensores compuestos.

Si varios sensores comparten el mismo tipo de sensor y la misma propiedad de activación, el primero de la lista se denomina sensor “predeterminado”. Es el que muestra getDefaultSensor(int sensorType, bool wakeUp).

Esta función devuelve la cantidad de sensores en la lista.

activate(sensor, true/false)

int (*activate)(struct sensors_poll_device_t *dev, int sensor_handle, int
  enabled);

Activa o desactiva un sensor.

sensor_handle es el identificador del sensor que se activará o desactivará. El identificador de un sensor se define con el campo handle de su estructura sensor_t.

enabled se establece en 1 para habilitar el sensor o en 0 para inhabilitarlo.

Los sensores de un solo disparo se desactivan automáticamente cuando reciben un evento, y deben aceptar la desactivación a través de una llamada a activate(..., enabled=0).

Los sensores que no activan el dispositivo nunca impiden que el SoC entre en modo de suspensión, es decir, el HAL no debe mantener un bloqueo de activación parcial en nombre de las aplicaciones.

Los sensores de activación, cuando entregan eventos de forma continua, pueden evitar que el SoC entre en modo de suspensión, pero si no se necesita entregar ningún evento, se debe liberar el bloqueo de activación parcial.

Si enabled es 1 y el sensor ya está activado, esta función no realiza ninguna operación y se ejecuta correctamente.

Si enabled es 0 y el sensor ya está desactivado, esta función no realiza ninguna operación y se ejecuta correctamente.

Esta función devuelve 0 si se ejecuta correctamente y un número de error negativo en caso contrario.

batch(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);

Establece los parámetros de un sensor, incluidos la frecuencia de muestreo y la latencia máxima del informe. Se puede llamar a esta función mientras el sensor está activado, en cuyo caso no debe provocar la pérdida de ninguna medición del sensor: la transición de una tasa de muestreo a otra no puede provocar la pérdida de eventos, ni tampoco la transición de una latencia máxima de informes alta a una latencia máxima de informes baja.

sensor_handle es el identificador del sensor que se configurará.

Actualmente, flags no se usa.

sampling_period_ns es el período de muestreo en el que se debe ejecutar el sensor, en nanosegundos. Consulta sampling_period_ns para obtener más detalles.

max_report_latency_ns es el tiempo máximo en el que se pueden retrasar los eventos antes de que se informen a través de la HAL, en nanosegundos. Consulta el párrafo max_report_latency_ns para obtener más detalles.

Esta función devuelve 0 si se ejecuta correctamente y un número de error negativo en caso contrario.

setDelay(sensor, período de muestreo)

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

Después de la versión 1.0 del HAL, esta función dejó de estar disponible y nunca se llama. En su lugar, se llama a la función batch para establecer el parámetro sampling_period_ns.

En la versión 1.0 del HAL, se usaba setDelay en lugar de batch para establecer sampling_period_ns.

flush(sensor)

int (*flush)(struct sensors_poll_device_1* dev, int sensor_handle);

Agrega un evento de vaciado completo al final de la FIFO de hardware para el sensor especificado y vacía la FIFO. Esos eventos se entregan como de costumbre (es decir, como si hubiera vencido la latencia de informes máxima) y se quitan de la FIFO.

La limpieza ocurre de forma asíncrona (es decir, esta función debe devolver un valor de inmediato). Si la implementación usa una sola FIFO para varios sensores, se vacía esa FIFO y el evento de vaciado completo se agrega 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 debe tener éxito y enviar un evento de descarga completa para ese sensor. Esto se aplica a todos los sensores, excepto a los de un solo disparo.

Cuando se llama a flush, incluso si ya hay un evento de vaciado en la FIFO para ese sensor, se debe crear uno adicional y agregarlo al final de la FIFO, y se debe vaciar la FIFO. La cantidad de llamadas a flush debe ser igual a la cantidad de eventos de descarga completa creados.

flush no se aplica a los sensores por única vez. Si sensor_handle hace referencia a un sensor por única vez, flush debe devolver -EINVAL y no generar ningún evento de metadatos de vaciado completo.

Esta función devuelve 0 si se ejecuta correctamente, -EINVAL si el sensor especificado es de un solo disparo o no se habilitó, y un número de error negativo en otros casos.

poll()

int (*poll)(struct sensors_poll_device_t *dev, sensors_event_t* data, int
  count);

Devuelve un array de datos del sensor completando el argumento data. Esta función debe bloquearse hasta que haya eventos disponibles. Devolverá la cantidad de eventos leídos si la operación se realiza correctamente o un número de error negativo en caso de error.

La cantidad de eventos que se muestran en data debe ser menor o igual que el argumento count. Esta función nunca debe devolver 0 (sin evento).

Secuencia de llamadas

Cuando se inicia el dispositivo, se llama a get_sensors_list.

Cuando se activa un sensor, se llamará a la función batch con los parámetros solicitados, seguida de activate(..., enable=1).

Ten en cuenta que, en la versión 1_0 del HAL, el orden era el opuesto: primero se llamaba a activate y, luego, a set_delay.

Cuando las características solicitadas de un sensor cambian mientras está activado, se llama a la función batch.

flush se puede llamar en cualquier momento, incluso en sensores no activados (en cuyo caso, debe devolver -EINVAL).

Cuando se desactiva un sensor, se llamará a activate(..., enable=0).

En paralelo a esas llamadas, se llamará a la función poll de forma repetida para solicitar datos. Se puede llamar a poll incluso cuando no hay sensores activados.

sensors_module_t

sensors_module_t es el tipo que se usa para crear el módulo de hardware de Android para los sensores. La implementación del HAL debe definir un objeto HAL_MODULE_INFO_SYM de este tipo para exponer la función get_sensors_list. Consulta la definición de sensors_module_t en sensors.h y la definición de hw_module_t para obtener más información.

sensors_poll_device_t / sensors_poll_device_1_t

sensors_poll_device_1_t contiene el resto de los métodos definidos anteriormente: activate, batch, flush y poll. Su campo common (de tipo hw_device_t) define el número de versión del HAL.

sensor_t

sensor_t representa un sensor de Android. Estos son algunos de sus campos importantes:

name: Es una cadena visible para el usuario que representa el sensor. Esta cadena suele contener el nombre de la parte del sensor subyacente, el tipo de sensor y si es un sensor de activación. Por ejemplo, “Acelerómetro LIS2HH12”, “Giroscopio sin calibrar MAX21000”, “Barómetro de activación BMP280”, “Vector de rotación del juego MPU6515”

handle: Es el número entero que se usa para hacer referencia al sensor cuando se registra o cuando genera eventos.

type: Es el tipo de sensor. Consulta la explicación del tipo de sensor en ¿Qué son los sensores de Android? para obtener más detalles y Tipos de sensores para conocer los tipos de sensores oficiales. En el caso de los tipos de sensores no oficiales, type debe comenzar con SENSOR_TYPE_DEVICE_PRIVATE_BASE.

stringType: Es el tipo de sensor como una cadena. Cuando el sensor tiene un tipo oficial, se establece en SENSOR_STRING_TYPE_*. Cuando el sensor tiene un tipo específico del fabricante, stringType debe comenzar con el nombre de dominio inverso del fabricante. Por ejemplo, un sensor (por ejemplo, un detector de unicornios) definido por el equipo de Cool-product en Fictional-Company podría usar stringType=”com.fictional_company.cool_product.unicorn_detector”. El stringType se usa para identificar de forma única los tipos de sensores no oficiales. Consulta sensors.h para obtener más información sobre los tipos y los tipos de cadenas.

requiredPermission: Es una cadena que representa el permiso que deben tener las aplicaciones para ver el sensor, registrarse en él y recibir sus datos. Una cadena vacía significa que las aplicaciones no requieren ningún permiso para acceder a este sensor. Algunos tipos de sensores, como el monitor de frecuencia cardíaca, tienen un requiredPermission obligatorio. Todos los sensores que proporcionan información sensible del usuario (como la frecuencia cardíaca) deben estar protegidos por un permiso.

flags: Marcas para este sensor que definen su modo de informes y si es un sensor de activación o no. Por ejemplo, un sensor de activación de un solo disparo tendrá flags = SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP. Los bits de la marca que no se usan en la versión actual del HAL deben ser iguales a 0.

maxRange: Es el valor máximo que puede informar el sensor, en la misma unidad que los valores informados. El sensor debe poder informar valores sin saturarse en un plazo de [-maxRange; maxRange]. Ten en cuenta que esto significa que el rango total del sensor en el sentido genérico es 2*maxRange. Cuando el sensor informa valores en varios ejes, el rango se aplica a cada eje. Por ejemplo, un acelerómetro de “+/- 2 g” informará maxRange = 2*9.81 = 2g.

Resolución: Es la diferencia más pequeña en el valor que puede medir el sensor. Por lo general, se calcula en función de maxRange y la cantidad de bits en la medición.

power: Es el costo de energía de habilitar el sensor, en miliamperios. Casi siempre es mayor que el consumo de energía que se indica en la hoja de datos del sensor subyacente. Consulta Sensores base != sensores físicos para obtener más detalles y Proceso de medición de energía para obtener detalles sobre cómo medir el consumo de energía de un sensor. Si el consumo de energía del sensor depende de si el dispositivo se está moviendo, el consumo de energía durante el movimiento es el que se informa en el campo power.

minDelay: Para los sensores continuos, es el período de muestreo, en microsegundos, que corresponde a la tasa más rápida que admite el sensor. Consulta sampling_period_ns para obtener detalles sobre cómo se usa este valor. Ten en cuenta que minDelay se expresa en microsegundos, mientras que sampling_period_ns se expresa en nanosegundos. Para los sensores de modo de informes especiales y de cambio, a menos que se especifique lo contrario, minDelay debe ser 0. En el caso de los sensores de un solo disparo, debe ser -1.

maxDelay: Para los sensores continuos y los que se activan con el cambio, es el período de muestreo, en microsegundos, que corresponde a la tasa más lenta que admite el sensor. Consulta sampling_period_ns para obtener detalles sobre cómo se usa este valor. Ten en cuenta que maxDelay se expresa en microsegundos, mientras que sampling_period_ns se expresa en nanosegundos. Para los sensores especiales y de un solo uso, maxDelay debe ser 0.

fifoReservedEventCount: Es la cantidad de eventos reservados para este sensor en la FIFO de hardware. Si hay una FIFO exclusiva para este sensor, fifoReservedEventCount es el tamaño de esta FIFO exclusiva. Si la FIFO se comparte con otros sensores, fifoReservedEventCount es el tamaño de la parte de la FIFO que se reserva para ese sensor. En la mayoría de los sistemas FIFO compartidos y en los sistemas que no tienen un FIFO de hardware, este valor es 0.

fifoMaxEventCount: Es la cantidad máxima de eventos que se pueden almacenar en las FIFO para este sensor. Siempre es mayor o igual que fifoReservedEventCount. Este valor se usa para estimar la rapidez con la que se llenará la FIFO cuando se registre en el sensor a una velocidad específica, suponiendo que no se activen otros sensores. En los sistemas que no tienen una FIFO de hardware, fifoMaxEventCount es 0. Consulta Procesamiento por lotes para obtener más detalles.

En el caso de los sensores con un tipo oficial, el framework reemplaza algunos de los campos. Por ejemplo, los sensores de acelerómetro deben tener un modo de generación de informes continuo, y los monitores de frecuencia cardíaca deben estar protegidos por el permiso SENSOR_PERMISSION_BODY_SENSORS.

sensors_event_t

Los eventos del sensor generados por los sensores de Android y registrados a través de la función poll son de type sensors_event_t. Estos son algunos campos importantes de sensors_event_t:

version: Debe ser sizeof(struct sensors_event_t).

sensor: Es el identificador del sensor que generó el evento, según lo define sensor_t.handle.

type: Es el tipo de sensor que generó el evento, según se define en sensor_t.type.

timestamp: Es la marca de tiempo del evento en nanosegundos. Es la hora en que ocurrió el evento (se dio un paso o se realizó una medición del acelerómetro), no la hora en que se informó el evento. timestamp debe sincronizarse con el reloj elapsedRealtimeNano y, en el caso de los sensores continuos, la fluctuación debe ser pequeña. A veces, es necesario filtrar las marcas de tiempo para satisfacer los requisitos del CDD, ya que usar solo la hora de interrupción del SoC para establecer las marcas de tiempo provoca una fluctuación demasiado alta, y usar solo la hora del chip del sensor para establecer las marcas de tiempo puede provocar una desincronización del reloj elapsedRealtimeNano, ya que el reloj del sensor se desvía.

Datos y campos superpuestos: Son los valores que mide el sensor. El significado y las unidades de esos campos son específicos para cada tipo de sensor. Consulta sensors.h y la definición de los diferentes tipos de sensores para obtener una descripción de los campos de datos. En el caso de algunos sensores, la precisión de las lecturas también se informa como parte de los datos, a través de un campo status. Este campo solo se canaliza para esos tipos de sensores seleccionados y aparece en la capa del SDK como un valor de precisión. En el caso de esos sensores, el hecho de que se debe establecer el campo de estado se menciona en la definición de su tipo de sensor.

Eventos de vaciado de metadatos completado

Los eventos de metadatos tienen el mismo tipo que los eventos de sensores normales: sensors_event_meta_data_t = sensors_event_t. Se devuelven junto con otros eventos del sensor a través de la sondeo. Tienen los siguientes campos:

version: Debe ser META_DATA_VERSION.

type: Debe ser SENSOR_TYPE_META_DATA

sensor, reserved, and timestamp: Debe ser 0

meta_data.what: Contiene el tipo de metadatos para este evento. Actualmente, hay un solo tipo de metadatos válido: META_DATA_FLUSH_COMPLETE.

Los eventos META_DATA_FLUSH_COMPLETE representan la finalización del vaciado de un FIFO del sensor. Cuando es meta_data.what=META_DATA_FLUSH_COMPLETE, meta_data.sensor debe establecerse en el identificador del sensor que se vació. Se generan cuando y solo cuando se llama a flush en un sensor. Consulta la sección sobre la función flush para obtener más información.