Android 系统Gsensor系统架构

简介: 一、首先建立这样一个全局的观念:     Android中sensor在Android系统架构中的位置及其工作。方框图如下: 从以上方框图中,可以看出Android中sensor在系统分为四层:驱动层(Sensor Driver)、硬件抽象层(Native)、中间层(Framework)、应用层(Java)。

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

    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. static int adxl345_init_client(struct i2c_client *client, int reset_cali)  
  2.   
  3. {  
  4.   
  5.     struct adxl345_i2c_data *obj = i2c_get_clientdata(client);  
  6.   
  7.     int res = 0;  
  8.   
  9.    
  10.   
  11.     adxl345_gpio_config();//配置GPIO口,这里由于不使用中断,所以将中断引脚配置成输入输出口。  
  12.   
  13.       
  14.   
  15.     res = ADXL345_CheckDeviceID(client); //检测设备ID,通过读ADXL345的DEVID寄存器  
  16.   
  17.     if(res != ADXL345_SUCCESS)  
  18.   
  19.     {  
  20.   
  21.         return res;  
  22.   
  23.     }     
  24.   
  25.    
  26.   
  27.     res = ADXL345_SetPowerMode(client, false);//设置电源模式,ADXL345有几种电源模式,这里设置false值指不让芯片处于messure模式  
  28.   
  29.     if(res != ADXL345_SUCCESS)  
  30.   
  31.     {  
  32.   
  33.         return res;  
  34.   
  35.     }  
  36.   
  37.       
  38.   
  39.    
  40.   
  41.     res = ADXL345_SetBWRate(client, ADXL345_BW_100HZ);//设置带宽,100Hz  
  42.   
  43.     if(res != ADXL345_SUCCESS ) //0x2C->BW=100Hz  
  44.   
  45.     {  
  46.   
  47.         return res;  
  48.   
  49.     }  
  50.   
  51.    
  52.   
  53.     //设置数据格式,具体见datasheet  
  54.   
  55.     res = ADXL345_SetDataFormat(client, ADXL345_FULL_RES|ADXL345_RANGE_2G);  
  56.   
  57.     if(res != ADXL345_SUCCESS) //0x2C->BW=100Hz  
  58.   
  59.     {  
  60.   
  61.         return res;  
  62.   
  63.     }  
  64.   
  65.    
  66.   
  67.     gsensor_gain.x = gsensor_gain.y = gsensor_gain.z = obj->reso->sensitivity;  
  68.   
  69.    
  70.   
  71.     //设置中断寄存器,关闭中断  
  72.   
  73.     res = ADXL345_SetIntEnable(client, 0x00);//disable INT          
  74.   
  75.     if(res != ADXL345_SUCCESS)   
  76.   
  77.     {  
  78.   
  79.         return res;  
  80.   
  81.     }  
  82.   
  83.    
  84.   
  85.     if(0 != reset_cali)  
  86.   
  87.     {   
  88.   
  89.         /*reset calibration only in power on*/  
  90.   
  91.         res = ADXL345_ResetCalibration(client);  
  92.   
  93.         if(res != ADXL345_SUCCESS)  
  94.   
  95.         {  
  96.   
  97.             return res;  
  98.   
  99.         }  
  100.   
  101.     }  
  102.   
  103.    
  104.   
  105. #ifdef CONFIG_ADXL345_LOWPASS  
  106.   
  107.     memset(&obj->fir, 0x00, sizeof(obj->fir));    
  108.   
  109. #endif  
  110.   
  111.    
  112.   
  113.     return ADXL345_SUCCESS;  
  114.   
  115. }  


 

    函数的分析都注释在原理里,红色部分。具体寄存器的设置查看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

相关文章
|
14天前
|
Android开发 Swift iOS开发
深入探索iOS与Android操作系统的架构差异及其对应用开发的影响
在当今数字化时代,移动设备已经成为我们日常生活和工作不可或缺的一部分。其中,iOS和Android作为全球最流行的两大移动操作系统,各自拥有独特的系统架构和设计理念。本文将深入探讨iOS与Android的系统架构差异,并分析这些差异如何影响应用开发者的开发策略和用户体验设计。通过对两者的比较,我们可以更好地理解它们各自的优势和局限性,从而为开发者提供有价值的见解,帮助他们在这两个平台上开发出更高效、更符合用户需求的应用。
|
5天前
|
机器学习/深度学习 存储 人工智能
【AI系统】模型演进与经典架构
本文探讨了AI计算模式对AI芯片设计的重要性,通过分析经典模型结构设计与演进、模型量化与压缩等核心内容,揭示了神经网络模型的发展现状及优化方向。文章详细介绍了神经网络的基本组件、主流模型结构、以及模型量化和剪枝技术,强调了这些技术在提高模型效率、降低计算和存储需求方面的关键作用。基于此,提出了AI芯片设计应考虑支持神经网络计算逻辑、高维张量存储与计算、灵活的软件配置接口、不同bit位数的计算单元和存储格式等建议,以适应不断发展的AI技术需求。
18 5
|
13天前
|
传感器 算法 物联网
智能停车解决方案之停车场室内导航系统(二):核心技术与系统架构构建
随着城市化进程的加速,停车难问题日益凸显。本文深入剖析智能停车系统的关键技术,包括停车场电子地图编辑绘制、物联网与传感器技术、大数据与云计算的应用、定位技术及车辆导航路径规划,为读者提供全面的技术解决方案。系统架构分为应用层、业务层、数据层和运行环境,涵盖停车场室内导航、车位占用检测、动态更新、精准导航和路径规划等方面。
61 4
|
16天前
|
Java Linux Android开发
深入探索Android系统架构:从Linux内核到应用层
本文将带领读者深入了解Android操作系统的复杂架构,从其基于Linux的内核到丰富多彩的应用层。我们将探讨Android的各个关键组件,包括硬件抽象层(HAL)、运行时环境、以及核心库等,揭示它们如何协同工作以支持广泛的设备和应用。通过本文,您将对Android系统的工作原理有一个全面的认识,理解其如何平衡开放性与安全性,以及如何在多样化的设备上提供一致的用户体验。
|
15天前
|
安全 Android开发 iOS开发
深入探讨Android与iOS的系统架构差异
本文旨在通过对比分析Android和iOS两大移动操作系统的系统架构,揭示它们在设计理念、安全性、应用生态及开发环境等方面的显著差异。我们将从底层架构出发,逐步剖析至用户界面层面,为开发者和科技爱好者提供一份详尽的技术参考。
24 1
|
23天前
|
前端开发 JavaScript 测试技术
android做中大型项目完美的架构模式是什么?是MVVM吗?如果不是,是什么?
在 Android 开发中,选择合适的架构模式对于构建中大型项目至关重要。常见的架构模式有 MVVM、MVP、MVI、Clean Architecture 和 Flux/Redux。每种模式都有其优缺点和适用场景,例如 MVVM 适用于复杂 UI 状态和频繁更新,而 Clean Architecture 适合大型项目和多平台开发。选择合适的架构应考虑项目需求、团队熟悉度和可维护性。
49 6
|
23天前
|
安全 搜索推荐 Android开发
深入探索Android与iOS的系统架构差异
【10月更文挑战第29天】 在当今的智能手机市场中,Android和iOS无疑是两大主流操作系统。本文旨在深入探讨这两个系统的架构差异,从底层的操作系统设计到用户界面的呈现,以及它们如何影响了开发者和用户的体验。通过对比分析,我们可以更清晰地理解这两种平台的优势与局限,为开发者在选择开发平台时提供有价值的参考,同时也为用户选择设备提供一定的指导。
43 2
|
22天前
|
算法 JavaScript Android开发
|
24天前
|
前端开发 安全 关系型数据库
秒合约系统/开发模式规则/技术架构实现
秒合约系统是一种高频交易平台,支持快速交易、双向持仓和高杠杆。系统涵盖用户注册登录、合约创建与编辑、自动执行、状态记录、提醒通知、搜索筛选、安全权限管理等功能。交易规则明确,设有价格限制和强平机制,确保风险可控。技术架构采用高并发后端语言、关系型数据库和前端框架,通过智能合约实现自动化交易,确保安全性和用户体验。
|
25天前
|
安全 搜索推荐 Android开发
揭秘安卓与iOS系统的差异:技术深度对比
【10月更文挑战第27天】 本文深入探讨了安卓(Android)与iOS两大移动操作系统的技术特点和用户体验差异。通过对比两者的系统架构、应用生态、用户界面、安全性等方面,揭示了为何这两种系统能够在市场中各占一席之地,并为用户提供不同的选择。文章旨在为读者提供一个全面的视角,理解两种系统的优势与局限,从而更好地根据自己的需求做出选择。
63 2