linux class device

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_ksetcp->class_subsys.kobj.ktype = &class_ktype; cp->class = cls;cls->p = cp;

error = kset_register(&cp->class_subsys); –注册一个kset,因为他也算是一个父,其子设备的dev->kobj.kset会指向该ksetif (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; –设置parentdev->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);}

有时我们选择改变,并非经过深思熟虑,

linux  class device

相关文章:

你感兴趣的文章:

标签云: