驱动篇:异步通知与异步 I/O(二)

驱动篇:异步通知与异步 I/O(二)

1.信号的释放
在设备驱动和应用程序的异步通知交互中,仅仅在应用程序端捕获信号是不够的,因为信号没有的源头在设备驱动端。因此,应该在合适的时机让设备驱动释放信号,在设备驱动程序中增加信号释放的相关代码。为了使设备支持异步通知机制,驱动程序中涉及以下 3 项工作:
l 支持 F_SETOWN 命令,能在这个控制命令处理中设置 filp->f_owner 为对应
进程 ID。不过此项工作已由内核完成,设备驱动无须处理。
l 支持 F_SETFL 命令的处理,每当 FASYNC 标志改变时,驱动程序中的 fasync()
函数将得以执行。因此,驱动中应该实现 fasync()函数。
l 在设备资源可获得时,调用 kill_fasync()函数激发相应的信号。
驱动中的上述 3 项工作和应用程序中的 3 项工作是一一对应的,图 9.2 所示为异步通知处理过程中用户空间和设备驱动的交互
在这里插入图片描述设备驱动中异步通知编程比较简单,主要用到一项数据结构和两个函数。数据结构是 fasync_struct 结构体,两个函数分别如下

处理 FASYNC 标志变更的函数。
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_struct 结构体指针放在设备结构体中仍然是最佳选择,代码清单 9.3 给出了支持异步通知的设备结构体模板。
struct xxx_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()
函数将文件从异步通知的列表中删除。代码清单 9.6 给出了支持异步通知的设备驱动
release()函数的模板。

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

static int xxx_release(struct inode *inode, struct file *filp)
 {
 struct xxx_dev *dev = filp->private_data;
 /* 将文件从异步通知列表中删除 */
 xxx_fasync(-1, filp, 0);
 ...
 return 0;
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值