1.使G-sensor正常工作需要做的事:

G-sensor driver文件包括:

driver/i2c/chips/lis331dl.c


driver/i2c/chips/sensorioctl.h


include/linux/lis331dl.h

并在/kernel/arch/arm/mach-s3c6410/mach-ur6410.c文件中i2c chanel1的结构变量i2c_devs1[] __initdata中需要添加G-sensor的设备信息,


以使driver成功加载。


同时在该文件中添加一个结构变量


//JayLin add for Gsensor


struct lis331dl_platform_data lisGsensor_platform_data={


.name="lis331dl",


.pin_clk=0,


.pin_data=0,


.open_drain=1,


.interrupt=IRQ_EINT(3),


};


该结构变量在i2c_devs1[] __initdata中被引用。

/kernel/arch/arm/mach-s3c6410/mach-ur6410.c 中需要包含lis331dl.h。

在rootfs/system/etc/init.board.sh的最后一行加上mknod /dev/sensorioctl c 51 201&创建节点供ioctl使用。

编译后的sensor.so放在/rootfs/system/lib/hw下。

sensor.so和driver之间通过ioctl实现对G-sensor的状态控制。ioctl的命令编号定义在头文件sensorioctl.h中,分别放在


kernel/include/linux下





android
sourcecode/hardware/libhardware/include/hardware下


供driver和sensor.so使用。

G-sensor driver工作的大致流程:

系统开机后,先加载i2c总线驱动,然后加载设备驱动。


在设备驱动中的init函数中通过调用i2c_add_driver(&lis331dl_i2c_driver)注册i2c_driver;此函数将driver注册到i2c_bus_type的总线上,此总线的匹配规则是利用i2c_client的名称和


i2c_driver中id_table中的名称作匹配。


其中i2c_client是注册板载信息是系统自动创建的,注册板载信息的过程就是在/kernel/arch/arm/mach-s3c6410 /mach-ur6410.c文件中i2c chanel1的结构变量i2c_devs1[] __initdata中需要添加G-sensor的设备信息。


当匹配成功时,i2c_driver中的probe()函数开始执行。


Probe()函数主要完成以下功能:


1.从i2c_client结构中得到初始化信息


2.创建G-sensor的工作队列


2.注册input_device设备


3.读取Chip ID


4.设置寄存器,使能G-sensor


5.设置并启动中断


当G-sensor上报数据的时候会触发中断,然后在中断处理函数中提交一个报值的任务到队列中并禁止中断。


在工作队列中读数G-sensor的数据并上报到input子系统中,最后使能中断。

2.android上层应用apk到G-sensor driver的大致流程:

Android对于Sensor的API定义在 hardware/libhardware/include/hardware/sensor.h中, 要求在sensor.so提供以下8个API函数


[控制方面]


int (*open_data_source)(struct sensors_control_device_t *dev);


int (*activate)(struct sensors_control_device_t *dev, int handle, int enabled);


int (*set_delay)(struct sensors_control_device_t *dev, int32_t ms);


int (*wake)(struct sensors_control_device_t *dev);


[数据方面]


int (*data_open)(struct sensors_data_device_t *dev, int fd);


int (*data_close)(struct sensors_data_device_t *dev);


int (*poll)(struct sensors_data_device_t *dev, sensors_data_t* data);


[模块方面]


int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t const** list);


JAVA
层Sensor的状态控制由SensorService来负责,它的java代码和JNI代码分别位于:


frameworks/base/services/java/com/android/server/SensorService.java


frameworks/base/services/jni/com_android_server_SensorService.cpp

在Java层Sensor的数据控制由SensorManager来负责,它的java代码和JNI代码分别位于:


frameworks/base/core/java/android/hardware/SensorManager.java


frameworks/base/core/jni/android_hardware_SensorManager.cpp

android framework中与sensor通信的是sensorService.java和sensorManager.java。


sensorService.java的具体通信是通过JNI调用sensorService.cpp中的方法实现的。


sensorManager.java的具体通信是通过JNI调用sensorManager.cpp中的方法实现的。

sensorService.cpp和sensorManger.cpp通过hardware.c与sensor.so通信。其中sensorService.cpp实现对sensor的状态控制,sensorManger.cpp实现对sensor的数据控制。


sensor.so通过ioctl控制sensor driver的状态,通过打开sensor driver对应的设备文件读取G-sensor采集的数据。

android SDK提供了4个类来于sensor通信,分别为 sensor,sensorEvent,sensorEventListener,sensorManager.其中 sensorEventListener用来在sensorManager中注册需要监听的sensor类型。

sensorManager.java提供registrater(),unregistrater()接口供sensorEventListener使用。


sensorManager.java不断轮询从sensor.so中取数据。取到数据后送给负责监听此类型sensor的 sensorEventListener.java。sensorEventListener.java通过在sensorManager.java中注 册可以监听特定类型的sensor传来的数据。

系统启动时执行systemProcess,会启动sensorService.java,在sensorService.java的构造函数中调用JNI方法_sensor_control_init()。


sensorService.cpp中相应的方法android_int()会被执行。该函数会调用hardware.c中的方法hw_get_module()此函数又通过调用load()函数在system/lib/hw下查找sensor.so


查找时会根据harware.c中定义好的sensor.*.so的扩展名的顺序查找,找到第一个匹配的时候即停止,并将该sensor.so中定义好的一个全局变量HAL_MODULE_INFO_SYM带回。该变量包含的一个


重要信息是它的一个成员结构变量中包含的一个函数指针open,该指针所指函数会对一个device结构变量赋值,从而带出sensorService.cpp 和sensorManager.cpp与sensor通信所需要的全部信息。


device结构变量有两种变体分别供sensorService.cpp和sensorManaer.cpp使用。其中主要是一些函数指针指向与sensor通信的函数。


sensorService.cpp和sensorManager.cpp在得到HAL_MODULE_INFO_SYM结构后都会调用 sensors.h的inline函数open()通过HAL_MODULE_INFO_SYM的open函数指针将所需的device信息取回。

系统在启动activityManager.java时,它会启动sensorManager.java,它也会调用hardware.c中的方法hw_get_module()带回HAL_MODULE_INFO_SYM。

3.关于Rotate的实现:

系统启动windowManger.java时,它会启动phoneWindowManager.java,该类有一个内部类myOrientationListener扩展自windowOrientationListener.java。


windowOrientationListener.java是一个辅助类,当device的方向发生变化时,供windowManger.java调用,用来接收数据。


windowOrientationListener.java 内部在sensorManger.java中进行了注册,它回监听G-sensor传来的数据,即x,y,z方向的加速度,收到数据后经过转换处理,若满足Roate条件则调用   盛世游戏:http://www.shengshiyouxi.com


IwindowManager接口的实现类windowManagerService.java中的setRotation()方法实现转屏。

SensorManager通过polling的方式从设备得到Sensor数据, Sensor数据的结构定义在sensor.h里,


其中SensorManager只处理了 vector.v, vector.status, time三个域, 分发给已注册的对这些消息的监听者

比如第一项 vector.v包含x,y,z三个方向的信息值,就是由 WindowOrientataionLister注册的,


当 SensorManager获取到这三个值之后,会传递给 WindowOrientataionLister,后者代码位于:


frameworkd/base/core/java/android/view/WindowOrientationListener.java


WindowOrientataionLister接收到这三个值之后,会计算出设备对应的orientation,并且执行 onOrientationChanged函数进一步上传

WindowOrientataionLister是个纯虚类,如果在APK里需要控制方向,可以重载一个实例,


而Android的系统实例对应在 PhoneWindowManager.java里,名字为MyOrientationListener


frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindowManager.java

如果需要旋转, MyOrientationListener则会调用以下代码进行窗口旋转:


mWindowManager.setRotation(rotation, false, mFancyRotationAnimation);

问题总结:


1.将lis302 G-sensor driver从spi总线移植到lis331 i2c总线时遇到的一些问题:


a).lis331用的中断管脚与lis302不同,通过硬件原理图可知lis331用的是GPN3.故需要在driver的probe中设置 writel((readl(S3C64XX_GPNCON) & ~(0xc0)) | (0x80), S3C64XX_GPNCON);


b).通过硬件原理图可知lis331的时钟线和数据线用的是i2c chanel1。故需要在/kernel/arch/arm/mach-s3c6410/mach-ur6410.c文件中i2c chanel1即结构变量i2c_devs1[] __initdata中


添加G-sensor的设备信息,以使driver成功加载。


c).lis331 driver是中断驱动的,每次G-sensor搜集到新数据都会产生中断,driver要在中断中通过i2cbus将数据从G-sensor中取回。由 于i2cbus的读写操作是可能休眠的,而中断中不允许调用可能休眠的函数,故通过linux提供的延迟机制work_queue来解决。

问题b)的原理:


i2c驱动包括总线驱动和设备驱动   盛世游戏:http://www.shengshiyouxi.com

总线驱动只是提供对一条特定总线的读写机制,本身并不会去做通信。通过i2c总线驱动提供的函数,设备驱动可以忽略不同总线控制器的差异,不考虑其细节的与硬件设备通讯。


一个总线驱动通常需要2个模块:struct i2c_adapter和struct i2c_algorithm 定义在include/linux/i2c.h中


struct i2c_algorithm是为了i2c总线驱动和具体的i2c总线能够对话。很多i2c总线驱动定义和使用它们自己的algorithm.对于一些i2c总线驱动来说,很多algorithm已经写好了。


drivers/i2c/buses中包含所有的i2c总线驱动,drivers/i2c/algos中包含了所有的algorithm.

设备驱动通过总线驱动中的读写函数同具体的i2c设备通信,一个设备驱动用两个模块来描述:struct i2c_driver 和struct i2c_client.


i2c_client代表着位于adapter总线上地址为address,使用driver来驱动的一个设备。它将总线驱动,设备驱动以及设备地址绑定到了一起。

2.实现sensor.so与driver之间的ioctl时遇到的问题:

Android中G-Sensor相关流程的更多相关文章

  1. Android中Linux suspend/resume流程

    Android中Linux suspend/resume流程首先我们从linux kernel 的suspend说起,不管你是使用echo mem > /sys/power/state 或者使用 ...

  2. 分析Android中View的工作流程

    在分析View的工作流程时,需要先分析一个很重要的类,MeasureSpec.这个类在View的测量(Measure)过程中会用到. MeasureSpec MeasureSpec是View的静态内部 ...

  3. Android中View的绘制流程(专题讲解)

    Android中的UI视图有两种方式实现:.xml文件(实现代码和UI的分离)和代码实现. Android的UI框架基本概念: 1. Activity:基本的页面单元,Activity包含一个Wind ...

  4. Android中的Activity相关知识总结

    一.什么是Activity? 简单理解:Activity是Android组件中最基本也是最为常见用的四大组件之一.是一个与用户交互的系统模块,一个Activity通常就是一个单独的屏幕(页面), 它上 ...

  5. Android中图片处理相关问题

    在Android的开发中,我们经常回去处理一些图片相关的问题,比如当加载图片到内存中产生的OOM(OutOfMemory)异常.图片加载到内存中占多大内存的问题.jpg png两种常见的图片的原理及区 ...

  6. Android中WebView的相关使用

    近期做的项目中,遇到个非常棘手的问题: 客户给我的数据是有限制的,因此,在返回某条详细页面内容的时候,他仅仅能给我一个html片段,里面包括 文字,图片以及附件的下载地址.假设网页模版规范的爱比較好说 ...

  7. 家庭记账本app进度之android中AlertDialog的相关应用以及对日期时间的相关操作(应用alertdialog使用的谈话框)

    对于AlertDialog的相关知识: 1.创建构造器AlertDialog.Builder的对象:    2.通过构造器对象调用setTitle.setMessage.setIcon等方法构造对话框 ...

  8. Android中与task相关的几个属性

    1.与任务相关的属性 taskAffinity :修改任何给定Activity的关联 系统使用包名标识应用的默认任务关联: taskAffinity属性取字符串值,必须不同于包名: taskAffin ...

  9. android中与Adapter相关的控件----ListView

    ListView讲解: 一.ListView这个控件是一个使用非常广泛的控件,值得深入的学习和研究.基本使用已经在Adapter中使用过了 二.常用的属性和方法 footerDividersEnabl ...

  10. android中与Adapter相关的控件----ExpandableListView

    ExpandableListView(可折叠的列表) 一.ExpandableListView(可折叠的列表)和ListView有很多地方差不多的,使用也差不多,只是他们使用适配器不一样的,Expan ...

随机推荐

  1. EasyUI - DateBox组件

    效果: html代码: <input type ="text" id ="box" /> JS代码: $(function () { //设置返回格 ...

  2. 在Python中使用正则表达式同时匹配邮箱和电话并进行简单的分类

    在Python使用正则表达式需要使用re(regular exprssion)模块,使用正则表达式的难点就在于如何写好p=re.compile(r' 正则表达式')的内容. 下面是在Python中使用 ...

  3. FZOJ2110: Star

    Problem Description Overpower often go to the playground with classmates. They play and chat on the ...

  4. 【LeetCode从零单排】No 3 Longest Substring Without Repeating Characters

    题目 Given a string, find the length of the longest substring without repeating characters. For exampl ...

  5. asp.net iis URLRewrite 实现方法详解

    原文 asp.net iis URLRewrite 实现方法详解 实现非常简单首先你要在你的项目里引用两个dll:actionlessform.dll.urlrewriter.dll,真正实现重写的是 ...

  6. iot 表 主键索引叶子块包含了表所有数据

    <pre name="code" class="html">iot表测试: 在create table语句后面使用organization inde ...

  7. 轻应用 lapp

    轻应用 LAPP (Light App) 即轻应用是一种无需下载.即搜即用的全功能 App,既有媲美甚至超越native app的用户体验,又具备webapp的可被检索与智能分发的特性,将有效解决优质 ...

  8. boost function对象

    本文根据boost的教程整理. 主要介绍boost function对象的用法. boost function boost function是什么 boost function是一组类和模板组合,用于 ...

  9. javascript (九)注释

    单行注释,采用双斜杠  // 多行注释,采用 /* */

  10. 14.2.5.5 Change Buffer

    14.2.5.5 Change Buffer change buffer是一个指定的数据结构 用于caches 数据到secondary index pages 当影响的pages 不是在buffer ...