sensors.h 中声明的传感器 HAL 接口表示 Android 框架与硬件专用软件之间的接口。HAL 实现必须定义 sensors.h 中声明的每个函数。主要函数如下:
get_sensors_list
- 返回所有传感器的列表。activate
- 启动或停止传感器。batch
- 设置传感器的参数,如采样率和最大报告延迟。setDelay
- 仅用于 1.0 版本的 HAL。设置指定传感器的采样率。flush
- flush 指定传感器的 FIFO 并在完成后报告 flush 完成事件。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(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);
在 1.0 版之后的 HAL 中,该函数已被弃用,并且无法再调用。我们将调用 batch
函数来设置 sampling_period_ns
参数。
在 1.0 版 HAL 中,使用 setDelay(而非 batch)来设置 sampling_period_ns。
flush(sensor)
int (*flush)(struct sensors_poll_device_1* dev, int sensor_handle);
将 flush 完成事件添加到指定传感器的硬件 FIFO 的末尾并 flush FIFO。这些事件会照常提交(即好像最大报告延迟已过期一样)并从 FIFO 中移除。
flush 会异步执行(即该函数必须立即返回)。如果实现将一个 FIFO 用于多个传感器,请 flush 该 FIFO,并且仅为指定传感器添加 flush 完成事件。
如果指定传感器没有 FIFO(无法缓冲),或者如果 FIFO 在调用时为空,flush
仍必须操作成功并为该传感器发送 flush 完成事件。这适用于除单次传感器以外的所有传感器。
当调用 flush
时,即使该传感器的 FIFO 中已经存在 flush 事件,也必须另外创建一个 flush 事件并将其添加到 FIFO 的末尾,并且必须 flush FIFO。flush
调用的次数必须等于创建的清空完成事件数。
flush
不适用于单次传感器。如果 sensor_handle
引用的是单次传感器,flush
必须返回 -EINVAL
,并且不会生成任何 flush 完成元数据事件。
如果操作成功,该函数返回 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)
。
请注意,在 1_0 版本的 HAL 中,顺序是相反的,先调用 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.h 中的 sensors_module_t
的定义以及 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 传感器。以下是 sensor_t 的一些重要字段:
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
必须以制造商的反向域名开头。例如,由 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 函数报告的传感器事件属于 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 层。对于这类传感器,其传感器类型定义中会提及必须设置 status 字段。
元数据清空完成事件
元数据事件的类型与常规传感器事件的类型相同: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 flush 完成。为 meta_data.what=META_DATA_FLUSH_COMPLETE
时,必须将 meta_data.sensor
设置为已清空的传感器的句柄。当且仅当对传感器调用 flush
时才会生成这类事件。如需了解详情,请参阅有关 flush 函数的部分。