Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1069791
  • 博文数量: 71
  • 博客积分: 3078
  • 博客等级: 少校
  • 技术积分: 945
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-16 20:10
个人简介

此博客已停用 个人博客: Mangogeek.com

文章分类
文章存档

2016年(1)

2015年(32)

2014年(25)

2011年(13)

分类: LINUX

2014-09-03 08:01:54

原文地址:linux class device 作者:steven_miao

linux  class device

谨以此文纪念过往的岁月。

1.class的创建
linux class顾名思义就是类,何所谓类呢?就是一组设备具有共同性而抽象出来的。这个概念在C++中很常见。linux中借用这个来管理一组类似的设备。
在linux中采用class_create来创建一个新类。

抓住主干来分析函数
struct class *__class_create(struct module *owner, const char *name,struct lock_class_key *key)
{
 struct class *cls;
 int retval;

 cls = kzalloc(sizeof(*cls), GFP_KERNEL);
 cls->name = name;                              --设置类名
 cls->owner = owner;                            --设置所有者
 cls->class_release = class_create_release;     --设置释放函数

 retval = __class_register(cls, key);           --这个是负责class的注册。
 return cls;
}
在linux中dev->kobj.kset指向其父的kset,dev->kobj.parent=&parent.kobj,同时会采用链表的办法实现设备兄弟之间的关系。
int __class_register(struct class *cls, struct lock_class_key *key)
{
 struct class_private *cp;
 int error;

 pr_debug("device class '%s': registering\n", cls->name);

 cp = kzalloc(sizeof(*cp), GFP_KERNEL);
 if (!cp)
  return -ENOMEM;
 klist_init(&cp->class_devices, klist_class_dev_get, klist_class_dev_put);
 INIT_LIST_HEAD(&cp->class_interfaces);
 kset_init(&cp->class_dirs);                  --这个是创建该class的kset
 __mutex_init(&cp->class_mutex, "struct class mutex", key);
 error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name); 
 if (error) {
  kfree(cp);
  return error;
 }

 /* set the default /sys/dev directory for devices of this class */
 if (!cls->dev_kobj)
  cls->dev_kobj = sysfs_dev_char_kobj;
  
 if (cls != &block_class)
  cp->class_subsys.kobj.kset = class_kset;     --设置该类的父kset为class_kset
  
 cp->class_subsys.kobj.ktype = &class_ktype;   
 cp->class = cls;
 cls->p = cp;

 error = kset_register(&cp->class_subsys);     --注册一个kset,因为他也算是一个父,其子设备的dev->kobj.kset会指向该kset
 if (error) {
  kfree(cp);
  return error;
 }
 error = add_class_attrs(class_get(cls));
 class_put(cls);
 return error;
}
上面的函数很好理解。不过这个需要在理解kobject,kset以及ktype这几者之间的关系,very important!!!在创建一个类后,就可以创建隶属于
该类的设备。

2.device_create
函数原型为:
struct device *device_create(struct class *class, struct device *parent,dev_t devt, void *drvdata, const char *fmt, ...)
参数class为class_create创建的一个新类。
device创建和上一次学习的device_register和有关联,因为在device_create中会有device_register的函数实现设备的注册。
struct device *device_create_vargs(struct class *class, struct device *parent,dev_t devt, void *drvdata, const char *fmt,va_list args)
{
 struct device *dev = NULL;
 int retval = -ENODEV;

 if (class == NULL || IS_ERR(class))
  goto error;

 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 if (!dev) {
  retval = -ENOMEM;
  goto error;
 }

 dev->devt = devt;
 dev->class = class;                --设置class类 ,这个会关系到以后dev->kobj.parent的值。
 dev->parent = parent;              --设置parent
 dev->release = device_create_release;
 dev_set_drvdata(dev, drvdata);    

 vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args);
 retval = device_register(dev);
 if (retval)
  goto error;

 return dev;

error:
 put_device(dev);
 return ERR_PTR(retval);
}

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