device_create()、device_register()、deivce_add()区别
来源:互联网 发布:谭浩强c语言 编辑:程序博客网 时间:2024/06/14 07:00
本文基于linux 3.10.40,其他版本仅供参考
在字符设备驱动开发的入门教程中,最常见的就是用device_create()函数来创建设备节点了,但是在之后阅读内核源码的过程中却很少见device_create()的踪影了,取而代之的是device_register()与device_add(),将device_create()函数展开不难发现:其实device_create()只是device_register()的封装,而device_register()则是device_add()的封装。
struct device *device_create(struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...){ ...... dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs); ...... return dev;}
struct device *device_create_vargs(struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, va_list args){ ...... dev->devt = devt; dev->class = class; dev->parent = parent; dev->release = device_create_release; dev_set_drvdata(dev, drvdata); ...... retval = device_register(dev); ......}
int device_register(struct device *dev){ device_initialize(dev); return device_add(dev);}
device_add()会在/sys目录对应设备目录下创建uevent属性节点,应用层的udev则会根据uevent来创建/dev目录下的设备节点,这里关于udev的部分不再赘述,我们继续分析device_create()、device_register()、device_add()三个函数在实际运用中的区别。
以一个简单的led设备字符设备驱动为例,下面分别用device_create()、device_register()、device_add()三个函数来创建设备节点“/dev/led”:
1. device_create()
static class *led_class;static int __init led_init(void){ int ret; dev_t devno; struct cdev *cdev; struct dev *dev; /* 注册设备号 */ ret = alloc_chrdev_region(&devno, 0, 1, "led"); if (ret < 0) return ret; /* 分配、初始化、注册cdev*/ cdev = cdev_alloc(); if (IS_ERR(cdev)) { ret = PTR_ERR(cdev); goto out_unregister_devno; } cdev_init(&cdev, &led_fops); cdev.owner = THIS_MODULE; ret = cdev_add(&cdev, devno, 1); if (ret) goto out_free_cdev; /* 创建设备类 */ led_class = class_create(THIS_MODULE, "led_class"); if (IS_ERR(led_class)) { ret = PTR_ERR(led_class); goto out_unregister_cdev; } /* 创建设备节点 */ dev = device_create(led_class, NULL, devno, NULL, "led"); if (IS_ERR(dev)) { ret = PTR_ERR(dev); goto out_del_class; } return 0;out_del_class: class_destroy(c78x_class); out_unregister_cdev: cdev_del(cdev);out_free_cdev: kfree(cdev);out_unregister_devno: unregister_chrdev_region(devno, 1); return ret;}module_init(led_init);
2. device_register()
static class *led_class;static int __init led_init(void){ ...... /* 注册设备号 */ ...... /* 分配、初始化、注册cdev*/ ...... /* 创建设备类 */ ...... /* 创建设备节点 */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { ret = -ENOMEM; goto out_del_class; } dev->class = led_class; // 关联设备类 dev->parent = NULL; dev->devt = devno; // 关联设备号 dev_set_drvdata(dev, NULL); dev_set_name(dev, "led"); // 设置节点名字 dev->release = device_create_release; ret = device_register(dev); if (ret) goto out_put_dev; return 0;out_put_dev: put_device(dev); kree(dev);out_del_class: class_destroy(c78x_class); out_unregister_cdev: cdev_del(cdev);out_free_cdev: kfree(cdev);out_unregister_devno: unregister_chrdev_region(devno, 1); return ret;}module_init(led_init);
3. device_add()
static class *led_class;static int __init led_init(void){ ...... /* 注册设备号 */ ...... /* 分配、初始化、注册cdev*/ ...... /* 创建设备类 */ ...... /* 创建设备节点 */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { ret = -ENOMEM; goto out_del_class; } dev->class = led_class; // 关联设备类 dev->parent = NULL; dev->devt = devno; // 关联设备号 dev_set_drvdata(dev, NULL); dev_set_name(dev, "led"); // 设置节点名字 dev->release = device_create_release; device_initialize(dev); ret = device_add(dev); if (ret) goto out_put_dev; return 0;out_put_dev: put_device(dev); kree(dev);out_del_class: class_destroy(c78x_class); out_unregister_cdev: cdev_del(cdev);out_free_cdev: kfree(cdev);out_unregister_devno: unregister_chrdev_region(devno, 1); return ret;}module_init(led_init);
阅读全文
1 0
- device_create()、device_register()、deivce_add()区别
- class_create(),device_create解析.device_create和device_add区别
- device_register()和platform_device_register()的区别
- device_register()和platform_device_register()的区别
- device_register()和platform_device_register()的区别
- device_register()和platform_device_register()的区别
- device_register()和platform_device_register()的区别
- device_register
- device_register
- device_register()和platform_device_register()的区别(转载)
- device_create
- device_create
- device_create
- device_register()分析
- device_register()分析
- device_register分析
- device_register()分析
- device_register()函数
- Kotlin基础 10
- NGUI UITexture 设置帧动画闪烁(不显示)问题
- Kickstart Practice Round 2017 Problem B. Vote
- 插入排序
- container_of宏
- device_create()、device_register()、deivce_add()区别
- PHP实现微信开放平台扫码登录源码下载
- 百度地图 加标注
- 动态目录地址
- Leetcode题解---WildCard Matching Java实现
- 时间和日期的相关类和方法Date&Time
- 纯静态html页面,js 如何拦截请求url的后缀不是.html的访问地址
- ueditor编辑器的初次使用
- java配置文件或者eclipse中url等使用造成程序报错问题