前面我们字符设备驱动开发使用的是register_chrdev函数注册字符设备,unregister_chrdev函数注销字符设备,驱动模块加载成功后我们还需要手动使用mknod命令创建设备结点。register_chrdev 和 unregister_chrdev是老版本的的驱动使用的函数,新的字符设备驱动使用Linux内核推荐的新字符设备驱动API函数。
一、新字符设备驱动
1、分配和释放设备号
以前我们使用register_chrdev函数注册新字符设备的时候需要给定一个主设备号就可以了,但是这样带来两个问题:
①、需要我们事先确定好哪些主设备号没有使用。
②、会将一个主设备号下的所有次设备号都使用掉,比如现在设置 LED 这个主设备号为
200,那么 0~1048575(2^20-1)这个区间的次设备号就全部都被 LED 一个设备分走了。这样太浪
费次设备号了!一个 LED 设备肯定只能有一个主设备号,一个次设备号。
解决这两个问题最好的方法就是要使用设备号的时候向 Linux 内核申请,需要几个就申请
几个,由 Linux 内核分配设备可以使用的设备号。在fs.h中,包含了Linux内核新的驱动注册函数。
①、没有指定你要申请的设备的设备号
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)
dev:我们前面已经分析过,起始就是unsigned int 类型的设备号。
baseminor:次设备号。
count:要申请的数量。
name:申请设备的名字。
②、指定了你要申请的设备号
int register_chrdev_region(dev_t from, unsigned count, const char *name)
from:给定的设备号。
count:要申请的数量。
name:申请设备的名字。
模板:
int major; /* 主设备号 */
int minor; /* 次设备号 */
dev_t devid; /* 设备号 */
if (major) { /* 定义了主设备号 */
devid = MKDEV(major, 0); /* 大部分驱动次设备号都选择 0*/
register_chrdev_region(devid, 1, "test");
} else { /* 没有定义设备号 */
alloc_chrdev_region(&devid, 0, 1, "test"); /* 申请设备号 */
major = MAJOR(devid); /* 获取分配号的主设备号 */
minor = MINOR(devid); /* 获取分配号的次设备号 */
}
MKDEV:用来构建设备号。MAJOR:获取主设备号。MINOR:获取次设备号。
无论你如何创建的设备号,注销设备号的函数都是同一个:
void unregister_chrdev_region(dev_t from, unsigned count)
from:要注销的设备号。
count: 要注销的数量。
我们新建一个文件,将上一次的文件拷贝到本次的实验中,并清理一下工程:

使用vscode打开工程,并将led.c文件改为Newchrdev.c。驱动函数的入口和出口函数都是不变的:

我们创建一个驱动的结构体,里面存放一些这个驱动的信息,比如说设备号,主设备号,次设备号这些信息,并实例化一个设备。

根据我们的模板在入口函数创建一个设备号 :

新字符设备驱动

最低0.47元/天 解锁文章
1658

被折叠的 条评论
为什么被折叠?



