异步通知《来自Linux驱动程序开发实例》

您所在的位置:读书频道 > 操作系统 > Linux > 1.2.8 异步通知

1.2.8 异步通知

2012-05-22 13:38 冯国进 机械工业出版社 我要评论(0) 字号: T | T
一键收藏,随时查看,分享好友!

《Linux驱动程序开发实例》第1章 Linux设备驱动程序模型,本章主要介绍Linux内核中的驱动程序模型,包括三类设备的驱动程序、proc文件系统、Sysfs文件系统、Kobject等内容。本节为大家介绍异步通知。

AD: 51CTO云计算架构师峰会 抢票进行中!


    1.2.8  异步通知

    驱动程序与应用程序不能直接通信,如果设备已经准备好数据,可以采用异步通知的方式通知应用层来读取,这样应用程序就不需要一直查询设备的状态。要支持异步通知,需要实现设备驱动程序的fasync接口。当一个打开的文件的FASYNC标志变化时file_operations ->fasync()接口将被调用。file_operations ->fasync函数会调用fasync_helper从相关的进程列表中添加或去除异步通知关联。

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

    当数据到达时 kill_fasync函数将被用来通知相关的进程:
       
       
    1. void kill_fasync(struct fasync_struct **fa, int sig, int band); 

    例1.8  异步通知实例

    代码见光盘\src\1drivermodel\1-8fasync。驱动层代码如下:

       
       
    1. struct simple_dev *simple_devices;  
    2. static unsigned char simple_inc=0;  
    3. static struct timer_list simple_timer;  
    4. static struct fasync_struct *fasync_queue=NULL;  
    5. int simple_open(struct inode *inode, struct file *filp)  
    6. {  
    7.     struct simple_dev *dev;  
    8.     dev = container_of(inode->i_cdev, struct simple_dev, cdev);  
    9.     filp->private_data = dev;  
    10.     simple_timer.function = &simple_timer_handler;  
    11.     simple_timer.expires = jiffies + 2*HZ;  
    12.     add_timer (&simple_timer);  
    13.     printk("add_timer...\n");  
    14.     return 0;  
    15. }  
    16. //异步通知处理函数  
    17. static int simple_fasync(int fd, struct file * filp, int mode)   
    18. {  
    19.     int retval;  
    20.     printk("simple_fasync...\n");  
    21.     retval=fasync_helper(fd,filp,mode,&fasync_queue);  
    22.     if(retval<0)  
    23.       return retval;  
    24.     return 0;  
    25. }  
    26. int simple_release(struct inode *inode, struct file *filp)  
    27. {  
    28.     simple_fasync(-1, filp, 0);  
    29.     return 0;  
    30. }  
    31. struct file_operations simple_fops = {  
    32.     .owner =    THIS_MODULE,  
    33.     .open =     simple_open,  
    34.     .release=   simple_release,  
    35.     .fasync=    simple_fasync,  
    36. };  

    当数据来临时通知应用层:
       
       
    1. static void simple_timer_handler( unsigned long data)  
    2. {  
    3.     printk("simple_timer_handler...\n");  
    4.     if (fasync_queue)  
    5.     {  
    6.       //POLL_IN为可读,POLL_OUT为可写  
    7.       kill_fasync(&fasync_queue, SIGIO, POLL_IN);  
    8.       printk("kill_fasync...\n");  
    9.     }  
    10.     return ;  
    11. }  

    POLL_IN表示设备可读,POLL_OUT表示设备可写。应用层参考代码如下:
       
       
    1. int fd;  
    2. void fasync_handler(int num)  
    3. {  
    4.    printf("fasync_handler entering\n");  
    5. }  
    6. void main()  
    7. {  
    8.   int i=2;  
    9.   char data[256];  
    10.   int oflags=0;  
    11.   int retval;  
    12.   signal(SIGIO, fasync_handler);//注册信号处理函数  
    13.   fd=open("/dev/fcn",O_RDWR);  
    14.   if(fd==-1)  
    15.   {  
    16.      perror("error open\n");  
    17.      exit(-1);  
    18.   }  
    19.   printf("open /dev/fcn successfully\n");  
    20.   //使能了异步的通知到当前进程  
    21.   fcntl(fd, F_SETOWN, getpid());  
    22.   oflags=fcntl(fd, F_GETFL);  
    23.   fcntl(fd, F_SETFL, oflags | FASYNC);//修改文件标志  
    24.   while(1);  
    25.   close(fd);  
    26. }  

    运行结果如下:
       
       
    1. [root@urbetter /home]# insmod demo.ko  
    2. [root@urbetter /home]# mknod /dev/fcn c 226 0  
    3. [root@urbetter /home]# ./test  
    4. add_timer...  
    5. open /dev/fcn successfullysimple_fasync...  
    6.  
    7. simple_timer_handler...  
    8. kill_fasync...  
    9. fasync_handler entering  

    【责任编辑: book TEL:(010)68476606】

    • 0
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值