在Linux 2.6内核中的字符设备用cdev结构来描述,其定义如下:
- struct
cdev - {
-
struct kobject kobj; -
struct module *owner; //所属模块 -
const struct file_operations *ops; //文件操作结构 -
struct list_head list; -
dev_t dev; //设备号,int 类型,高12位为主设备号,低20位为次设备号 -
unsigned int count; - };
- struct
cdev *cdev_alloc(void);//分配一个cdev - void
cdev_init(struct cdev *, const struct file_operations *);//初始化cdev的file_operation - void
cdev_put(struct cdev *p);// //减少使用计数 - //注册设备,通常发生在驱动模块的加载函数中
- int
cdev_add(struct cdev *, dev_t, unsigned); - //注销设备,通常发生在驱动模块的卸载函数中
- void
cdev_del(struct cdev *);
使用cdev_add注册字符设备前应该先调用register_chrdev_region或alloc_chrdev_region分配设备号。register_chrdev_region函数用于指定设备号的情况,alloc_chrdev_region函数用于动态申请设备号,系统自动返回没有占用的设备号。
- int
register_chrdev_region(dev_t from, unsigned count, const char *name) ; - int
alloc_chrdev_region(dev_t *dev,unsigned baseminor,unsigned count,const char *name);
- void
unregister_chrdev_region(dev_t from,unsigned count) ;
struct
-
.owner = THIS_MODULE, -
.read = simple_read, -
.write = simple_write, -
.open = simple_open, -
.release = simple_release, - };
-
- void
simple_cleanup_module(void) - {
-
dev_t devno = MKDEV(simple_MAJOR, simple_MINOR); -
if (simple_devices) -
{ -
cdev_del(&simple_devices->cdev); -
kfree(simple_devices); -
} -
unregister_chrdev_region(devno,1); - }
- //模块初始化
- int
simple_init_module(void) - {
-
int result; -
dev_t dev = 0; -
dev = MKDEV(simple_MAJOR, simple_MINOR); -
result = register_chrdev_region(dev, 1, "DEMO");//申请设备号 -
if (result <</SPAN> 0) -
{ -
printk(KERN_WARNING "DEMO: can't get major %d\n", simple_MAJOR); -
return result; -
} -
simple_devices = kmalloc(sizeof(struct simple_dev), GFP_KERNEL); -
if (!simple_devices) -
{ -
result = -ENOMEM; -
goto fail; -
} -
memset(simple_devices, 0, sizeof(struct simple_dev)); -
//初始化设备结构 -
cdev_init(&simple_devices->cdev, &simple_fops); -
simple_devices->cdev.owner = THIS_MODULE; -
simple_devices->cdev.ops = &simple_fops; -
result = cdev_add (&simple_devices->cdev, dev, 1);//添加字符设备 -
if(result) -
{ -
printk(KERN_NOTICE "Error %d adding DEMO\n", result); -
goto fail; -
} -
return 0; - fail:
-
simple_cleanup_module(); -
return result; - }
- module_init(simple_init_module);
- module_exit(simple_cleanup_module);