问题:两个注册设备驱动的函数有什么区别?
一个是:register_chrdev()另外一个是:cdev_add()
例一:
//加载模块
static int __init XXX_init(void)
register_chrdev(111,"my_led",&my_dev_fops);//注册设备
}
//卸载模块
static int __exit XXX_exit(void){
unregister_chrdev(111,"my_led");//释放占用的设备号并注销
}
例二:博客中的字符驱动
1 //设备结构体
2 struct xxx_dev_t
3 {
4 struct cdev cdev;
5 ...
6 } xxx_dev;
7 //设备驱动模块加载函数
8 static int _ _init xxx_init(void)
9 {
10 ...
11 cdev_init(&xxx_dev.cdev, &xxx_fops); //初始化 cdev
12 xxx_dev.cdev.owner = THIS_MODULE;
13 //获取字符设备号
14 if (xxx_major)
15 {
16 register_chrdev_region(xxx_dev_no, 1, DEV_NAME);
17 }
18 else
19 {
20 alloc_chrdev_region(&xxx_dev_no, 0, 1, DEV_NAME);
21 }
22
23 ret = cdev_add(&xxx_dev.cdev, xxx_dev_no, 1); //注册设备
24 ...
25 }
26 /*设备驱动模块卸载函数*/
27 static void _ _exit xxx_exit(void)
28 {
29 unregister_chrdev_region(xxx_dev_no, 1); //释放占用的设备号
30 cdev_del(&xxx_dev.cdev); //注销设备
31 ...
32 }
register_chrdev()是向系统注册设备,注册设备时包括分配设备号(主设备都确定了)为设备分配资源等,所有的操作在这个函数中一步完成;
一个是:register_chrdev()另外一个是:cdev_add()
例一:
//加载模块
static int __init XXX_init(void)
register_chrdev(111,"my_led",&my_dev_fops);//注册设备
}
//卸载模块
static int __exit XXX_exit(void){
unregister_chrdev(111,"my_led");//释放占用的设备号并注销
}
例二:博客中的字符驱动
1 //设备结构体
2 struct xxx_dev_t
3 {
4 struct cdev cdev;
5 ...
6 } xxx_dev;
7 //设备驱动模块加载函数
8 static int _ _init xxx_init(void)
9 {
10 ...
11 cdev_init(&xxx_dev.cdev, &xxx_fops); //初始化 cdev
12 xxx_dev.cdev.owner = THIS_MODULE;
13 //获取字符设备号
14 if (xxx_major)
15 {
16 register_chrdev_region(xxx_dev_no, 1, DEV_NAME);
17 }
18 else
19 {
20 alloc_chrdev_region(&xxx_dev_no, 0, 1, DEV_NAME);
21 }
22
23 ret = cdev_add(&xxx_dev.cdev, xxx_dev_no, 1); //注册设备
24 ...
25 }
26 /*设备驱动模块卸载函数*/
27 static void _ _exit xxx_exit(void)
28 {
29 unregister_chrdev_region(xxx_dev_no, 1); //释放占用的设备号
30 cdev_del(&xxx_dev.cdev); //注销设备
31 ...
32 }
register_chrdev()是向系统注册设备,注册设备时包括分配设备号(主设备都确定了)为设备分配资源等,所有的操作在这个函数中一步完成;
但是cdev_add()是在你申请了设备号,cdev结构体初始化后进行的一个向chrdevs[255]指针数组上添加一个设备,主设备号确定,次设备号是一个范围。