linux中class_create和class_register说明

来源:互联网 发布:蛇吞象是真的吗 知乎 编辑:程序博客网 时间:2024/05/22 00:56
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()实现的。

 

 

 

img生活的悲欢离合永远在地平线以外,而眺望是一种青春的姿态...
PS.文章是笔者分享的学习笔记,若你觉得可以、还行、过得去、甚至不太差的话,可以“推荐”一下的哦。就此谢过!
分类: Driver
标签: linux, class, class_register, class_create, class_unregister, class_destroy
好文要顶关注我 收藏该文
如果天空不死
关注 - 9
粉丝 - 1062
+加关注
0
0
«上一篇:[转载] make menuconfig/.config/Kconfig解析
»下一篇:Android中字符设备驱动和应用实例(一) 驱动部分
posted on 2013-05-15 22:45 如果天空不死 阅读(2835) 评论(0)编辑 收藏
0 0