Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2974517
  • 博文数量: 523
  • 博客积分: 11908
  • 博客等级: 上将
  • 技术积分: 5475
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-03 15:50
文章分类

全部博文(523)

文章存档

2019年(3)

2013年(4)

2012年(71)

2011年(78)

2010年(57)

2009年(310)

分类: LINUX

2011-04-27 12:02:03

fasync这个东西就是为了使驱动的读写和application的读写分开,使得application可以在驱动读写时去做别的事,通过kill_fasync
(kill_fasync(&async, SIGIO, POLL_IN);)发SIGIO信号给应用,应用通过fcntl把自己这个SIGIO的信号换成自己的响应函数,当驱动发
(kill_fasync(&async, SIGIO, POLL_IN);)给应用时应用就调用了自己的handler去处理。fasync_helper作用就是初始化fasync这个东西,包括分配内存和设置属性。最后记得在驱动的release里把fasync_helper初始化的东西free掉。
POLL_IN POLL_OUT
=================================================================================
驱动程序向用户程序发信号
---------------------------------------------
    当设备有IO事件发生,就有机制保证向应用进程发送信号,显然设备驱动程序扮演重要角色,实际终端tty、网络socket等的标准实现已经包括了实时信号驱动的支持,所以,在Linux中它们可以如上直接使用。但有些设备的驱动程序还并没有支持,所以需要定制设备驱动程序。以下两个API应该是可以屏蔽所有相关琐碎操作(类似send_sig())的标准接口:
    int fasync_helper (int fd, struct file *filp, int mode, struct fasync_struct **fa);     
    void kill_fasync (struct fasync_struct **fa, int sig, int band);
   
    如果需要支持异步通知机制,如下设备结构中需要有异步事件通知队列(它应该与睡眠队列类似),并且增加fasync()接口的实现(该函数将本进程登记到async_queue上去)。 当一个打开的文件FASYNC标志变化时(调用fcntl()函数,设置FASYNC文件标志时),fasync()接口将被调用。
    struct kpp_dev {
        struct cdev cdev;
        struct fasync_struct *async_queue;
    };
    
    static int kpp_fasync(int fd, struct file *filp, int mode)
    {
        struct kpp_dev *dev = filp->private_data;
        return fasync_helper(fd, filp, mode, &dev->async_queue);
    }
    事件发生的时机,就是中断服务程序或相应的软中断中调用kill_fasync():
    if (dev->async_queue)
        kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
    如果是写操作,就是POLL_OUT。注意,无论用户进程设定了什么期望的信号,在这个环节,发送的一般就是SIGIO。注意在设备文件关闭(release方法)时,注意执行fasync(),使得本文件的操作从上述的设备异步事件等待链表中剥离。
    static int kpp_release(struct inode *inode, struct file *filp)
    {
        kpp_fasync(-1, filp, 0);
        return 0;
    }

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/woxiaozhi/archive/2010/10/11/5934138.aspx
阅读(1505) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~