[AndroidO] [RK3399] -- Sensor_HAL分析

本文转自:https://blog.csdn.net/new_abc/article/details/8971807

写的优秀,特此记录

首先是sensor这个模块的id定义,主要是实现了一个sensors_module_t结构:

   

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 = "MMA8451Q & AK8973A & gyro Sensors Module",
            .author = "The RKdroid Project",
            .methods = &sensors_module_methods,
        },
        .get_sensors_list = sensors__get_sensors_list
    };


sensors__get_sensors_list函数返回这个平台的所有sensor

  

  static int sensors__get_sensors_list(struct sensors_module_t* module,
            struct sensor_t const** list)
    {
        *list = sSensorList;
        return ARRAY_SIZE(sSensorList);
    }


对应sSensorList是一个sensor_t的结构

 

   static const struct sensor_t sSensorList[] = {
            { "MMA8452Q 3-axis Accelerometer",    
                    "Freescale Semiconductor",
                    1, SENSORS_HANDLE_BASE+ID_A,
                    SENSOR_TYPE_ACCELEROMETER, 4.0f*9.81f, (4.0f*9.81f)/256.0f, 0.2f, 0, { } },
            { "AK8975 3-axis Magnetic field sensor",
                    "Asahi Kasei",
                    1, SENSORS_HANDLE_BASE+ID_M,
                    SENSOR_TYPE_MAGNETIC_FIELD, 2000.0f, 1.0f/16.0f, 6.8f, 0, { } },
            { "AK8975 Orientation sensor",
                    "Asahi Kasei",
                    1, SENSORS_HANDLE_BASE+ID_O,
                    SENSOR_TYPE_ORIENTATION, 360.0f, 1.0f, 7.0f, 0, { } },
     
        { "ST 3-axis Gyroscope sensor",
              "STMicroelectronics",
              1, SENSORS_HANDLE_BASE+ID_GY,
              SENSOR_TYPE_GYROSCOPE, RANGE_GYRO, CONVERT_GYRO, 6.1f, 1190, { } },
                
        { "AL3006Proximity sensor",
            "Dyna Image Corporation",
            1, SENSORS_HANDLE_BASE+ID_P,
            SENSOR_TYPE_PROXIMITY,
            PROXIMITY_THRESHOLD_CM, PROXIMITY_THRESHOLD_CM,
            0.5f, 0, { } },
            
            { "AL3006 light sensor",
                    "Dyna Image Corporation",
                    1, SENSORS_HANDLE_BASE+ID_L,
                    SENSOR_TYPE_LIGHT, 10240.0f, 1.0f, 0.5f, 0, { } },
    };


这个是我手头上的这块板子所提供的sensor

open_sensors用来打开所有的sensor,并返回一个hw_device_t

   

 static int open_sensors(const struct hw_module_t* module, const char* name,
            struct hw_device_t** device)
    {
        return init_nusensors(module, device);
    }


对应init_nusensors

   

 int init_nusensors(hw_module_t const* module, hw_device_t** device)
    {
        D("Entered.");
        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;
    }


首先new 了一个sensors_poll_context_t,然后设置device,并返回
对应new  sensors_poll_context_t我们看一下其实现

   

sensors_poll_context_t::sensors_poll_context_t()
    {
        D("Entered.");
        
        mSensors[light] = new LightSensor();
        mPollFds[light].fd = mSensors[light]->getFd();
        mPollFds[light].events = POLLIN;
        mPollFds[light].revents = 0;
     
        mSensors[proximity] = new ProximitySensor();
        mPollFds[proximity].fd = mSensors[proximity]->getFd();
        mPollFds[proximity].events = POLLIN;
        mPollFds[proximity].revents = 0;
        
     
        mSensors[mma] = new MmaSensor();
        mPollFds[mma].fd = mSensors[mma]->getFd();
        mPollFds[mma].events = POLLIN;
        mPollFds[mma].revents = 0;
     
        mSensors[akm] = new AkmSensor();
        mPollFds[akm].fd = mSensors[akm]->getFd();
        mPollFds[akm].events = POLLIN;
        mPollFds[akm].revents = 0;
     
        mSensors[gyro] = new GyroSensor();
        mPollFds[gyro].fd = mSensors[gyro]->getFd();
        mPollFds[gyro].events = POLLIN;
        mPollFds[gyro].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;
    }


mSensors是一个SensorBase类型的类,而mPollFds是一个pollfd的结构。

mSensors保存了各个打开的sensor,mPollFds用来监听sensor的时候用的。

我们以打开陀螺仪为例,看一下其打开过程

   

GyroSensor::GyroSensor()
        : SensorBase(GY_DEVICE_NAME, "gyro"),
          mEnabled(0),
          mInputReader(32)
    {
        mPendingEvent.version = sizeof(sensors_event_t);
        mPendingEvent.sensor = ID_GY;
        mPendingEvent.type = SENSOR_TYPE_GYROSCOPE;
        mPendingEvent.gyro.status = SENSOR_STATUS_ACCURACY_HIGH;
        memset(mPendingEvent.data, 0x00, sizeof(mPendingEvent.data));
        int err = 0;
        err = open_device();
        err = err<0 ? -errno : 0;
        if(err)
        {
            LOGD("%s:%s\n",__func__,strerror(-err));
            return;
        }
        
        int flags = 0;
        if (!ioctl(dev_fd, L3G4200D_IOCTL_GET_ENABLE, &flags)) {
            if (flags)  {
                mEnabled = 1;
            }
        }
     
        if (!mEnabled) {
            close_device();
        }
    }


mPendingEvent是一个  sensors_event_t结构,首先对其sensor、type等赋值,然后调用open_device打开陀螺仪设备,然后调用ioctlL3G4200D_IOCTL_GET_ENABLE查看sensor是否启用

注意这里不要忽略了SensorBase(GY_DEVICE_NAME, "gyro")

我们看一下它做了什么。

这里GY_DEVICE_NAME对应"/dev/gyrosensor"

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


设置dev_name和data_name后调用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;
     
        return getInput(inputName);
    }


再继续看一下getInput

   

static int getInput(const char *inputName)
    {
        int fd = -1;
        unsigned i;
        static bool first = true;
        static struct input_dev dev[255];
     
        if (first) {
            int fd = -1;
            const char *dirname = "/dev/input";
            char devname[PATH_MAX];
            char *filename;
            DIR *dir;
            struct dirent *de;
     
            first = false;
            for (i = 0; i < sizeof(dev)/sizeof(dev[0]); i++) {
                dev[i].fd = -1;
                dev[i].name[0] = '\0';
            }
            i = 0;
     
            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) {
                        dev[i].fd = fd;
                        strncpy(dev[i].name, name, sizeof(dev[i].name));
                    }
                }
                i++;
            }
            closedir(dir);
        }
     
        for (i = 0; i < sizeof(dev)/sizeof(dev[0]); i++) {
            if (!strncmp(inputName, dev[i].name, sizeof(dev[i].name))) {
                fd = dev[i].fd;
                break;
            }
        }
        LOGE_IF(fd < 0, "couldn't find '%s' input device", inputName);
     
        return fd;
    }


这个函数的作用就是打开"/dev/input",查找其中的输入设备名字与传入参数匹配的那一个,这里是"gyro",并返回相应的打开句柄。

再回到open_device

   

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


这里只是简单的打开设备,对应"/dev/gyrosensor"

 

这样,再回到sensors_poll_context_t的构造函数,就把各个sensor设备都打开了,注意这里的mPollFds. Fd是data_fd,即打开“/dev/input/*”设备的句柄

到这里,sensor就已经打开了。

再看一下其它的函数。

Activate、setDelay都是直接调用相应的sensor接口直接调用相应sensor的接口,主要是pollEvents  

  int sensors_poll_context_t::pollEvents(sensors_event_t* data, int count)
    {
        D("Entered : count = %d", count);
        int nbEvents = 0;
        int n = 0;
     
        do {
            // see if we have some leftover from the last poll()
            for (int i=0 ; count && i<numSensorDrivers ; i++) {//调用各个sensor的readEvents读取数据
                SensorBase* const sensor(mSensors[i]);
                if ((mPollFds[i].revents & POLLIN) || (sensor->hasPendingEvents())) {
                    int nb = sensor->readEvents(data, count);    // num of evens received.
                    D("nb = %d.", nb);
                    if (nb < count) {
                        // no more data for this sensor
                        mPollFds[i].revents = 0;
                    }
                    count -= nb;
                    nbEvents += nb;
                    data += nb;
                    D("count = %d, nbEvents = %d, data = 0x%p.", count, nbEvents, data);
                }
            }
     
            if (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
            D("n =0x%x, count = 0x%x.", n, count);
        } while (n && count);
     

        D("to return : nbEvents = %d", nbEvents);

        return nbEvents;

    }


我们这里看一下GyroSensor的readEvents

   

 int GyroSensor::readEvents(sensors_event_t* data, int count)
    {
        //LOGD("*******************Gyro readEvents");
        //LOGD("count: %d, mHasPendingEvent: %d", count, mHasPendingEvent);
        static int64_t prev_time;
        int64_t time;
     
        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;
        input_event const* event;
        float gyrox = 0, gyroy = 0, gyroz = 0;
     
    #if FETCH_FULL_EVENT_BEFORE_RETURN
    again:
    #endif
        while (count && mInputReader.readEvent(&event)) {//读取当前一个event,返回还有的数据大小
     
            //LOGD("GyroSensor::readEvents() coutn = %d, event->value = %f", count, event->value);
            int type = event->type;
            if (type == EV_REL) {//为事件相对坐标
                float value = event->value;
                if (event->code == EVENT_TYPE_GYRO_X) {
                    gyrox = value;
                } else if (event->code == EVENT_TYPE_GYRO_Y) {
                    gyroy = value;
                } else if (event->code == EVENT_TYPE_GYRO_Z) {
                    gyroz = value;
                }
     
            NineAxisTypeDef nineInput;
                nineInput.ax =  1;
                nineInput.ay =  1;
                nineInput.az =  1000;
                nineInput.mx =  300;
                nineInput.my =  300;
                nineInput.mz =  300;
                nineInput.gx =  gyrox;
                nineInput.gy =  gyroy;
                nineInput.gz =  gyroz;
     
                nineInput.time = getTimestamp()/1000000;
     
                FusionTypeDef fusionData = MEMSAlgLib_Fusion_Update(nineInput);
                float offx, offy, offz;
                MEMSAlgLib_Fusion_Get_GyroOffset(&offx,&offy,&offz);
                //LOGD("gyro offset: %f, %f, %f", offx, offy, offz);
                mPendingEvent.data[0] = (gyrox-offx) * CONVERT_GYRO_X;
                mPendingEvent.data[1] = (gyroy-offy) * CONVERT_GYRO_Y;
                mPendingEvent.data[2] = (gyroz-offz) * CONVERT_GYRO_Z;
     
            mPendingEvent.gyro.x =  mPendingEvent.data[0];
                mPendingEvent.gyro.y =  mPendingEvent.data[1];
                mPendingEvent.gyro.z =  mPendingEvent.data[2];
            //LOGD("mPendingEvent: %f, %f, %f", mPendingEvent.gyro.x, mPendingEvent.gyro.y, mPendingEvent.gyro.z);
            }else if (type == EV_SYN) {//表示Motion的一系列动作结束
               
                time = timevalToNano(event->time);
                if(mEnabled) {
                    mPendingEvent.timestamp = time;
     
                    *data++ = mPendingEvent;
                    count--;
                    numEventReceived++;
                }
     
            }else {
                LOGE("GyroSensor: unknown event (type=%d, code=%d)", type, event->code);
            }
            mInputReader.next();
        }
     
    #if FETCH_FULL_EVENT_BEFORE_RETURN
        /* if we didn't read a complete event, see if we can fill and
           try again instead of returning with nothing and redoing poll. */
        if (numEventReceived == 0 && mEnabled == 1) {
            n = mInputReader.fill(data_fd);
            if (n)
                goto again;
        }
    #endif
     
        return numEventReceived;
    }


这里看一下mInputReader,是一个InputEventCircularReader结构,表示的是一个环形的读入数据缓冲区

   

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);
            // dumpEvents(mHead, numEventsRead);
            D("nread = %ld, numEventsRead = %d.", nread, numEventsRead);
            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;
    }


mCurr表示未读事件的第一个,初始为缓冲区首部

Fill函数是把调用read从相应的输入设备读入数据mHead位置

readEvent函数返回mCurr和剩余的数据大小

next函数让mCurr移一个input_event


到这里,sensor HAL层就分析完了

 


---------------------  
作者:new_abc  
来源:CSDN  
原文:https://blog.csdn.net/new_abc/article/details/8971807  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值