Chinaunix首页 | 论坛 | 博客
  • 博客访问: 80254
  • 博文数量: 15
  • 博客积分: 346
  • 博客等级: 一等列兵
  • 技术积分: 170
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-14 17:20
文章分类
文章存档

2012年(15)

分类: LINUX

2012-05-14 19:34:53

---头文件

点击(此处)折叠或打开

  1. #include <linux/module.h>
  2. #include <linux/types.h>
  3. #include <linux/fs.h>
  4. #include <linux/error.h>
  5. #include <linux/mm.h>
  6. #include <linux/sched.h>
  7. #include <linux/init.h>
  8. #include <linux/cdev.h>
  9. #include <asm/io.h>
  10. #include <asm/system.h>
  11. #include <asm/uaccess.h>

---设备号的申请

点击(此处)折叠或打开

  1. static int mem_major = MEMDEV_MAJOR;

  2. int result;
  3. dev_t devno = MKDEV(mem_major, 0);

  4. if (mem_major)
  5.     result = register_chrdev_region(devno, 1, "chrdev");
  6. else
  7. {
  8.     //该处的chrdev的名字显示在/proc/devices里面,跟/dev中的设备节点木有关系,他们通过主设备号关联
  9.     result = alloc_chrdev_region(&devno, 0, 1, "chrdev");
  10.     mem_major = MAJOR(devno);
  11.     printk("Major-->%d\n", mem_major);
  12. }

  13. if (result < 0)
  14.     return result;
---利用private

点击(此处)折叠或打开

  1. /* 对于存在多个次设备的情况下filp->private_data就能发挥特殊作用 */
  2. int mem_open(struct inode *inode, struct file *filp)
  3. {
  4.     struct mem_dev *dev;
  5.     int num = MINOR(inode->i_rdev);//或者num = iminor(inode);
  6.     if (num >= MEMDEV_NR_DEVS)
  7.         return -ENODEV;
  8.     dev = &mem_devp[num];

  9.     filp->private_data = dev;
  10. }
---设备的初始化、注册和注销

点击(此处)折叠或打开

  1. struct cdev cdev;
  2. cdev_init(&cdev, &mem_fops);
  3. cdev.owner = THIS_MODULE;
  4. //cdev.ops = &mem_fops;
  5. //或者用下面的代码
  6. struct cdev *cdev = cdev_alloc();
  7. cdev->ops = &mem_fops;

  8. cdev_add(&cdev, MKDEV(mem_major, 0), MEMDEV_NR_DEVS);

  9. cdev_del(&cdev);
  10. unregister_chrdev_region(MKDEV(mem_major, 0), MEMDEV_NR_DEVS);
---创建、注销设备文件

点击(此处)折叠或打开

  1. //手动创建设备节点
  2. mknod filename type major minor
  3. //自动生成设备节点
  4. //2.6.12
  5. #ifdef CONFIG_DEVFS_FS
  6. devfs_mk_cdev(devno, S_IFCHR|S_IRUGO|S_IWUSR, "globalmem");
  7. #endif
  8. //2.6.32
  9. struct class *my_class;
  10. my_class = class_create(THIS_MODULE, "my_class");
  11. if (IS_ERR(my_class))
  12.     return -1;
  13. device_create(my_class, NULL, MKDEV(globalmem_major, 0), NULL, "globalmemdev");
  14. //自动注销设备节点
  15. device_destroy(my_class, MKDEV(globalmem_major, 0));
  16. class_destroy(my_class);
--poll模板

点击(此处)折叠或打开

  1. static unsigned int xxx_poll(struct file *filp, poll_tabel *wait)
  2. {
  3.     unsigned int mask = 0;
  4.     struct xxx_dev *dev = filp->private_data;

  5.     poll_wait(filp, &dev->r_wait, wait);
  6.     poll_wait(filp, &dev->w_wait, wait);

  7.     if (...)
  8.     {
  9.         mask |= POLLIN | POLLRDNORM;
  10.     }

  11.     if (xxx)
  12.     {
  13.         mask |= POLLOUT | POLLWRNORM;
  14.     }

  15.     ...
  16.     return mask;
  17. }
--应用层select
需要注意的是:读写集都要添加(否则,可能会有问题),根据需要选择while语句里面的if分支。

点击(此处)折叠或打开

  1. fd_set rfds, wfds;
  2. while(1)
  3. {
  4.     FD_ZERO(&rfds);
  5.     FD_ZERO(&wfds);
  6.     FD_SET(fd, &rfds);
  7.     FD_SET(fd, &wfds);

  8.     select(fd + 1, &rfds, &wfds, NULL, NULL);
  9.     if (FD_ISSET(fd, &rfds))
  10.     {
  11.         if (size = read(fd, buf_r, 10) < 10)
  12.         {
  13.             xxx;
  14.         }
  15.         else
  16.             xxx;
  17.     }

  18.     if (FD_ISSET(fd, &wfds))
  19.     {

  20.     }
  21. }
---tasklet和工作队列

点击(此处)折叠或打开

  1. //tasklet
  2. void xxx_do_tasklet(unsigned long);
  3. DECLARE_TASKLET(xxx_tasklet, xxx_do_tasklet, 0);

  4. /*中断底半部*/
  5. void xxx_do_tasklet(unsigned long)
  6. {
  7. }

  8. /*中断顶半部*/
  9. irqreturn_t xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  10. {
  11.     ...
  12.     tasklet_schedule(&xxx_tasklet);
  13.     ...
  14. }

  15. //工作队列
  16. struct work_struct xxx_wq;
  17. void xxx_do_work(unsigned long);

  18. /*中断底半部*/
  19. void xxx_do_work(unsigned long)
  20. {
  21. }

  22. /*中断顶半部*/
  23. irqreturn_t xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  24. {
  25.     ...
  26.     schedule_work(&xxx_wq);
  27.     ...
  28. }

  29. int __init xxx_init(void)
  30. {
  31. ...
  32.     INIT_WORK(&xxx_wq, (void(*)(void*))xxx_do_work, NULL);
  33. ...
  34. }




阅读(1024) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:ubuntu 11.10 非root下sudo不输入密码

给主人留下些什么吧!~~