卓派观点

 
分析一下android2.3中SensorBase.cpp的程序流程

在移植sensor的hal层代码时, SensorBase.cpp作为所有sensor类的基类, 定义了一些很有用的方法.

下面jwisp结合实际实验, 来跟大家分析下SensorBase的作用和流程

SensorBase::SensorBase(
        const char* dev_name,
        const char* data_name)
    : dev_name(dev_name), data_name(data_name),
      dev_fd(-1), data_fd(-1)
{
    data_fd = openInput(data_name);
}

SensorBase的构造, 子类会先调用父类的这个方法,

在SensorBase构造中, 将子类传来的设备名称dev_name和数据设备名data_name赋值本类成员,

然后通过openInput函数,打开data_name然后将open后的句柄, 传递给data_fd

SensorBase::~SensorBase() {
    if (data_fd >= 0) {
        close(data_fd);
    }
    if (dev_fd >= 0) {
        close(dev_fd);
    }
}

析构函数, 关闭data_fd和dev_fd

int SensorBase::open_device() {
    if (dev_fd<0 && dev_name) {
        dev_fd = open(dev_name, O_RDONLY);
        LOGE_IF(dev_fd<0, "Couldn't open %s (%s)", dev_name, strerror(errno));
    }
    return 0;
}
int SensorBase::close_device() {
    if (dev_fd >= 0) {
        close(dev_fd);
        dev_fd = -1;
    }
    return 0;
}

通过设备句柄, 打开和关闭设备

int SensorBase::getFd() const {
    return data_fd;
}

int SensorBase::setDelay(int32_t handle, int64_t ns) {
    return 0;
}

bool SensorBase::hasPendingEvents() const {
    return false;
}

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;
}

这四个函数, 基本上是由子类覆写的.

getFd()得到data_fd句柄

setDelay()设置上报延迟频率

hasPendingEvents()是否还有未上报的事件

getTimestamp()获得时间戳

接下来就是本类最重要的openInput()方法了

int SensorBase::openInput(const char* inputName) {
    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->d_name[1] == '\0' ||
                        (de->d_name[1] == '.' && de->d_name[2] == '\0')))
            continue;
        strcpy(filename, de->d_name);
        fd = open(devname, O_RDONLY);
        if (fd>=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;
}

此方法最终返回的是, 传入的inputName相对应的字符设备的句柄

首先打开的是dirname (jwisp这里是/dev/input/)

打开后,轮询所有的字符节点, 从轮询到的字符节点获取name, 若name与传递来的子类inputName相同则将打开这个设备的句柄返回.

若不相同则关闭其他设备.

版权所有,转载请注明出处。
转载自 <a href="http://www.jwisp.com/?p=113" title="分析一下android2.3中SensorBase.cpp的程序流程" rel="bookmark">分析一下android2.3中SensorBase.cpp的程序流程 | 卓派</a>

我简单说几句


随机推荐

最新评论

固定链接

随机链接