• Android sensor 系统框架 (一)



    这几天深入学习了Android sensor框架,以此博客记录和分享分析过程,其中难免会有错误的地方,欢迎指出!

    这里主要分析KERNEL->HAL->JNI这3层的流程。主要从以下几方面开始着手:
    (A) 驱动层向上提供了那些文件节点给系统层读写?
    (B) 系统层通过什么方式访问驱动层?
    (C) 如何统一各种sensors的接口,生成.so库?
    (D) 如何加载访问.so库 
    (E) 实现sensor service (未写,待续)
    (F) JNI接口 (未写,待续)


    (A) 驱动层向上提供了那些文件节点给系统层读写?
        关于linux基本驱动框架,不在本文范围,这里不再分析。学习过Linux驱动的都知道应用层要访问内核驱动,都是通过open、
    read、write等系统函数操作驱动注册的文件节点进行的。这里以n2dm g-sensor的驱动为例,找出这些文件节点。文件路径:

        ./kernel/drivers/input/misc/n2dm.c

     1     static int n2dm_acc_probe(struct i2c_client *client,const struct i2c_device_id *id)
     2     {
     3         ......
     4         acc->input_dev->name = "accelerometer";
     5         err = input_register_device(acc->input_dev);   /* 生成 /dev/input/event2 */
     6         ......
     7         err = misc_register(&n2dm_acc_misc_device);    /* 生成 /sys/class/n2dm_acc */
     8         ......
     9         gsensor_class = class_create(THIS_MODULE,"xr-gsensor");
    10         gsensor_cmd_dev = device_create(gsensor_class, NULL, 0, NULL, "device");
    11         device_create_file(gsensor_cmd_dev, &dev_attr_gsensor);  /* 生成 /sys/class/xr-gsensor/device/gsensor */
    12         device_create_file(gsensor_cmd_dev, &dev_attr_delay_acc); /* 生成 /sys/class/xr-gsensor/device/delay_acc */
    13         
    14         ......
    15     }

        由以上代码可知,这个驱动生成了/dev/input/event2、/sys/class/n2dm_acc、/sys/class/xr-gsensor/device/gsensor、
    /sys/class/xr-gsensor/device/delay_acc这4个文件节点,其中/sys/class/n2dm_acc文件节点用不到,可以不用理会。其余3
    个文件节点的作用分别是:
    1. /dev/input/event2:驱动通过这个文件节点上报输入事件,如这个是g-sensor传感器,会上报x,y,z三轴事件,数据格式:

    input_report_abs(acc->input_dev, ABS_X, xyz[0]);
    input_report_abs(acc->input_dev, ABS_Y, xyz[1]);
    input_report_abs(acc->input_dev, ABS_Z, xyz[2]);
    input_sync(acc->input_dev);

    2. /sys/class/xr-gsensor/device/gsensor数据格式:

        "1"     /* 使能g-sensor */
        "0"     /* 禁止g-sensor */

    3. /sys/class/xr-gsensor/device/delay_acc数据格式:

        十进制数值  /* g-sensor 数据刷新频率,时间ms */

    (B) 系统层通过什么方式访问驱动层?

        系统层肯定是通过open、read、write、ioctl等函数读写文件节点的方式访问驱动层,读写这些文件节点的代码路径在:

        vendor/sprd/open-source/libs/libsensors_sprd/

        这个目录下是各种传感器,如:g-sensor、光感、陀螺仪等的系统访问驱动的接口文件,这里以g-sensor为例来分析,
    文件路径:

        vendor/sprd/open-source/libs/libsensors_sprd/Acc_Xr.cpp
        vendor/sprd/open-source/libs/libsensors_sprd/AccSensor.h
        vendor/sprd/open-source/libs/libsensors_sprd/InputEventReader.cpp
        vendor/sprd/open-source/libs/libsensors_sprd/InputEventReader.h
        vendor/sprd/open-source/libs/libsensors_sprd/sensors.cpp
        vendor/sprd/open-source/libs/libsensors_sprd/sensors.h

        其中,vendor/sprd/open-source/libs/libsensors_sprd/InputEventReader.cpp文件的作用是为事件读取提供一个环形
    缓冲区,vendor/sprd/open-source/libs/libsensors_sprd/sensors.cpp的作用是抽象所有的sensor为一个sensor hal。

    AccSensor.h

     1     class AccSensor : public SensorBase {
     2     public:
     3                 AccSensor();
     4         virtual ~AccSensor();
     5     
     6     #ifndef ACC_NULL
     7         enum {
     8             Accelerometer = 0,
     9             numSensors
    10         };
    11     #else
    12         static const int numSensors = 0;
    13     #endif
    14     
    15         virtual int readEvents(sensors_event_t* data, int count);
    16         virtual bool hasPendingEvents() const;
    17         virtual int setDelay(int32_t handle, int64_t ns);
    18         virtual int setEnable(int32_t handle, int enabled);
    19         virtual int64_t getDelay(int32_t handle);
    20         virtual int getEnable(int32_t handle);
    21         virtual int populateSensorList(struct sensor_t *list);
    22     private:
    23         int mEnabled;
    24         int64_t mDelay;
    25         int mLayout;
    26         InputEventCircularReader mInputReader;
    27         sensors_event_t mPendingEvent;
    28         bool mHasPendingEvent;
    29         char input_sysfs_path[PATH_MAX];
    30         int input_sysfs_path_len;
    31     
    32         int setInitialState();
    33         SensorCoordinate mSensorCoordinate;
    34     };

        AccSensor.h 文件定义了一个AccSensor类,派生于SensorBase,而Acc_Xr.cpp就是实现了这个类里面的方法

        Acc_Xr.cpp

     1     AccSensor::AccSensor() :
     2         SensorBase(NULL, XR_ACC_INPUT_NAME),
     3             mEnabled(0), mDelay(-1), mInputReader(32), mHasPendingEvent(false),
     4             mSensorCoordinate()
     5     {
     6         ......
     7         mPendingEvent.sensor = ID_A;
     8         ......
     9     
    10         strcpy(input_sysfs_path, XR_GSENSOR_DEVICE_NAME);
    11         input_sysfs_path_len = strlen(input_sysfs_path);
    12         ......
    13         
    14         /* AccSensor的构造函数主要做了:
    15          * 1. 构造SensorBase,扫描所有的/dev/input/event*,并判断该文件节点下是否存在一个名为XR_ACC_INPUT_NAME
    16          *    (accelerometer)的输入设备,我的设备是/dev/input/event2,如果存在,则返回该文件节点的fd
    17          * 2. 获得input_sysfs_path文件节点为XR_GSENSOR_DEVICE_NAME(/sys/class/xr-gsensor/device/)
    18          * 3. 初始化一个环形缓冲区
    19          * 4. 设置sensor类型ID_A
    20          */
    21     }    
    22         
    23     int AccSensor::setEnable(int32_t handle, int enabled) 
    24     {
    25         ......
    26         if(enabled==1)
    27         strcpy(enable,"1");                                                                                        
    28         else if(enabled==0)                                                                                        
    29         strcpy(enable,"0");                                                                                        
    30         else 
    31         strcpy(enable,"2");
    32         ......
    33         
    34         /* 设置sensor状态,1:使能,0:禁止 
    35          * 把状态值写到文件节点:/sys/class/xr-gsensor/device/gsensor
    36          */
    37         strcpy(&input_sysfs_path[input_sysfs_path_len], "gsensor");
    38         err = write_sys_attribute(input_sysfs_path, enable, 1);
    39         ......
    40         mEnabled &= ~(1);
    41         mEnabled |= uint32_t(newState);
    42         
    43         ......
    44     }
    45 
    46 
    47     int AccSensor::setDelay(int32_t handle, int64_t delay_ns)
    48     {
    49         ......
    50         ms = delay_ns / 1000000;
    51         strcpy(&input_sysfs_path[input_sysfs_path_len], "delay_acc");
    52         bytes = sprintf(buffer, "%d", ms);
    53         write_sys_attribute(input_sysfs_path, buffer, bytes);
    54         ......
    55     }
    56     
    57     
    58     int AccSensor::readEvents(sensors_event_t * data, int count)
    59     {
    60         ......
    61         /* 从文件节点/dev/input/event2中读取驱动层提交的事件,
    62          * 并写入环形队列
    63          */
    64         ssize_t n = mInputReader.fill(data_fd);
    65         ......
    66         /* 从队列中取出一个事件 */
    67         while (count && mInputReader.readEvent(&event)) {
    68             ......
    69             /* 写入到sensors_event_t缓冲区 */
    70             *data++ = mPendingEvent;
    71             count--;
    72             numEventReceived++;
    73             ......
    74             /* 指向下一个事件 */
    75             mInputReader.next();
    76         }
    77         
    78         return numEventReceived;
    79     }
    80     
    81     
    82     int AccSensor::populateSensorList(struct sensor_t *list)
    83     {
    84         /* 把该sensor加入list链表 
    85          * 所有的sensor都要加入到这个链表,以便统一管理
    86          */
    87         memcpy(list, sSensorList, sizeof(struct sensor_t) * numSensors);
    88         return numSensors;
    89     }

    (C) 如何统一各种sensors的接口,生成.so库?

        通过vendor/sprd/open-source/libs/libsensors_sprd/sensors.cpp 和
    vendor/sprd/open-source/libs/libsensors_sprd/sensors.h 统一管理所有
    sensor,抽象所有接口

        sensors.cpp

      1     static int sensors__get_sensors_list(struct sensors_module_t *module,
      2                          struct sensor_t const **list)
      3     {
      4         /* 获取sensor链表首指针 */
      5         *list = sSensorList;
      6         /* 返回该sensor总数 */
      7         return numSensors;
      8     }
      9     
     10     static struct hw_module_methods_t sensors_module_methods = {
     11     open:   open_sensors
     12     };
     13 
     14     /* sensors.cpp最终的目的就是要构造这个结构体 */   
     15     struct sensors_module_t HAL_MODULE_INFO_SYM = {                                                                
     16             common:{
     17                     tag: HARDWARE_MODULE_TAG,                                                                      
     18                     version_major: 1,                                                                              
     19                     version_minor: 0,
     20                     /* 加载so库时,是通过SENSORS_HARDWARE_MODULE_ID
     21                      * 找到这个结构体
     22                      */
     23                     id: SENSORS_HARDWARE_MODULE_ID,                                                                
     24                     name: "SPRD Sensor module",                                                                    
     25                     author: "Spreadtrum",
     26                     methods: &sensors_module_methods,                                                              
     27                     dso: 0,
     28                     reserved:{},                                                                                   
     29             },
     30             get_sensors_list:sensors__get_sensors_list,                                                            
     31     }; 
     32 
     33 
     34     sensors_poll_context_t::sensors_poll_context_t()
     35     {
     36         /* 实例化一个AccSensor类的对象 
     37          * 这个对象代表一个g-sensor
     38          */
     39         mSensors[acc] = new AccSensor();
     40         /* 获得sensor索引 */
     41         numSensors +=
     42             mSensors[acc]->populateSensorList(sSensorList + numSensors);
     43         /* 读取/dev/input/event2节点的fd */
     44         mPollFds[acc].fd = mSensors[acc]->getFd();
     45         /* 有数据输入就产生POLLIN事件 */
     46         mPollFds[acc].events = POLLIN;
     47         mPollFds[acc].revents = 0;
     48         ......
     49         
     50         /* 实例化一个磁力计对象 */
     51         mSensors[ori] = new OriSensor();                                                                           
     52         numSensors +=                                                                                              
     53             mSensors[ori]->populateSensorList(sSensorList + numSensors);                                           
     54         mPollFds[ori].fd = mSensors[ori]->getFd();                                                                 
     55         mPollFds[ori].events = POLLIN;                                                                             
     56         mPollFds[ori].revents = 0;  
     57         
     58         /* 实例化一个光感对象 */  
     59         ......
     60         
     61         /* 以下创建的管道,感觉没啥用,多余的
     62          * 因为在activate中写管道,在pollEvent中度管道,
     63          * 读到消息后并没有做什么相关处理,有知道的兄弟
     64          * 麻烦指教一下,非常感谢!
     65          */
     66         int wakeFds[2];
     67         /* 创建一个管道 */
     68         int result = pipe(wakeFds);
     69         ALOGE_IF(result < 0, "error creating wake pipe (%s)", strerror(errno));
     70         fcntl(wakeFds[0], F_SETFL, O_NONBLOCK);
     71         fcntl(wakeFds[1], F_SETFL, O_NONBLOCK);
     72         /* 写管道的fd */
     73         mWritePipeFd = wakeFds[1];
     74         
     75         /* 读管道的fd */
     76         mPollFds[wake].fd = wakeFds[0];
     77         mPollFds[wake].events = POLLIN;
     78         mPollFds[wake].revents = 0;  
     79     }
     80     
     81     
     82     int sensors_poll_context_t::activate(int handle, int enabled)
     83     {
     84         /* 获得sensor类型 */
     85         int drv = handleToDriver(handle);
     86         ......
     87         /* 使能该sensor,如:如果这是g-sensor,则调用的是
     88          * AccSensor::setEnable(int32_t handle, int enabled) 
     89          */
     90         err = mSensors[drv]->setEnable(handle, enabled);
     91         /* 往管道写一个WAKE_MESSAGE消息 */
     92         const char wakeMessage(WAKE_MESSAGE);
     93         int result = write(mWritePipeFd, &wakeMessage, 1);
     94     }
     95 
     96 
     97     int sensors_poll_context_t::setDelay(int handle, int64_t ns)
     98     {
     99         ......
    100         return setDelay_sub(handle, ns);
    101     }
    102     
    103     int sensors_poll_context_t::setDelay_sub(int handle, int64_t ns)
    104     {
    105         /* 获得sensor类型 */
    106         int drv = handleToDriver(handle);
    107         
    108         /* 获取sensor的状态,使能还是禁止
    109          * 如:如果这是g-sensor,则调用的是
    110          * AccSensor::getEnable(int32_t handle)
    111          */
    112         int en = mSensors[drv]->getEnable(handle);
    113         /* 获取sensor的输入事件频率
    114          * 如:如果这是g-sensor,则调用的是
    115          * AccSensor::getDelay(int32_t handle) 
    116          */
    117         int64_t cur = mSensors[drv]->getDelay(handle);
    118         ......
    119         
    120         /* 设置sensor的输入事件频率
    121          * 如:如果这是g-sensor,则调用的是
    122          * AccSensor::setDelay(int32_t handle, int64_t delay_ns)
    123          */
    124         err = mSensors[drv]->setDelay(handle, ns);  
    125         ......
    126     }
    127     
    128     
    129     int sensors_poll_context_t::pollEvents(sensors_event_t * data, int count)
    130     {
    131         ......
    132         do {
    133             /* 轮询读各个sensor的输入事件 */
    134             for (int i = 0; count && i < numSensorDrivers; i++) {
    135                 SensorBase *const sensor(mSensors[i]);
    136                 ......
    137                 /* 读事件 */
    138                 int nb = sensor->readEvents(data, count);
    139                 ....
    140                 count -= nb;
    141                 nbEvents += nb;                                                                                
    142                 data += nb; 
    143             }
    144             /* 还有事件没读完 */
    145             if (count) { 
    146                 do {
    147                     /* 休眠等待事件输入,如果超时则退出 */
    148                     n = poll(mPollFds, numFds,
    149                         nbEvents ? 0 : polltime);                                                                 
    150                 } while (n < 0 && errno == EINTR);  
    151                 
    152                 if (mPollFds[wake].revents & POLLIN) {
    153                     ......
    154                     /* 从管道读出msg,然而什么都没干,why? */
    155                     int result = read(mPollFds[wake].fd, &msg, 1);
    156                     ......
    157                 }
    158             }
    159        } while (n && count);
    160          
    161        return nbEvents;
    162     }
    163     
    164     static int poll__activate(struct sensors_poll_device_t *dev,
    165                   int handle, int enabled)
    166     {
    167         sensors_poll_context_t *ctx = (sensors_poll_context_t *) dev;
    168         return ctx->activate(handle, enabled);
    169     }
    170     
    171     static int poll__setDelay(struct sensors_poll_device_t *dev,
    172                   int handle, int64_t ns)
    173     {
    174         sensors_poll_context_t *ctx = (sensors_poll_context_t *) dev;
    175         return ctx->setDelay(handle, ns);
    176     }
    177     
    178     static int poll__poll(struct sensors_poll_device_t *dev,
    179                   sensors_event_t * data, int count)
    180     {
    181         sensors_poll_context_t *ctx = (sensors_poll_context_t *) dev;
    182         return ctx->pollEvents(data, count);
    183     }
    184 
    185 
    186     /** Open a new instance of a sensor device using name */
    187     static int open_sensors(const struct hw_module_t *module, const char *id,
    188                 struct hw_device_t **device)
    189     {
    190         int status = -EINVAL;
    191         sensors_poll_context_t *dev = new sensors_poll_context_t();
    192     
    193         memset(&dev->device, 0, sizeof(sensors_poll_device_t));
    194         
    195         /* 构造sensors_poll_context_t结构体 */
    196         dev->device.common.tag = HARDWARE_DEVICE_TAG;
    197         dev->device.common.version = 0;
    198         dev->device.common.module = const_cast < hw_module_t * >(module);
    199         dev->device.common.close = poll__close;
    200         dev->device.activate = poll__activate;
    201         dev->device.setDelay = poll__setDelay;
    202         dev->device.poll = poll__poll;
    203     
    204         *device = &dev->device.common;
    205         status = 0;
    206     
    207         return status;
    208     }

        Android.mk

        

        ......
        LOCAL_MODULE := sensors.$(TARGET_BOARD_PLATFORM)  #这里的TARGET_BOARD_PLATFORM是sc8830
        ......

    mmm ./vendor/sprd/open-source/libs/libsensors_sprd -B
    生成sensors.sc8830.so

    这样就实现了硬件和应用的分离,应用要访问硬件是只要加载这个so库就行了

  • 相关阅读:
    数据结构_bubble_sort
    数据结构_sfdg(小F打怪)
    数据结构_yjjsj(伊姐姐数字游戏)
    数据结构 queue
    数据结构 Job
    数据结构 happiness
    数据结构_calculator
    js并归排序的思路
    js神秘的电报密码---哈弗曼编码
    js同时获得数组的两个最小值
  • 原文地址:https://www.cnblogs.com/hackfun/p/7327320.html
Copyright © 2020-2023  润新知