Уровень аппаратной абстракции датчиков (HAL) — это интерфейс между платформой датчиков Android и датчиками устройства, такими как акселерометр или гироскоп. HAL датчиков определяет функции, которые должны быть реализованы, чтобы платформа могла управлять датчиками.
Sensors HAL 2.0 доступен в Android 10 и выше для новых и обновленных устройств. Sensors HAL 2.0 основан на Sensors HAL 1.0 , но имеет несколько ключевых отличий, которые препятствуют обратной совместимости. Sensors HAL 2.0 использует быстрые очереди сообщений (FMQ) для отправки событий датчиков из HAL в среду датчиков Android.
Sensors HAL 2.1 доступен в Android 11 и выше для новых и обновленных устройств. Sensors HAL 2.1 — это итерация Sensors HAL 2.0, которая предоставляет доступ к типу датчика HINGE_ANGLE и обновляет различные методы для приема типа HINGE_ANGLE .
Интерфейс HAL 2.1
Основной источник документации для Sensors HAL 2.1 находится в определении HAL по адресу hardware/interfaces/sensors/2.1/ISensors.hal . В случае противоречия требований между этой страницей и ISensors.hal , используйте требования из ISensors.hal .
Интерфейс HAL 2.0
Основной источник документации для Sensors HAL 2.0 находится в определении HAL по адресу hardware/interfaces/sensors/2.0/ISensors.hal . В случае противоречия требований между этой страницей и ISensors.hal , используйте требования из ISensors.hal .
Внедрить датчики HAL 2.0 и HAL 2.1
Для реализации Sensors HAL 2.0 или 2.1 объект должен расширять интерфейс ISensors и реализовывать все функции, определенные в 2.0/ISensors.hal или 2.1/ISensors.hal .
Инициализация HAL
Для использования Sensors HAL необходимо инициализировать его с помощью платформы Android Sensors. Платформа вызывает функцию initialize() для HAL 2.0 и функцию initialize_2_1() для HAL 2.1, чтобы передать Sensors HAL три параметра: два дескриптора FMQ и один указатель на объект ISensorsCallback .
HAL использует первый дескриптор для создания объекта Event FMQ, используемого для записи событий датчиков в фреймворк. HAL использует второй дескриптор для создания объекта Wake Lock FMQ, используемого для синхронизации при снятии блокировки пробуждения для событий датчиков WAKE_UP . HAL должен сохранить указатель на объект ISensorsCallback , чтобы можно было вызывать необходимые функции обратного вызова.
Функция initialize() или initialize_2_1() должна быть первой функцией, вызываемой при инициализации Sensors HAL.
Отобразить доступные датчики
Чтобы получить список всех доступных статических датчиков в устройстве, используйте функцию getSensorsList() в HAL 2.0 и функцию getSensorsList_2_1() в HAL 2.1. Эта функция возвращает список датчиков, каждый из которых однозначно идентифицируется своим дескриптором. Дескриптор для данного датчика не должен изменяться при перезапуске процесса, в котором размещен HAL датчиков. Дескрипторы могут изменяться при перезагрузке устройства и при перезапуске системного сервера.
Если несколько датчиков имеют одинаковый тип и свойство пробуждения, то первый датчик в списке называется датчиком по умолчанию и возвращается приложениям, использующим функцию getDefaultSensor(int sensorType, bool wakeUp) .
Список стабильности датчиков
После перезапуска HAL-интерфейса Sensors, если данные, возвращаемые функциями getSensorsList() или getSensorsList_2_1() указывают на существенное изменение по сравнению со списком датчиков, полученным до перезапуска, платформа запускает перезапуск среды выполнения Android. Существенные изменения в списке датчиков включают случаи, когда датчик с заданным дескриптором отсутствует или изменил свои атрибуты, или когда вводятся новые датчики. Хотя перезапуск среды выполнения Android нарушает работу пользователя, он необходим, поскольку платформа Android больше не может соответствовать контракту API Android, согласно которому статические (нединамические) датчики не изменяются в течение жизненного цикла приложения. Это также может помешать платформе восстановить активные запросы к датчикам, сделанные приложениями. Поэтому разработчикам HAL-интерфейсов рекомендуется предотвращать ненужные изменения списка датчиков.
Для обеспечения стабильной работы с дескрипторами датчиков HAL должен детерминированно сопоставлять заданный физический датчик в устройстве с его дескриптором. Хотя интерфейс Sensors HAL не предписывает какой-либо конкретной реализации, у разработчиков есть ряд вариантов для выполнения этого требования.
Например, список датчиков можно отсортировать, используя комбинацию фиксированных атрибутов каждого датчика, таких как производитель, модель и тип датчика. Другой вариант основан на том, что набор статических датчиков устройства фиксирован на аппаратном уровне, поэтому HAL необходимо знать, когда все ожидаемые датчики завершили инициализацию, прежде чем возвращать результат из getSensorsList() или getSensorsList_2_1() . Этот список ожидаемых датчиков может быть скомпилирован в двоичный файл HAL или сохранен в конфигурационном файле в файловой системе, а порядок их появления может быть использован для получения стабильных дескрипторов. Хотя наилучшее решение зависит от конкретных особенностей реализации вашего HAL, ключевое требование заключается в том, что дескрипторы датчиков не должны изменяться при перезапуске HAL.
Настройка датчиков
Перед активацией датчика необходимо настроить период выборки и максимальную задержку передачи данных с помощью функции batch() .
Датчик должен иметь возможность перенастраиваться в любое время с помощью batch() без потери данных.
Период выборки
Период выборки имеет различное значение в зависимости от типа настраиваемого датчика:
- Непрерывный режим: события, регистрируемые датчиками, генерируются с непрерывной частотой.
- При изменении: События генерируются не быстрее, чем длится период выборки, и могут генерироваться со скоростью, меньшей, чем длится период выборки, если измеренное значение не изменяется.
- Однократный отбор проб: период выборки не учитывается.
- Примечание: более подробную информацию см. в разделе «Типы датчиков» .
Чтобы узнать о взаимодействии между периодом выборки и режимами передачи данных датчика, см. раздел «Режимы передачи данных» .
Максимальная задержка передачи данных
Максимальная задержка отправки устанавливает максимальное время в наносекундах, в течение которого события могут быть задержаны и сохранены в аппаратном FIFO перед записью в Event FMQ через HAL, пока SoC находится в активном состоянии.
Значение, равное нулю, означает, что события должны быть зарегистрированы сразу после их измерения, либо без сохранения данных в FIFO, либо с очисткой FIFO, как только в нем появится хотя бы одно событие от датчика.
Например, акселерометр, активируемый с частотой 50 Гц и имеющий нулевую максимальную задержку передачи данных, генерирует прерывания 50 раз в секунду, когда SoC находится в активном состоянии.
Когда максимальная задержка передачи данных превышает ноль, события датчика не обязательно сообщать сразу после их обнаружения. События могут временно храниться в аппаратном FIFO и передаваться партиями, при условии, что задержка между событиями не превышает максимальную задержку передачи данных. Все события, начиная с предыдущей партии, записываются и возвращаются одновременно. Это уменьшает количество прерываний, отправляемых в SoC, и позволяет SoC переключаться в режим пониженного энергопотребления, пока датчик захватывает и обрабатывает данные партиями.
Каждому событию присваивается временная метка. Задержка времени, когда сообщается о событии, не должна влиять на временную метку события. Временная метка должна быть точной и соответствовать времени, когда событие физически произошло, а не времени, когда о нем было сообщено.
Дополнительную информацию и требования к передаче событий с датчиков с ненулевой максимальной задержкой передачи см. в разделе «Пакетная обработка» .
Активировать датчики
Данная платформа включает и отключает датчики с помощью функции activate() . Перед активацией датчика платформа должна сначала настроить его с помощью batch() .
После деактивации датчика дальнейшие события от этого датчика не должны записываться в Event FMQ.
Датчики смыва
Если датчик настроен на пакетную обработку данных, платформа может принудительно выполнить немедленную очистку пакетных событий датчика, вызвав метод flush() . Это приводит к немедленной записи пакетных событий датчика для указанного дескриптора датчика в Event FMQ. HAL-интерфейс датчиков должен добавить событие завершения очистки в конец событий датчика, записанных в результате вызова flush() .
Очистка буфера происходит асинхронно (то есть эта функция должна немедленно завершиться). Если в реализации используется один FIFO для нескольких датчиков, очистка этого FIFO выполняется, и событие завершения очистки добавляется только для указанного датчика.
Если указанный датчик не имеет FIFO (буферизация невозможна) или если FIFO был пуст на момент вызова, flush() все равно должна успешно завершиться и отправить событие flush для этого датчика. Это относится ко всем датчикам, кроме одноразовых.
Если flush() вызывается для однократного датчика, то flush() должна возвращать BAD_VALUE и не генерировать событие завершения операции flush.
Запись событий с датчиков в FMQ
Event FMQ используется модулем Sensors HAL для передачи событий датчиков в среду разработки датчиков Android.
Event FMQ — это синхронизированный FMQ, что означает, что любая попытка записать в FMQ больше событий, чем позволяет доступное пространство, приводит к неудачной записи. В таком случае HAL должен определить, следует ли записывать текущий набор событий двумя меньшими группами событий или записывать все события вместе, когда будет достаточно места.
Когда HAL-интерфейс для датчиков запишет необходимое количество событий датчиков в Event FMQ, он должен уведомить фреймворк о готовности событий, записав бит EventQueueFlagBits::READ_AND_PROCESS в функцию EventFlag::wake объекта Event FMQ. Флаг события можно создать из Event FMQ с помощью EventFlag::createEventFlag и функции getEventFlagWord() объекта Event FMQ.
Sensors HAL 2.0/2.1 поддерживает как write , так и writeBlocking в Event FMQ. Реализация по умолчанию предоставляет пример использования функции write . Если используется функция writeBlocking , флаг readNotification должен быть установлен в значение EventQueueFlagBits::EVENTS_READ , которое устанавливается фреймворком при чтении событий из Event FMQ. Флаг уведомления о записи должен быть установлен в значение EventQueueFlagBits::READ_AND_PROCESS , которое уведомляет фреймворк о том, что события были записаны в Event FMQ.
События WAKE_UP
События WAKE_UP — это события датчиков, которые заставляют процессор приложения (AP) проснуться и немедленно обработать событие. Всякий раз, когда событие WAKE_UP записывается в Event FMQ, Sensors HAL должен обеспечить блокировку пробуждения, чтобы гарантировать, что система останется в бодрствующем состоянии до тех пор, пока платформа не сможет обработать событие. После получения события WAKE_UP платформа обеспечивает свою собственную блокировку пробуждения, позволяя Sensors HAL освободить свою блокировку. Для синхронизации момента освобождения блокировки пробуждения Sensors HAL используйте Wake Lock FMQ.
HAL-модуль датчиков должен считывать FMQ-сообщение Wake Lock, чтобы определить количество событий WAKE_UP , обработанных фреймворком. HAL-модуль должен снимать блокировку пробуждения для событий WAKE_UP только в том случае, если общее количество необработанных событий WAKE_UP равно нулю. После обработки событий датчиков фреймворк подсчитывает количество событий, помеченных как события WAKE_UP , и записывает это число обратно в FMQ-сообщение Wake Lock.
Данная структура устанавливает уведомление о записи WakeLockQueueFlagBits::DATA_WRITTEN в очередь Wake Lock FMQ всякий раз, когда происходит запись данных в эту очередь.
Динамические датчики
Динамические датчики — это датчики, которые физически не являются частью устройства, но могут использоваться в качестве входных данных для устройства, например, геймпад с акселерометром.
При подключении динамического датчика необходимо вызвать функцию onDynamicSensorConnected в ISensorsCallback из HAL-интерфейса датчиков. Это уведомляет фреймворк о новом динамическом датчике и позволяет управлять им через фреймворк, а также получать данные о событиях датчика от клиентов.
Аналогично, при отключении динамического датчика необходимо вызвать функцию onDynamicSensorDisconnected в ISensorsCallback , чтобы фреймворк мог удалить любой датчик, который больше недоступен.
Прямой канал
Прямой канал — это метод работы, при котором события с датчиков записываются в определенную область памяти, а не в Event FMQ, минуя Android Sensors Framework. Клиент, зарегистрировавший прямой канал, должен считывать события с датчиков непосредственно из той области памяти, которая использовалась для создания прямого канала, и не будет получать события с датчиков через фреймворк. Функция configDirectReport() аналогична функции batch() для обычной работы и настраивает прямой канал отчетов.
Функции registerDirectChannel() и unregisterDirectChannel() создают или уничтожают новый прямой канал.
Режимы работы
Функция setOperationMode() позволяет фреймворку настроить датчик таким образом, чтобы он мог передавать данные с датчика. Это полезно для тестирования, особенно для алгоритмов, которые находятся ниже по иерархии фреймворка.
Функции injectSensorData() и injectSensorsData_2_1() в HAL 2.0 обычно используются для передачи рабочих параметров в HAL датчиков. Эти функции также могут использоваться для внедрения событий датчика в конкретный датчик.
Проверка
Для проверки правильности вашей реализации HAL для датчиков запустите тесты CTS и VTS для датчиков.
Тесты CTS
Тесты Sensor 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
Тесты VTS для Sensors HAL 2.0 находятся в каталоге hardware/interfaces/sensors/2.0/vts . Тесты VTS для Sensors HAL 2.1 находятся в каталоге hardware/interfaces/sensors/2.1/vts . Эти тесты гарантируют корректную реализацию Sensors HAL и выполнение всех требований, указанных в файлах ISensors.hal и ISensorsCallback.hal .
Обновите Sensors HAL с версии 2.0 до 2.1.
При обновлении с версии 2.0 до Sensors HAL 2.1 ваша реализация HAL должна включать методы initialize_2_1() , getSensorsList_2_1() и injectSensorsData_2_1() , а также типы HAL 2.1. Эти методы должны соответствовать тем же требованиям, которые были изложены для HAL 2.0 выше.
Поскольку HAL минорных версий должны поддерживать все функции предыдущих HAL, HAL версии 2.1 должны поддерживать инициализацию как HAL версии 2.0. Чтобы избежать сложностей, связанных с поддержкой обеих версий HAL, настоятельно рекомендуется использовать Multi-HAL 2.1.
Пример реализации собственного HAL для Sensors 2.1 можно найти в файле Sensors.h .
Обновите Sensors HAL с версии 1.0 до 2.0.
При обновлении Sensors HAL с версии 1.0 убедитесь, что ваша реализация HAL соответствует следующим требованиям.
Инициализация HAL
Для установления FMQ-соединений между фреймворком и HAL необходимо поддерживать функцию initialize() .
Отобразить доступные датчики
В Sensors HAL 2.0 функция getSensorsList() должна возвращать одно и то же значение в течение одной загрузки устройства, даже после перезапуска Sensors HAL. Новое требование к функции getSensorsList() заключается в том, что она должна возвращать одно и то же значение в течение одной загрузки устройства, даже после перезапуска Sensors HAL. Это позволяет платформе пытаться восстановить соединения с датчиками, если системный сервер перезапускается. Значение, возвращаемое функцией getSensorsList() может измениться после перезагрузки устройства.
Запись событий с датчиков в FMQ
Вместо ожидания вызова функции poll() , в Sensors HAL 2.0, Sensors HAL должен заблаговременно записывать события датчиков в Event FMQ всякий раз, когда эти события становятся доступны. HAL также отвечает за запись правильных битов в EventFlag для инициирования чтения FMQ в рамках фреймворка.
События WAKE_UP
В Sensors HAL 1.0 HAL мог снять блокировку пробуждения для любого события WAKE_UP при любом последующем вызове poll() после отправки события WAKE_UP в poll() поскольку это указывало на то, что платформа обработала все события датчиков и получила блокировку пробуждения, если это было необходимо. Поскольку в Sensors HAL 2.0 HAL больше не знает, когда платформа обработала события, записанные в FMQ, блокировка пробуждения FMQ позволяет платформе сообщать HAL о том, когда она обработала события WAKE_UP .
В Sensors HAL 2.0 блокировка пробуждения, обеспечиваемая Sensors HAL для событий WAKE_UP , должна начинаться с SensorsHAL_WAKEUP .
Динамические датчики
В Sensors HAL 1.0 динамические датчики возвращались с помощью функции poll() . Sensors HAL 2.0 требует, чтобы onDynamicSensorsConnected и onDynamicSensorsDisconnected в ISensorsCallback вызывались всякий раз, когда изменяются соединения динамических датчиков. Эти коллбэки доступны как часть указателя ISensorsCallback , предоставляемого через функцию initialize() .
Режимы работы
Режим DATA_INJECTION для датчиков WAKE_UP должен поддерживаться в Sensors HAL 2.0.
Поддержка нескольких HAL
Sensors HAL 2.0 и 2.1 поддерживают многоканальный HAL с использованием фреймворка Sensors Multi-HAL . Подробности реализации см. в разделе «Перенос с Sensors HAL 1.0» .