转自:http://blog.chinaunix.net/uid-29595319-id-4200772.html

G-sensor

G-sensor是加速度传感器,可以通过其来获得分别来自三个不同轴向上的加速度用以通知上层应用做出相应处理。

由于地球的引力作用,gsensor平放时,Z轴方向能感应到1g的重力加速度,如果移动或倾斜,此时垂直的重力加速度会分解到X,Y,Z轴上。所以旋转手机时,X,Y,Z轴的值不断变化,可以理解为手机处在一个坐标系中,我们判断手机是否旋转就是判断X,Y,Z当前的值。

下图为基本原理图:

飞思卡尔mma7455 管脚配置图:

I2C总线连接适配电路图:

G-sensor的应用

如甩动换歌,换墙纸,TV调台,实现根据手机放置状态自动切换横竖屏,如翻转静音等应用功能。

在系统中G-sensor的两种使用方式

<1> 中断方式:在此方式中首先会对G-sensor器件设定一个阈(yu)值,器件感知加速度当值大于设定的阈值时器件触发CPU中断,系统得到一次甩动事件,系统将该事件处理为一个消息并将其发送给应用层,应用层得到消息判断任务状态如果有MP3,TV等任务运行及对该任务进行切歌换台等操作,如果无任务则切换墙纸。

<2> 查询方式:当进入某个需要使用到G-sensor的应用时,应用先打开一个定时器每当定时器超时溢出时便查询一次G-sensor当前状态值,用以判断当前手机状态。如果三个轴向上的值超过一定范围即认为手机静置状态改变调用相应处理函数执行操作。该种方式主要应用于视频播放即菜单显示的横竖屏切换。

相关代码

   Custom_equipment.h

Custom_equipment.c

由于使用不同的芯片所以在代码中作了兼容匹配。对应每一个芯片都有一套

[chipname]_init                初始化函数

[chipname]_enablelatch,         中断使能函数

[chipname]_clearlatch,          清中断函数

[chipname]_read_x_value,        读x轴值

[chipname]_read_y_value,        读y轴值

[chipname]_read_z_value,        读z轴值

[chipname]_entersleep           进入睡眠

函数,函数的函数指针在名为GSensor_Funcs的结构体中。在函数gsensor_read_and_check_id函数中通过读取芯片id然后将对应结构体赋给结构体指针gsensor_func在通过该指针调用对应函数,从而实现了芯片的自动匹配。read_position_status_handler函数为最终的G-sersor的最终处理函数。当该函数被调用后如果有符合要求的事件产生则该函数会向上发出一条消息供给应用层处理。在此函数中有一个名为g_gsensor_settings[]的数组,该数组记录的是需要使用G-sensor的应用程序的开关。传感器三个轴向上的加速度值存储在另外一个名为curr_gsensor_info[3]的数组之中。

Email:wei7758@126.com

Blog:http://blog.csdn.net/yinwei520

Author: Yww

Time:2011-8-22

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

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 plaincopyprint?
  1. static int adxl345_init_client(struct i2c_client *client, int reset_cali)
  2. {
  3. struct adxl345_i2c_data *obj = i2c_get_clientdata(client);
  4. int res = 0;
  5. adxl345_gpio_config();//配置GPIO口,这里由于不使用中断,所以将中断引脚配置成输入输出口。
  6. res = ADXL345_CheckDeviceID(client); //检测设备ID,通过读ADXL345的DEVID寄存器
  7. if(res != ADXL345_SUCCESS)
  8. {
  9. return res;
  10. }
  11. res = ADXL345_SetPowerMode(client, false);//设置电源模式,ADXL345有几种电源模式,这里设置false值指不让芯片处于messure模式
  12. if(res != ADXL345_SUCCESS)
  13. {
  14. return res;
  15. }
  16. res = ADXL345_SetBWRate(client, ADXL345_BW_100HZ);//设置带宽,100Hz
  17. if(res != ADXL345_SUCCESS ) //0x2C->BW=100Hz
  18. {
  19. return res;
  20. }
  21. //设置数据格式,具体见datasheet
  22. res = ADXL345_SetDataFormat(client, ADXL345_FULL_RES|ADXL345_RANGE_2G);
  23. if(res != ADXL345_SUCCESS) //0x2C->BW=100Hz
  24. {
  25. return res;
  26. }
  27. gsensor_gain.x = gsensor_gain.y = gsensor_gain.z = obj->reso->sensitivity;
  28. //设置中断寄存器,关闭中断
  29. res = ADXL345_SetIntEnable(client, 0x00);//disable INT
  30. if(res != ADXL345_SUCCESS)
  31. {
  32. return res;
  33. }
  34. if(0 != reset_cali)
  35. {
  36. /*reset calibration only in power on*/
  37. res = ADXL345_ResetCalibration(client);
  38. if(res != ADXL345_SUCCESS)
  39. {
  40. return res;
  41. }
  42. }
  43. #ifdef CONFIG_ADXL345_LOWPASS
  44. memset(&obj->fir, 0x00, sizeof(obj->fir));
  45. #endif
  46. return ADXL345_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接口

G-sensor 介绍相关推荐

  1. xliff:g标签介绍:

    <xliff:g>标签介绍: <string name="appwidget_text_format"><xliff:g id="prefi ...

  2. CMOS Sensor介绍

    CMOS Sensor 介绍 引言 CMOS图像传感器的工作原理 曝光控制 CMOS图像传感器的光学原理 CMOS图像传感器的性能 引言 随着应用领域不断发展,CMOS 图像传感器(CMOS Imag ...

  3. 硬盘的P表和G表介绍

    转自中国存储网,原文链接:硬盘的P表和G表介绍 导读:对硬盘中的P表以及G表等进行介绍:P表和G表用于记录硬盘的缺陷扇区的情况,使硬盘在工作时不会在缺陷扇区中读写数据,防止数据损坏. 在存储百科的(硬 ...

  4. gcc g++ 参数介绍

    C和C++ 编译器是集成的.他们都要用四个步骤中的一个或多个处理输入文件: 预处理 (preprocessing),编译(compilation),汇编(assembly)和连接(linking).源 ...

  5. 摄像机sensor介绍

    Sensor即传感器,是摄像机的核心部件,作用是将光信号转换成电信号,方便处理和存储.Sensor的类型有两种,CCD和CMOS. CCD即电荷耦合器( charge-couled device),C ...

  6. G Suit 介绍

    数以百万计的G套件用户.数以百万计的人你的应用程序可以触及. 建立在G套件. 你的团队. G Suite是一组应用程序,包括Gmail.文档.表格.幻灯片.站点等,以及供组织使用的一组消息传递.协作. ...

  7. 重力感应器G—sensor 驱动分析

    重力传感器代码分析 重力传感器驱动的功能,主要是向HAL层提供IOCTRL接口,并通过input设备上报数据.芯片实际数据的读取是采用i2c协议读取原始数据,并且作为i2c设备挂载在系统上工作的. 1 ...

  8. android APK 调用G—sensor驱动的过程

    android上层应用apk到G-sensor driver的大致流程: Android HAL层,即硬件抽象层,是Google响应厂家"希望不公开源码"的要求推出的新概念 1,源 ...

  9. android gsensor 坐标,MTK Android G sensor 原理,配置,调试

    原理图: g_sensor的驱动目录在mediatek/custom/common/kernel/accelerometer下. 一.g_sensor 的移植步骤 1.在ProjectConfig.m ...

  10. android g sensor,android gsensor 休眠震动唤醒功能怎么实现

    一.唤醒源 设备休眠后,通过触发唤醒源使设备恢复正常工作模式.设备唤醒源有多种,对于Android设备常见的就有PowerKey.来电唤醒.Alarm唤醒等. 唤醒源的实现处于内核空间,本文重点讨论下 ...

最新文章

  1. (二)Javascript面向对象编程:构造函数的继承
  2. 构建之法4、17章观后感
  3. Linux套接字聊天
  4. SylixOS 系统初探
  5. (五)LESS 规范
  6. jQuery Validate 合法性,限制性校验
  7. 井下关于风速的规定_矿井有害气体最高允许浓度、温度、风速的规定
  8. win32开发(自定义消息)
  9. 拥抱开源未来 百度Doris进入顶级开源社区Apache
  10. lsof 一切皆文件
  11. Linux常用基本命令:三剑客命令之-awk内置函数用法
  12. activity finish后没有destroy_Activity 基础知识点
  13. 19【CTR15】会话兴趣⽹络
  14. 网页制作初期,必须的东西
  15. 【数字信号】基于matlab GUI DTMF双音多频电话拨号仿真【含Matlab源码 805期】
  16. 高斯模型matlab程序代码,我找到的高斯混合模型的代码
  17. LaTeX数学符号大全(转载)
  18. Fiddler证书过期解决
  19. 高频交易及化资策与区
  20. 全面落地,2014大数据应用案例TOP100

热门文章

  1. 一元云购qq互联回调地址错误解决办法
  2. java输战舰_什么是最好的战舰AI?
  3. EINT DINT ERTM DRTM理解
  4. python 百度翻译爬虫(可翻译句子及文章)(偷偷说一句,保姆级教程哦)
  5. kubuntu16.04安装和卸载fcitx输入法
  6. git 强制拉取最新代码
  7. SQL Server 升序和降序排列
  8. 简历包装严重,作为面试官,我是如何甄别应聘者的包装程度
  9. vs工程生成自定义图标的exe
  10. Help Bubu UVALive - 4490