《深入浅出Linux设备驱动》第一章 设备驱动概述(3)
作者 佚名技术
来源 Linux系统
浏览
发布时间 2012-05-16
52 } 53 /*根据写入的值点亮和熄灭LED*/ 54 if (dev->value == 1) 55 light_on(); 56 else 57 light_off(); 58 59 return 1; 60 } 61 62 /* ioctl函数 */ 63 int light_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 64 unsigned long arg) 65 { 66 struct light_dev *dev = filp->private_data; 67 68 switch (cmd) 69 { 70 case LIGHT_ON: 71 dev->value = 1; 72 light_on(); 73 break; 74 case LIGHT_OFF: 75 dev->value = 0; 76 light_off(); 77 break; 78 default: 79 /* 不能支持的命令 */ 80 return - ENOTTY; 81 } 82 83 return 0; 84 } 85 86 struct file_operations light_fops = 87 { 88 .owner = THIS_MODULE, 89 .read = light_read, 90 .write = light_write, 91 .ioctl = light_ioctl, 92 .open = light_open, 93 .release = light_release, 94 }; 95 96 /*设置字符设备cdev结构体*/ 97 static void light_setup_cdev(struct light_dev *dev, int index) 98 { 99 int err, devno = MKDEV(light_major, index); 100 101 cdev_init(&dev->cdev, &light_fops); 102 dev->cdev.owner = THIS_MODULE; 103 dev->cdev.ops = &light_fops; 104 err = cdev_add(&dev->cdev, devno, 1); 105 if (err) 106 printk(KERN_NOTICE "Error %d adding LED%d", err, index); 107 } 108 109 /*模块加载函数*/ 110 int light_init(void) 111 { 112 int result; 113 dev_t dev = MKDEV(light_major, 0); 114 115 /* 申请字符设备号*/ 116 if (light_major) 117 result = register_chrdev_region(dev, 1, "LED"); 118 else 119 { 120 result = alloc_chrdev_region(&dev, 0, 1, "LED"); 121 light_major = MAJOR(dev); 122 } 123 if (result < 0) 124 return result; 125 126 /* 分配设备结构体的内存 */ 127 light_devp = kmalloc(sizeof(struct light_dev), GFP_KERNEL); 128 if (!light_devp) /*分配失败*/ 129 { 130 result = - ENOMEM; 131 goto fail_malloc; 132 } 133 memset(light_devp, 0, sizeof(struct light_dev)); 134 light_setup_cdev(light_devp, 0); 135 light_init(); 136 return 0; 137 138 fail_malloc: unregister_chrdev_region(dev, light_devp); 139 return result; 140 } 141 142 /*模块卸载函数*/ 143 void light_cleanup(void) 144 { 145 cdev_del(&light_devp->cdev); /*删除字符设备结构体*/ 146 kfree(light_devp); /*释放在light_init中分配的内存*/ 147 unregister_chrdev_region(MKDEV(light_major, 0), 1); /*删除字符设备*/ 148 } 149 150 module_init(light_init); 151 module_exit(light_cleanup); 上述代码的行数与代码清单1-3已经不能比拟,除了代码清单1-3中的硬件操作函数仍然需要外,代码清单1-4中还包含了大量对我们暂时陌生的元素,如结构体file_operations、cdev,Linux内核模块声明用的MODULE_AUTHOR、 MODULE_LICENSE、module_init、module_exit,以及用于字符设备注册、分配和注销用的函数register_chrdev_region()、alloc_chrdev_region()、unregister_chrdev_region()等.我们也不能理解为什么驱动中要包含light_init ()、light_cleanup ()、light_read()、light_write()等这样的函数. 此时,我们只需要有一个感性认识,那就是,上述暂时陌生的元素都是Linux内核给字符设备定义的为实现驱动与内核接口而定义的.Linux对各类设备的驱动都定义了类似的 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |
你可能对下面的文章感兴趣
关于《深入浅出Linux设备驱动》第一章 设备驱动概述(3)的所有评论