linux驱动开发--字符设备:创建一组设备节点

www.edpli.com


为设备驱动支持多个设备个体做准备,针对cdev进行改进
将代表字符设备的cdev对象包含在设备驱动定义的私有数据结构体中
对设备驱动私有数据结构体采用内核内存分配方式为其分配内存

将为每个设备添加cdev对象和创建设备节点封装为一个独立函数

支持多个设备个体
为设备驱动支持多个设备个体对驱动进行改进
循环调用为每个设备添加cdev对象和创建设备节点而封装的独立函数实现在系统中添加对多个设备个体的支持


[objc] view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /**

  2. *Copyright (c) 2013.TianYuan

  3. *All rights reserved.

  4. *

  5. *文件名称: char_device_driver06.c

  6. *文件标识: 支持多设备:创建10个设备节点文件,操作函数还需修改

  7. *#测试: cat /dev/cdd0

  8. *当前版本:1.0

  9. *作者:wuyq

  10. *

  11. *取代版本:xxx

  12. *原作者:xxx

  13. *完成日期:2013-11-26

  14. */

  15. #include <linux/init.h>

  16. #include <linux/module.h>

  17. #include <linux/fs.h>

  18. #include <linux/cdev.h>

  19. #include <linux/device.h>

  20. #include <linux/slab.h>

  21. MODULE_LICENSE("GPL");  

  22. #define CDD_MAJOR   200//cat /proc/devices找一个尚未使用的

  23. #define CDD_MINOR   0

  24. #define CDD_COUNT   10

  25. dev_t dev = 0;  

  26. u32 cdd_major = 0;  

  27. u32 cdd_minor = 0;  

  28. structclassclass *dev_class = NULL;  

  29. struct cdd_cdev{  

  30. struct cdev cdev;  

  31. structdevice *dev_device;  

  32.    u8 led;  

  33. };  

  34. structcdd_cdev *cdd_cdevp = NULL;  

  35. int cdd_open(struct inode* inode, structfile *filp)  

  36. {  

  37. structcdd_cdev *pcdevp = NULL;  

  38.    printk("enter cdd_open!\n");  

  39.    pcdevp = container_of(inode->i_cdev, struct cdd_cdev, cdev);  

  40.    printk("led = %d\n", pcdevp->led);  

  41. return0;  

  42. }  

  43. int cdd_read(structfile *filp, char__user *buf, size_t count, loff_t *offset)  

  44. {  

  45.    printk("enter cdd_read!\n");  

  46. return0;  

  47. }  

  48. int cdd_write(structfile *filp, constchar__user *buf, size_t count, loff_t *offset)  

  49. {  

  50.    printk("enter cdd_write!\n");  

  51. return0;  

  52. }  

  53. int cdd_ioctl(structinode *inode, structfile *filp, unsigned int cmd, unsigned long data)  

  54. {  

  55.    printk("enter cdd_ioctl!\n");  

  56. return0;  

  57. }  

  58. int cdd_release(structinode *inode, structfile *filp)  

  59. {  

  60.    printk("enter cdd_release!\n");  

  61. return0;  

  62. }  

  63. struct file_operations cdd_fops = {  

  64. .owner = THIS_MODULE,  

  65. .open = cdd_open,  

  66. .read = cdd_read,  

  67. .write = cdd_write,  

  68. .ioctl = cdd_ioctl,  

  69. .release = cdd_release,  

  70.    };  

  71. int __init cdd_init(void)  

  72. {  

  73. int ret = 0;  

  74. int i = 0;  

  75. if(cdd_major){  

  76.        dev = MKDEV(CDD_MAJOR, CDD_MINOR);//生成设备号

  77. //注册设备号;1、要注册的起始设备号2、连续注册的设备号个数3、名字

  78.        ret = register_chrdev_region(dev, CDD_COUNT, "cdd_demo");  

  79.    }else{  

  80. // 动态分配设备号

  81.        ret = alloc_chrdev_region(&dev, cdd_minor, CDD_COUNT, "cdd_demo02");  

  82.    }  

  83. if(ret < 0){  

  84.        printk("register_chrdev_region failed!\n");  

  85. goto failure_register_chrdev;  

  86.    }  

  87. //获取主设备号

  88.    cdd_major = MAJOR(dev);  

  89.    printk("cdd_major = %d\n", cdd_major);  

  90.    cdd_cdevp = kzalloc(sizeof(struct cdd_cdev)*CDD_COUNT, GFP_KERNEL);  

  91. if(IS_ERR(cdd_cdevp)){  

  92.        printk("kzalloc failed!\n");  

  93. goto failure_kzalloc;  

  94.    }  

  95. /*创建设备类*/

  96.    dev_class = class_create(THIS_MODULE, "cdd_class");  

  97. if(IS_ERR(dev_class)){  

  98.        printk("class_create failed!\n");  

  99. goto failure_dev_class;  

  100.    }  

  101. for(i=0; i<CDD_COUNT; i++){  

  102. /*初始化cdev*/

  103.        cdev_init(&(cdd_cdevp[i].cdev), &cdd_fops);  

  104. /*添加cdev到内核*/

  105.        cdev_add(&(cdd_cdevp[i].cdev), dev+i, 1);  

  106. /* “/dev/xxx” */

  107.        device_create(dev_class, NULL, dev+i, NULL, "cdd%d", i);  

  108.        cdd_cdevp[i].led = i;  

  109.    }  

  110. return0;  

  111. failure_dev_class:  

  112.    kfree(cdd_cdevp);  

  113. failure_kzalloc:  

  114.    unregister_chrdev_region(dev, CDD_COUNT);  

  115. failure_register_chrdev:  

  116. return ret;  

  117. }  

  118. void __exit cdd_exit(void)  

  119. {  

  120. /*逆序消除*/

  121. int i = 0;  

  122. for(; i < CDD_COUNT; i++){  

  123.        device_destroy(dev_class, dev+i);  

  124.        cdev_del(&(cdd_cdevp[i].cdev));  

  125. //cdev_del(&((cdd_cdevp+i)->cdev));

  126.    }  

  127.    class_destroy(dev_class);  

  128.    kfree(cdd_cdevp);  

  129.    unregister_chrdev_region(dev, CDD_COUNT);  

  130. }    

  131. module_init(cdd_init);  

  132. module_exit(cdd_exit);