La couche d'abstraction matérielle des capteurs (HAL) est l'interface entre le framework de capteurs Android et les capteurs d'un appareil, tels qu'un accéléromètre ou un gyroscope. Le HAL Capteurs définit les fonctions qui doivent être implémentées pour permettre au framework de contrôler les capteurs.
Sensors HAL 2.0 est disponible dans Android 10 et supérieur pour les appareils nouveaux et mis à niveau. Sensors HAL 2.0 est basé sur Sensors HAL 1.0 mais présente plusieurs différences essentielles qui l'empêchent d'être rétrocompatible. Capteurs HAL 2.0 utilise des files d'attente de messages rapides (FMQ) pour envoyer des événements de capteur depuis HAL vers le framework de capteurs Android.
Capteurs HAL 2.1 est disponible dans Android 11 et supérieur pour les appareils nouveaux et mis à niveau. Sensors HAL 2.1 est une itération de Sensors HAL 2.0 qui expose le type de capteur HINGE_ANGLE et met à jour diverses méthodes pour accepter le type HINGE_ANGLE
.
Interface HAL 2.1
La principale source de documentation pour Sensors HAL 2.1 se trouve dans la définition HAL à hardware/interfaces/sensors/2.1/ISensors.hal . S'il existe un conflit d'exigences entre cette page et ISensors.hal
, utilisez l'exigence dans ISensors.hal
.
Interface HAL 2.0
La principale source de documentation pour Sensors HAL 2.0 se trouve dans la définition HAL à hardware/interfaces/sensors/2.0/ISensors.hal . S'il existe un conflit d'exigences entre cette page et ISensors.hal
, utilisez l'exigence dans ISensors.hal
.
Implémentation des capteurs HAL 2.0 et HAL 2.1
Pour implémenter Sensors HAL 2.0 ou 2.1, un objet doit étendre l'interface ISensors
et implémenter toutes les fonctions définies dans 2.0/ISensors.hal
ou 2.1/ISensors.hal
.
Initialisation de HAL
La couche HAL Sensors doit être initialisée par le framework de capteurs Android avant de pouvoir être utilisée. Le framework appelle la fonction initialize()
pour HAL 2.0 et la fonction initialize_2_1()
pour HAL 2.1 pour fournir trois paramètres à Sensors HAL : deux descripteurs FMQ et un pointeur vers un objet ISensorsCallback
.
Le HAL utilise le premier descripteur pour créer l'événement FMQ utilisé pour écrire des événements de capteur dans le cadre. Le HAL utilise le deuxième descripteur pour créer le Wake Lock FMQ utilisé pour synchroniser lorsque le HAL libère son wakelock pour les événements de capteur WAKE_UP
. La couche HAL doit enregistrer un pointeur vers l'objet ISensorsCallback
afin que toutes les fonctions de rappel nécessaires puissent être appelées.
La fonction initialize()
ou initialize_2_1()
doit être la première fonction appelée lors de l'initialisation de Sensors HAL.
Exposer les capteurs disponibles
Pour obtenir une liste de tous les capteurs statiques disponibles dans l'appareil, utilisez la fonction getSensorsList()
sur HAL 2.0 et la fonction getSensorsList_2_1()
sur HAL 2.1. Cette fonction renvoie une liste de capteurs, chacun identifié de manière unique par son handle. Le handle d'un capteur donné ne doit pas changer lorsque le processus hébergeant la HAL Sensors redémarre. Les descripteurs peuvent changer lors des redémarrages de l'appareil et lors des redémarrages du serveur système.
Si plusieurs capteurs partagent le même type de capteur et la même propriété de réveil, le premier capteur de la liste est appelé capteur par défaut et est renvoyé aux applications qui utilisent la getDefaultSensor(int sensorType, bool wakeUp)
.
Stabilité de la liste des capteurs
Après un redémarrage de Sensors HAL, si les données renvoyées par getSensorsList()
ou getSensorsList_2_1()
indiquent un changement significatif par rapport à la liste de capteurs récupérée avant le redémarrage, le framework déclenche un redémarrage du runtime Android. Les modifications importantes apportées à la liste des capteurs incluent les cas où un capteur avec une poignée donnée est manquant ou a changé d'attributs, ou lorsque de nouveaux capteurs sont introduits. Bien que le redémarrage de l'environnement d'exécution Android perturbe l'utilisateur, il est nécessaire car le framework Android ne peut plus respecter le contrat d'API Android selon lequel les capteurs statiques (non dynamiques) ne changent pas pendant la durée de vie d'une application. Cela peut également empêcher le framework de rétablir les demandes de capteurs actifs effectuées par les applications. Par conséquent, il est conseillé aux fournisseurs HAL d'empêcher les modifications évitables de la liste des capteurs.
Pour garantir des poignées de capteur stables, la HAL doit mapper de manière déterministe un capteur physique donné dans l'appareil à sa poignée. Bien qu'aucune implémentation spécifique ne soit imposée par l'interface Sensors HAL, les développeurs disposent d'un certain nombre d'options pour répondre à cette exigence.
Par exemple, la liste des capteurs peut être triée à l'aide d'une combinaison des attributs fixes de chaque capteur, tels que le fournisseur, le modèle et le type de capteur. Une autre option repose sur le fait que l'ensemble de capteurs statiques de l'appareil est fixé dans le matériel, de sorte que HAL doit savoir quand tous les capteurs attendus ont terminé l'initialisation avant de revenir de getSensorsList()
ou getSensorsList_2_1()
. Cette liste de capteurs attendus peut être compilée dans le binaire HAL ou stockée dans un fichier de configuration dans le système de fichiers, et l'ordre d'apparition peut être utilisé pour dériver des poignées stables. Bien que la meilleure solution dépende des détails d'implémentation spécifiques de votre HAL, la principale exigence est que les poignées de capteur ne changent pas lors des redémarrages de HAL.
Configuration des capteurs
Avant qu'un capteur ne soit activé, le capteur doit être configuré avec une période d'échantillonnage et une latence de rapport maximale à l'aide de la fonction batch()
.
Un capteur doit pouvoir être reconfiguré à tout moment à l'aide de batch()
sans perte de données de capteur.
Période d'échantillonnage
La période d'échantillonnage a une signification différente selon le type de capteur en cours de configuration :
- Continu : les événements de capteur sont générés à un rythme continu.
- Sur changement : les événements ne sont pas générés plus rapidement que la période d'échantillonnage et peuvent être générés à un rythme plus lent que la période d'échantillonnage si la valeur mesurée ne change pas.
- One-shot : la période d'échantillonnage est ignorée.
- Spécial : Pour plus de détails, voir Types de capteurs .
Pour en savoir plus sur l'interaction entre une période d'échantillonnage et les modes de rapport d'un capteur, voir Modes de rapport .
Latence maximale des rapports
La latence de rapport maximale définit la durée maximale en nanosecondes pendant laquelle les événements peuvent être retardés et stockés dans la FIFO matérielle avant d'être écrits dans la FMQ d'événement via la HAL pendant que le SoC est éveillé.
Une valeur de zéro signifie que les événements doivent être signalés dès qu'ils sont mesurés, soit en sautant complètement la FIFO, soit en vidant la FIFO dès qu'un événement du capteur est présent dans la FIFO.
Par exemple, un accéléromètre activé à 50 Hz avec une latence de rapport maximale de zéro déclenche des interruptions 50 fois par seconde lorsque le SoC est éveillé.
Lorsque la latence de rapport maximale est supérieure à zéro, les événements de capteur n'ont pas besoin d'être signalés dès qu'ils sont détectés. Les événements peuvent être stockés temporairement dans le FIFO matériel et signalés par lots, tant qu'aucun événement n'est retardé de plus que la latence de rapport maximale. Tous les événements depuis le lot précédent sont enregistrés et renvoyés en même temps. Cela réduit le nombre d'interruptions envoyées au SoC et permet au SoC de passer à un mode de consommation réduite pendant que le capteur capture et regroupe les données.
Chaque événement est associé à un horodatage. Le fait de retarder l'heure à laquelle un événement est signalé ne doit pas avoir d'incidence sur l'horodatage de l'événement. L'horodatage doit être précis et correspondre à l'heure à laquelle l'événement s'est produit physiquement, et non à l'heure à laquelle il a été signalé.
Pour plus d'informations et d'exigences sur le signalement des événements de capteur avec une latence de signalement maximale différente de zéro, consultez Traitement par lot .
Activation des capteurs
Le framework active et désactive les capteurs à l'aide de la activate()
. Avant d'activer un capteur, le framework doit d'abord configurer le capteur à l'aide de batch()
.
Après la désactivation d'un capteur, les événements de capteur supplémentaires de ce capteur ne doivent pas être écrits dans la FMQ d'événement.
Capteurs de rinçage
Si un capteur est configuré pour traiter par lots les données de capteur, le framework peut forcer un vidage immédiat des événements de capteur par lots en appelant flush()
. Cela entraîne l'écriture immédiate des événements de capteur groupés pour le descripteur de capteur spécifié dans la FMQ d'événement. La couche HAL Sensors doit ajouter un événement flush complete à la fin des événements de capteur qui sont écrits à la suite d'un appel à flush()
.
Le vidage se produit de manière asynchrone (c'est-à-dire que cette fonction doit être renvoyée immédiatement). Si l'implémentation utilise un seul FIFO pour plusieurs capteurs, ce FIFO est vidé et l'événement de vidage complet est ajouté uniquement pour le capteur spécifié.
Si le capteur spécifié n'a pas de FIFO (pas de mise en mémoire tampon possible), ou si le FIFO était vide au moment de l'appel, flush()
doit toujours réussir et envoyer un événement flush complete pour ce capteur. Ceci s'applique à tous les capteurs autres que les capteurs monocoup.
Si flush()
est appelé pour un capteur ponctuel, alors flush()
doit renvoyer BAD_VALUE
et ne pas générer d'événement flush complete.
Écriture d'événements de capteur dans la FMQ
L'Event FMQ est utilisé par Sensors HAL pour pousser les événements de capteur dans le framework de capteurs Android.
La FMQ d'événement est une FMQ synchronisée, ce qui signifie que toute tentative d'écrire plus d'événements dans la FMQ que l'espace disponible n'autorise entraîne un échec d'écriture. Dans ce cas, la HAL devrait déterminer s'il faut écrire l'ensemble actuel d'événements sous la forme de deux petits groupes d'événements ou écrire tous les événements ensemble lorsque suffisamment d'espace est disponible.
Lorsque la couche HAL Sensors a écrit le nombre souhaité d'événements de capteur dans la FMQ Event, la couche HAL Sensors doit informer le framework que les événements sont prêts en écrivant le EventQueueFlagBits::READ_AND_PROCESS
dans la fonction EventFlag::wake
::wake de la FMQ Event. L'EventFlag peut être créé à partir de l'Event FMQ en utilisant EventFlag::createEventFlag
et la fonction getEventFlagWord()
de l'Event FMQ.
Capteurs HAL 2.0/2.1 prend en charge à la fois l' write
et le writeBlocking
d'écriture sur l'Event FMQ. L'implémentation par défaut fournit une référence pour l'utilisation de write
. Si la fonction writeBlocking
est utilisée, l'indicateur readNotification
doit être défini sur EventQueueFlagBits::EVENTS_READ
, qui est défini par le framework lorsqu'il lit des événements à partir de Event FMQ. L'indicateur de notification d'écriture doit être défini sur EventQueueFlagBits::READ_AND_PROCESS
, qui notifie au framework que des événements ont été écrits dans Event FMQ.
Événements WAKE_UP
Les événements WAKE_UP
sont des événements de capteur qui provoquent le réveil du processeur d'application (AP) et le traitement immédiat de l'événement. Chaque fois qu'un événement WAKE_UP
est écrit dans la FMQ d'événement, la HAL des capteurs doit sécuriser un verrou de réveil pour s'assurer que le système reste éveillé jusqu'à ce que le framework puisse gérer l'événement. Lors de la réception d'un événement WAKE_UP
, le framework sécurise son propre verrou de réveil, permettant à la HAL Sensors de libérer son verrou de réveil. Pour synchroniser lorsque Sensors HAL libère son wakelock, utilisez Wake Lock FMQ.
La couche HAL Sensors doit lire la FMQ Wake Lock pour déterminer le nombre d'événements WAKE_UP
que le framework a gérés. La couche HAL ne doit libérer son verrou de réveil pour les événements WAKE_UP
que si le nombre total d'événements WAKE_UP
non gérés est égal à zéro. Après avoir traité les événements de capteur, la structure compte le nombre d'événements qui sont marqués comme événements WAKE_UP
et réécrit ce nombre dans Wake Lock FMQ.
Le framework définit la notification d'écriture WakeLockQueueFlagBits::DATA_WRITTEN
sur la FMQ Wake Lock chaque fois qu'il écrit des données sur la FMQ Wake Lock.
Capteurs dynamiques
Les capteurs dynamiques sont des capteurs qui ne font pas physiquement partie de l'appareil mais qui peuvent être utilisés comme entrée de l'appareil, comme une manette de jeu avec un accéléromètre.
Lorsqu'un capteur dynamique est connecté, la fonction onDynamicSensorConnected
dans ISensorsCallback
doit être appelée depuis Sensors HAL. Cela notifie le cadre du nouveau capteur dynamique et permet au capteur d'être contrôlé via le cadre et de faire en sorte que les événements du capteur soient consommés par les clients.
De même, lorsqu'un capteur dynamique est déconnecté, la fonction onDynamicSensorDisconnected
dans ISensorsCallback
doit être appelée pour que le framework puisse supprimer tout capteur qui n'est plus disponible.
Canal direct
Le canal direct est une méthode de fonctionnement dans laquelle les événements de capteur sont écrits dans une mémoire spécifique au lieu de l'événement FMQ en contournant le cadre de capteurs Android. Un client qui enregistre un canal direct doit lire les événements de capteur directement à partir de la mémoire qui a été utilisée pour créer le canal direct et ne recevra pas les événements de capteur via le framework. La fonction configDirectReport()
est similaire à batch()
pour un fonctionnement normal et configure le canal de rapport direct.
Les fonctions registerDirectChannel()
et unregisterDirectChannel()
créent ou détruisent un nouveau canal direct.
Modes de fonctionnement
La fonction setOperationMode()
permet au framework de configurer un capteur afin que le framework puisse injecter des données de capteur dans le capteur. Ceci est utile pour les tests, en particulier pour les algorithmes qui existent sous le framework.
La fonction injectSensorData()
dans HAL 2.0 et la fonction injectSensorsData_2_1()
dans HAL 2.0 sont normalement utilisées pour pousser les paramètres opérationnels dans Sensors HAL. La fonction peut également être utilisée pour injecter des événements de capteur dans un capteur spécifique.
Validation
Pour valider votre implémentation de Sensors HAL, exécutez les tests de capteur CTS et VTS.
Essais CTS
Les tests Sensor CTS existent à la fois dans les tests CTS automatisés et dans l'application manuelle CTS Verifier.
Les tests automatisés sont situés dans cts/tests/sensor/src/android/hardware/cts . Ces tests vérifient les fonctionnalités standard des capteurs, telles que l'activation des capteurs, le traitement par lots et les taux d'événements des capteurs.
Les tests CTS Verifier se trouvent dans cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors . Ces tests nécessitent une entrée manuelle de la part de l'opérateur de test et garantissent que les capteurs rapportent des valeurs précises.
La réussite des tests CTS est essentielle pour s'assurer que l'appareil testé répond à toutes les exigences CDD.
Essais VTS
Les tests VTS pour Sensors HAL 2.0 se trouvent dans hardware/interfaces/sensors/2.0/vts . Les tests VTS pour Sensors HAL 2.1 se trouvent dans hardware/interfaces/sensors/2.1/vts . Ces tests garantissent que Sensors HAL est correctement implémenté et que toutes les exigences dans ISensors.hal
et ISensorsCallback.hal
sont correctement respectées.
Mise à niveau vers Sensors HAL 2.1 à partir de 2.0
Lors de la mise à niveau vers Sensors HAL 2.1 à partir de la version 2.0, votre implémentation HAL doit inclure les méthodes initialize_2_1()
, getSensorsList_2_1()
et injectSensorsData_2_1()
, ainsi que les types HAL 2.1. Ces méthodes doivent répondre aux mêmes exigences décrites pour HAL 2.0 ci-dessus.
Étant donné que les HAL de version mineure doivent prendre en charge toutes les fonctions des HAL précédents, les HAL 2.1 doivent prendre en charge l'initialisation en tant que HAL 2.0. Pour éviter la complexité de la prise en charge des deux versions HAL, il est fortement recommandé d'utiliser Multi-HAL 2.1.
Pour un exemple d'implémentation de votre propre HAL Sensors 2.1, voir Sensors.h .
Mise à niveau vers Sensors HAL 2.0 à partir de 1.0
Lors de la mise à niveau vers Sensors HAL 2.0 à partir de la version 1.0, assurez-vous que votre implémentation HAL répond aux exigences suivantes.
Initialisation de HAL
La fonction initialize()
doit être prise en charge pour établir des FMQ entre le framework et HAL.
Exposer les capteurs disponibles
Dans Sensors HAL 2.0, la fonction getSensorsList()
doit renvoyer la même valeur lors du démarrage d'un seul périphérique, même lors des redémarrages de Sensors HAL. Une nouvelle exigence de la fonction getSensorsList()
est qu'elle doit renvoyer la même valeur lors du démarrage d'un seul périphérique, même lors des redémarrages de Sensors HAL. Cela permet à la structure de tenter de rétablir les connexions des capteurs si le serveur système redémarre. La valeur renvoyée par getSensorsList()
peut changer après que l'appareil a effectué un redémarrage.
Écriture d'événements de capteur dans la FMQ
Au lieu d'attendre que poll()
soit appelé, dans Sensors HAL 2.0, Sensors HAL doit écrire de manière proactive des événements de capteur dans Event FMQ chaque fois que des événements de capteur sont disponibles. Le HAL est également responsable de l'écriture des bits corrects dans EventFlag
pour provoquer une lecture FMQ dans le cadre.
Événements WAKE_UP
Dans Sensors HAL 1.0, HAL était capable de libérer son verrou de réveil pour tout événement WAKE_UP
lors de tout appel ultérieur à poll()
après qu'un WAKE_UP
été publié sur poll()
car cela indiquait que le framework avait traité tous les événements de capteur et avait obtenu un verrouillage de réveil, si nécessaire. Parce que, dans Sensors HAL 2.0, le HAL ne sait plus quand le framework a traité des événements écrits dans la FMQ, le Wake Lock FMQ permet au framework de communiquer avec le HAL lorsqu'il a géré des événements WAKE_UP
.
Dans Sensors HAL 2.0, le wakelock sécurisé par Sensors HAL pour les événements WAKE_UP
doit commencer par SensorsHAL_WAKEUP
.
Capteurs dynamiques
Les capteurs dynamiques ont été renvoyés à l'aide de la fonction poll()
dans Sensors HAL 1.0. Capteurs HAL 2.0 nécessite que onDynamicSensorsConnected
et onDynamicSensorsDisconnected
dans ISensorsCallback
soient appelés chaque fois que les connexions de capteurs dynamiques changent. Ces rappels sont disponibles dans le cadre du pointeur ISensorsCallback
fourni via la fonction initialize()
.
Modes de fonctionnement
Le mode DATA_INJECTION
pour les capteurs WAKE_UP
doit être pris en charge dans Sensors HAL 2.0.
Prise en charge multi-HAL
Les capteurs HAL 2.0 et 2.1 prennent en charge le multi-HAL à l'aide du framework Sensors Multi-HAL . Pour plus de détails sur l'implémentation, voir Portage depuis Sensors HAL 1.0 .