Sensors HAL 1.0

Интерфейс Sensors HAL, объявленный в файле sensors.h, представляет собой интерфейс между фреймворком Android и программным обеспечением, предназначенным для конкретного оборудования. В реализации HAL должна быть определена каждая функция, объявленная в файле sensors.h. Основные функции:

  • get_sensors_list – возвращает список всех датчиков.
  • activate – запустить или остановить датчик.
  • batch – задает параметры датчика, такие как частота выборки и максимальная задержка при передаче данных.
  • setDelay – используется только в HAL версии 1.0. Задает частоту дискретизации для определенного датчика.
  • flush – очищает очередь FIFO указанного датчика и сообщает о завершении очистки.
  • poll – возвращает доступные события датчиков.

Реализация должна быть безопасной для потоков и позволять вызывать эти функции из разных потоков.

В интерфейсе также определены несколько типов, используемых этими функциями. Основные типы:

  • sensors_module_t
  • sensors_poll_device_t
  • sensor_t
  • sensors_event_t

Помимо информации в разделах ниже, вы можете найти дополнительные сведения об этих типах в файле sensors.h.

get_sensors_list(list)

int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t
  const** list);

Предоставляет список датчиков, реализованных HAL. Подробнее о том, как определяются датчики…

Порядок, в котором датчики указаны в списке, определяет порядок, в котором они будут передаваться приложениям. Обычно сначала показываются базовые датчики, а затем – составные.

Если несколько датчиков имеют одинаковый тип и свойство пробуждения, первый из них в списке называется датчиком по умолчанию. Это значение возвращается методом getDefaultSensor(int sensorType, bool wakeUp).

Эта функция возвращает количество датчиков в списке.

activate(sensor, true/false)

int (*activate)(struct sensors_poll_device_t *dev, int sensor_handle, int
  enabled);

Включает или отключает датчик.

sensor_handle – дескриптор датчика, который нужно активировать или деактивировать. Дескриптор датчика определяется полем handle структуры sensor_t.

enabled – значение 1, чтобы включить датчик, или 0, чтобы отключить его.

Одноразовые датчики автоматически отключаются после получения события, но их также можно отключить с помощью вызова activate(..., enabled=0).

Датчики, не предназначенные для пробуждения, никогда не препятствуют переходу системы на кристалле в спящий режим. Это означает, что HAL не должен удерживать частичную блокировку пробуждения от имени приложений.

Датчики пробуждения, непрерывно передающие события, могут помешать переходу SoC в режим ожидания, но если передавать ничего не нужно, частичную блокировку пробуждения необходимо снять.

Если для правила enabled задано значение 1 и датчик уже активирован, эта функция не выполняет никаких действий и завершается успешно.

Если для правила enabled установлено значение "0" и датчик уже деактивирован, функция не выполняет никаких действий и завершается успешно.

Если функция выполнена успешно, она возвращает значение 0, в противном случае – отрицательное число ошибки.

batch(sensor, flags, sampling period, maximum report latency)

int (*batch)(
     struct sensors_poll_device_1* dev,
     int sensor_handle,
     int flags,
     int64_t sampling_period_ns,
     int64_t max_report_latency_ns);

Задает параметры датчика, в том числе частоту выборки и максимальную задержку отчета. Эту функцию можно вызвать, когда датчик активирован. В этом случае она не должна приводить к потере измерений. Переход от одной частоты дискретизации к другой не должен приводить к потере событий, как и переход от высокой максимальной задержки отчета к низкой.

sensor_handle – дескриптор датчика, который нужно настроить.

flags сейчас не используется.

sampling_period_ns – период выборки, с которым должен работать датчик, в наносекундах. Подробнее о sampling_period_ns…

max_report_latency_ns – максимальное время задержки событий перед передачей через HAL в наносекундах. Подробную информацию можно найти в разделе max_report_latency_ns.

В случае успеха функция возвращает 0, в противном случае – отрицательное число ошибки.

setDelay(sensor, sampling period)

int (*setDelay)(
     struct sensors_poll_device_t *dev,
     int sensor_handle,
     int64_t sampling_period_ns);

Начиная с версии HAL 1.0 эта функция устарела и больше не вызывается. Вместо этого для настройки параметра sampling_period_ns вызывается функция batch.

В HAL версии 1.0 для установки значения sampling_period_ns вместо batch использовалась функция setDelay.

flush(sensor)

int (*flush)(struct sensors_poll_device_1* dev, int sensor_handle);

Добавьте событие полной очистки в конец аппаратного FIFO для указанного датчика и очистите FIFO. Эти события доставляются обычным образом (как если бы истек максимальный период задержки отчета) и удаляются из FIFO.

Сброс выполняется асинхронно (то есть эта функция должна возвращать значение немедленно). Если в реализации используется один FIFO для нескольких датчиков, то FIFO очищается и событие завершения очистки добавляется только для указанного датчика.

Если у указанного датчика нет FIFO (буферизация невозможна) или если FIFO был пуст во время вызова, функция flush все равно должна быть выполнена успешно и отправить событие завершения очистки для этого датчика. Это относится ко всем датчикам, кроме одноразовых.

При вызове flush, даже если событие очистки уже находится в FIFO для этого датчика, необходимо создать ещё одно и добавить его в конец FIFO, а затем очистить FIFO. Количество вызовов flush должно быть равно количеству созданных событий flush complete.

flush не применяется к одноразовым датчикам. Если sensor_handle относится к одноразовому датчику, flush должен возвращать -EINVAL и не создавать событие завершения очистки метаданных.

Если функция выполнена успешно, она возвращает 0. Если указанный датчик является одноразовым или не включен, возвращается значение -EINVAL. В остальных случаях возвращается отрицательное число ошибки.

poll()

int (*poll)(struct sensors_poll_device_t *dev, sensors_event_t* data, int
  count);

Возвращает массив данных датчиков, заполняя аргумент data. Эта функция должна блокировать работу до тех пор, пока не будут доступны события. В случае успеха функция возвращает количество прочитанных событий, а в случае ошибки – отрицательное число.

Количество событий, возвращаемых в data, должно быть меньше или равно аргументу count. Эта функция никогда не должна возвращать 0 (нет события).

Последовательность звонков

При загрузке устройства вызывается функция get_sensors_list.

Когда датчик активируется, функция batch вызывается с запрошенными параметрами, а затем вызывается функция activate(..., enable=1).

Обратите внимание, что в HAL версии 1_0 порядок был обратным: сначала вызывался метод activate, а затем set_delay.

Функция batch вызывается, когда запрошенные характеристики датчика меняются во время его активации.

flush можно вызвать в любое время, даже для неактивированных датчиков (в этом случае метод должен возвращать -EINVAL).

Когда датчик деактивируется, вызывается метод activate(..., enable=0).

Параллельно с этими вызовами функция poll будет вызываться многократно для запроса данных. poll можно вызвать, даже если датчики не активированы.

sensors_module_t

sensors_module_t – тип, используемый для создания модуля аппаратного обеспечения Android для датчиков. Реализация HAL должна определять объект HAL_MODULE_INFO_SYM этого типа, чтобы предоставлять функцию get_sensors_list. Подробнее об определении sensors_module_t в файле sensors.h и определении hw_module_t…

sensors_poll_device_t / sensors_poll_device_1_t

sensors_poll_device_1_t содержит остальные методы, определенные выше: activate, batch, flush и poll. Поле common (тип hw_device_t) определяет номер версии HAL.

sensor_t

sensor_t представляет датчик Android. Вот некоторые из его важных полей:

name: строка, представляющая датчик и видимая пользователю. Эта строка часто содержит название детали основного датчика, тип датчика и информацию о том, является ли он датчиком пробуждения. Примеры: "LIS2HH12 Accelerometer", "MAX21000 Uncalibrated Gyroscope", "BMP280 Wake-up Barometer", "MPU6515 Game Rotation Vector".

handle – целое число, используемое для обращения к датчику при регистрации или создании событий на его основе.

type: тип датчика. Подробнее о типах датчиков рассказывается в статье Что такое датчики Android?, а официальные типы датчиков перечислены в этой статье. Для неофициальных типов датчиков значение type должно начинаться с SENSOR_TYPE_DEVICE_PRIVATE_BASE.

stringType: тип датчика в виде строки. Если у датчика есть официальный тип, укажите значение SENSOR_STRING_TYPE_*. Если у датчика есть тип, заданный производителем, значение stringType должно начинаться с обратного доменного имени производителя. Например, датчик (скажем, детектор единорогов), разработанный командой Cool-product в компании Fictional-Company, может использовать stringType=”com.fictional_company.cool_product.unicorn_detector”. Параметр stringType используется для уникальной идентификации неофициальных типов датчиков. Подробнее о типах и строковых типах можно узнать в файле sensors.h.

requiredPermission: строка, представляющая разрешение, которое должно быть у приложений, чтобы они могли видеть датчик, регистрироваться в нем и получать его данные. Пустая строка означает, что приложениям не требуется никаких разрешений для доступа к этому датчику. Для некоторых типов датчиков, например пульсометра, обязательно указывать requiredPermission. Все датчики, предоставляющие конфиденциальную информацию о пользователе (например, о пульсе), должны быть защищены разрешением.

flags: флаги для этого датчика, определяющие режим его работы и то, является ли он датчиком пробуждения. Например, у одноразового датчика пробуждения будет значение flags = SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP. Биты флага, которые не используются в текущей версии HAL, должны быть равны 0.

maxRange: максимальное значение, которое может передавать датчик, в тех же единицах, что и передаваемые значения. Датчик должен быть способен передавать значения без насыщения в течение [-maxRange; maxRange]. Обратите внимание, что это означает, что общий диапазон датчика в общем смысле составляет 2*maxRange. Если датчик передает значения по нескольким осям, диапазон применяется к каждой из них. Например, акселерометр с диапазоном "+/- 2g" будет сообщать значение maxRange = 2*9.81 = 2g.

Разрешение. Наименьшая разница в значениях, которую может измерить датчик. Обычно вычисляется на основе maxRange и количества битов в измерении.

power: энергопотребление датчика в миллиамперах. Это почти всегда больше, чем энергопотребление, указанное в техническом описании базового датчика. Подробнее о том, почему базовые датчики не равны физическим… Подробнее о том, как измерять энергопотребление датчика… Если энергопотребление датчика зависит от того, движется ли устройство, то в поле power указывается энергопотребление во время движения.

minDelay – для непрерывных датчиков период выборки в микросекундах, соответствующий максимальной скорости, которую поддерживает датчик. Подробнее о том, как используется это значение, рассказывается в описании параметра sampling_period_ns. Обратите внимание, что значение minDelay выражается в микросекундах, а sampling_period_ns – в наносекундах. Для датчиков, работающих в режиме отслеживания изменений и специальном режиме отчетности, если не указано иное, значение minDelay должно быть равно 0. Для датчиков, которые срабатывают один раз, должно быть указано значение -1.

maxDelay. Для непрерывных датчиков и датчиков, реагирующих на изменения, – период выборки в микросекундах, соответствующий самой низкой частоте, которую поддерживает датчик. Подробнее о том, как используется это значение, читайте в разделе sampling_period_ns. Обратите внимание, что значение maxDelay указывается в микросекундах, а sampling_period_ns – в наносекундах. Для специальных и одноразовых датчиков значение maxDelay должно быть равно 0.

fifoReservedEventCount: количество событий, зарезервированных для этого датчика в аппаратном FIFO. Если для этого датчика есть отдельный буфер FIFO, то fifoReservedEventCount – это размер этого буфера. Если FIFO используется совместно с другими датчиками, fifoReservedEventCount – это размер части FIFO, зарезервированной для этого датчика. В большинстве систем с очередью FIFO, а также в системах без аппаратной очереди FIFO это значение равно 0.

fifoMaxEventCount: максимальное количество событий, которые могут храниться в FIFO для этого датчика. Это значение всегда больше или равно fifoReservedEventCount. Это значение используется для оценки того, как быстро буфер FIFO заполнится при регистрации данных с датчика с определенной частотой, если другие датчики не активированы. В системах, где нет аппаратного FIFO, значение fifoMaxEventCount равно 0. Подробнее о пакетной обработке…

Для датчиков с официальным типом некоторые поля переопределяются фреймворком. Например, акселерометры должны работать в режиме непрерывной передачи данных, а пульсометры – быть защищены разрешением SENSOR_PERMISSION_BODY_SENSORS.

sensors_event_t

События, генерируемые датчиками Android и передаваемые через функцию poll, имеют тип type sensors_event_t. Вот некоторые важные поля sensors_event_t:

version: – должно быть указано значение sizeof(struct sensors_event_t).

sensor: дескриптор датчика, который сгенерировал событие, как определено в sensor_t.handle.

type: тип датчика, который сгенерировал событие, как определено в sensor_t.type.

timestamp – временная метка события в наносекундах. Это время, когда произошло событие (был сделан шаг или выполнено измерение акселерометра), а не время, когда было зарегистрировано событие. timestamp должен быть синхронизирован с часами elapsedRealtimeNano, а в случае непрерывных датчиков дрожание должно быть небольшим. Фильтрация временных меток иногда необходима для соблюдения требований CDD, поскольку использование только времени прерывания SoC для установки временных меток приводит к слишком сильному дрожанию, а использование только времени чипа датчика для установки временных меток может привести к рассинхронизации с часами elapsedRealtimeNano, поскольку часы датчика дрейфуют.

Данные и перекрывающиеся поля. Значения, полученные с помощью датчика. Значение и единицы измерения этих полей зависят от типа датчика. Описание полей данных можно найти в файле sensors.h и в разделе Типы датчиков. Для некоторых датчиков точность показаний также указывается в данных в поле status. Это поле передается только для определенных типов датчиков и отображается на уровне SDK как значение точности. Для таких датчиков в определении типа датчика указано, что поле статуса должно быть задано.

События завершения сброса метаданных

События метаданных имеют тот же тип, что и обычные события датчиков: sensors_event_meta_data_t = sensors_event_t. Они возвращаются вместе с другими событиями датчиков через опрос. Они содержат следующие поля:

version: должно быть META_DATA_VERSION.

type: должно быть SENSOR_TYPE_META_DATA.

sensor, reserved и timestamp: должно быть равно 0.

meta_data.what: содержит тип метаданных для этого события. В настоящее время поддерживается только один тип метаданных: META_DATA_FLUSH_COMPLETE.

События META_DATA_FLUSH_COMPLETE представляют собой завершение очистки FIFO датчика. Если задано значение meta_data.what=META_DATA_FLUSH_COMPLETE, то для параметра meta_data.sensor необходимо указать дескриптор очищенного датчика. Они создаются только тогда, когда для датчика вызывается функция flush. Подробнее о функции flush…