|
|
这两个数据结构中的成员函数,就是我们编写sensors.c中要实现的主要内容。frameworks中的JAVA代码通过JNI接口调用 sensors.c。 以下是对HTC G1传感器C程序的分析。 sensors.c需要完成的就是senseors.h中成员函数定义的功能
#define LOG_TAG "Sensors"
#include <hardware/sensors.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <math.h>
#include <poll.h>
#include <pthread.h>
#include <linux/input.h>
#include <linux/akm8976.h>
#include <cutils/atomic.h>
#include <cutils/log.h>
#include <cutils/native_handle.h>
#define MAX_NUM_SENSORS 4 //系统中的传感器数量
#define SUPPORTED_SENSORS ((1<<MAX_NUM_SENSORS)-1)
#define ID_A (0)
#define ID_M (1)
#define ID_O (2)
#define ID_T (3)
#define SENSORS_ACCELERATION (1<<ID_A)
#define SENSORS_MAGNETIC_FIELD (1<<ID_M)
#define SENSORS_ORIENTATION (1<<ID_O)
#define SENSORS_TEMPERATURE (1<<ID_T)
struct sensors_control_context_t {
struct sensors_control_device_t device;
int akmd_fd; //控制接口的fd。用来控制sensors
uint32_t active_sensors;
};
struct sensors_data_context_t {
struct sensors_data_device_t device;
int events_fd; // 数据接口的fd.用来接受数据和事件。
sensors_data_t sensors[MAX_NUM_SENSORS];
uint32_t pendingSensors;
};
static const struct sensor_t sSensorList[] = {
{ "AK8976A 3-axis Accelerometer",
"The Android Open Source Project",
1, SENSORS_HANDLE_BASE+ID_A,
SENSOR_TYPE_ACCELEROMETER, 2.8f, 1.0f/4032.0f, 3.0f, { } },
{ "AK8976A 3-axis Magnetic field sensor",
"The Android Open Source Project",
1, SENSORS_HANDLE_BASE+ID_M,
SENSOR_TYPE_MAGNETIC_FIELD, 2000.0f, 1.0f, 6.7f, { } },
{ "AK8976A Orientation sensor",
"The Android Open Source Project",
1, SENSORS_HANDLE_BASE+ID_O,
SENSOR_TYPE_ORIENTATION, 360.0f, 1.0f, 9.7f, { } },
{ "AK8976A Temperature sensor",
"The Android Open Source Project",
1, SENSORS_HANDLE_BASE+ID_T,
SENSOR_TYPE_TEMPERATURE, 80.0f, 1.0f, 0.0f, { } },
};
static int open_sensors(const struct hw_module_t* module, const char* name,
struct hw_device_t** device);
static uint32_t sensors__get_sensors_list(struct sensors_module_t* module,
struct sensor_t const** list)
{
*list = sSensorList;
return sizeof(sSensorList)/sizeof(sSensorList[0]);
}
static struct hw_module_methods_t sensors_module_methods = {
.open = open_sensors
};
struct sensors_module_t HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.id = SENSORS_HARDWARE_MODULE_ID,
.name = "AK8976A SENSORS Module",
.author = "The Android Open Source Project",
.methods = &sensors_module_methods,
},
.get_sensors_list = sensors__get_sensors_list
};
#define AKM_DEVICE_NAME "/dev/akm8976_aot"
// sensor IDs must be a power of two and
// must match values in SensorManager.java
#define EVENT_TYPE_ACCEL_X ABS_X
#define EVENT_TYPE_ACCEL_Y ABS_Z
#define EVENT_TYPE_ACCEL_Z ABS_Y
#define EVENT_TYPE_ACCEL_STATUS ABS_WHEEL
#define EVENT_TYPE_YAW ABS_RX
#define EVENT_TYPE_PITCH ABS_RY
#define EVENT_TYPE_ROLL ABS_RZ
#define EVENT_TYPE_ORIENT_STATUS ABS_RUDDER
#define EVENT_TYPE_MAGV_X ABS_HAT0X
#define EVENT_TYPE_MAGV_Y ABS_HAT0Y
#define EVENT_TYPE_MAGV_Z ABS_BRAKE
#define EVENT_TYPE_TEMPERATURE ABS_THROTTLE
#define EVENT_TYPE_STEP_COUNT ABS_GAS
// 720 LSG = 1G
#define LSG (720.0f)
// conversion of acceleration data to SI units (m/s^2)
#define CONVERT_A (GRAVITY_EARTH / LSG)
#define CONVERT_A_X (-CONVERT_A)
#define CONVERT_A_Y (CONVERT_A)
#define CONVERT_A_Z (-CONVERT_A)
// conversion of magnetic data to uT units
#define CONVERT_M (1.0f/16.0f)
#define CONVERT_M_X (-CONVERT_M)
#define CONVERT_M_Y (-CONVERT_M)
#define CONVERT_M_Z (CONVERT_M)
#define SENSOR_STATE_MASK (0x7FFF)
static int open_input(int mode)
{
int fd = -1;
const char *dirname = "/dev/input";
char devname[PATH_MAX];
char *filename;
DIR *dir;
struct dirent *de;
dir = opendir(dirname);
if(dir == NULL)
return -1;
strcpy(devname, dirname);
filename = devname + strlen(devname);
*filename++ = '/';
while((de = readdir(dir))) {
if(de->d_name[0] == '.' &&
(de%