本文主要是介绍android sensors,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前段时间在调试Android的时候,涉及到sensors的移植,在Android中 Sensors子系统架构如下:其中Sensor HAL以上都已由android实现的,在具体Android Sensors移植中,需要用户实现的sensor Hal及以下,下面我们来分析一下sensors HAL的具体实现 Sensors的硬件抽像层中,有几个关键的结构体需要用户处理,它的定义位于libhardware/include/hardware/sensors.h文件中,sensors_module_t结构体用来定义sensor模块,sensor_t结构体用来定义一个sensors设备,sensors_event_t用来定义sensor数据,sensors_poll_device_t用来定义sensor的控制 |
sensors.c主要实现sensors_module_t和sensor_t结构体,定义了sensors模块的主要功能 |
#include #include #include #include #include #include #include #include #include
#include #include
#include "SensorsControl.h"
#ifdef LOG_TAG #undef LOG_TAG #endif #define LOG_TAG "yamaha_sensors"
#define YLOGD(...) LOGD(__VA_ARGS__) #define YLOGI(...) LOGI(__VA_ARGS__) #define YLOGE(...) LOGE(__VA_ARGS__) #define YLOGW(...) LOGW(__VA_ARGS__)
//-------------------------------------------------------------------------------------------------------- #define POLLTIMEOUT (-1)
#define MAX_DEVICE_NAME (32) #define MAX_CLASS_PATH (256)
//-------------------------------------------------------------------------------------------------------- static const struct sensor_t sSupportedSensors[NUM_SENSORS] = { #if defined(SENSOR_SUPPORT_ACCELEROMETER) { .name = "BMA150 3-axis Accelerometer", .vendor = "Bosh", .version = 120, .handle = ID_ACCELEROMETER, .type = SENSOR_TYPE_ACCELEROMETER, .maxRange = 4.0f * 9.81f, .resolution = (4.0f * 9.81f)/256.0f, .power = 2.0f, .reserved = {0}, }, #endif #if defined(SENSOR_SUPPORT_MAGNETIC_FIELD) { .name = "MS-3C Magnetic Sensor", .vendor = "Yamaha Corporation", .version = 120, .handle = ID_MAGNETIC_FIELD, .type = SENSOR_TYPE_MAGNETIC_FIELD, .maxRange = 2000.0f, .resolution = 1.0f/16.0f, .power = 4.0f, /* typ 4mA (Normal), typ 1uA (Standby) */ .reserved = {0}, }, #endif #if defined(SENSOR_SUPPORT_ORIENTATION) { .name = "MS-3C Orientation Sensor", .vendor = "Yamaha Corporation", .version = 120, .handle = ID_ORIENTATION, .type = SENSOR_TYPE_ORIENTATION, .maxRange = 360.0f, .resolution = 1.0f, .power = 1.0f, .reserved = {0}, }, #endif };
//-------------------------------------------------------------------------------------------------------- static int sensors_list(struct sensors_module_t *module, struct sensor_t const**sensor) { *sensor = sSupportedSensors;
return NUM_SENSORS; }
//-------------------------------------------------------------------------------------------------------- static int open_sensors(const struct hw_module_t* module, const char* name,struct hw_device_t** device) { YLOGD("open_sensors");
return init_sensors_control(module, device); }
//-------------------------------------------------------------------------------------------------------- static struct hw_module_methods_t sensors_module_methods = { .open = open_sensors, };
//-------------------------------------------------------------------------------------------------------- const struct sensors_module_t HAL_MODULE_INFO_SYM = { .common = { .tag = HARDWARE_MODULE_TAG, .version_major = 1, .version_minor = 2, .id = SENSORS_HARDWARE_MODULE_ID, .name = "Yamaha Sensors module", .author = "Yamaha Corporation", .methods = &sensors_module_methods, }, .get_sensors_list = sensors_list, };
|
|
SensorBace.cpp:为各sensors实现的基类,openDataFd会返回sensors EVENT设备文件的句柄 |
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include
//-------------------------------------------------------------------------------------------------------- #include "SensorBase.h"
//-------------------------------------------------------------------------------------------------------- #ifdef LOG_TAG #undef LOG_TAG #endif
#define LOG_TAG "SensorBase"
#define YLOGD(...) LOGD(__VA_ARGS__) #define YLOGI(...) LOGI(__VA_ARGS__) #define YLOGE(...) LOGE(__VA_ARGS__) #define YLOGW(...) LOGW(__VA_ARGS__)
//-------------------------------------------------------------------------------------------------------- SensorBase::SensorBase(const char* name) : name(name), data_fd(-1),mHasPendingEvent(false), mEnabled(0) { data_fd = openDataFd(name);
// sysfs classpath read if (getInputClasspath(name) < 0) YLOGE("getInputClasspath failed [%s]\n", name);
YLOGD("SensorBase::SensorBase : [Name : %s, data_fd : %d, classname : %s]\n", name, data_fd, classpath); }
//-------------------------------------------------------------------------------------------------------- SensorBase::~SensorBase() { if (data_fd >= 0) close(data_fd); }
//-------------------------------------------------------------------------------------------------------- int SensorBase::getFd() const { return data_fd; }
//-------------------------------------------------------------------------------------------------------- int SensorBase::setDelay(int32_t handle, int64_t ns) { int err = 0;
int msDelay = (int)(ns / 1000000LL); // convert to ms
YLOGD("SensorBase::setDelay : [Name : %s, Handle : %d, ns : %lld, delay = %d]\n", name, handle, ns, msDelay);
if (setInputAttr("delay", msDelay) < 0) { YLOGE("setInputAttr failed -> delay : [%s]\n", name); err = -1; }
return err; }
//-------------------------------------------------------------------------------------------------------- int SensorBase::enable(int32_t handle, int enabled) { int err = 0;
YLOGD("SensorBase::enable : [Name : %s, Handle : %d, enabled : %d]\n",name, handle, enabled);
// class path -> set enable, set wake if (setInputAttr("enable", enabled) < 0) { YLOGE("setInputAttr failed -> enable : [%s]\n", name); err = -1; }
if (setInputAttr("wake", enabled) < 0) { YLOGE("setInputAttr failed -> wake : [%s]\n", name); err = -1; }
mEnabled = enabled; mHasPendingEvent = true;
return err; }
//-------------------------------------------------------------------------------------------------------- int SensorBase::getInitialValues(sensors_vec_t* sensor, float divf) { char buf[sizeof("-2147483647") * 3 + 1]; /* including spaces, LF and '\0' */ char *p, space[] = " "; int i;
if (getInputAttr("data", buf, sizeof(buf)) < 0) { for (i = 0; i < 3; i++) sensor->v[i] = 0; return 0; }
for (i = 0; i < 3; i++) { if (i == 0) p = strtok(buf, space); else p = strtok(NULL, space);
if (p == NULL) sensor->v[i] = 0; else sensor->v[i] = atoi(p) / divf;
YLOGD("initial value[%s] [%.3f]\n", name, sensor->v[i]); }
return 0; }
//-------------------------------------------------------------------------------------------------------- int SensorBase::getInitialStatus(sensors_vec_t* sensor) { int status;
if (getInputAttr("status", &status) < 0) sensor->status = 0; else sensor->status =(int8_t)status;
YLOGD("SensorBase::getInitialStatus : [Name : %s, status : %d]\n", name,status); return 0; }
//-------------------------------------------------------------------------------------------------------- bool SensorBase::hasPendingEvents() const { return mHasPendingEvent; }
//-------------------------------------------------------------------------------------------------------- int64_t SensorBase::getTimestamp() { struct timespec t;
t.tv_sec = t.tv_nsec = 0; clock_gettime(CLOCK_MONOTONIC, &t);
return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec; }
//-------------------------------------------------------------------------------------------------------- int SensorBase::getInputClasspath(const char *inputName) { DIR *dir; const char *dirname = "/sys/class/input";
char buf[PATH_MAX]; struct dirent *de;
int fd = -1, nread, found = 0;
if (name == NULL || classpath == NULL) return -EINVAL;
// Open Input class dir if((dir = opendir(dirname)) == NULL) return -errno;
while((de = readdir(dir))) {
if (strncmp(de->d_name, "input", strlen("input")) != 0) continue;
memset(classpath, 0x00, sizeof(classpath)); snprintf(classpath, PATH_MAX, "%s/%s/", dirname, de->d_name);
snprintf(buf, sizeof(buf), "%s/name", classpath);
if((fd = open(buf, O_RDONLY)) < 0) continue;
if ((nread = read(fd, buf, sizeof(buf))) < 0) { close(fd); continue; }
buf[nread - 1] = '\0';
if (strcmp(buf, inputName) == 0) { close(fd); closedir(dir); return 0; // Classpath found!! }
close(fd); fd = -1; }
closedir(dir); *classpath = '\0';
return -EINVAL; // Classpath not found }
//-------------------------------------------------------------------------------------------------------- int SensorBase::getInputAttr(const char *attr, char *value, int len) { char fname[PATH_MAX]; int fd, nread;
if (classpath == NULL || *classpath == '\0' || attr == NULL || value ==NULL || len < 1) return -EINVAL;
memset(fname, 0x00, sizeof(fname));
snprintf(fname, sizeof(fname), "%s/%s", classpath, attr); fname[sizeof(fname) - 1] = '\0';
if((fd = open(fname, O_RDONLY)) < 0) return -errno;
if ((nread = read(fd, value, len)) < 0) { close(fd); return -errno; } close(fd);
value[nread - 1] = '\0';
return 0; }
//-------------------------------------------------------------------------------------------------------- int SensorBase::getInputAttr(const char *attr, int *value) { char buf[sizeof("-2147483647")]; int rt;
if (value == NULL) return -EINVAL; if ((rt = getInputAttr(attr, buf, sizeof(buf))) < 0) return rt;
*value = atoi(buf);
return 0; }
//-------------------------------------------------------------------------------------------------------- int SensorBase::setInputAttr(const char *attr, char *value, int len) { char fname[PATH_MAX]; int fd;
if (classpath == NULL || *classpath == '\0' || attr == NULL || value ==NULL || len < 1) return -EINVAL;
memset(fname, 0x00, sizeof(fname));
snprintf(fname, sizeof(fname), "%s/%s", classpath, attr); fname[sizeof(fname) - 1] = '\0';
if((fd = open(fname, O_WRONLY)) < 0) return -errno;
if (write(fd, value, len) < 0) { close(fd); return -errno; }
close(fd);
return 0; }
int SensorBase::setInputAttr(const char *attr, int value) { char buf[sizeof("-2147483647")];
memset(buf, 0x00, sizeof(buf));
sprintf(buf, "%d", value);
return setInputAttr(attr, buf, sizeof(buf)); } int SensorBase::openDataFd(const char *inputName) { DIR *dir; struct dirent *de; const char *dirname = "/dev/input"; char *filename, devname[PATH_MAX];
int fd = -1;
if((dir = opendir(dirname)) == NULL) return -1;
memset(devname, 0x00, sizeof(devname)); strcpy(devname, dirname);
filename = devname + strlen(devname); *filename++ = '/';
while((de = readdir(dir))) { if(de->d_name[0] == '.' && (de->d_name[1] == '\0' || (de->d_name[1] =='.' && de->d_name[2] == '\0'))) continue;
strcpy(filename, de->d_name);
if((fd = open(devname, O_RDONLY)) >= 0) { char name[80]; if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) name[0]= '\0';
if (!strcmp(name, inputName)) break; else { close(fd); fd = -1; } } } closedir(dir);
LOGE_IF(fd < 0, "couldn't find '%s' input device", inputName);
return fd; }
|
|
InputEventReader.cpp文件的主要功能会读取sensors的输入事件 |
#include #include #include #include
#include #include
#include
#include
#include "InputEventReader.h"
/*****************************************************************************/
struct input_event;
InputEventCircularReader::InputEventCircularReader(size_t numEvents) : mBuffer(new input_event[numEvents * 2]), mBufferEnd(mBuffer + numEvents), mHead(mBuffer), mCurr(mBuffer), mFreeSpace(numEvents) { }
InputEventCircularReader::~InputEventCircularReader() { delete [] mBuffer; }
ssize_t InputEventCircularReader::fill(int fd) { size_t numEventsRead = 0; if (mFreeSpace) { const ssize_t nread = read(fd, mHead, mFreeSpace * sizeof(input_event)); if (nread<0 || nread % sizeof(input_event)) { // we got a partial event!! return nread<0 ? -errno : -EINVAL; }
numEventsRead = nread / sizeof(input_event); if (numEventsRead) { mHead += numEventsRead; mFreeSpace -= numEventsRead; if (mHead > mBufferEnd) { size_t s = mHead - mBufferEnd; memcpy(mBuffer, mBufferEnd, s * sizeof(input_event)); mHead = mBuffer + s; } } }
return numEventsRead; }
ssize_t InputEventCircularReader::readEvent(input_event const** events) { *events = mCurr; ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace; return available ? 1 : 0; }
void InputEventCircularReader::next() { mCurr++; mFreeSpace++; if (mCurr >= mBufferEnd) { mCurr = mBuffer; } }
|
|
SensorsControl.cpp文件为sensors的控制文件,实现sensors_poll_device_t结构体,在init_sensors_control函数中写义了sensors_poll_context_t类的对像,在sensors_poll_context_t类的构造函数中, 定义了具体sensors类的对像,init_sensors_control函数是在sensors模块被打开时调用的 |
//------------------------------------------------------------------- #include #include #include #include #include #include #include #include
#include #include
//------------------------------------------------------------------- #include "SensorsControl.h" #include "AccelerometerSensor.h" #include "GeomagneticSensor.h" #include "OrientationSensor.h"
//------------------------------------------------------------------- #ifdef LOG_TAG #undef LOG_TAG #endif
#define LOG_TAG "SensorsControl"
#define YLOGD(...) //#define YLOGD(...) LOGD(__VA_ARGS__) #define YLOGI(...) LOGI(__VA_ARGS__) #define YLOGE(...) LOGE(__VA_ARGS__) #define YLOGW(...) LOGW(__VA_ARGS__)
//------------------------------------------------------------------- struct sensors_poll_context_t { struct sensors_poll_device_t device; // must be first
sensors_poll_context_t (); ~sensors_poll_context_t ();
int activate (int handle, int enabled); int setDelay (int handle, int64_t ns); int pollEvents (sensors_event_t* data, int count);
private: enum { Accelerometer = 0, Geomagnetic = 1, Orientation = 2, numSensorDrivers, numFds, };
static const size_t wake = numFds - 1; static const char WAKE_MESSAGE = 'W'; struct pollfd mPollFds[numFds]; int mWritePipeFd; SensorBase* mSensors[numSensorDrivers];
int handleToDriver(int handle) const { if(handle < numSensorDrivers) return handle;
return -EINVAL; } };
//------------------------------------------------------------------- sensors_poll_context_t::sensors_poll_context_t() { mSensors[Accelerometer] = new AccelerometerSensor(); mPollFds[Accelerometer].fd = mSensors[Accelerometer]->getFd(); mPollFds[Accelerometer].events = POLLIN; mPollFds[Accelerometer].revents = 0;
mSensors[Geomagnetic] = new GeomagneticSensor(); mPollFds[Geomagnetic].fd = mSensors[Geomagnetic]->getFd(); mPollFds[Geomagnetic].events = POLLIN; mPollFds[Geomagnetic].revents = 0;
mSensors[Orientation] = new OrientationSensor(); mPollFds[Orientation].fd = mSensors[Orientation]->getFd(); mPollFds[Orientation].events = POLLIN; mPollFds[Orientation].revents = 0;
int wakeFds[2]; int result = pipe(wakeFds);
LOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno)); fcntl(wakeFds[0], F_SETFL, O_NONBLOCK); fcntl(wakeFds[1], F_SETFL, O_NONBLOCK);
mWritePipeFd = wakeFds[1];
mPollFds[wake].fd = wakeFds[0]; mPollFds[wake].events = POLLIN; mPollFds[wake].revents = 0; }
//-------------------------------------------------------------------------------------------------------- sensors_poll_context_t::~sensors_poll_context_t() { for (int i=0 ; i<numSensorDrivers ; i++) { delete mSensors[i]; } close(mPollFds[wake].fd); close(mWritePipeFd); }
//-------------------------------------------------------------------------------------------------------- int sensors_poll_context_t::activate(int handle, int enabled) {
YLOGD("sensors_poll_context_t::activate : [Handle : %d, enabled : %d]\n",handle, enabled);
int index = handleToDriver(handle); if (index < 0) return index; int err = mSensors[index]->enable(handle, enabled); if (enabled && !err) { const char wakeMessage(WAKE_MESSAGE); int result = write(mWritePipeFd, &wakeMessage, 1); LOGE_IF(result<0, "error sending wake message (%s)", strerror(errno)); } return err; }
//------------------------------------------------------------------- int sensors_poll_context_t::setDelay(int handle, int64_t ns) {
int index = handleToDriver(handle); if (index < 0) return index; return mSensors[index]->setDelay(handle, ns); }
//------------------------------------------------------------------- int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count) { int nbEvents = 0; int n = 0;
YLOGD("IN ----> sensors_poll_context_t::pollEvents : [count : %d]\n",count);
do { // see if we have some leftover from the last poll() for (int i=0 ; count && i<numSensorDrivers ; i++) { SensorBase* const sensor(mSensors[i]); if ((mPollFds[i].revents & POLLIN) || (sensor->hasPendingEvents())){ int nb = sensor->readEvents(data, count); if (nb < count) { // no more data for this sensor mPollFds[i].revents = 0; } count -= nb; nbEvents += nb; data += nb; } }
if (count) { YLOGD("sensors_poll_context_t :: %d\n", count); // we still have some room, so try to see if we can get // some events immediately or just wait if we don't have // anything to return n = poll(mPollFds, numFds, nbEvents ? 0 : -1); if (n<0) { LOGE("poll() failed (%s)", strerror(errno)); return -errno; } if (mPollFds[wake].revents & POLLIN) { char msg; int result = read(mPollFds[wake].fd, &msg, 1); LOGE_IF(result<0, "error reading from wake pipe (%s)",strerror(errno)); LOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int(msg)); mPollFds[wake].revents = 0; } } // if we have events and space, go read them } while (n && count);
YLOGD("OUT ----> sensors_poll_context_t::pollEvents : [count : %d, nbEvents]\n", count, nbEvents);
return nbEvents; }
//------------------------------------------------------------------- static int poll__close(struct hw_device_t *dev) { sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; if (ctx) { delete ctx; } return 0; }
//------------------------------------------------------------------- static int poll__activate(struct sensors_poll_device_t *dev, int handle, int enabled) { sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; return ctx->activate(handle, enabled); }
//------------------------------------------------------------------- static int poll__setDelay(struct sensors_poll_device_t *dev, int handle, int64_t ns) { sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; return ctx->setDelay(handle, ns); }
//------------------------------------------------------------------- static int poll__poll(struct sensors_poll_device_t *dev, sensors_event_t* data, int count) { sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev; return ctx->pollEvents(data, count); }
//------------------------------------------------------------------- int init_sensors_control(hw_module_t const* module, hw_device_t** device) { int status = -EINVAL;
sensors_poll_context_t *dev = new sensors_poll_context_t(); memset(&dev->device, 0, sizeof(sensors_poll_device_t));
dev->device.common.tag = HARDWARE_DEVICE_TAG; dev->device.common.version = 0; dev->device.common.module = const_cast<hw_module_t*>(module); dev->device.common.close = poll__close; dev->device.activate = poll__activate; dev->device.setDelay = poll__setDelay; dev->device.poll = poll__poll;
*device = &dev->device.common;
status = 0;
return status; }
|
|
AccelerometerSensor.cpp文件为具体重力加速度传感器的实现 |
//-------------------------------------------------------------------#include #include #include #include #include #include #include
#include
//------------------------------------------------------------------- #include "AccelerometerSensor.h"
//------------------------------------------------------------------- #ifdef LOG_TAG #undef LOG_TAG #endif
#define LOG_TAG "AccelerometerSensor"
#define YLOGD(...) LOGD(__VA_ARGS__) #define YLOGI(...) LOGI(__VA_ARGS__) #define YLOGE(...) LOGE(__VA_ARGS__) #define YLOGW(...) LOGW(__VA_ARGS__)
//------------------------------------------------------------------- AccelerometerSensor::AccelerometerSensor() : SensorBase(INPUT_CLASSNAME_ACCELEROMETER), mfdiv(1000000), mInputReader(4) { memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data));
mPendingEvent.version = sizeof(sensors_event_t); mPendingEvent.sensor = ID_ACCELEROMETER; mPendingEvent.type = SENSOR_TYPE_ACCELEROMETER;
// Initialize AccelerometerSensor getInitialStatus(&mPendingEvent.acceleration); getInitialValues(&mPendingEvent.acceleration, mfdiv); }
//------------------------------------------------------------------- AccelerometerSensor::~AccelerometerSensor() { }
//-------------------------------------------------------------------intAccelerometerSensor::readEvents(sensors_event_t* data, int count) { if (count < 1) return -EINVAL;
if (mHasPendingEvent) { mHasPendingEvent = false; mPendingEvent.timestamp = getTimestamp(); *data = mPendingEvent;
return mEnabled ? 1 : 0; }
ssize_t n = mInputReader.fill(data_fd);
if (n < 0) return n;
int numEventReceived = 0, breaked = 0;
input_event const* event;
while (count && mInputReader.readEvent(&event)) { switch(event->type) { case EV_ABS: switch(event->code) { case ABS_X: mPendingEvent.acceleration.x = event->value / mfdiv; break; case ABS_Y: mPendingEvent.acceleration.y = event->value / mfdiv; break; case ABS_Z: mPendingEvent.acceleration.z = event->value / mfdiv; break; case ABS_STATUS: mPendingEvent.acceleration.status =event->value; break; case ABS_WAKE: breaked =1; break; default : break; } break; case EV_SYN: mPendingEvent.timestamp = timevalToNano(event->time); if (mEnabled) { *data++ = mPendingEvent; count--; numEventReceived++; } break; default : YLOGE("unknown event (type=%d, code=%d)", event->type, event->code); break; } mInputReader.next(); }
if(breaked) { YLOGE("ABS_WAKE event (type=%d, code=%d) : break!!", event->type,event->code); return 0; }
return numEventReceived; } |
这篇关于android sensors的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!