一、首先建立这样一个全局的观念:

Android中sensor在Android系统架构中的位置及其工作。方框图如下:

从以上方框图中,可以看出Android中sensor在系统分为四层:驱动层(Sensor Driver)、硬件抽象层(Native)、中间层(Framework)、应用层(Java)。硬件抽象层与中间层可以合并一起作为Framework层。

针对我们xx这里一个具体的Gsensor,下面将以具体的源码形式来讲解以上的这个系统框图。

二、驱动层(Sensor Driver Layer)

芯片ADXL345为GSensor,至于硬件的具体工作原理,须分析ADXL345的DataSheet。驱动源码位于:xx\custom\common\kernel\accelerometer\adxl345目录。

由于ADXL345是以I2C形式接口挂接到Linux系统,因此同时需要分析Linux的I2C子系统架构(略)。其源码位于:

1、 xx\platform\xx\kernel\drivers\i2c

2、 kernel\drivers\i2c

查看ADXL345.c文件,分析针对于其硬件工作原理的几个函数。硬件初始化:

[cpp] view plain copy
  1. staticintadxl345_init_client(structi2c_client*client,intreset_cali)
  2. {
  3. structadxl345_i2c_data*obj=i2c_get_clientdata(client);
  4. intres=0;
  5. adxl345_gpio_config();//配置GPIO口,这里由于不使用中断,所以将中断引脚配置成输入输出口。
  6. res=ADXL345_CheckDeviceID(client);//检测设备ID,通过读ADXL345的DEVID寄存器
  7. if(res!=ADXL345_SUCCESS)
  8. {
  9. returnres;
  10. }
  11. res=ADXL345_SetPowerMode(client,false);//设置电源模式,ADXL345有几种电源模式,这里设置false值指不让芯片处于messure模式
  12. if(res!=ADXL345_SUCCESS)
  13. {
  14. returnres;
  15. }
  16. res=ADXL345_SetBWRate(client,ADXL345_BW_100HZ);//设置带宽,100Hz
  17. if(res!=ADXL345_SUCCESS)//0x2C->BW=100Hz
  18. {
  19. returnres;
  20. }
  21. //设置数据格式,具体见datasheet
  22. res=ADXL345_SetDataFormat(client,ADXL345_FULL_RES|ADXL345_RANGE_2G);
  23. if(res!=ADXL345_SUCCESS)//0x2C->BW=100Hz
  24. {
  25. returnres;
  26. }
  27. gsensor_gain.x=gsensor_gain.y=gsensor_gain.z=obj->reso->sensitivity;
  28. //设置中断寄存器,关闭中断
  29. res=ADXL345_SetIntEnable(client,0x00);//disableINT
  30. if(res!=ADXL345_SUCCESS)
  31. {
  32. returnres;
  33. }
  34. if(0!=reset_cali)
  35. {
  36. /*resetcalibrationonlyinpoweron*/
  37. res=ADXL345_ResetCalibration(client);
  38. if(res!=ADXL345_SUCCESS)
  39. {
  40. returnres;
  41. }
  42. }
  43. #ifdefCONFIG_ADXL345_LOWPASS
  44. memset(&obj->fir,0x00,sizeof(obj->fir));
  45. #endif
  46. returnADXL345_SUCCESS;
  47. }


函数的分析都注释在原理里,红色部分。具体寄存器的设置查看ADXL345的datasheet,具体I2C的通信查看I2C.c文件(i2c控制器的驱动)。

关键问题:这里有个问题,没有弄懂,就是从ADXL345数据寄存器里读取原始数据之后,这个数据并不是我们应用程序所要用的,它需要转化,经过查看代码,可以发现这样一段注释:

/*

* @sign, map: only used in accelerometer/magnetic field

* sometimes, the sensor output need to be remapped before reporting to framework.

* the 'sign' is only -1 or +1 to align the sign for framework's coordinate system

* the 'map' align the value for framework's coordinate system. Take accelerometer

* as an exmaple:

* assume HAL receives original acceleration: acc[] = {100, 0, 100}

* sign[] = {1, -1, 1, 0};

* map[] = {HWM_CODE_ACC_Y, HWM_CODE_ACC_X, HWM_CODE_ACC_Z, 0};

* according to the above 'sign' & 'map', the sensor output need to remap as {y, -x, z}:

* float resolution = unit_numerator*GRAVITY_EARTH/unit_denominator;

* acc_x = sign[0]*acc[map[0]]*resolution;

* acc_y = sign[1]*acc[map[1]]*resolution;

* acc_z = sign[2]*acc[map[2]]*resolution;

*/

struct hwmsen_convert {

s8 sign[C_MAX_HWMSEN_EVENT_NUM];

u8 map[C_MAX_HWMSEN_EVENT_NUM];

};

这样一个转换算法的物理意义是怎样的?????

三、硬件抽象层(Native)

硬件抽象层主要是提供硬件层实现的接口,其代码路径如下:

hardware\libhardware\include\hardware\ sensors.h

其中:

struct sensors_module_t为sensor模块的定义。

struct sensors_module_t {

struct hw_module_t common;

int (*get_sensors_list)(struct sensors_module_t* module,

struct sensor_t const** list);

};

Struct sensor_t为某一个sensor的描述性定义。

struct sensor_t {

const char* name; /* 传感器的名称 */

const char* vendor; /* 传感器的vendor */

int version; /* 传感器的版本 */

int handle; /* 传感器的句柄 */

int type; /* 传感器的类型 */

float maxRange; /* 传感器的最大范围 */

float resolution; /* 传感器的辨析率 */

float power; /* 传感器的耗能(估计值,mA单位)*/

void* reserved[9];

}

struct sensors_event_t表示传感器的数据

/**

* Union of the various types of sensor data

* that can be returned.

*/

typedef struct sensors_event_t {

int32_t version; /* must be sizeof(struct sensors_event_t) */

int32_t sensor; /* sensor identifier */

int32_t type; /* sensor type */

int32_t reserved0; /* reserved */

int64_t timestamp; /* time is in nanosecond */

union {

float data[16];

/* acceleration values are in meter per second per second (m/s^2) */

sensors_vec_t acceleration;

/* magnetic vector values are in micro-Tesla (uT) */

sensors_vec_t magnetic;

sensors_vec_t orientation; /* orientation values are in degrees */

sensors_vec_t gyro; /* gyroscope values are in rad/s */

float temperature; /* temperature is in degrees centigrade (Celsius) */

float distance; /* distance in centimeters */

float light; /* light in SI lux units */

float pressure; /* pressure in hectopascal (hPa) */

};

uint32_t reserved1[4];

} sensors_event_t;

显然,在看完这些数据结构之后,我们都会有这样一个疑问:

这里只是申明了一些结构体,而这些结构体在使用时需要定义,而且结构体中还有一些函数指针,这些函数指针所对应的函数实现又在哪里呢??显然,那必定还要有一个.c源文件来实现这样的一些函数。经过搜索,其文件名为:sensors_hwmsen.c,路径为:

\xxk\source\hardware\sensor\hwmsen。在这里,你会看到get_sensors_list等函数的实现。

四、中间层(Framework)

这里,我也把它叫做JNI层,这里实现了JNI接口。其源码目录如下:

frameworks\base\core\jni\ android_hardware_SensorManager.cpp

在源码里,我们可以看到JNI接口的函数列表:

static JNINativeMethod gMethods[] = {

{"nativeClassInit", "()V", (void*)nativeClassInit },

{"sensors_module_init","()I", (void*)sensors_module_init },

{"sensors_module_get_next_sensor","(Landroid/hardware/Sensor;I)I",

(void*)sensors_module_get_next_sensor },

{"sensors_create_queue", "()I", (void*)sensors_create_queue },

{"sensors_destroy_queue", "(I)V", (void*)sensors_destroy_queue },

{"sensors_enable_sensor", "(ILjava/lang/String;II)Z",

(void*)sensors_enable_sensor },

{"sensors_data_poll", "(I[F[I[J)I", (void*)sensors_data_poll },

};

这些JNI接口所对应的实现,请看源码。

当然了,你可能又有疑问了,上层Java又是怎样来调用这些本地接口的呢??在android_hardware_SensorManager.cpp源码下面有这样一个函数:

int register_android_hardware_SensorManager(JNIEnv *env)

{

return jniRegisterNativeMethods(env, "android/hardware/SensorManager",

gMethods, NELEM(gMethods));

}

这个函数就将以上的JNI接口(gMethods数组)注册进系统。看上去很简单,其实过程是很复杂的。整个 native方法初始化过程如下:start(AndroidRuntime.cpp,938 行)->startReg(AndroidRuntime.cpp,1360 行)-> register_jni_procs(AndroidRuntime.cpp,1213行)。这样JAVA上层就能够调用这些JNI接口来操纵底层硬件 了。

五、应用层(Java)

传感器系统的JAVA部分包含了以下几个文件:

u SensorManager.java

实现传感器系统核心的管理类SensorManager

u Sensor.java

单一传感器的描述性文件Sensor

u SensorEvent.java

表示传感器系统的事件类SensorEvent

u SensorEventListener.java

传感器事件的监听者SensorEventListener接口

u SensorListener.java

传感器的监听者SensorListener接口


原文转载于:http://blog.chinaunix.net/uid-25150360-id-3173793.html

更多相关文章

  1. 箭头函数的基础使用
  2. Python技巧匿名函数、回调函数和高阶函数
  3. Android(安卓)中插件的编写方法
  4. Android(安卓)Recovery Ui 分析
  5. Android的MediaPlayer架构介绍
  6. android JNI 学习笔记
  7. Android(安卓)RIL结构分析与移植
  8. android使用HttpClient和URLConnection获取网页内容
  9. Android通过OpenSL ES播放音频套路详解

随机推荐

  1. Android应用内切换语言
  2. android 电话状态的监听
  3. Android(安卓)实现闪屏页和右上角的倒计
  4. Android笔试总结
  5. Android的Activity屏幕切换动画(二)-左右
  6. android开源项目二、
  7. Android(安卓)JNI开发详解(7)-线程操作,异
  8. Android平板开发
  9. Android存储系统之架构篇
  10. Android中EventBus(事件总线)传递数据