zoukankan      html  css  js  c++  java
  • linux中class_create和class_register说明

    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 <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!
    ");
    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 <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
    ", __func__ );
    12     kfree(cls);
    13 }
    14 
    15 static int __init class_create_destroy_init(void)
    16 {
    17     printk("%s
    ", __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!
    ");
    26         return -1;
    27     }
    28     printk("create mem class success
    ");
    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!
    ");
    40         kfree(mem_class);
    41         return -1;    
    42     }
    43     printk("class_register success
    ");
    44 
    45 
    46     return 0;
    47 }
    48 
    49 static void __exit class_create_destroy_exit(void)
    50 {
    51     printk("%s
    ", __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
    ", 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
    ", 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
    ", __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()实现的。

  • 相关阅读:
    在VS2008中使用WSE 3.0【转】
    .Net调用Java端带有WS-Security支持的Web Service各方案实战【转】
    Java与WCF交互(一):Java客户端调用WCF服务 【转】
    Java与WCF交互(二):WCF客户端调用Java web service【转】
    c#调用带有安全认证的java webservice
    利用Web Services开发分布式应用
    注册dll文件
    Oracle:"ORA-00942: 表或视图不存在"
    sql_server角色成员身份权限
    10013: 以一种访问权限不允许的方式做了一个访问套接字的尝试【WCF异常】
  • 原文地址:https://www.cnblogs.com/jingzhishen/p/3998247.html
Copyright © 2011-2022 走看看