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