阻塞型字符设备驱动的编写

设置一个阻塞型字符设备驱动


  1. 在设备的读操作中加入阻塞函数:

...

While(!have_data)

{

      if (filp->f_flags & O_NONBLOCK)

            return -EAGAIN;

     wait_event_interruptible(dev->inq,have_data);

}

...

  1. 在设备的写操作完成后唤醒设备
     ...

have_data = true;    /*有新的数据可读了*/

Wake_up(&dev->inq);   /*唤醒读进程*/

      ...

  1. 另外,需要在设备的初始化初始化等待队列。

init_waitqueue_head(&(mem_devp[i].inq));


以上方法可以满足一般的需求,但是当一个应用程序需要同时监控多个设备文件的IO状态时,仅仅使用上面的read和write就不够了,需要引入poll和select方法。

 

设备的poll select方法

 

select 系统调用用于多路监控,当没有一个文件满足要求时,select将阻塞调用进程。

 

相应地,设备的select 方法由驱动程序的poll方法实现,当应用程序调用设备的select 时,poll 首先使用poll_wait将等待队列添加到 poll_table中,当条件成熟时(poll_wait 返回),再将描述设备是否可读或可写的掩码返回给select

 

工作原理,poll方法只是做一个登记,真正的阻塞发生在select.c中的do_select函数。

 

 

方法:

  1. 在一个阻塞型设备的基础上增加poll方法

 

  1. 在设备的fops中增加mem_poll方法:

#include<linux/poll.h>

 

 unsigned int mem_poll(struct file *filp,poll_table *wait)

 {

     struct mem_dev  *dev = filp->private_data;

     unsigned int mask = 0;

     

     /*将等待队列添加到poll_table */

     poll_wait(filp, &dev->inq,  wait);

   

     if (have_data)

mask|= POLLIN | POLLRDNORM;  /* readable */

 

     return mask;

 }

  1. 在应用程序中的使用:

 

#include<sys/select.h>

….

int fd;

fd_set rds;

fd = open ("/dev/memdevo", O_RDWR);

 

FD_ZERO(&rds);    //初始化rds结构

FD_SET(fd, &rds); //将设备文件与rds结构关联起来

 

ret = select (fd +1, &rds, NULL, NULL, NULL);

if (ret < 0) { … }

if (FD_ISSET(fd, &rds ))

read (fd, Buf, sizeof(Buf));

 

...

 

 

 

 

疑惑:这里只是给设备增加了一个mem_poll方法,而设备的读和写还是和阻塞型设备的实现一样。用户直接使用read, write还是可以实现设备的阻塞的。那还要poll为什么。

解惑:pollselect 更重要的意义在于它们可以使应用程序同时等待多个数据流,它们是readwrite的补充。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值