歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

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。

Copyright © Linux教程網 All Rights Reserved