linux driver ------ 字符设备驱动 之 “ 创建设备节点流程 ”
在字符设备驱动开发的入门教程中,最常见的就是用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()函数,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, , , "led");
if (ret < )
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, );
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 ; 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, ); 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 ; 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, ); 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 ; 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, ); return ret;
} module_init(led_init);
linux driver ------ 字符设备驱动 之 “ 创建设备节点流程 ”的更多相关文章
- 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联
转载自:http://www.kancloud.cn/yueqian_scut/emlinux/106829 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动.设备驱动模型和sy ...
- [kernel]字符设备驱动、平台设备驱动、设备驱动模型、sysfs几者之间的比较和关联
转自:http://www.2cto.com/kf/201510/444943.html Linux驱动开发经验总结,绝对干货! 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动 ...
- Linux 设备驱动开发 —— platform设备驱动应用实例解析
前面我们已经学习了platform设备的理论知识Linux 设备驱动开发 —— platform 设备驱动 ,下面将通过一个实例来深入我们的学习. 一.platform 驱动的工作过程 platfor ...
- linux驱动之设备号与创建设备节点
设备号: 1.自己主动分配 major = register_chrdev(0,"first_drv",&first_sdv_fops);//注冊 注冊设备时给设备号写0, ...
- 乾坤合一~Linux设备驱动之块设备驱动
1. 题外话 在蜕变成蝶的一系列学习当中,我们已经掌握了大部分Linux驱动的知识,在乾坤合一的分享当中,以综合实例为主要讲解,在一个月的蜕茧成蝶的学习探索当中,觉得数据结构,指针,链表等等占据了代码 ...
- 蜕变成蝶~Linux设备驱动之watchdog设备驱动
看门狗(watchdog )分硬件看门狗和软件看门狗.硬件看门狗是利用一个定时器 电路,其定时输出连接到电路的复位端,程序在一定时间范围内对定时器清零 (俗称 “喂狗”),如果程序出现故障,不在定时周 ...
- 蜕变成蝶~Linux设备驱动之按键设备驱动
在上述的驱动系列博客中,我们已经了解了关于阻塞和非阻塞.异步通知.轮询.内存和I/O口访问.并发控制等知识,按键设备驱动相对来说是比较简单的,本章内容可以加深我们对字符设备驱动架构.阻塞与非阻塞.中断 ...
- Linux 内核驱动自动创建设备节点并挂载设备
*注:本文来自http://blog.csdn.net/lwj103862095/article/details/17470573 一.首先需要在最开始定义两个数据结构: static struct ...
- linux driver ------ platform模型,通过杂项设备(主设备号是10)注册设备节点
注册完设备和驱动之后,就需要注册设备节点 Linux杂项设备出现的意义在于:有很多简单的外围字符设备,它们功能相对简单,一个设备占用一个主设备号对于内核资源来说太浪费.所以对于这些简单的字符设备它们共 ...
随机推荐
- 深度学习中dropout策略的理解
现在有空整理一下关于深度学习中怎么加入dropout方法来防止测试过程的过拟合现象. 首先了解一下dropout的实现原理: 这些理论的解释在百度上有很多.... 这里重点记录一下怎么实现这一技术 参 ...
- js数组中两个有相同删除一个
for (var i = 0; i < project.Before.length; i++) { var j = 0; ...
- BZOJ2434 [NOI2011] 阿狸的打字机 【树链剖分】【线段树】【fail树】【AC自动机】
题目分析: 画一下fail树,就会发现就是x的子树中属于y路径的,把y剖分一下,用线段树处理 $O(n*log^2 n)$. 代码: #include<bits/stdc++.h> usi ...
- RMQ--ST表
RMQ即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值. ST表既ST算法是一个非常有名的在线处 ...
- python学习日记(文件操作)
文件操作概述 计算机系统分为:操作系统,计算机硬件,应用程序. 我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作硬件,众所周知,应用程序 ...
- Angular、React.js 和Node.js到底选谁?
为了工作,程序员选择正确的框架和库来构建应用程序是至关重要的,这也就是为什么Angular和React之间有着太多的争议.Node.js的出现,让这场战争变得更加复杂,虽然有选择权通常是一件很棒的事情 ...
- 【Loj116】有源汇有上下界最大流(网络流)
[Loj116]有源汇有上下界最大流(网络流) 题面 Loj 题解 模板题. #include<iostream> #include<cstdio> #include<c ...
- 【BZOJ5197】Gambling Guide (最短路,期望)
[BZOJ5197]Gambling Guide (最短路,期望) 题面 BZOJ权限题 洛谷 题解 假设我们求出了每个点的期望,那么对于一个点,只有向期望更小的点移动的时候才会更新答案. 即转移是: ...
- 【BZOJ4771】七彩树(主席树)
[BZOJ4771]七彩树(主席树) 题面 BZOJ 题解 如果没有深度限制,每次只询问子树内的颜色个数,除了树套树\(dfs\)序加前驱或者后继强行二维数点之外,还有这样一种做法: 把所有相同颜色的 ...
- 洛谷P4243/bzoj1558 [JSOI2009]等差数列(线段树维护差分+爆炸恶心的合并)
题面 首先感谢这篇题解,是思路来源 看到等差数列,就会想到差分,又有区间加,很容易想到线段树维护差分.再注意点细节,\(A\)操作完美解决 然后就是爆炸恶心的\(B\)操作,之前看一堆题解的解释都不怎 ...