`

[转]Android中G-Sensor相关流程

阅读更多
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下

androidsourcecode/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条件则调用
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驱动包括总线驱动和设备驱动

总线驱动只是提供对一条特定总线的读写机制,本身并不会去做通信。通过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时遇到的问题:
sensor.so中pull数据时打开的文件是input子系统中逻辑input设备的表示层即event handler层中的evdev.c创建的,如果通过此文件描述符实现ioctl,则只能实现与event handler通信,无法实际控制
Gsnsor driver. event handler层与物理设备的实际driver是通过input.c联系起来的,但input.c中没有实现将event handler层的ioctl传递到实际driver中。
故采用另创建一个设备节点用来实现sensor.so与driver之间的ioctl.
分享到:
评论

相关推荐

    Android中G-Sensor相关流程

    Android 中 G-Sensor 相关流程 Android 中 G-Sensor 相关流程是指在 Android 系统中使用 G-Sensor 传感器的整个过程,从驱动程序的加载到应用程序的使用。下面将详细介绍 Android 中 G-Sensor 相关流程。 首先,在...

    G-Sensor工作流程

    本文将深入剖析Android 4.2版本中G-Sensor的工作流程,包括SensorService如何创建和管理实例,以及数据从底层硬件到应用程序层的传输过程。 #### 二、SensorService的核心功能 SensorService的主要功能包括以下几...

    android平台sensor从底层到上层流程介绍.doc

    非常详细的sensor流程整理总结,图文结合。值得从事android hal层开发的人一看。 从这个图来看Sensor的架构还是非常的清淅, 黄色部分表示硬件,它要挂在I2C总线上 红色部分表示驱动,把驱动注册到Kernel的Input ...

    mtk g_sensor 驱动 重力传感器 详解

    在Android系统中,重力传感器(Gravity Sensor)是一种至关重要的硬件组件,它允许设备感知到三维空间中的重力加速度。在MTK(MediaTek)平台上,重力传感器的驱动程序,即mtk g_sensor,负责与硬件交互,将传感器...

    gsensor驱动调用框架流程

    总结,Android系统中Gsensor的工作流程大致如下:驱动层初始化并管理硬件,硬件抽象层和中间层封装了低级接口,提供了更高级别的API,应用层通过Java API与框架层交互,获取并处理传感器数据。这个流程确保了Android...

    高通sensor调试方法

    在高通平台进行sensor调试时,可以通过多种方式获取传感器的相关信息。本节主要介绍两种类型的调试信息及其获取方式。 1. **打印字符串log文件**:这类信息在编译阶段就已经定义好格式和大小,主要用于记录关键的...

    Android Sensor 分析

    ### Android Sensor 分析 #### 一、概述 随着智能手机功能的日益强大,各种传感器成为现代移动设备不可或缺的一部分。从Android 1.5版本开始,Android系统便开始支持多种类型的传感器,如加速度传感器、磁力传感器...

    andorid之摄像头驱动流程--MTK平台

    在Android系统中,摄像头驱动流程对于理解整个相机功能的实现至关重要。MTK(MediaTek)平台作为常见的手机SoC(System on Chip)供应商,其摄像头驱动流程也具有一定的特异性。下面将详细解析这一过程。 首先,...

    Android6.0开发中屏幕旋转原理与流程分析

    Android 系统屏幕旋转得以实现,是靠从底层驱动gsensor 中获取数据,从而判断屏幕方向的。kernel sensor的驱动先就不在这里赘述,简单介绍下,gsensor 驱动注册input 事件 在/dev/input/下,可以通过adb getevent -p...

    Android应用源码之加速度传感器.zip

    在Android平台上,加速度传感器是移动设备中一个重要的硬件组件,它能够感知设备在三维空间中的运动和方向变化。这个"Android应用源码之加速度传感器.zip"文件很可能包含了一个完整的示例项目,用于演示如何在...

    Spreadtrum Android 8810_6820 FAQ 1207

    **3.5 Gsensor/MSensor** - **添加G/M/L/P-sensor驱动**: 1. 根据传感器型号查找对应的驱动代码。 2. 将驱动代码集成到系统中。 - **layout调整**: 1. 根据实际布局调整配置文件。 2. 测试传感器输出。 - **...

    Spreadtrum Android 8810_6820 FAQ 1207.pdf

    **3.5 Gsensor/MSensor** - 加速度计和磁力传感器对于提供方位感知功能非常重要。 **3.5.1 如何添加G/M/L/P-sensor驱动** - 添加这些传感器的驱动程序可以实现更多高级功能。 **3.5.2 layout调整** - layout调整...

    驱动综合能力面试1

    【驱动综合能力面试】主要考察的是候选人在Android系统下的驱动开发和调试技能,以及相关硬件交互的经验。在面试中,面试官可能会询问以下关键知识点: 1. **驱动调试经验**: - TP(触摸屏)驱动:理解触摸事件的...

    全志A20_原厂开发文档资料

    4. **全志A20平台G-sensor模块开发说明文档V2.0_20130628.pdf**:G-sensor指的是加速度传感器,文档讲解了如何在A20平台上集成和使用加速度传感器,用于实现设备的运动感应和自动屏幕旋转等功能。 5. **全志A20_LCD...

    基于Android的跌倒监护app (源码 + 说明文档 + 演示视频)

    在源码部分,我们可以看到Android Studio项目的完整结构,包括`MainActivity.java`、`SensorService.java`等关键文件。`MainActivity`是用户界面的主要入口,而`SensorService`则负责处理传感器数据并进行跌倒检测...

    基于嵌入式智能手环的设计与开发.doc

    重力传感器(G-sensor)是智能手环中的关键组件之一,主要用于检测用户的活动状态。其工作原理是通过检测重力在不同方向上的分量来判断设备的姿态变化。当智能手环垂直放置时,若设备发生倾斜,则质量块会因为重力的...

    驱动综合能力面试-V1.21

    1. 驱动调试经验:这份测试涵盖了多种Android设备中的关键驱动模块,包括触摸屏(TP)、摄像头、加速度计(G-sensor)、GPIO、Wi-Fi、蓝牙(BT)、HDMI、LCD、红外遥控(IR-Remote)、输入设备、音频编解码芯片、...

Global site tag (gtag.js) - Google Analytics