1. Sensor驱动概述:Sensor在Android系统中的角色、Sensor HAL架构简介、Sensor驱动开发流程概览

大家好,我是你们的讲师。今天咱们开始第一讲,聊聊Sensor驱动在Android系统里到底扮演什么角色。说实话,我刚开始接触这个领域时,也觉得Sensor就是个“小透明”——不就是个加速度计、陀螺仪嘛,能有多复杂?直到我在一个项目里,因为Sensor数据延迟导致AR应用画面抖动,被测试团队追着改了三版驱动……嗯,从那以后我再也不敢小看它了。

1.1 Sensor在Android系统中的角色

你想想看,你的手机能自动旋转屏幕、能计步、能玩AR游戏,靠的是什么?就是Sensor。在Android系统里,Sensor是连接物理世界和数字世界的桥梁。它把加速度、角速度、磁场强度这些物理量,变成上层应用能理解的数字信号。

具体来说,Sensor在Android系统中的位置是这样的:

  • 应用层:调用SensorManager API,比如getDefaultSensor()、registerListener()。这部分是Java写的,跑在应用进程里。
  • Framework层:SensorService负责管理所有Sensor,把数据从底层传到上层。这里有个关键点——数据是事件驱动的,不是轮询的。
  • HAL层:硬件抽象层,这是咱们今天的重点。它把内核驱动的接口封装成统一的API,供Framework调用。
  • Kernel层:真正的硬件驱动,读写寄存器、处理中断、上报数据。

我个人习惯把Sensor系统比作一个“数据管道”。应用层是水龙头,内核层是水源,HAL层就是中间的阀门和过滤器。任何一个环节出问题,水就流不畅——说白了,就是数据延迟或者丢数据。

核心要点:Sensor在Android系统中的角色就是“数据采集与传递”。它不负责计算,只负责把原始数据准确、及时地送到上层。

1.2 Sensor HAL架构简介

HAL,全称Hardware Abstraction Layer。为什么要有这一层?我举个例子你就明白了。不同厂商的加速度计芯片,寄存器地址、初始化流程、数据格式可能完全不同。如果没有HAL,Framework层就得为每款芯片写一套代码——那Android系统就没法兼容这么多设备了。

Android的Sensor HAL架构,说白了就是定义了一套标准接口。你只要实现这些接口,你的Sensor就能被系统识别和使用。这套接口定义在hardware/libhardware/include/hardware/sensors.h里。

核心的数据结构就两个:

结构体 作用
sensor_t 描述Sensor的静态信息,比如名字、厂商、类型、最大范围、分辨率等
sensors_event_t 描述Sensor的动态数据,比如时间戳、x/y/z轴数值、精度等

HAL层需要实现的函数接口,核心就这几个:

// 打开Sensor设备
static int open_sensors(const struct hw_module_t* module, 
                        const char* id, 
                        struct hw_device_t** device);

// 获取Sensor列表
static int sensor_get_sensors_list(struct sensors_module_t* module,
                                   struct sensor_t const** list);

// 激活/去激活Sensor
int activate(struct sensors_polldevice_t* dev, 
             int handle, 
             int enabled);

// 设置数据上报频率
int setDelay(struct sensors_polldevice_t* dev, 
             int handle, 
             int64_t period_ns);

// 轮询获取数据(poll模式)
int poll(struct sensors_polldevice_t* dev, 
         sensors_event_t* data, 
         int count);

我在项目中遇到过一个问题:某款陀螺仪的setDelay实现里,把period_ns单位搞错了,导致上层设置200Hz采样率,实际只有20Hz。查了两天才发现是纳秒和微秒的换算问题。嗯,这里要注意——period_ns的单位是纳秒,不是微秒。

避坑指南:我曾经在调试Sensor HAL时,发现poll函数一直返回0。后来发现是activate函数里没有正确设置硬件使能位。记住:activate是开关,setDelay是调速,两个必须配合使用。

1.3 Sensor驱动开发流程概览

做Sensor驱动开发,说白了就是三步走:

  1. 内核驱动:让硬件能工作,能读写数据。这部分涉及I2C/SPI通信、中断处理、寄存器配置。
  2. HAL层适配:把内核驱动的接口封装成Android HAL标准接口。这部分是咱们课程的重点。
  3. Framework集成:让SensorService能识别你的Sensor,并正确上报数据。这部分通常不需要改代码,但需要配置android.hardware.sensor的权限和特性。

整个流程的依赖关系,我画了一张图帮你理解:

Sensor驱动开发流程 应用层 (App) SensorManager API → getDefaultSensor() / registerListener() Framework层 (SensorService) 管理Sensor列表 / 数据分发 / 权限控制 HAL层 (硬件抽象层) open_sensors() / activate() / setDelay() / poll() 内核层 (Kernel Driver) I2C/SPI通信 / 中断处理 / 寄存器配置 / 数据上报 数据流向上 HAL接口调用 系统调用/ioctl

从这张图你能看到,数据是从下往上流的。内核驱动采集到原始数据,通过HAL层封装成标准格式,Framework层负责分发,应用层最终使用。反过来,控制命令是从上往下流的——应用设置采样率,Framework传给HAL,HAL再通过驱动配置硬件。

我个人习惯的开发顺序是:先搞定内核驱动,确保能用cat /sys/class/sensor/xxx/value读到数据。然后再写HAL层,用sensorstest工具验证。最后才集成到Framework里。这样每一步都能独立验证,出了问题也好定位。

注意事项:千万不要跳过内核驱动的验证直接写HAL!我曾经在一个项目里,HAL写完了才发现内核驱动上报的数据符号位是反的——正加速度显示为负值。如果先验证内核驱动,这个问题在第一天就能发现,而不是等到集成测试时才暴露。

好了,这一讲的内容就是这些。Sensor在Android系统中的角色、HAL架构的核心接口、以及开发流程的概览,咱们都过了一遍。下一讲开始,我会带你手把手搭建开发环境,然后从内核驱动开始,一步步实现一个完整的Sensor驱动。

可可精品资料库