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 实现的传感器列表。请参阅 sensor_t,详细了解如何定义传感器。

传感器在列表中出现的顺序就是传感器报告给应用的顺序。通常,基础传感器先出现,然后是复合传感器。

如果多个传感器共享相同的传感器类型和唤醒属性,则列表中第一个传感器称为“默认”传感器。它是 getDefaultSensor(int sensorType, bool wakeUp) 返回的传感器。

此函数返回列表中传感器的数量。

activate(sensor, true/false)

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

激活或停用传感器。

sensor_handle 是要激活/停用传感器的句柄。传感器的句柄由其 sensor_t 结构的 handle 字段定义。

enabled 设置为 1 以启用传感器,设置为 0 以停用传感器。

单次触发传感器在接收到事件后会自动停用,但它们仍然必须接受通过调用 activate(..., enabled=0) 来停用。

非唤醒传感器永远不会阻止 SoC 进入暂停模式;也就是说,HAL 不应代表应用程序持有部分唤醒锁。

唤醒传感器在持续传递事件时,可以阻止 SoC 进入暂停模式,但是如果不需要传递任何事件,则必须释放部分唤醒锁。

如果 enabled 为 1 并且传感器已激活,则此函数为空操作并成功。

如果 enabled 为 0 并且传感器已停用,则此函数为空操作并成功。

此函数在成功时返回 0,否则返回负错误号。

batch(传感器, 标志, 采样周期, 最大报告延迟)

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(传感器, 采样周期)

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

在 HAL 1.0 版本之后,此函数已被弃用,并且永远不会被调用。而是调用 batch 函数来设置 sampling_period_ns 参数。

在 HAL 1.0 版本中,使用 setDelay 而不是 batch 来设置 sampling_period_ns

flush(传感器)

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 不适用于单次触发传感器;如果 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.hsensors_module_t 的定义以及 hw_module_t 的定义。

sensors_poll_device_t / sensors_poll_device_1_t

sensors_poll_device_1_t 包含上面定义的其余方法:activatebatchflushpoll。其 common 字段(类型为 hw_device_t)定义了 HAL 的版本号。

sensor_t

sensor_t 代表一个 Android 传感器。以下是它的一些重要字段

name: 代表传感器的用户可见字符串。此字符串通常包含底层传感器的部件名称、传感器的类型以及它是否是唤醒传感器。例如,“LIS2HH12 加速度计”、“MAX21000 未校准陀螺仪”、“BMP280 唤醒气压计”、“MPU6515 游戏旋转矢量”

handle: 注册到传感器或从中生成事件时用于引用传感器的整数。

type: 传感器的类型。有关更多详细信息,请参见 什么是 Android 传感器? 中的传感器类型说明,有关官方传感器类型,请参见 传感器类型。对于非官方传感器类型,type 必须以 SENSOR_TYPE_DEVICE_PRIVATE_BASE 开头

stringType: 传感器类型的字符串表示形式。当传感器具有官方类型时,设置为 SENSOR_STRING_TYPE_*。当传感器具有制造商特定的类型时,stringType 必须以制造商反向域名开头。例如,由 Fictional-Company 的 Cool-product 团队定义的传感器(例如,独角兽检测器)可以使用 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

resolution: 传感器可以测量的最小数值差异。通常根据 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 的大小。如果 FIFO 与其他传感器共享,则 fifoReservedEventCount 是 FIFO 中为该传感器保留的部分的大小。在大多数共享 FIFO 系统以及没有硬件 FIFO 的系统上,此值为 0。

fifoMaxEventCount: 可以存储在此传感器的 FIFO 中的最大事件数。这始终大于或等于 fifoReservedEventCount。此值用于估计以特定速率注册到传感器时 FIFO 将多快变满,假设没有激活其他传感器。在没有硬件 FIFO 的系统上,fifoMaxEventCount 为 0。有关更多详细信息,请参见批量处理

对于具有官方传感器类型的传感器,某些字段会被框架覆盖。例如,加速度计传感器被强制为具有连续报告模式,而心率监测器被强制受到 SENSOR_PERMISSION_BODY_SENSORS 权限的保护。

sensors_event_t

由 Android 传感器生成并通过 poll 函数报告的传感器事件类型为 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 时钟失去同步,因为传感器时钟会漂移。

data 和重叠字段: 传感器测得的值。这些字段的含义和单位特定于每种传感器类型。有关数据字段的说明,请参见 sensors.h 以及不同传感器类型的定义。对于某些传感器,读数的精度也通过 status 字段作为数据的一部分报告。此字段仅针对那些选定的传感器类型进行管道传输,在 SDK 层显示为精度值。对于这些传感器,在其传感器类型定义中提到了必须设置状态字段的事实。

元数据刷新完成事件

元数据事件与普通传感器事件具有相同的类型:sensors_event_meta_data_t = sensors_event_t。它们与通过 poll 返回的其他传感器事件一起返回。它们具有以下字段

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 函数的部分。