Linux驱动之设备模型(7)

8.类

8.1  class

l  Class是对设备按照功能进行的分类,这样做是为了给用户空间提供一个比较友好的界面。Class也是一个kset,对应于/sys/class下的一个目录

int __initclasses_init(void)

{

         /* 对应/sys/class目录 */

         class_kset =kset_create_and_add("class", NULL, NULL);

         if (!class_kset)

                   return -ENOMEM;

         return 0;

}

 

l  在设备模型中类由class结构表示

struct class {

         const char                  *name;         /* 类名 */

         struct module           *owner;

 

         struct class_attribute               *class_attrs; /* 类属性 */

         struct device_attribute            *dev_attrs;  /* 类设备属性 */

         struct bin_attribute                   *dev_bin_attrs;

         struct kobject                     *dev_kobj;

         /* 当设备添加时被调用,产生uevent添加相应的环境变量 */

         int (*dev_uevent)(struct device *dev,struct kobj_uevent_env *env);

         char *(*devnode)(struct device *dev,mode_t *mode);

 

         void (*class_release)(struct class*class);  /* 注销类时调用 */

         void (*dev_release)(struct device*dev);  /* 设备移除时调用 */

 

                   /*电源管理 */

         const struct dev_pm_ops *pm;

 

         /* 私有数据:内嵌的kset,设备kset,驱动kset,设备链,驱动链 */

         struct subsys_private *p;

};

 

8.2    Class属性

l  Class属性用class_attribute来表示

structclass_attribute {

         struct attribute attr;

         ssize_t (*show)(struct class *class,struct class_attribute *attr,

                            char *buf);

         ssize_t (*store)(struct class *class,struct class_attribute *attr,

                            const char *buf,size_t count);

};                                    

CLASS_ATTR(_name,_mode, _show, _store)

l  属性操作

int __must_checkclass_create_file(struct class *class,

                                                 const struct class_attribute *attr);

voidclass_remove_file(struct class *class,

                                  const struct class_attribute *attr);

 

8.3    Class基本操作

l  class注册和注销

intclass_register(struct class *class);

voidclass_unregister(struct class *class);

 

l  class创建和销毁

struct class*class_create(struct module *owner, const char *name)

voidclass_destroy(struct class *cls);

        

l  向类添加设备和删除设备

struct device*device_create(struct class *class, struct device *parent,

                                 dev_t devt, void *drvdata, const char*fmt, ...)

         voiddevice_destroy(struct class *class, dev_t devt)

         devt:设备号

 

8.4  实例解析

/*

* for learn class

*/

#include <linux/init.h>

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/device.h>

 

static char *Version = "revision 1.0,scclass";

 

/* 定义一个类,并将符号导出 */

struct class *scclass;

EXPORT_SYMBOL_GPL(scclass);

 

/*

* export class attribute

*/

static ssize_t class_show_version(structclass *class,

                                     structclass_attribute *attr, char *buf)

{

         returnsprintf(buf, "%s\n", Version);

}

CLASS_ATTR(version, 0666,class_show_version, NULL);

 

static int __init scclass_init(void)

{

         interr;

 

         /*创建名为scclass类 */

         scclass= class_create(THIS_MODULE, "scclass");

         err= PTR_ERR(scclass);

         if(IS_ERR(scclass))

                   returnerr;

         /*创建属性文件version */

         err= class_create_file(scclass, &class_attr_version);

         if(err)

                   gotoerr_class_create;

 

         printk("classcreate\n");

         return0;

 

err_class_create:

         class_destroy(scclass);

         returnerr;

}

 

static void __exit scclass_exit(void)

{

         class_remove_file(scclass,&class_attr_version);

         class_destroy(scclass);

         printk("classdestory\n");

}

 

module_init(scclass_init);

module_exit(scclass_exit);

 

MODULE_LICENSE("GPL");

MODULE_AUTHOR("CJOK<cjok.liao@gmail.com>");

上面代码只是创建一个类,我们还需要向类里添加设备,修改设备代码:

@@ -8,6 +8,7 @@


 extern struct bus_type scbus_type;
 extern struct device scbus;
+extern struct class *scclass;


 static char *Version = "revision 1.0, scdevice";


@@ -45,6 +46,8 @@
    ret = device_create_file(&scdevice, &dev_attr_version);
    if (ret)
        goto err_create;
+   
+   device_create(scclass, NULL, 0, 0, "scdevice0");


    printk("Create a scdevice");
    return 0;
@@ -56,6 +59,7 @@


 static void __exit scdevice_exit(void)
 {
+   device_destroy(scclass, 0);
    device_remove_file(&scdevice, &dev_attr_version);

灰色为添加的代码

 

试验结果:



  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值