关注嵌入式安卓物联网行业及人才培养,每日更新,欢迎订阅及留言讨论~~~

作者:倪键树,嵌入式安卓物联网讲师。



Andriod Sensor 架构深入剖析

1 Android sensor架构

Android4.0系统内置对传感器的支持达13种,它们分别是:加速度传感器(accelerometer)、磁力传感器(magnetic field)、方向传感器(orientation)、陀螺仪(gyroscope)、环境光照传感器(light)、压力传感器(pressure)、温度传感器(temperature)和距离传感器(proximity)等。

Android实现传感器系统包括以下几个部分:

类别

名称

代码

用户空间

Java应用程序

用户实现

Java framework框架层

SensorManager.java

SensorListener.java

SensorEvent.java

JNI

adroid_hardware_SensorManager.cpp

com_android_server_SensorService.cpp

HAL硬件抽象层

用户实现(sensor.c)

内核空间

设备驱动程序

用户实现

具体硬件

重力传感器、温度传感器LM75、电压测量传感器


用户实现


各部分之间架构图如下:

Andriod Sensor 架构深入剖析_温度传感器


2 Sensor HAL层接口

Google为Sensor提供了统一的HAL接口,不同的硬件厂商需要根据该接口来实现并完成具体的硬件抽象层,Android中Sensor的HAL接口定义在:hardware/libhardware/include/hardware/sensors.h

对传感器类型的定义:

Andriod Sensor 架构深入剖析_Andriod的传感器_02


传感器模块的定义结构体如下:

Andriod Sensor 架构深入剖析_温度传感器_03

该接口的定义实际上是对标准的硬件模块hw_module_t的一个扩展,增加了一个get_sensors_list函数,用于获取传感器的列表。

对任意一个sensor设备都会有一个sensor_t结构体,其定义如下:

Andriod Sensor 架构深入剖析_压力传感器_04

每个传感器的数据由sensors_event_t结构体表示,定义如下:

Andriod Sensor 架构深入剖析_Andriod的传感器_05

其中,sensor为传感器的标志符,而不同的传感器则采用union方式来表示,sensors_vec_t结构体用来表示不同传感器的数据,sensors_vec_t定义如下:

Andriod Sensor 架构深入剖析_温度传感器_06

Sensor设备结构体sensors_poll_device_t,对标准硬件设备hw_device_t结构体的扩展,主要完成读取底层数据,并将数据存储在struct sensors_poll_device_t结构体中,poll函数用来获取底层数据,调用时将被阻塞定义如下:

Andriod Sensor 架构深入剖析_温度传感器_07


控制设备打开/关闭结构体定义如下:

Andriod Sensor 架构深入剖析_Andriod的传感器_08


3 Sensor HAL实现(以LM75温度传感器为例子)

(1)打开设备流程图


Andriod Sensor 架构深入剖析_压力传感器_09

(2)实现代码分析

在代码中含有两个传感器ADC电位器和LM75温度传感器,所以在sensor.c中,首先需要定义传感器数组device_sensor_list[],其实就是初始化struct sensor_t结构体,初始化如下:

Andriod Sensor 架构深入剖析_压力传感器_10

定义open_sensors函数,来打开Sensor模块,代码如下:

Andriod Sensor 架构深入剖析_压力传感器_11

在这个方法中,首先需要为hw_device_t分配内存空间,并对其初始化,设置重要方法的实现。

control_open_data_source()打开传感器并使能设备:

Andriod Sensor 架构深入剖析_压力传感器_12

调用sensor__data_poll方法读取数据:

1./*轮询读取数据*/

2.

3.staticintsensors__data_poll(structsensors_data_context_t *dev, sensors_data_t * values)

4.{

5.intn;

6.int mag;

7.float temp;

8.charbuf[10];

9.

10.while (1) {

11.if(count % 3 == 2) // 读取ADC值

12.   {

13.if( read(dev->event_fd[0], &mag, sizeof(mag)) < 0)

14.     {

15.      LOGE("read adc error");

16.     }else{

17.

18.      dev->sensors[ID_MAGNETIC_FIELD].magnetic.v[0]=(float)mag;

19.      LOGE("read adc %f\n",(float)mag);

20.      *values= dev->sensors[ID_MAGNETIC_FIELD];

21.      values->sensor= ID_MAGNETIC_FIELD;

22.      count++;

23.     }

24.     usleep(500000);

25.return ID_MAGNETIC_FIELD;

26.   }

27.elseif(count%3 == 1)//读取温度传感器值

28.   {

29.

30.     memset(buf,0 ,sizeof(buf));

31.if((n = read(dev->event_fd[1], buf, 10)) < 0)

32.     {

33.      LOGE("read temp error");

34.     }else{

35.      buf[n- 1] = '\0';

36.      temp=(float) (atoi(buf) / 1000);

37.      dev->sensors[ID_TEMPERATURE].temperature= temp;

38.      LOGE("read temp %f\n",temp);

39.      *values= dev->sensors[ID_TEMPERATURE];

40.      values->sensor= ID_TEMPERATURE;

41.      count++;

42.     }

43.     close(dev->event_fd[1]);

44.     dev->event_fd[1]=open("/sys/bus/i2c/devices/0-0048/temp1_input",O_RDONLY);

45.     usleep(500000);

46.return ID_TEMPERATURE;

47.   }

48.elseif(count%3 == 0)//读取方向传感器模拟值

49.   {

50.     LOGI("read orientation\n");

51./* fill up data of orientation */

52.     dev->sensors[ID_ORIENTATION].orientation.azimuth= x + 5;

53.     dev->sensors[ID_ORIENTATION].orientation.pitch= y + 5;

54.     dev->sensors[ID_ORIENTATION].orientation.roll= z + 5;

55.     *values= dev->sensors[ID_ORIENTATION];

56.     values->sensor= ID_ORIENTATION;

57.     count++;

58.     x+= 0.0001; y += 0.0001; z += 0.0001;

59.     usleep(500000);

60.return ID_ORIENTATION;

61.   }

62.  }

63.}