Email: wei7758@126.com
Blog: http://blog.csdn.net/yinwei520
Author: yww
Time: 2011-8-22
I. First, establish such a global concept:
Position and work of sensor in Android system architecture. The diagram is as follows:
From the diagram above, we can see that in Android, sensor is divided into four layers: Driver layer (sensor driver), Hardware Abstraction Layer (native), middle layer (framework), and application layer (Java ). The hardware abstraction layer and the intermediate layer can be combined as the framework layer.
For a specific gsensor here, we will explain the above system diagram in the form of source code.
Ii. Driver Layer)
The adxl345 chip is a gsensor. As to the working principle of the hardware, the datasheet of adxl345 must be analyzed. The driver source code is located in the directory XX \ custom \ common \ kernel \ accelerometer \ adxl345.
Because adxl345 is connected to the Linux system through I2C interfaces, it is necessary to analyze the Linux I2C subsystem architecture (omitted ). The source code is located:
1. XX \ platform \ XX \ kernel \ drivers \ I2C
2. kernel \ drivers \ I2C
View the adxl345.c file and analyze several functions for the working principle of the hardware. Hardware initialization:
Static int Merge (struct i2c_client * client, int reset_cali) {struct merge * OBJ = i2c_get_clientdata (client); int res = 0; adxl345_gpio_config (); // configure the gpio port, the interrupt pin is configured as an input/output port because no interruption is used. Res = adxl345_checkdeviceid (client); // detect the device ID by reading the devid register if (res! = Adxl345_success) {return res;} res = adxl345_setpowermode (client, false); // sets the power mode. The adxl345 has several power modes, if (res! = Adxl345_success) {return res;} res = adxl345_setbwrate (client, adxl345_bw_100hz); // set the bandwidth, 100Hz if (res! = Adxl345_success) // 0x2c-> BW = 100Hz {return res;} // set the data format. For details, see datasheet res = adxl345_setdataformat (client, adxl345_full_res | adxl345_range_2g ); if (res! = Adxl345_success) // 0x2c-> BW = 100Hz {return res;} gsensor_gain.x = gsensor_gain.y = gsensor_gain.z = obj-> reso-> sensiti; // sets the interrupt register, disable interrupted res = adxl345_setintenable (client, 0x00); // disable int if (res! = Adxl345_success) {return res;} If (0! = Reset_cali) {/* reset calibration only in power on */RES = adxl345_resetcalibration (client); If (res! = Adxl345_success) {return res ;}# ifdef config_adxl345_lowpass memset (& obj-> fir, 0x00, sizeof (obj-> fir); # endif return adxl345_success ;}
Function Analysis is annotated in the red part of the principle. View the datasheet of adxl345 for specific register settings, and view the I2C. c file for specific I2C communication (the driver of the I2C Controller ).
Key Issue: there is a problem here. If you do not understand it, it means that after reading the raw data from the adxl345 data register, this data is not used by our application and needs to be converted, after checking the code, you can find such a comment:
/*
* @ 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];
};
What is the physical meaning of such a conversion algorithm ?????
Iii. Hardware Abstraction Layer (native)
The hardware abstraction layer provides interfaces implemented by the hardware layer. The code path is as follows:
Hardware \ libhardware \ include \ hardware \ sensors. h
Where:
Struct sensors_module_t is the definition of the sensor module.
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 is a descriptive definition of a sensor.
Struct sensor_t {
Const char * Name;/* sensor name */
Const char * vendor;/* vendor of the sensor */
Int version;/* sensor version */
Int handle;/* sensor handle */
Int type;/* sensor type */
Float maxrange;/* maximum sensor range */
Float resolution;/* sensor discrimination rate */
Float power;/* sensor energy consumption (estimated value, Ma unit )*/
Void * Reserved [9];
}
Struct sensors_event_t indicates the sensor data
/**
* 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 (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;
Obviously, after reading these data structures, we will have such a question:
Here we only declare some struct, which need to be defined during use, and there are some function pointers in the struct. Where is the function implementation corresponding to these function pointers ?? Obviously, there must be a. c source file to implement such functions. After searching, the file name is sensors_hwmsen.c and the path is:
\ Xxk \ source \ hardware \ sensor \ hwmsen. Here, you will see the implementation of functions such as get_sensors_list.
4. intermediate layer (framework)
Here, I also call it the JNI layer, which implements the JNI interface. The source code directory is as follows:
Frameworks \ base \ core \ JNI \ android_hardware_sensormanager.cpp
In the source code, we can see the JNI interface function list:
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 },
};
For the implementation of these JNI interfaces, see the source code.
Of course, you may have another question. How does upper-layer Java call these local interfaces ?? The following function is available in the android_hardware_sensormanager.cpp source code:
Int register_android_hardware_sensormanager (jnienv * env)
{
Return jniregisternativemethods (ENV, "android/hardware/sensormanager ",
Gmethods, nelem (gmethods ));
}
This function registers the preceding JNI interface (gmethods array) to the system. It looks very simple. In fact, the process is very complicated. The entire native method initialization process is as follows: Start (androidruntime. cpp, row 938)-> starregulatory (androidruntime. cpp, row 1360)-> register_jni_procs (androidruntime. cpp, row 1213 ). In this way, the Java upper layer can call these JNI interfaces to manipulate the underlying hardware.
V. Application Layer (Java)
The Java section of the sensor system contains the following files:
U sensormanager. Java
Implement the core management class sensormanager of the Sensor System
U sensor. Java
Descriptive file Sensor for a single sensor
U sensorevent. Java
Represents the sensor system event class sensorevent
U sensoreventlistener. Java
Sensor event listener sensoreventlistener Interface
U sensorlistener. Java
Sensor listener sensorlistener Interface