字符设备驱动的改进

1、编程上的区别

原来的驱动
major = register_chrdev(0, "button_drv", &button_ops);
button_class = class_create(THIS_MODULE, "button_drv");
button_class_device = class_device_create(button_class, NULL, MKDEV(major, 0), NULL, "by_button");
现在的驱动
alloc_chrdev_region(&dev_id, 0, 2, "bym_drv");	//分配设备号范围
major = MAJOR(dev_id);	//取得分配到的设备号的主设备号
cdev_init(cdev, &drv_ops);
cdev_add(cdev, dev_id, 2);	//添加cdev设备
drv_class = class_create(THIS_MODULE, "bym_drv");	//创建类
class_device_create(drv_class, 0, MKDEV(major, 0), 0, "bym_test_drv0");	//在类上面创建设备节点

2、为什么要改变字符设备驱动的写法

原来的方法注册得到的设备驱动程序一个就对应一整个主设备号加0~255的次设备号,这样会造成设备驱动只能加载256个,次设备号就完全浪费掉了,使用新的驱动编写方法能够具体控制到一个次设备号对应到一个驱动程序,这样的话每个主设备号下面就能够挂载256个驱动程序,有效利用了设备号

3、注册加载过程区别

原来的:
int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops)
	cd = __register_chrdev_region(major, 0, 256, name);	
		if (major == 0) {				//分配主设备号
		for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i--) {
			if (chrdevs[i] == NULL)
				break;
		}
	err = cdev_add(cdev, MKDEV(cd->major, 0), 256);	//将设备注册

现在的:
alloc_chrdev_region(&dev_id, 0, 2, "bym_drv");	//分配设备号范围,人为指定为两个次设备号对应一个驱动
	__register_chrdev_region(0, 0, 2, "bym_drv");	//注册相应的设备范围region(区域/范围)
major = MAJOR(dev_id);	//取得分配到的设备号的主设备号
	
/* 如果已经有了主设备号 */
dev_id = MKDEV(major, 0);
register_chrdev_region(dev_id, 2, "bym_drv");	
	for (n = dev_id; n < dev_id + 2; n = next) {	//查询注册
			next = MKDEV(MAJOR(n)+1, 0);
			if (next > dev_id + 2)
				next = dev_id + 2;
			cd = __register_chrdev_region(MAJOR(n), MINOR(n),
					   next - n, name);
			if (IS_ERR(cd))
				goto fail;
	}
/* 以上是有了主设备号之后 */
	
cdev_init(cdev, &drv_ops);
cdev_add(cdev, dev_id, 2);	//添加cdev设备

4、新字符设备驱动的写法

1、构造file_operations结构体,构造open,read,write等函数

2、分配主设备号

如果开始没有主设备号的话,要先分配设备号,alloc_chrdev_region(&dev_id, 0, 2, "bym_drv");//分配设备号范围,人为指定为两个次设备号对应一个驱动,得到主设备号major = MAJOR(dev_id);//取得分配到的设备号的主设备号

3、如果有主设备号

如果有了主设备号,直接注册次设备号

dev_id = MKDEV(major, 0);
register_chrdev_region(dev_id, 2, "bym_drv");

4、cdev结构体初始化与添加(其实就是填充cdev结构体)

cdev_init(cdev, &drv_ops);
cdev_add(cdev, dev_id, 2);	//添加cdev设备

5、创建设备节点

drv_class = class_create(THIS_MODULE, "bym_drv");	//创建类
class_device_create(drv_class, 0, MKDEV(major, 0), 0, "bym_test_drv0");
class_device_create(drv_class, 0, MKDEV(major, 1), 0, "bym_test_drv1");

6、使用open,read,write等函数进行设备操作

你可能感兴趣的:(ARM,s3c2440,linux驱动)