Датчики 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. Подробную информацию о том, как определяются датчики, см. в параметре sensor_t .

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

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

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

активировать(датчик, 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) .

Датчики, не предназначенные для пробуждения, никогда не препятствуют переходу SoC в режим приостановки; то есть 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 вместо параметра batch для установки sampling_period_ns использовался параметр setDelay.

flush(sensor)

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

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

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

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

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

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

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

голосование()

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-датчик . Вот некоторые из его важных полей:

Имя: Видимая пользователю строка, представляющая датчик. Эта строка часто содержит название компонента базового датчика, его тип и информацию о том, является ли он датчиком пробуждения. Например: «LIS2HH12 Акселерометр», «MAX21000 Некалиброванный гироскоп», «BMP280 Барометр пробуждения», «MPU6515 Вектор вращения в игре».

Идентификатор: Целочисленное значение, используемое для ссылки на датчик при регистрации или генерации событий.

Тип: Тип датчика. Подробнее о типах датчиков см. в разделе «Что такое датчики 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 указывается потребляемая мощность во время движения.

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. Если 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 :

версия: Должна быть sizeof(struct sensors_event_t)

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

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

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

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

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

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

версия: Должна быть META_DATA_VERSION

тип: Должен быть SENSOR_TYPE_META_DATA

датчик, зарезервировано и метка времени : должно быть равно 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 .