Датчики HAL 2.0

Уровень аппаратной абстракции датчиков (HAL) — это интерфейс между сенсорной платформой Android и датчиками устройства, такими как акселерометр или гироскоп. HAL «Датчики» определяет функции, которые необходимо реализовать, чтобы позволить платформе управлять датчиками.

Датчики HAL 2.0 доступны в Android 10 и более поздних версиях для новых и обновленных устройств. Sensors HAL 2.0 основан на Sensors HAL 1.0, но имеет несколько ключевых отличий, которые не позволяют обеспечить обратную совместимость. Датчики HAL 2.0 использует очереди быстрых сообщений (FMQ) для отправки событий датчиков из HAL в структуру датчиков Android.

Датчики HAL 2.1 доступны в Android 11 и более поздних версиях для новых и обновленных устройств. Датчики HAL 2.1 — это итерация датчиков HAL 2.0, которая предоставляет тип датчика HINGE_ANGLE и обновляет различные методы для принятия типа HINGE_ANGLE .

Интерфейс HAL 2.1

Основной источник документации для датчиков HAL 2.1 находится в определении HAL по адресу hardware/interfaces/sensors/2.1/ISensors.hal . Если существует конфликт требований между этой страницей и ISensors.hal , используйте требование в ISensors.hal .

Интерфейс HAL 2.0

Основной источник документации для датчиков 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 Sensors три параметра: два дескриптора FMQ и один указатель на объект ISensorsCallback .

HAL использует первый дескриптор для создания FMQ событий, используемого для записи событий датчиков в платформу. HAL использует второй дескриптор для создания FMQ Wake Lock, используемого для синхронизации, когда 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 больше не может соответствовать контракту Android API, согласно которому статические (нединамические) датчики не изменяются в течение срока службы приложения. Это также может помешать платформе восстановить активные запросы датчиков, сделанные приложениями. Поэтому поставщикам HAL рекомендуется предотвращать изменения списка датчиков, которых можно избежать.

Чтобы обеспечить стабильные дескрипторы датчиков, HAL должен детерминированно сопоставить данный физический датчик в устройстве с его дескриптором. Хотя интерфейс Sensors HAL не требует какой-либо конкретной реализации, у разработчиков есть ряд возможностей для удовлетворения этого требования.

Например, список датчиков можно отсортировать, используя комбинацию фиксированных атрибутов каждого датчика, таких как производитель, модель и тип датчика. Другой вариант основан на том факте, что набор статических датчиков устройства фиксирован аппаратно, поэтому HAL должен знать, когда все ожидаемые датчики завершили инициализацию, прежде чем вернуться из getSensorsList() или getSensorsList_2_1() . Этот список ожидаемых датчиков можно скомпилировать в двоичный файл 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.

Датчики 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 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 2.0 и функция injectSensorsData_2_1() в HAL 2.0 обычно используются для передачи рабочих параметров в 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 для датчиков HAL 2.0 находятся в файле hardware/interfaces/sensors/2.0/vts . Тесты VTS для датчиков HAL 2.1 расположены в hardware/interfaces/sensors/2.1/vts . Эти тесты гарантируют, что Sensors HAL реализован правильно и что все требования в ISensors.hal и ISensorsCallback.hal выполняются должным образом.

Обновление до Датчики 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.

Пример реализации собственных датчиков 2.1 HAL см. в Sensors.h .

Обновление до датчиков 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

Датчики HAL 2.0 и 2.1 поддерживают multi-HAL с использованием платформы Sensors Multi-HAL . Подробности реализации см. в разделе Портирование с датчиков HAL 1.0 .