• sysfs_create_group创建sysfs接口


    在调试驱动,可能需要对驱动里的某些变量进行读写,或函数调用。可通过sysfs接口创建驱动对应的属性,使得可以在用户空间通过sysfs接口的show和store函数与硬件交互;

    Syss接口可通过sysfs_create_group()来创建,如果设备驱动要创建,需要用到函数宏DEVICE_ATTR;

    另外总线对应BUS_ATTR、设备驱动对应DRIVER_ATTR、类(class)对应CLASS_ATTR,均在kernel/include/linux/device.h下定义:

     1 //下面的show和store只是简单举例
     2 static ssize_t gpio_show(struct device *d, struct device_attribute*attr, char *buf)
     3 {
     4        printk("gpio_show()
    ");
     5        returnpr_info("store
    ");
     6 }
     7  
     8 static ssize_t gpio_store(struct device *d, struct device_attribute *attr,const char *buf,size_t count)
     9 {
    10        printk("gpio_store()
    ");
    11        returnpr_info("store
    ");
    12 }
    13  
    14 //用DEVICE_ATTR宏创建属性gpio文件,如果show()或是store()没有功能,就以NULL代替
    15 static DEVICE_ATTR(gpio, S_IWUSR |S_IRUGO, gpio_show, gpio_store);
    16  
    17 //属性结构体数组最后一项必须以NULL结尾。
    18 static struct attribute *gpio_attrs[] = {
    19        &dev_attr_gpio.attr,
    20        NULL
    21 };

    DEVICE_ATTR:

    DEVICE_ATTR 的定义DEVICE_ATTR(_name,_mode, _show, _store);可知这里gpio是name,mode是S_IWUSR |S_IRUGO,读操作_show是gpio_show函数,写操作_store 是gpio_store函数;

    因为:

    1 #define DEVICE_ATTR(_name, _mode, _show, _store) 
    2     struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)

    device_attribute:

    1 /* interface for exporting device attributes */
    2 struct device_attribute {
    3     struct attribute    attr;
    4     ssize_t (*show)(struct device *dev, struct device_attribute *attr,
    5             char *buf);
    6     ssize_t (*store)(struct device *dev, struct device_attribute *attr,
    7              const char *buf, size_t count);
    8 };

    Mode是权限位,在kernel/include/uapi/linux/stat.h;

     1 #define S_IRWXU 00700 //用户可读写和执行
     2 #define S_IRUSR 00400//用户可读
     3 #define S_IWUSR 00200//用户可写
     4 #define S_IXUSR 00100//用户可执行
     5  
     6 #define S_IRWXG 00070//用户组可读写和执行
     7 #define S_IRGRP 00040//用户组可读
     8 #define S_IWGRP 00020//用户组可写
     9 #define S_IXGRP 00010//用户组可执行
    10  
    11 #define S_IRWXO 00007//其他可读写和执行
    12 #define S_IROTH 00004//其他可读
    13 #define S_IWOTH 00002//其他可写
    14 #define S_IXOTH 00001//其他可执行

    device_attribute结构体

    为了使对属性的读写变得有意义,一般将attribute结构嵌入到其他数据结构中。子系统通常都会定义自己的属性结构,并且提供添加和删除属性文件的包装函数,比如设备属性结构体定义:

    1 /* interface for exporting device attributes */  
    2 struct device_attribute {  
    3        struct attribute    attr;  
    4        ssize_t (*show)(structdevice *dev, struct device_attribute *attr,  
    5                      char*buf);  
    6        ssize_t (*store)(structdevice *dev, struct device_attribute *attr,  
    7                       const char *buf, size_t count);  
    8 };

    2.     定义attribute属性结构体数组到属性组中:

     1 static const struct attribute_group gpio_attr_grp = {
     2        .attrs = gpio_attrs,
     3 }
     4 我们这里只有一个属性结构体数组只有一个成员,可以有多个,比如:
     5 static struct attribute *gpio_keys_attrs[] = {
     6        &dev_attr_keys.attr,
     7        &dev_attr_switches.attr,
     8        &dev_attr_disabled_keys.attr,
     9        &dev_attr_disabled_switches.attr,
    10        &dev_attr_test.attr,
    11        NULL,
    12 };

    属性attribute结构体定义:

    1 struct attribute {  
    2        const char           *name;  
    3        umode_t                     mode;  
    4 #ifdef CONFIG_DEBUG_LOCK_ALLOC  
    5        bool                     ignore_lockdep:1;  
    6        struct lock_class_key *key;  
    7        struct lock_class_key skey;  
    8 #endif  
    9 };

    创建sysfs接口后,就可以在adb shell 终端查看到和操作接口了。当我们将数据 echo 到接口中时,在用户空间完成了一次 write 操作,对应到 kernel ,调用了驱动中的”store”。当我们cat一个接口时则会调用”show” 。这样就建立了 android 层到 kernel 的桥梁,操作的细节在”show”和”store” 中完成的。

    3.     创建属性文件的sysfs接口:

    1 ret = sysfs_create_group(&pdev->dev.kobj,&gpio_attr_grp);
    2 sysfs_create_group()在kobj目录下创建一个属性集合,并显示集合中的属性文件。如果文件已存在,会报错。
    3  
    4 //删除接口
    5 sysfs_remove_group(&pdev->dev.kobj,&gpio_keys_attr_group);
    6 sysfs_remove_group()在kobj目录下删除一个属性集合,并删除集合中的属性文件

     

     
  • 相关阅读:
    PMP CMM
    PM过程的一些典型场景和问题
    PMP的六大管理学定律
    项目经理面试指南
    Sd
    Java 对象池实现
    Java 线程池的实现
    Sd
    Sd
    02.JSP的3个编译指令
  • 原文地址:https://www.cnblogs.com/linhaostudy/p/8377895.html
Copyright © 2020-2023  润新知