一、建立字符设备描述结构体
struct Chrdev{
dev_t devid;
struct cdev cdev;
struct class *class;
struct device *device;
int major;
int minor;
...
};
struct Chrdev chrdev;
二、编写操作函数
static int chrdev_open(struct inode *inode, struct file *filp)
{
filp->private_data = &chrdev;
return 0;
}
static ssize_t chardev_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
{
...
memcpy(readbuf, kerneldata, sizeof(kerneldata));
retvalue = copy_to_user(buf, readbuf, cnt);
if(retvalue == 0){
printk("kernel senddata ok!\r\n");
}else{
printk("kernel senddata failed!\r\n");
}
...
return 0;
}
static ssize_t chrdev_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{
...
int retvalue;
unsigned char databuf[cnt];
retvalue = copy_from_user(databuf, buf, cnt);
if(retvalue < 0) {
printk("kernel write failed!\r\n");
return -EFAULT;
}
...
return 0;
}
static int chrdev_release(struct inode *inode, struct file *filp)
{
return 0;
}
static struct file_operations newchrled_fops = {
.owner = THIS_MODULE,
.open = chrdev_open,
.read = chrdev_read,
.write = chrdev_write,
.release = chrdev_release,
};
三、编写初始化函数
static int __init chrdev_init(void)
{
...
if (chrdev.major) {
chrdev.devid = MKDEV(chedev.major, 0);
register_chrdev_region(chedev.devid, NEWCHRLED_CNT, NEWCHRLED_NAME);
} else {
alloc_chrdev_region(&chedev.devid, 0, NEWCHRLED_CNT, NEWCHRLED_NAME);
chedev.major = MAJOR(chedev.devid);
chedev.minor = MINOR(chedev.devid);
}
printk("chrdev major=%d,minor=%d\r\n",chrdev.major, chrdev.minor);
chrdev.cdev.owner = THIS_MODULE;
cdev_init(&chrdev.cdev, &chrdev_fops);
cdev_add(&chrdev.cdev, chrdev.devid, NEWCHRLED_CNT);
chedev.class = class_create(THIS_MODULE, NEWCHRLED_NAME);
if (IS_ERR(chedev.class)) {
return PTR_ERR(chedev.class);
}
chedev.device = device_create(chrdev.class, NULL, chedevd.devid, NULL, NEWCHRLED_NAME);
if (IS_ERR(chedev.device)) {
return PTR_ERR(chrdev.device);
}
...
return 0;
}
四、驱动出入口函数
static void __exit chrdev_exit(void)
{
...
cdev_del(&chrdev.cdev);
unregister_chrdev_region(chrdev.devid, 1);
device_destroy(chrdev.class, chredv.devid);
class_destroy(chrdev.class);
}
module_init(chrdev_init);
module_exit(chrdev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("ht");