首页 / LINUX / linux驱动程序中的异步编程
linux驱动程序中的异步编程
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了linux驱动程序中的异步编程,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2579字,纯文字阅读大概需要4分钟。
内容图文
linux驱动程序中的异步编程A
前面介绍的等待队列和轮询编程提供了较好的解决设备访问的机制,但是这些机制都
是由应用程序发起的,都需要应用程序主动访问设备。更完美的方式是由驱动程序主
动通知应用程序,也就是说,当驱动程序满足某些条件后,会主动通知应用程序处理
,这些处理方式有些像面向对象编程的事件,而在linux内核使用的事件是接下来要介
绍的信号。
#include<sys/types.h>
#include<sys/stat.h>
#include<stdio.h>
#include<fcntl.h>
#include<signal.h>
#include<unistd.h>
#define MAX_LEN 100
void input_handler(int num) //捕获处理函数
{
char data[MAX_LEN];
int len;
len=read(STDIN_FILENO,&data,MAX_LEN);
data[len]=0;
printf("input available:%s\n",data);
}
main()
{
int oflags;
signal(SIGIO,input_handler); //捕获SIGIO信号
//通过F_SETOWN将标准输入设备文件(驱动)STDIN_FILENO--的拥有者设置为
//当前进程,这样从设备驱动STDIN_FILENO发出的信号才能被当前进程所接到。
fcntl(STDIN_FILENO,F_SETOWN,getpid());
oflags=fcntl(STDIN_FILENO,F_GETFL);
// 通过F_SETFL使设备文件支持FASYNC,也就是异步通知模式。
fcntl(STDIN_FILENO,F_SETFL,oflags|FASYNC);
while(1);
}
B
设备驱动中异步通知编程比较简单,主要用到一项数据结构和两个函数。
数据结构是 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 结构体指针放在设备结构体中仍然是最
佳选择,代码清单给出了支持异步通知的设备结构体模板。
struct xxx_dev
{
struct cdev cdev; /*cdev 结构体*/
...
struct fasync_struct *async_queue; /* 异步结构体指针 */
};
在设备驱动的 fasync() 函数中,只需要简单地将该函数的 3 个参数以及
fasync_struct 结构体指针的指针作为第 4 个参数传入 fasync_helper()函数即
可。代码清单给出了支持异步通知的设备驱动程序 fasync()函数的模板。
//处理应用程序的F_SETFL命令的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);
}
static struct file_operations dev_fops=
{
.owner=...
.read=....
.write=...
.fasync=xxx_fasync;
}
在设备资源可以获得时,应该调用 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()函数将文件从异步通知的列表中删除。下面代码清单给出了支持异步通知的
设备驱动release()函数的模板。
static int xxx_release(struct inode *inode, struct file *filp)
{
struct xxx_dev *dev = filp->private_data;
/* 将文件从异步通知列表中删除 */
xxx_fasync(-1, filp, 0);
...
return 0;
}
应用程序:
打开两个终端,一个运行应用程序,另外一个执行 echo "hello" >/dev/设备名 ,
执行完这条指令后,驱动调用write函数,驱动程序中的write函数中会调用
kill_fasync(&dev->async_queue, SIGIO, POLL_IN); /* 产生异步读信号 */ ,
这样应用程序马上捕捉到SIGIO,此时应用程序进入处理接受信号函数。
原文:http://blog.csdn.net/u012590688/article/details/46226019
内容总结
以上是互联网集市为您收集整理的linux驱动程序中的异步编程全部内容,希望文章能够帮你解决linux驱动程序中的异步编程所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。