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

本文详细分析了Android 2.3版本中SensorBase.cpp文件的功能和工作流程,包括构造函数、设备的打开与关闭、上报延迟设置以及时间戳获取等关键操作。特别强调了openInput()方法,该方法通过遍历/dev/input/目录下的字符设备,找到匹配的传感器设备并返回其句柄。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在移植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相同则将打开这个设备的句柄返回.

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

更多: http://www.jwisp.com/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值