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. 操作系统栈溢出检測之ucosII篇

    操作系统栈溢出检測之uc/osII篇 Author               :       David Lin (林鹏) E-mail               :       linpeng1 ...

  2. 关于自动刷新CSS

    由于最近系统调整大量的css,希望用户在浏览的时候能即时看到css的更改,而不是继续看到的是客户机上的缓存css. 在网络上找了下,发现很多人推荐一个叫cssrefresh的小工具. http://w ...

  3. 极限挑战—C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码)

    原文:极限挑战-C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码) 实际工作中有时候需要把大量数据导入数据库,然后用于各种程序计算,本实验将使用5中方法完成这个过程,并详细记录各种方 ...

  4. web攻击方式和防御方法

    在http请求报文中载入攻击代码,就能发起对web应用的攻击.通过url查询字段或者表单.http首部.cookie等途径吧攻击代码传入,若这时web应用存在安全漏洞,那内部信息就会遭到窃取! 对we ...

  5. PB+MS SQL+触发器必须指出

    PB+MS SQL+触发器必须指出: 若触发器存在两笔以上的返回值,比方两条update 语句,被误判为数据有改变.存盘不成功. 提示: Row changed between retrieve an ...

  6. Swift - 多层无缝循环滚动背景(SpriteKit游戏开发)

    在游戏开发中,比如跑酷游戏.我们需要实现背景的无限循环滚动,来营造运动的效果.除了单层的背景滚动,还有视差滚动. 视差滚动是指让多层背景以不同的速度移动,形成立体的效果,从而带来非常出色的视觉体验. ...

  7. SVM(支持向量机)(二)—Lagrange Duality(拉格朗日对偶问题)

    (整理自AndrewNG的课件,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) SVM有点让人头疼,但还是要弄明白.把这一大块搞懂了,会很有成就感 ...

  8. 使用微软Remote Desktop 手机远程控制 windows

    在我的电脑上右击选择“属性”,打开属性面板.然后点击左边的“远程设置”. 2/2 如果你要操作的计算机出入外网(大多数是家里网线进线直连电脑),就选择远程桌面选择框中的“允许运行任意版本远程桌面的计算 ...

  9. win32 字体变换与窗口同大同小

    #include <windows.h> #include "res/resource.h" LRESULT CALLBACK WinProc(HWND hwnd, U ...

  10. 暂停和屏蔽右键网页中的Flash

    如何暂停网页中的Flash?原理很简单,就是屏蔽Flash的消息即可.屏蔽右键也可以通过此方法 直接贴代码吧,加了注释,很容易就能懂了 新建工程,加一个WebBrowser,再加两个按钮.Flash ...