Android Sensors HAL调试

 

前段时间在调试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_tsensor_t结构体,定义了sensors模块的主要功能

#include <fcntl.h>

#include <errno.h>

#include <math.h>

#include <poll.h>

#include <unistd.h>

#include <dirent.h>

#include <sys/select.h>

#include <cutils/log.h>

#include <linux/input.h>

 

#include <hardware/hardware.h>

#include <hardware/sensors.h>

 

#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 <hardware/sensors.h>

#include <stdio.h>

#include <stdlib.h>

#include <stdint.h>

#include <string.h>

#include <fcntl.h>

#include <errno.h>

#include <math.h>

#include <poll.h>

#include <unistd.h>

#include <dirent.h>

#include <ctype.h>

#include <linux/input.h>

#include <cutils/log.h>

#include <sys/select.h>

#include <sys/cdefs.h>

#include <sys/types.h>

 

//--------------------------------------------------------------------------------------------------------

#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 <stdint.h>

#include <errno.h>

#include <unistd.h>

#include <poll.h>

 

#include <sys/cdefs.h>

#include <sys/types.h>

 

#include <linux/input.h>

 

#include <cutils/log.h>

 

#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 <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 <cutils/atomic.h>

#include <cutils/log.h>

 

//-------------------------------------------------------------------

#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 <fcntl.h>

#include <errno.h>

#include <math.h>

#include <poll.h>

#include <unistd.h>

#include <dirent.h>

#include <sys/select.h>

 

#include <cutils/log.h>

 

//-------------------------------------------------------------------

#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() {

}

 

//-------------------------------------------------------------------int AccelerometerSensor::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;

}

 

 

Logo

开源、云原生的融合云平台

更多推荐