设备驱动中异步通知编程

设备驱动中异步通知编程主要用到一项数据结构两个函数

1.数据结构------fasync_struct结构体。

2.两个函数

   (1)处理FASYNC标志变更的

int fasync_helper(int fd, struct file *filp, int mode, struct fasync_struct **fa);

   (2)释放信号用的函数

void kill_fasync(struct fasync_struct **fa, int sig, int band);


和其他的设备驱动一样,将fasync_struct结构体指针放在设备结构体中仍然是最佳选择,如下给出了支持异步通知的设备结构体模板

struct xx_dev {
    struct cdev cdev;   /* cdev结构体 */
    ....
    struct fasync_struct *async_queue; /* 异步结构体指针*/
};


在设备驱动的fasync()函数中,只要简单的将该函数的3个参数及fasync_struct结构体指针的指针作为第4个参数传入fasync_helper()函数即可。下面代码给出了支持异步通知的设备驱动程序fasync()函数的模板:

static int xxx_fasync(int fd, struct file *filp, int mode)
{
    struct xxx_dev *dev = filp->private_data;
    return fasync_helper(fd, filp, mode, &dev->async_queue);
}


在设备资源可以获得时,应该调用kill_fasync()释放SIGIO信号,可读时第3个参数设置为POLL_IN,可写时第3个参数设置为POLL_OUT。

static ssize_t xxx_write(struct file *filp, const char __user **buf, size_t count, loff_t *f_pos)
{
    struct xxx_dev *dev = filp->private_data;
    ....
    /* 产生异步读信号 */
    if (dev->async_queue)
        kill_fasync(&dev->async_queue, SIGIO, POLL_IN);

    ...
}   


最后,在文件关闭时,即在设备驱动的release()函数中,应该调用设备驱动的fasync()函数将文件从异步通知的列表中删除。

static int xxx_release(struct inode *inode, struct file *filp)
{
    /* 将文件从异步通知队列中删除 */
    xxx_fasync(-1, filp, 0);
    ...
    return 0;
}  










原文地址:https://www.cnblogs.com/dyllove98/p/3138851.html