Linux字符设备驱动

2014-11-24 13:57:53 · 作者: · 浏览: 3

/*Linux字符设备驱动源代码scdd.c*/


#include /*模块头文件*/


#include


#include /*dev_t头文件*/


#include /*MAJOR和MINOR宏头文件*/


#include /*register_chrdev_region等函数


file_operations结构体*/


#include /*struct cdev结构体*/


#include /*copy_to_user函数*/



#define DEVICE_NAME "scdd" /*定义设备名*/


#define DEVICE_MAJOR 250



struct cdev my_cdev;



int scdd_open(struct inode *inode,structfile *filp)


{


return0;


}


int scdd_close(struct inode *inode,structfile *filp)


{


return0;


}


ssize_t scdd_read(struct file *filp,char__user *buff,size_t size,loff_t *offp)


{


intleft;


chardata=1;



for(left=size;left>0;left--)


{


/*拷贝数据到用户空间*/


copy_to_user(buff,&data,1);


buff++;


}


returnsize;


}


ssize_t scdd_write(struct file *filp,char__user *buff,size_t size,loff_t *offp)


{


return0;


}


/*file_operations结构体*/


struct file_operations scdd_fops={


.owner=THIS_MODULE,


.read=scdd_read,


.write=scdd_write,


.open=scdd_open,


.release=scdd_close,


};


static int __init scdd_init(void)


{ /*模块初始化函数*/


intsmajor;


smajor=DEVICE_MAJOR;


dev_tdev_n=MKDEV(smajor,0);


/*申请设备号*/


if(!register_chrdev_region(dev_n,1,DEVICE_NAME))


{ /*静态申请*/


printk("registersuccess\n");


}else


{


gotoregister_error;


}


/*else


{ /*动态申请*/


/*alloc_chrdev_region(&dev_n,0,1,DEVICE_NAME);


smajor=MAJOR(dev_n);


}*/



/*初始化cdev结构体*/


cdev_init(&my_cdev,&scdd_fops);


my_cdev.owner=THIS_MODULE;


my_cdev.ops=&scdd_fops;



/*注册字符设备*/


cdev_add(&my_cdev,dev_n,1);


return0;



register_error:


unregister_chrdev_region(MKDEV(DEVICE_MAJOR,0),1);


return0;


}


static void __exit scdd_exit(void)


{ /*模块卸载函数*/


cdev_del(&my_cdev);


unregister_chrdev_region(MKDEV(DEVICE_MAJOR,0),1);


}



module_init(scdd_init);


module_exit(scdd_exit);


MODULE_LICENSE("Dual BSD/GPL");



这个程序只是简单演示字符注册的一个完整过程,并不带有复杂的操作,调用read时向用户空间写全1