Уровень аппаратной абстракции датчиков (HAL) — это интерфейс между сенсорной платформой Android и датчиками устройства, такими как акселерометр или гироскоп. HAL «Датчики» определяет функции, которые необходимо реализовать, чтобы позволить платформе управлять датчиками.
Датчики AIDL HAL доступны в Android 13 и более поздних версиях для новых и обновленных устройств. Датчики AIDL HAL, основанные на датчиках HAL 2.1 , используют интерфейс AIDL HAL и предоставляют типы датчиков отслеживания положения головы и IMU с ограниченной осью.
Интерфейс AIDL HAL
Основной источник документации для датчиков AIDL HAL находится в определении HAL по адресу hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl .
Внедрение датчиков AIDL HAL
Чтобы реализовать HAL Sensors AIDL, объект должен расширять интерфейс ISensors
и реализовывать все функции, определенные в hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl .
Инициализируйте HAL
Датчики HAL должны быть инициализированы платформой датчиков Android, прежде чем их можно будет использовать. Платформа вызывает функцию initialize()
, чтобы предоставить HAL Sensors три параметра: два дескриптора FMQ и один указатель на объект ISensorsCallback
.
HAL использует первый дескриптор для создания FMQ событий, используемого для записи событий датчиков в платформу. HAL использует второй дескриптор для создания FMQ Wake Lock, используемого для синхронизации, когда HAL снимает блокировку пробуждения для событий датчика WAKE_UP
. HAL должен сохранить указатель на объект ISensorsCallback
, чтобы можно было вызвать любые необходимые функции обратного вызова.
Функция initialize()
должна быть первой функцией, вызываемой при инициализации HAL датчиков.
Разоблачить доступные датчики
Чтобы получить список всех доступных статических датчиков на устройстве, используйте функцию getSensorsList()
. Эта функция возвращает список датчиков, каждый из которых уникально идентифицируется своим дескриптором. Дескриптор данного датчика не должен меняться при перезапуске процесса, в котором размещен HAL датчиков. Дескрипторы могут меняться при перезагрузке устройства и при перезагрузке системного сервера.
Если несколько датчиков имеют один и тот же тип датчика и свойство пробуждения, то первый датчик в списке называется датчиком по умолчанию и возвращается в приложения, использующие функцию getDefaultSensor(int sensorType, bool wakeUp)
.
Стабильность списка датчиков
Если после перезапуска Sensors HAL данные, возвращаемые методом getSensorsList()
указывают на значительные изменения по сравнению со списком датчиков, полученным до перезапуска, платформа запускает перезапуск среды выполнения Android. Существенные изменения в списке датчиков включают случаи, когда датчик с данным дескриптором отсутствует или имеет измененные атрибуты, а также когда вводятся новые датчики. Хотя перезапуск среды выполнения Android мешает пользователю, он необходим, поскольку платформа Android больше не может соответствовать контракту API Android, согласно которому статические (нединамические) датчики не изменяются в течение срока службы приложения. Это также может помешать платформе восстановить активные запросы датчиков, сделанные приложениями. Поэтому поставщикам HAL рекомендуется предотвращать изменения списка датчиков, которых можно избежать.
Чтобы обеспечить стабильные дескрипторы датчиков, HAL должен детерминированно сопоставить данный физический датчик в устройстве с его дескриптором. Хотя интерфейс Sensors HAL не требует какой-либо конкретной реализации, у разработчиков есть ряд возможностей для удовлетворения этого требования.
Например, список датчиков можно отсортировать, используя комбинацию фиксированных атрибутов каждого датчика, таких как производитель, модель и тип датчика. Другой вариант основан на том факте, что набор статических датчиков устройства фиксирован аппаратно, поэтому HAL должен знать, когда все ожидаемые датчики завершили инициализацию, прежде чем вернуться из getSensorsList()
. Этот список ожидаемых датчиков можно скомпилировать в двоичный файл HAL или сохранить в файле конфигурации в файловой системе, а порядок появления можно использовать для получения стабильных дескрипторов. Хотя лучшее решение зависит от конкретных деталей реализации вашего HAL, ключевым требованием является то, чтобы дескрипторы датчиков не менялись при перезапуске HAL.
Настройка датчиков
Прежде чем активировать датчик, для него необходимо настроить период выборки и максимальную задержку отчета с помощью функции batch()
.
Датчик должен иметь возможность переконфигурировать в любое время с помощью batch()
без потери данных датчика.
Период выборки
Период выборки имеет разное значение в зависимости от типа настраиваемого датчика:
- Непрерывно: события датчика генерируются с постоянной частотой.
- При изменении: события генерируются не быстрее, чем период выборки, и могут генерироваться со скоростью, меньшей, чем период выборки, если измеренное значение не изменяется.
- Однократный: период выборки игнорируется.
- Специальный: более подробную информацию см. в разделе «Типы датчиков» .
Чтобы узнать о взаимодействии между периодом выборки и режимами отчетов датчика, см. Режимы отчетов .
Максимальная задержка отчетов
Максимальная задержка отчетов устанавливает максимальное время в наносекундах, в течение которого события могут быть задержаны и сохранены в аппаратном FIFO перед записью в Event FMQ через HAL, пока SoC активен.
Нулевое значение означает, что о событиях необходимо сообщать сразу после их измерения, либо вообще пропуская FIFO, либо очищая FIFO, как только в FIFO появится одно событие от датчика.
Например, акселерометр, активированный на частоте 50 Гц с максимальной задержкой сообщения, равной нулю, прерывает 50 раз в секунду, когда SoC находится в активном состоянии.
Если максимальная задержка отчета больше нуля, о событиях датчика не нужно сообщать сразу после их обнаружения. События могут временно храниться в аппаратном FIFO и сообщаться пакетами, если ни одно событие не задерживается более чем на максимальную задержку отчета. Все события с момента предыдущего пакета записываются и возвращаются сразу. Это уменьшает количество прерываний, отправляемых на SoC, и позволяет SoC переключаться в режим пониженного энергопотребления, пока датчик собирает и группирует данные.
С каждым событием связана временная метка. Задержка времени сообщения о событии не должна влиять на метку времени события. Временная метка должна быть точной и соответствовать времени физического события, а не времени, когда о нем было сообщено.
Дополнительную информацию и требования к сообщению о событиях датчика с ненулевой максимальной задержкой сообщения см. в разделе Пакетная обработка .
Активировать датчики
Платформа включает и отключает датчики с помощью функции activate()
. Прежде чем активировать датчик, платформа должна сначала настроить датчик с помощью batch()
.
После деактивации датчика дополнительные события датчика от этого датчика не должны записываться в Event FMQ.
Датчики промывки
Если датчик настроен на пакетную обработку данных датчика, платформа может принудительно сбросить пакетные события датчика, вызвав flush()
. Это приводит к немедленной записи пакетных событий датчика для указанного дескриптора датчика в FMQ событий. HAL Sensors должен добавить событие завершения очистки в конец событий датчика, которые записываются в результате вызова flush()
.
Сброс происходит асинхронно (то есть эта функция должна немедленно завершить выполнение). Если реализация использует один FIFO для нескольких датчиков, этот FIFO очищается, а событие завершения очистки добавляется только для указанного датчика.
Если указанный датчик не имеет FIFO (буферизация невозможна) или если FIFO был пуст во время вызова, flush()
все равно должен завершиться успешно и отправить событие завершения очистки для этого датчика. Это относится ко всем датчикам, кроме датчиков однократного действия.
Если flush()
вызывается для однократного датчика, то flush()
должен возвращать BAD_VALUE
, а не генерировать событие завершения очистки.
Запись событий датчика в FMQ
Event FMQ используется датчиками HAL для передачи событий датчиков в структуру датчиков Android.
FMQ событий является синхронизированным FMQ, что означает, что любая попытка записать в FMQ больше событий, чем позволяет доступное пространство, приводит к сбою записи. В таком случае HAL должен определить, следует ли записывать текущий набор событий в виде двух меньших групп событий или записывать все события вместе, когда доступно достаточно места.
Когда HAL Sensors записал желаемое количество событий датчиков в Event FMQ, HAL Sensors должен уведомить платформу о готовности событий, записав бит EventQueueFlagBits::READ_AND_PROCESS
в функцию EventFlag::wake
Event FMQ. EventFlag можно создать из Event FMQ с помощью EventFlag::createEventFlag
и функции getEventFlagWord()
Event FMQ.
Датчики AIDL HAL поддерживают как write
, так и writeBlocking
в FMQ событий. Реализация по умолчанию предоставляет ссылку на использование write
. Если используется функция writeBlocking
, для флага readNotification
должно быть установлено значение EventQueueFlagBits::EVENTS_READ
, которое устанавливается платформой при чтении событий из Event FMQ. Флаг уведомления о записи должен быть установлен на EventQueueFlagBits::READ_AND_PROCESS
, который уведомляет платформу о том, что события были записаны в Event FMQ.
WAKE_UP события
События WAKE_UP
— это события датчика, которые заставляют процессор приложения (AP) просыпаться и немедленно обрабатывать событие. Всякий раз, когда событие WAKE_UP
записывается в Event FMQ, HAL датчиков должен обеспечить блокировку пробуждения, чтобы гарантировать, что система остается в бодрствующем состоянии до тех пор, пока платформа не сможет обработать событие. При получении события WAKE_UP
платформа обеспечивает собственную блокировку пробуждения, позволяя HAL датчиков снять блокировку пробуждения. Чтобы синхронизировать, когда датчики HAL снимают блокировку пробуждения, используйте FMQ Wake Lock.
HAL датчиков должен прочитать FMQ Wake Lock, чтобы определить количество событий WAKE_UP
, обработанных платформой. HAL должен снимать блокировку пробуждения для событий WAKE_UP
только в том случае, если общее количество необработанных событий WAKE_UP
равно нулю. После обработки событий датчика платформа подсчитывает количество событий, помеченных как события WAKE_UP
, и записывает это число обратно в FMQ Wake Lock.
Платформа устанавливает уведомление о записи WakeLockQueueFlagBits::DATA_WRITTEN
в FMQ Wake Lock всякий раз, когда она записывает данные в FMQ Wake Lock.
Динамические датчики
Динамические датчики — это датчики, которые физически не являются частью устройства, но могут использоваться в качестве входных данных для устройства, например геймпад с акселерометром.
Когда подключен динамический датчик, функция onDynamicSensorConnected
в ISensorsCallback
должна быть вызвана из HAL датчиков. Это уведомляет платформу о новом динамическом датчике и позволяет управлять датчиком через структуру, а также передавать события датчика клиентам.
Аналогичным образом, когда динамический датчик отключен, необходимо вызвать функцию onDynamicSensorDisconnected
в ISensorsCallback
, чтобы платформа могла удалить любой датчик, который больше не доступен.
Прямой канал
Прямой канал — это метод работы, при котором события датчиков записываются в определенную память, а не в Event FMQ, минуя Android Sensors Framework. Клиент, регистрирующий прямой канал, должен считывать события датчика непосредственно из памяти, которая использовалась для создания прямого канала, и не будет получать события датчика через платформу. Функция configDirectReport()
аналогична batch()
для нормальной работы и настраивает канал прямого отчета.
Функции registerDirectChannel()
и unregisterDirectChannel()
создают или уничтожают новый прямой канал.
Режимы работы
Функция setOperationMode()
позволяет платформе настроить датчик так, чтобы платформа могла вводить данные датчика в датчик. Это полезно для тестирования, особенно для алгоритмов, которые существуют ниже фреймворка.
Функция injectSensorData()
обычно используется для передачи рабочих параметров в HAL датчиков. Эту функцию также можно использовать для передачи событий датчика в конкретный датчик.
Валидация
Чтобы проверить реализацию датчиков HAL, запустите тесты датчиков CTS и VTS.
CTS-тесты
Тесты CTS датчика существуют как в автоматических тестах CTS, так и в ручном приложении CTS Verifier.
Автоматизированные тесты расположены в папке cts/tests/sensor/src/android/hardware/cts . Эти тесты проверяют стандартные функции датчиков, такие как активация датчиков, группирование и частота событий датчиков.
Тесты CTS Verifier расположены в папке cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors . Эти тесты требуют ручного ввода данных оператором-испытателем и гарантируют, что датчики сообщают точные значения.
Прохождение тестов CTS имеет решающее значение для обеспечения соответствия тестируемого устройства всем требованиям CDD.
тесты СУДС
Тесты VTS для датчиков AIDL HAL расположены в файле hardware/interfaces/sensors/aidl/vts/ . Эти тесты гарантируют, что Sensors HAL реализован правильно и что все требования в ISensors.aidl
и ISensorsCallback.aidl
правильно выполнены.
Инициализируйте HAL
Функция initialize()
должна поддерживаться для установления FMQ между платформой и HAL.
Разоблачить доступные датчики
В HAL Sensors AIDL функция getSensorsList()
должна возвращать одно и то же значение во время загрузки одного устройства, даже при перезапуске HAL Sensors. Новое требование к функции getSensorsList()
заключается в том, что она должна возвращать одно и то же значение во время загрузки одного устройства, даже при перезапуске Sensors HAL. Это позволяет платформе попытаться восстановить соединения датчиков при перезапуске системного сервера. Значение, возвращаемое функцией getSensorsList()
может измениться после перезагрузки устройства.
Запись событий датчика в FMQ
Вместо ожидания вызова poll()
в HAL Sensors AIDL HAL Sensors должен заранее записывать события датчиков в Event FMQ всякий раз, когда события датчиков доступны. HAL также отвечает за запись правильных битов в EventFlag
, чтобы вызвать чтение FMQ в рамках платформы.
WAKE_UP события
В Sensors HAL 1.0 HAL мог снять блокировку пробуждения для любого события WAKE_UP
при любом последующем вызове poll()
после того, как WAKE_UP
был отправлен в poll()
поскольку это указывало на то, что платформа обработала все события датчиков и получила блокировка пробуждения, если необходимо. Поскольку в HAL Sensors AIDL HAL больше не уведомляется, когда платформа обрабатывает события, записанные в FMQ, FMQ Wake Lock позволяет платформе связываться с HAL, когда она обрабатывает события WAKE_UP
.
В HAL Sensors AIDL блокировка пробуждения, обеспечиваемая HAL Sensors для событий WAKE_UP
, должна начинаться с SensorsHAL_WAKEUP
.
Динамические датчики
Динамические датчики возвращались с помощью функции poll()
в Sensors HAL 1.0. AIDL HAL для датчиков требует, чтобы onDynamicSensorsConnected
и onDynamicSensorsDisconnected
в ISensorsCallback
вызывались всякий раз, когда изменяются соединения динамических датчиков. Эти обратные вызовы доступны как часть указателя ISensorsCallback
, который предоставляется через функцию initialize()
.
Режимы работы
Должен поддерживаться режим DATA_INJECTION
для датчиков WAKE_UP
.
Поддержка нескольких HAL
Sensors AIDL HAL поддерживает multi-HAL с использованием платформы Sensors Multi-HAL . Подробности реализации см. в разделе Портирование с датчиков HAL 2.1 .