Интерфейс Sensors HAL, объявленный в файле sensors.h, представляет собой интерфейс между фреймворком Android и программным обеспечением, предназначенным для конкретного оборудования. В реализации HAL должна быть определена каждая функция, объявленная в файле sensors.h. Основные функции:
get_sensors_list– возвращает список всех датчиков.activate– запустить или остановить датчик.batch– задает параметры датчика, такие как частота выборки и максимальная задержка при передаче данных.setDelay– используется только в HAL версии 1.0. Задает частоту дискретизации для определенного датчика.flush– очищает очередь FIFO указанного датчика и сообщает о завершении очистки.poll– возвращает доступные события датчиков.
Реализация должна быть безопасной для потоков и позволять вызывать эти функции из разных потоков.
В интерфейсе также определены несколько типов, используемых этими функциями. Основные типы:
sensors_module_tsensors_poll_device_tsensor_tsensors_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…