字符设备驱动程序自动创建设备节点详解
Posted 正在起飞的蜗牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符设备驱动程序自动创建设备节点详解相关的知识,希望对你有一定的参考价值。
1、设备节点介绍
(1)在linux中一切皆是文件,对上层程序来说设备驱动程序不过就是设备文件,在我们向内核注册好驱动程序后,需要创建对应的设备节点,然后上层应用程序通过读写设备节点的方式去操作硬件;
(2)设备节点本质上就是文件,不是普通类型的文件,是字符设备文件、块设备文件、网络设备文件等特殊文件,但是都是用统一的open、read等函数去操作;
(3)设备节点在"/dev/"目录下;
2、手动创建设备节点
(1)在驱动程序注册成功后,可以用mknod命令可以手动创建设备节点;
(2)比如:mknod /dev/com1 c 237 1
,创建主设备号是237次设备号是1的设备节点/dev/com1;
补充:必须想办法知道驱动程序注册时候的主次设备号;
3、用udev自动创建设备节点
3.1、udev介绍
(1)udev 是一个工作在用户空间的工具, 它能根据系统中硬件设备的状态动态的更新设备文件, 包括设备文件的创建, 删除, 权限等;
(2)udev 运行在用户模式, 而非内核中;
(3) 创建的文件通常都定义在/dev 目录下,但也可以在配置文件中指定。
自动创建设备节点的步骤
(1)在/sys/class/目录下创建一个类;
(2)在对应的类下面创建设备;
3.2、创建类和注销类
//创建类
#define class_create(owner, name) \\
( \\
static struct lock_class_key __key; \\
__class_create(owner, name, &__key); \\
)
//注销类:传入创建类时返回的struct class结构体指针
void class_destroy(struct class *cls)
if ((cls == NULL) || (IS_ERR(cls)))
return;
class_unregister(cls);
创建类:
(1)返回值:返回一个struct class结构体指针;
(2)owner:模块所有者,一般填THIS_MODULE;
(3)name:类名字;
(4)函数功能:返回一个struct class结构体指针,在/sys/class/目录下新建名字为name的类;
3.3、创建设备和注销设备
//创建类下面的设备
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, ...);
//注销创建的设备:传入struct class结构体指针和主次设备号
void device_destroy(struct class *class, dev_t devt);
创建设备:
(1)返回值:struct device结构体指针,用来表示新创建的设备;
(2)class:创建的类,就是这个设备属于哪个类;
(3)parent:设备的父节点,没有就填NULL;
(4)devt:驱动程序的主次设备号;
(5)drvdata:添加到设备的数据,调用的时候会用到,没有就填NULL;
(6)fmt:这是个可变参数,传入的是设备的名字;fmt可以和sprintf()函数做类比,可以用%d、%s等来构造设备的名字;
(7)函数功能:在指定类创建名字是fmt的设备,并在创建**/dev/fmt**设备节点;
3.4、自动创建设备节点的代码实例
static int major = 237;
static int minor = 0;
static dev_t devno;
struct device *class_dev = NULL;
struct class *cls;
static struct file_operations hello_ops =
.open = hello_open,
.release = hello_release,
;
static int hello_init(void)
int result;
int error;
//注册字符驱动程序
result = register_chrdev(major, "hello", &hello_ops);
//创建类
cls = class_create(THIS_MODULE, "hellocls");
//生成设备号
devno = MKDEV(major, minor);
//创建设备
class_dev = device_create(cls, NULL, devno, NULL, "hellodev");
return 0;
out_err_2:
class_destroy(cls);
out_err_1:
unregister_chrdev(major,"hello");
return result;
3.5、代码实现效果
(1)在/sys/class/目录下多了hellocls类;
(2)hellocls类下面有hellodev设备;
(3)hellodev设备下面有文件,里面记录了主次设备号,设备名等信息;
(4)会在/dev/目录下创建hellodev设备的设备节点:/dev/hellodev;
4、两种创建方式对比
(1)手动创建设备节点:必须在设备驱动注册成功之后拿到主次设备号,用mknod命令去创建设备节点,虽然可以用脚本来实现,但是还是比较笨拙;
(2)自动创建设备节点:直接在设备驱动代码中添加自动创建设备节点的代码,驱动程序注册成功后便创建好了设备节点,明显比较方便;
总结:尽量使用自动创建设备节点,少使用手动创建设备节点;
参考内容:博主“一口linux”的驱动讲解部分;
以上是关于字符设备驱动程序自动创建设备节点详解的主要内容,如果未能解决你的问题,请参考以下文章
Linux——Linux驱动之字符类设备驱动编写实践,从0到1手把手教你字符类设备如何申请设备号,如何注册设备,如何自动创建设备节点
Linux——Linux驱动之字符类设备驱动编写实践,从0到1手把手教你字符类设备如何申请设备号,如何注册设备,如何自动创建设备节点