Linux驱动模型之class结构解析
来源:互联网 发布:淘宝玉兰油沐浴露 编辑:程序博客网 时间:2024/05/29 12:22
、、、、http://blog.csdn.net/yinwei520/article/details/6592060
class,是设备类,完全是抽象出来的概念,没有对应的实体。所谓设备类,是指提供的用户接口相似的一类设备的集合,常见的设备类的有block、tty、input、usb等等。
类是一个设备的高层视图,它抽象出了底层的实现细节,从而允许用户空间使用设备所提供的功能,而不用关心设备是如何连接和工作的。类成员通常由上层代码所控制,而无需驱动的明确支持。但有些情况下驱动也需要直接处理类。
在驱动开发中,多使用mknod命令手动创建设备节点,但当动态申请设备号时必须通过命令查出设备号,再添加。或者使用DEVFS文件系统函数添加设备节点。DEVFS在现在linux内核中已取消,取而代之的是UDEV,UDEV是处于用户态的程序。它根据内核发出的EVENTS,动态创建事件。内核是通过device_create发出event.而在device_create中就有一个参数是class,这个参数最终会在device_create中->device_create_vargs->device_register->device_add中调用device_create_sys_dev_entry在/sys/dev目录建立对设备的软链接。、
首先还是来看下calss相关的数据结构:
- struct class {
- const char *name; //设备的名称,出现在/sys/class目录下
- struct module *owner; //所属模块
- struct class_attribute *class_attrs;//类属性
- struct device_attribute *dev_attrs;//类设备属性
- struct kobject *dev_kobj;//记录本类设备应属于的哪种设备
- 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); //class释放时调用
- void (*dev_release)(struct device *dev); //设备释放时调用
- int (*suspend)(struct device *dev, pm_message_t state);/* 设备暂停 */
- int (*resume)(struct device *dev); /* 设备启动 */
- const struct kobj_ns_type_operations *ns_type;
- const void *(*namespace)(struct device *dev);
- const struct dev_pm_ops *pm;//电源管理用的函数集
- struct class_private *p;
- };
- struct class_private {
- struct kset class_subsys;//kset类型,代表class在sysfs中的位置
- struct klist class_devices; //klist类型,是class下的设备链表
- struct list_head class_interfaces;//list_head类型的类接口链表
- struct kset class_dirs;
- struct mutex class_mutex;//互斥信号量,
- struct class *class; //回指所属的struct class结构
- };
- //描述设备类对外的一种接口
- struct class_interface {
- struct list_head node;//class->p->class_interface链表上的节点
- struct class *class;//指向所属class的指针
- int (*add_dev) (struct device *, struct class_interface *);//有设备添加到所属class时调用的函数
- void (*remove_dev) (struct device *, struct class_interface *);//remove_dev()是在设备删除时调用
- };
- static const struct sysfs_ops class_sysfs_ops = {
- .show = class_attr_show,
- .store = class_attr_store,
- };
- static struct kobj_type class_ktype = {
- .sysfs_ops = &class_sysfs_ops,
- .release = class_release,
- .child_ns_type = class_child_ns_type,
- };
再来看一下相关的操作函数:
- int __init classes_init(void)
- {
- class_kset = kset_create_and_add("class", NULL, NULL);//在sysfs顶层创建class目录
- if (!class_kset)
- return -ENOMEM;
- return 0;
- }
再来看下提供给外面调用的创建class函数
- #define class_create(owner, name) \
- ({ \
- static struct lock_class_key __key; \
- __class_create(owner, name, &__key); \
- })
- 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);//分配class结构
- if (!cls) {
- retval = -ENOMEM;
- goto error;
- }
- cls->name = name;//设置name
- cls->owner = owner;//设置owner
- cls->class_release = class_create_release;//设置类释放函数
- retval = __class_register(cls, key);//注册calss
- if (retval)
- goto error;
- return cls;
- error:
- kfree(cls);
- return ERR_PTR(retval);
- }
- 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);//分配class_private结构
- if (!cp)
- return -ENOMEM;
- klist_init(&cp->class_devices, klist_class_dev_get, klist_class_dev_put);//初始化class_private结构
- INIT_LIST_HEAD(&cp->class_interfaces);
- kset_init(&cp->class_dirs);//初始化kset,并未加到sysfs
- __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
- cls->dev_kobj = sysfs_dev_char_kobj;
- #if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK)
- /* let the block class directory show up in the root of sysfs */
- if (cls != &block_class)
- cp->class_subsys.kobj.kset = class_kset;
- #else
- cp->class_subsys.kobj.kset = class_kset;
- #endif
- cp->class_subsys.kobj.ktype = &class_ktype;
- cp->class = cls;
- cls->p = cp;
- error = kset_register(&cp->class_subsys);//将class注册到sysfs中
- if (error) {
- kfree(cp);
- return error;
- }
- error = add_class_attrs(class_get(cls));//添加相关的属性文件
- class_put(cls);
- return error;
- }
还有 一个就是class_interface_register,把class_interface添加到指定的class上
- int class_interface_register(struct class_interface *class_intf)
- {
- struct class *parent;
- struct class_dev_iter iter;
- struct device *dev;
- if (!class_intf || !class_intf->class)
- return -ENODEV;
- parent = class_get(class_intf->class);//增加class的引用计数
- if (!parent)
- return -EINVAL;
- mutex_lock(&parent->p->class_mutex);
- list_add_tail(&class_intf->node, &parent->p->class_interfaces);
- if (class_intf->add_dev) {
- class_dev_iter_init(&iter, parent, NULL, NULL);
- while ((dev = class_dev_iter_next(&iter)))
- class_intf->add_dev(dev, class_intf);//添加到class的接口列表中
- class_dev_iter_exit(&iter);
- }
- mutex_unlock(&parent->p->class_mutex);
- return 0;
- }
0 0
- Linux驱动模型之class结构解析
- linux设备驱动模型十之class
- LINUX设备驱动模型之class
- linux设备驱动模型之class
- linux驱动结构之class及相关结构体
- linux驱动结构之class及相关结构体
- linux驱动结构之class及相关结构体
- linux设备驱动模型--class
- linux设备驱动模型一上层容器之class
- Linux Kernel设备驱动模型之class注册
- Linux Kernel设备驱动模型之class迭代设备
- Linux Kernel设备驱动模型之class 接口注册
- Linux Kernel设备驱动模型之class 查找设备
- Linux Kernel设备驱动模型之class 初始化
- linux设备驱动模型一上层容器之class
- 设备驱动模型之class
- linux设备驱动模型一三基础结构之Kobject
- linux设备驱动模型一三基础结构之Kset
- HDU 1040 As Easy As A+B(水~)
- validate() 表单验证插件的使用
- eclipse 异常 Subversion Native Library Not Available解决方案
- vmware虚拟机在ubuntu升级后 vmware tools 无法正常使用
- ID3信息
- Linux驱动模型之class结构解析
- 黑马程序员——java基础 反射 (复习)
- Android 打造可下拉的EditText--DropEditText
- 基于Doxygen的C/C++注释原则
- Linux下doxygen的使用
- This is it——Zero to Hero
- The Java EE 6 Tutorial Servlet Lifecycle
- doxygen的使用与C/C++注释规范
- 写一个完整的代理, 包括声明和实现