一个主设备号是如何支持多个次设备?

1、主次设备号

参考博客:《字符设备驱动详解(主次设备号、注册/卸载字符设备驱动、创建设备节点、地址映射)》

2、次设备号介绍

(1)在老的驱动程序里是不需要次设备号的,在老版内核中注册驱动用register_chrdev()函数,只需要传入主设备号,次设备号默认是0;
(2)后面的驱动注册函数,需要通过alloc_chrdev_region()函数先申请设备号,其中就包括第一个设备号和次设备号的个数;
(3)主设备号和次设备号共同表示一个设备驱动;

3、使用次设备号的好处

(1)共享主设备号的驱动程序一般都是一类设备,这样方便管理和理解;
(2)某些时候不同的设备是可以共享同一个驱动程序,只需要在驱动程序中对次设备进行区分,这样多个设备就只占用一个主设备号;比如串口驱动,不同的串口操作方法都是一样的,不一样的是串口对应的寄存器基地址,如果我们能在驱动程序中通过次设备号知道此次是操作哪个串口,然后就使用对应的寄存器基地址,就可以实现多个串口共用一个驱动程序;
(3)多个设备共享一个主设备号,通过次设备号区分,可以节省主设备号。在内核中,字符设备驱动都注册到chrdevs全局变量中,这是一个结构体指针数组,总共有255个成员,也就是说内核最多支持255个字符设备驱动;

4、驱动程序如何区分次设备号

4.1、创建设备节点

(1)创建设备节点会指定主次设备号,通过主次设备号就可以找到对应的驱动程序;
(2)(参考博客:《字符设备驱动程序自动创建设备节点详解》《设备节点如何与设备驱动关联》

4.2、上层应用程序打开设备节点

//驱动代码中struct file_operations结构体的open函数指针
int open(struct inode *, struct file *)
{
	//将描述字符设备的struct cdev结构体传给struct file结构体,后续操作会用到
	file->private_data = inode->i_cdev;
	return 0;
}

(1)在创建设备节点时指定了主次设备号,所以open函数打开设备节点时,struct inode结构体中就报错了主次设备号和对应的struct cedv结构体指针;
(2)只有在open设备节点时才会传入struct inode结构体指针和struct file结构体指针,但是在struct file结构体指针中时不包含主次设备号信息的;
(3)struct file结构体中有个private_data 变量,时专门用来存私有数据的,我们可以在open打开时将主次设备号保存到private_data 变量中;

4.3、应用程序读写驱动程序

//驱动代码中struct file_operations结构体的read函数指针
ssize_t read(struct file *file, char __user *buf, size_t size, loff_t *pos)
{
	struct cdev *cd;
	unsigned int minor;

	//得到open函数打开设备节点时保存的数据
	cd = (struct cdev *)file->private_data;
	
	//获得次设备号
	minor = MINOR(cd->dev)
	
	//根据不同的次设备进行操作
	······
	
	return size;
}

(1)应用程序在调用read、write等操作驱动程序函数时,都会把struct file结构体传入,在open时我们已经把字符设备驱动的相关信息保存到struct file结构体的private_data中;
(2)在操作前去解析struct file结构体的private_data变量,得到次设备号,有了次设备号后续就可以进行差别的操作;
补充:上面只介绍了read函数,但是其他的操作函数也是一样的,都会传入struct file结构体指针;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

正在起飞的蜗牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值