Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4523323
  • 博文数量: 1148
  • 博客积分: 25453
  • 博客等级: 上将
  • 技术积分: 11949
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-06 21:14
文章分类

全部博文(1148)

文章存档

2012年(15)

2011年(1078)

2010年(58)

分类: LINUX

2012-01-03 20:54:47

《精通linux设备驱动程序开发》第五章-字符设备驱动程序

==================================================================
注意:在官网源程序中,在/dev/下建立 设备节点,这句话有问题,导致
  1. device_create(cmos_class, NULL, MKDEV(MAJOR(cmos_dev_number), i),
  2.                       "cmos%d", i);
我在建立节点的时候,只能建立 /dev/cmos0 而不能建立/dev/cmos1

这里附上修改过的源码附件: cmos.rar   将rar修改为tar.bz2
  1. #include <linux/init.h>
  2. #include <linux/kernel.h>
  3. #include <linux/module.h>
  4. #include <linux/fs.h>
  5. #include <linux/cdev.h>
  6. #include <linux/types.h>
  7. #include <linux/slab.h>//kmalloc()
  8. #include <asm/uaccess.h>//copy_from_user
  9. #include <linux/pci.h>

  10. #define NUM_CMOS_BANKS 2

  11. /* Per-device (per-bank) structure */
  12. struct cmos_dev {
  13.     unsigned short current_pointer; /* Current pointer within the
  14.          bank */
  15.     unsigned int size; /* Size of the bank */
  16.     int bank_number; /* CMOS bank number */
  17.     struct cdev cdev; /* The cdev structure */
  18.     char name[10]; /* Name of I/O region */
  19.     /* ... */ /* Mutexes, spinlocks, wait
  20.          queues, .. */
  21. };
  22. struct cmos_dev *cmos_devp[NUM_CMOS_BANKS];

  23. static struct file_operations cmos_fops = {
  24.     .owner = THIS_MODULE, /* Owner *///<linux/fs.h>
  25. #if 0
  26.     .open = cmos_open, /* Open method */
  27.     .release = cmos_release, /* Release method */
  28.     .read = cmos_read, /* Read method */
  29.     .write = cmos_write, /* Write method */
  30.     .llseek = cmos_llseek, /* Seek method */
  31.     .ioctl = cmos_ioctl, /* Ioctl method */
  32. #endif
  33. };

  34. static dev_t cmos_dev_number; /* Allotted device number */
  35. struct class *cmos_class; /* Tie with the device model */

  36. #define CMOS_BANK_SIZE (0xFF*8)
  37. #define DEVICE_NAME "ywxcmos"
  38. #define CMOS_BANK0_INDEX_PORT 0x70
  39. #define CMOS_BANK0_DATA_PORT 0x71
  40. #define CMOS_BANK1_INDEX_PORT 0x72
  41. #define CMOS_BANK1_DATA_PORT 0x73


  42. unsigned char addrports[NUM_CMOS_BANKS] = {CMOS_BANK0_INDEX_PORT,
  43.                                            CMOS_BANK1_INDEX_PORT,};
  44. unsigned char dataports[NUM_CMOS_BANKS] = {CMOS_BANK0_DATA_PORT,
  45.                                            CMOS_BANK1_DATA_PORT,};

  46. static int __init cmos_init(void)
  47. {
  48.     int i;
  49.     int ret;
  50.     if(alloc_chrdev_region(&cmos_dev_number, 0,2, DEVICE_NAME) < 0) // register 2 dev
  51.     {
  52.         printk(KERN_DEBUG "Can't register device\n");
  53.         return -1;
  54.     }
  55.     //sys/class/ywxcmos_class/
  56.     cmos_class = class_create(THIS_MODULE, "ywxcmos_class");

  57.          
  58.     for(i = 0; i < NUM_CMOS_BANKS; i++)
  59.     {    
  60.         cmos_devp[i] = kmalloc(sizeof(struct cmos_dev), GFP_KERNEL);
  61.         if (!cmos_devp[i])
  62.         {
  63.             printk("Bad Kmalloc\n");
  64.             return -ENOMEM;
  65.         }

  66.         sprintf(cmos_devp[i]->name, "ywxcmos%d", i);

  67.         //proc/ioports cmoso cmos1
  68.         release_region(addrports[i], 2);////////add me

  69.         if(!(request_region(addrports[i], 2, cmos_devp[i]->name)))
  70.         {
  71.             printk("ywxcmos: I/O port 0x%x is not free.\n", addrports[i]);
  72.             return -EIO;
  73.         }

  74.         cmos_devp[i]->bank_number = i;
  75.         cdev_init(&cmos_devp[i]->cdev, &cmos_fops);
  76.         cmos_devp[i]->cdev.owner = THIS_MODULE;
  77.         ret = cdev_add(&cmos_devp[i]->cdev, (cmos_dev_number + i), 1);
  78.         if(ret)
  79.         {
  80.             printk("Bad cdev\n");
  81.             return ret;
  82.         }
  83.     }
  84.     
  85.     //dev/ywxcmos0 /dev/ywxcmos1
  86.     device_create(cmos_class, NULL, MKDEV(MAJOR(cmos_dev_number), 0),NULL,"ywxcmos0");
  87.     device_create(cmos_class, NULL, MKDEV(MAJOR(cmos_dev_number), 1),NULL,"ywxcmos1");
  88.     printk("ywxCMOS Driver Initialized.\n");
  89.     return 0;
  90. }

  91. /* Driver Exit */
  92. static void __exit cmos_cleanup(void)
  93. {
  94.     int i;

  95.     printk("exit starting...\n");
  96.     /* Release the major number */
  97.     unregister_chrdev_region((cmos_dev_number), NUM_CMOS_BANKS);

  98.     /* Release I/O region */
  99.     for(i=0; i<NUM_CMOS_BANKS; i++)
  100.     {
  101.         device_destroy (cmos_class, MKDEV(MAJOR(cmos_dev_number), i));
  102.         release_region(addrports[i], 2);
  103.         cdev_del(&cmos_devp[i]->cdev);
  104.         kfree(cmos_devp[i]);
  105.     }

  106.     /* Destroy cmos_class */
  107.     class_destroy(cmos_class);
  108.     printk("exit finished..\n");
  109. }

  110. MODULE_LICENSE("GPL");

  111. module_init(cmos_init);
  112. module_exit(cmos_cleanup);

显示测试:
  1. ywx@ywx:~/Desktop/module/jingtong/cmos$ sudo insmod ./cmos.ko
  2. ywx@ywx:~/Desktop/module/jingtong/cmos$ ls /dev/ywxcmos*
  3. /dev/ywxcmos0 /dev/ywxcmos1  在/dev/下新建了设备节点
  4. ywx@ywx:~/Desktop/module/jingtong/cmos$ cat /proc/devices | grep ywx
  5. 250 ywxcmos 这是动态分配的主设备号
  6. ywx@ywx:~/Desktop/module/jingtong/cmos$ ls /sys/class/ywxcmos_class/
  7. ywxcmos0 ywxcmos1在/sys/class/下新建了 ywxcmos_class 设备类
  8. ywx@ywx:~/Desktop/module/jingtong/cmos$ grep cmos /proc/ioports
  9.   0070-0071 : ywxcmos0  io分配的内存 request_region
  10.   0072-0073 : ywxcmos1
  11. ywx@ywx:~/Desktop/module/jingtong/cmos$ sudo rmmod cmos
  12. ywx@ywx:~/Desktop/module/jingtong/cmos$ dmesg | tail -5
  13. [ 521.275943] [<c0217d85>] ? sys_close+0x75/0xc0
  14. [ 521.275947] [<c05cc204>] syscall_call+0x7/0xb
  15. [ 521.282050] ywxCMOS Driver Initialized.
  16. [ 610.405604] exit starting...
  17. [ 610.410214] exit finished..

==================================================================
参考资料:
精通linux设备驱动程序开发 笔记之九
精通linux设备驱动程序开发官网
   listing05.1.html



阅读(4793) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~