下面是一个简单的字符设备驱动程序,主要是一个模拟设备,使用了系统的内存,相信大家都能看懂,毕竟简单,而且注释清楚,编译测试的方法大家都知道吧,这里要说的就是习惯的测试方法是通过echo向设备文件写入内容,然后通过cat显示内容,但是希望大家看到,该设备只有4字节的内存,测试的时候建议大家可以试一试写入的内容小于4字节和大于4字节,大家自己看看出现什么事,呵呵:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- #define MEMSIZE 4
-
- #define MAJORNUM 2538
-
- static int major = MAJORNUM;
-
-
- struct char_mem_t {
- struct cdev memdev;
- int device[MEMSIZE];
- }char_mem;
-
-
- static ssize_t char_mem_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
- {
-
- unsigned long p = *ppos;
- int ret = 0;
-
-
- if(p > MEMSIZE)
- return 0;
- if(count > MEMSIZE - p)
- count = MEMSIZE - p;
-
-
- if(copy_to_user(buf, (void*)(char_mem.device+p), count))
- ret = -EFAULT;
- else
- {
- *ppos += count;
- ret = count;
-
- printk(KERN_INFO "read %d bytes from %d", count, p);
- }
-
- return ret;
- }
-
- static ssize_t char_mem_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
- {
-
- unsigned long p = *ppos;
- int ret = 0;
-
-
- if(p >= MEMSIZE)
- return 0;
- if(count > MEMSIZE - p)
- count = MEMSIZE - p;
-
-
- if(copy_from_user((void*)(char_mem.device+p), buf, count))
- ret = -EFAULT;
- else
- {
- *ppos += count;
- ret = count;
-
- printk(KERN_INFO "write %d bytes to %d", count, p);
- }
-
- return ret;
- }
-
- static loff_t char_mem_llseek(struct file *filp, loff_t offset, int orig)
- {
- loff_t ret = 0;
-
- switch(orig) {
-
- case 0:
- if(offset < 0)
- {
- ret = -EINVAL;
- break;
- }
- if((unsigned int)offset > MEMSIZE)
- {
- ret = -EINVAL;
- break;
- }
- filp->f_pos = (unsigned int) offset;
- ret = filp->f_pos;
- break;
-
- case 1:
- if((filp->f_pos + offset) > MEMSIZE)
- {
- ret = -EINVAL;
- break;
- }
- if((filp->f_pos + offset) < 0)
- {
- ret = -EINVAL;
- break;
- }
- filp->f_pos += offset;
- ret = filp->f_pos;
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
- }
-
-
- static const struct file_operations char_mem_ops = {
- .owner = THIS_MODULE,
- .llseek = char_mem_llseek,
- .read = char_mem_read,
- .write = char_mem_write,
-
- };
-
-
- static int charmem_init(void)
- {
- int result = 0;
- int err = 0;
- dev_t dev = MKDEV(major, 0);
-
- if(major)
- {
- result = register_chrdev_region(dev, 1, "charmem");
- }
- else
- {
- result = alloc_chrdev_region(&dev, 0, 1, "charmem");
- major = MAJOR(dev);
- }
-
-
- if(result < 0)
- return result;
-
-
- cdev_init(&char_mem.memdev, &char_mem_ops);
- char_mem.memdev.owner = THIS_MODULE;
- err = cdev_add(&char_mem.memdev, dev, 1);
-
-
- if(err)
- printk(KERN_INFO "Error %d adding char_mem device", err);
-
- }
-
- static void charmem_exit(void)
- {
-
- cdev_del(&char_mem.memdev);
-
- unregister_chrdev_region(MKDEV(major, 0), 1);
- }
-
-
- MODULE_AUTHOR("chenlong12580");
- MODULE_LICENSE("Dual BSD/GPL");
-
-
- module_init(charmem_init);
- module_exit(charmem_exit);
阅读(1649) | 评论(0) | 转发(0) |