设备驱动中异步通知编程主要用到一项数据结构和两个函数。
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; }