linux中class_create和class_register說明


linux中class_create和class_register說明

 

本文介紹linux中class_create和class_register的相關使用方法

1 class結構體介紹

    內核中定義了struct class結構體,顧名思義,一個struct class結構體類型變量對應一個類,內核同時提供了class_create(…)函數,可以用它來創建一個類,這個類存放於sysfs下面,一旦創建好了這個類,再調用device_create(…)函數來在/dev目錄下創建相應的設備節點。這樣,加載模塊的時候,用戶空間中的udev會自動響應device_create(…)函數,去/sysfs下尋找對應的類從而創建設備節點。

 

2 class相關API說明

如下表:

 

3 class_create()使用示例

示例一,通過class_create()、class_destroy()去注冊和注銷/sys/class/my_char_dev

代碼如下:

 1 #include <linux/module.h>
 2 #include <linux/init.h>
 3 #include <linux/device.h>
 4 
 5 struct class *mem_class;
 6 
 7 static int __init class_create_destroy_init(void)
 8 {
 9     // class_create動態創建設備的邏輯類,並完成部分字段的初始化,然后將其添加到內核中。創建的邏輯類位於/sys/class/。
10     // 參數:
11     //        owner, 擁有者。一般賦值為THIS_MODULE。
12     //        name, 創建的邏輯類的名稱。
13     mem_class = class_create(THIS_MODULE, "my_char_dev");
14     if (mem_class==NULL)
15     {
16         printk("<0> create class failed!\n");
17         return -1;
18     }
19 
20     return 0;
21 }
22 
23 static void __exit class_create_destroy_exit(void)
24 {
25     if (mem_class != NULL) 
26     {
27         class_destroy(mem_class);
28         mem_class = NULL;
29     }
30 
31 }
32 
33 module_init(class_create_destroy_init);
34 module_exit(class_create_destroy_exit);
35 
36 MODULE_LICENSE("GPL");
View Code

 

4 class_register()使用示例

示例二,通過class_register()、class_unregister()去注冊和注銷/sys/class/my_char_dev

代碼如下:

 1 #include <linux/module.h>
 2 #include <linux/init.h>
 3 #include <linux/device.h>
 4 #include <linux/slab.h>
 5 
 6 #define CLASS_NAME "my_char_dev"
 7 struct class *mem_class;
 8 
 9 static void class_create_release (struct class *cls)
10 {
11     printk("%s\n", __func__ );
12     kfree(cls);
13 }
14 
15 static int __init class_create_destroy_init(void)
16 {
17     printk("%s\n", __func__);
18 
19     int ret;
20 
21     // 申請class結構體內存
22     mem_class = kzalloc(sizeof(*mem_class), GFP_KERNEL);
23     if (mem_class == NULL) 
24     {
25         printk("create mem class failed!\n");
26         return -1;
27     }
28     printk("create mem class success\n");
29 
30     mem_class->name = CLASS_NAME;
31     mem_class->owner = THIS_MODULE;
32     // 注銷時class時的回調函數,在此回調函數中釋放之前所分配的class結構體內存
33     mem_class->class_release = class_create_release;
34 
35     // 將class注冊到內核中,同時會在/sys/class/下創建class對應的節點
36     int retval = class_register(mem_class);
37     if (ret) 
38     {
39         printk("class_register failed!\n");
40         kfree(mem_class);
41         return -1;    
42     }
43     printk("class_register success\n");
44 
45 
46     return 0;
47 }
48 
49 static void __exit class_create_destroy_exit(void)
50 {
51     printk("%s\n", __func__);
52 
53     if (mem_class != NULL) 
54     {
55         class_unregister(mem_class);
56         mem_class = NULL;
57     }
58 }
59 
60 module_init(class_create_destroy_init);
61 module_exit(class_create_destroy_exit);
62 
63 MODULE_LICENSE("GPL");
View Code

 

附錄一,class_create()和class_register()對比

實際上,示例一和示例二是等價的。具體的可以通過查看class_create()和class_register()、class_destroy()和class_unregister()的源碼去驗證。

class_register()的代碼如下:

1 // 將class注冊到/sys/class/中
2 #define class_register(class)           \ 
3 ({                      \ 
4     static struct lock_class_key __key; \ 
5     __class_register(class, &__key);    \ 
6 })
View Code

 

class_register()是通過調用__class_register()來注冊到sysfs中的。

__class_register()的代碼如下:

 1 int __class_register(struct class *cls, struct lock_class_key *key) 
 2 { 
 3     struct class_private *cp; 
 4     int error; 
 5  
 6     pr_debug("device class '%s': registering\n", cls->name); 
 7  
 8     cp = kzalloc(sizeof(*cp), GFP_KERNEL); 
 9     if (!cp) 
10         return -ENOMEM; 
11     klist_init(&cp->class_devices, klist_class_dev_get, klist_class_dev_put); 
12     INIT_LIST_HEAD(&cp->class_interfaces); 
13     kset_init(&cp->class_dirs); 
14     __mutex_init(&cp->class_mutex, "struct class mutex", key); 
15     error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name); 
16     if (error) { 
17         kfree(cp); 
18         return error; 
19     } 
20  
21     /* set the default /sys/dev directory for devices of this class */ 
22     if (!cls->dev_kobj) 
23         cls->dev_kobj = sysfs_dev_char_kobj; 
24  
25 #if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK) 
26     /* let the block class directory show up in the root of sysfs */ 
27     if (cls != &block_class) 
28         cp->class_subsys.kobj.kset = class_kset; 
29 #else 
30     cp->class_subsys.kobj.kset = class_kset; 
31 #endif 
32     cp->class_subsys.kobj.ktype = &class_ktype; 
33     cp->class = cls; 
34     cls->p = cp; 
35 
36     // 將class注冊到內核中
37     error = kset_register(&cp->class_subsys); 
38     if (error) { 
39         kfree(cp); 
40         return error; 
41     } 
42     error = add_class_attrs(class_get(cls)); 
43     class_put(cls); 
44     return error; 
45 }
View Code

class_unregister()的代碼如下:

1 void class_unregister(struct class *cls) 
2 { 
3     pr_debug("device class '%s': unregistering\n", cls->name); 
4     remove_class_attrs(cls); 
5     // 將class從內核中注銷
6     kset_unregister(&cls->p->class_subsys); 
7 }
View Code

 

 

下面,我們查看class_create()、class_destroy()的相關代碼。

class_create()的代碼如下:

1 #define class_create(owner, name)       \ 
2 ({                      \ 
3     static struct lock_class_key __key; \ 
4     __class_create(owner, name, &__key);    \ 
5 })
View Code

 

class_create()是通過調用__class_create()注冊到內核中的。

__class_create()的代碼如下:

 1 struct class *__class_create(struct module *owner, const char *name, 
 2                  struct lock_class_key *key) 
 3 { 
 4     struct class *cls; 
 5     int retval; 
 6  
 7     // 分配class結構體
 8     cls = kzalloc(sizeof(*cls), GFP_KERNEL); 
 9     if (!cls) { 
10         retval = -ENOMEM; 
11         goto error; 
12     } 
13  
14     cls->name = name; 
15     cls->owner = owner; 
16     // class對應的釋放函數,在class從內核中注銷時會執行該函數
17     cls->class_release = class_create_release; 
18      
19     // 通過調用__class_register()將class注冊到內核中
20     retval = __class_register(cls, key); 
21     if (retval) 
22         goto error; 
23      
24     return cls; 
25      
26 error: 
27     kfree(cls); 
28     return ERR_PTR(retval); 
29 } 
View Code

 

class_create_release的代碼如下:

1 static void class_create_release(struct class *cls) 
2 { 
3     pr_debug("%s called for %s\n", __func__, cls->name); 
4     // 釋放class結構體
5     kfree(cls); 
6 }
View Code

 

實際上,__class_create()是通過調用__class_register()注冊到sysfs中的!所以,本質上,class_create()和class_register()的作用是類似的。

class_destroy()的代碼如下:

1 void class_destroy(struct class *cls) 
2 { 
3     if ((cls == NULL) || (IS_ERR(cls))) 
4         return; 
5     // 調用class_unregister()將class從內核中注銷
6     class_unregister(cls); 
7 } 
View Code

 

實際上,class_destroy()是通過調用class_unregister()實現的。

 

 

 


免責聲明!

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



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