关于字符设备驱动程序的一个样例
2015-09-10 16:50
344 查看
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/uaccess.h> #include <linux/cdev.h> #define HELLO_MAJOR 248 #define HELLO_MINOR 1 #define HELLO_SIZE 4096 #define DEVICE_NAME "hello" static unsigned char hello_count = 0; static int hello_major = HELLO_MAJOR; static int hello_minor = HELLO_MINOR; static struct cdev *pdev = NULL; int hello_open(struct inode *inode, struct file *file) { if(hello_count > 0) return -1; file->private_data = kmalloc(HELLO_SIZE, GFP_KERNEL); if(file->private_data == NULL) return -1; memset(file->private_data, 0, HELLO_SIZE); printk(KERN_INFO "hello_open succeed: %d: %d\n", MAJOR(inode->i_rdev), MINOR(inode->i_rdev)); hello_count ++; return 0; } int hello_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { switch(cmd) { case 0x01: printk(KERN_INFO "hello_ioctl succeed: %d\n", cmd); break; default: printk(KERN_ERR "hello_ioctl failed: %d\n", cmd); break; } return 0; } ssize_t hello_read(struct file *file, char __user *buffer, size_t length, loff_t *offset) { if(length < HELLO_SIZE || copy_to_user(buffer, file->private_data, length) != 0) { printk(KERN_ERR "hello_read failed!\n"); return -1; } printk(KERN_INFO "hello_read succeed\n"); return 0; } ssize_t hello_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset) { if(length > HELLO_SIZE || copy_from_user(file->private_data, buffer, length) != 0) { printk(KERN_ERR "hello_write failed!\n"); return -1; } printk(KERN_INFO "hello_write succeed\n"); return 0; } int hello_close(struct inode *inode, struct file *file) { if(file->private_data) kfree(file->private_data); hello_count --; return 0; } static struct file_operations hello_fops = { .owner = THIS_MODULE, .open = hello_open, .ioctl = hello_ioctl, .read = hello_read, .write = hello_write, .release = hello_close, }; static int __init hello_init(void) { int ret = 0; dev_t dev_num = MKDEV(hello_major, hello_minor); ret = register_chrdev_region(dev_num, 1, DEVICE_NAME); if(ret != 0) { ret = alloc_chrdev_region(&dev_num, 0, 1, DEVICE_NAME); if(ret != 0) return ret; hello_major = MAJOR(dev_num); hello_minor = MINOR(dev_num); } pdev = kmalloc(sizeof(struct cdev), GFP_KERNEL); if(pdev == NULL) goto ErrP; memset(pdev, 0, sizeof(struct cdev)); cdev_init(pdev, &hello_fops); pdev->owner = THIS_MODULE; pdev->ops = &hello_fops; printk(KERN_INFO "Hello, World\n"); return cdev_add(pdev, dev_num, 1); ErrP: unregister_chrdev_region(dev_num, 1); printk(KERN_ERR "hello_init failed!\n"); return -1; } static void __exit hello_exit(void) { if(pdev) { cdev_del(pdev); kfree(pdev); } unregister_chrdev_region(MKDEV(hello_major, hello_minor), 1); printk(KERN_INFO "Goodbye, World\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_AUTHOR("ljk@xdja.com"); MODULE_DESCRIPTION("LiJinKui"); MODULE_LICENSE("GPL");
相关文章推荐
- 【扩展欧几里得+解不等式】sgu106The equation
- poj 2431 贪心(最少的加油次数)
- 支持向量机通俗导论(理解SVM的三层境界)
- 文章标题
- Objective-c 内存溢出问题经验汇总
- POJ - 1251 Jungle Roads(最小生成树简单题)
- Android拓展系列(4)--vim编辑器的基本使用
- iBeacon工程
- shell中的${},##和%%的使用
- 唯一约束 和 唯一索引 有什么区别?
- android如何使用资源文件定义的颜色
- Mac 命令
- js闭包的用途详解
- Algorithm --> 树中求顶点A和B共同祖先
- .NET自动更新
- A - Prime Ring Problem(素数环,深搜,打表)
- JQuery select与radio的取值与赋值
- shell脚本中报错dirname:无效选项 -- b
- HDOJ 2087 剪花布条
- autoresizingMask