我是靠谱客的博主 可靠天空,最近开发中收集的这篇文章主要介绍Linux驱动开发--实现设备的异步通知,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

异步通知:即设备准备就绪时主动通知设备

基本实现原理:

    1,当设备可读时,发送一个信号通知应用程序

    2,应用程序接收到信号后,执行读操作

    举例:异步通知编程:

void input_handler(int num)
{
   char data[MAX_LEN];
   int len;
 //读取并输出STDIN_FILENO 上的输入
   len = read(STDIN_FILENO, &data, MAX_LEN);
   data[len] = 0;
   printf("input available:%sn", data);
 }

 int main()
{
   int oflags;
 //启动信号驱动机制
   signal(SIGIO, input_handler);
   fcntl(STDIN_FILENO, F_SETOWN, getpid());
   oflags = fcntl(STDIN_FILENO, F_GETFL);
   fcntl(STDIN_FILENO, F_SETFL, oflags | FASYNC);
 //最后进入一个死循环,仅为保持进程不终止,如果程序中没有这个死循环
 //会立即执行完毕
   while (1);
 }
由此可见,为了在用户空间中能处理一个设备释放的信号,它必须完成以下3 项工作。
 通过F_SETOWN IO 控制命令设置设备文件的拥有者为本进程,这样从设备驱动发出的信号才能
被本进程接收到。
 通过F_SETFL IO 控制命令设置设备文件支持FASYNC,即异步通知模式。

 通过signal()函数连接信号和信号处理函数。


为了使设备支持异步通知机制,驱动程序中涉及以下3 项工作。
 支持F_SETOWN 命令,能在这个控制命令处理中设置filp->f_owner 为对应进程ID。不过此项工
作已由内核完成,设备驱动无须处理。
 支持F_SETFL 命令的处理,每当FASYNC 标志改变时,驱动程序中的fasync()函数将得以执行。
因此,驱动中应该实现fasync()函数。

 在设备资源可获得时,调用kill_fasync()函数激发相应的信号。



设备驱动中异步通知:

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   xxx_dev{
struct  cdev  cdev;
...
struct  fasync_struct  * async_queue; /*异步结构体指针*/
};

在设备驱动的fasync()函数中,只需要简单地将该函数的3 个参数以及fasync_struct 结构体指针的指针作为第4 个参数传入fasync_helper()函数即可。
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)
{
struct xxx_dev *dev = filp->private_data;
/* 将文件从异步通知列表中删除 */
xxx_fasync(-1, filp, 0);
...
return 0;
}




最后

以上就是可靠天空为你收集整理的Linux驱动开发--实现设备的异步通知的全部内容,希望文章能够帮你解决Linux驱动开发--实现设备的异步通知所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部