Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3169974
  • 博文数量: 685
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5303
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-19 14:17
个人简介

文章分类

全部博文(685)

文章存档

2015年(116)

2014年(569)

分类: LINUX

2014-08-21 13:40:16

原文地址:http://blog.csdn.net/angle_birds/article/details/16802099

本文介绍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   
2 #include   
3 #include   
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");
复制代码

 

4 class_register()使用示例

示例二,通过class_register()、class_unregister()去注册和注销/sys/class/my_char_dev

代码如下:

复制代码
 1 #include   2 #include   3 #include   4 #include   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");
复制代码

 

附录一,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 })

 

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 }
复制代码

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 }
复制代码

 

 

下面,我们查看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 })

 

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 } 
复制代码

 

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 }

 

实际上,__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 } 
复制代码

 

实际上,class_destroy()是通过调用class_unregister()实现的。


阅读(1087) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~