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()\n");
 5        returnpr_info("store\n");
 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()\n");
11        returnpr_info("store\n");
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目錄下刪除一個屬性集合,並刪除集合中的屬性文件

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM