`
java-mans
  • 浏览: 11413395 次
文章分类
社区版块
存档分类
最新评论

【Linux 驱动】第六章 高级字符驱动程序操作----异步通知

 
阅读更多

一,概念

异步通知:一旦设备就绪,则主动通知应用程序,应用程序根本就不需要查询设备状态。(类似于中断)信号是异步的,一个进程不必通过任何操作来等待信号的到达


在linux中,异步通知是使用信号来实现的,而在linux,大概有30种信号,比如大家熟悉的ctrl+c的sigint信号,进程能够忽略或者捕获除过SIGSTOP和SIGKILL的全部信号,当信号背捕获以后,有相应的函数来处理它。


二,应用程序角度考虑

应用程序为了启用文件的异步通知机制,必须执行两个步骤:
1)指定一个进程作为文件的"属主",进程可以使用fcntl执行F_SETOWN命令(此时进程id号被保存在filp->f_owner中),目的是为了让内核知道应该通知哪个进程。
2)用户通过fcntl的F_SETFL命令设置FASYNC标志。
执行完上述两个步骤后,输入文件可以在数据到达时请求发送一个ISGIO信号(驱动程序发送),该信号发送到存放在filp->f_owner中的进程。

如下示例代码启用stdin文件的异步通知机制:
  1. signal(SIGIO,&input_handler);
  2. fcntl(STDIN_FILENO,F_SETOWN,getpid());
  3. oflags=fcntl(STDIN_FILENO,F_GETFL);
  4. fcntl(STDIN_FILENO,F_SETFL,oflags|FASYNC);

应用程序中还有两点注意:应用程序不是所有设备都支持异步通知,通常应用程序假设只有套接字和终端才有异步通知能力;如果有多个文件可以异步通知输入的进程,应用程序需要借助poll或者select来确定输入的来源(利用FD_ISSET来判断)。


三,驱动程序角度考虑

那么驱动程序如何来实现异步信号呢?

内核已经提供了很方便的函数给我们使用,为了实现异步信号,驱动程序需要做三件事情:

1)实现fasync方法:该方法也只需要做一步,调用内核提供的fasync_helper函数,如下是scullp设备提供的实现代码:

  1. staticintscull_p_fasync(intfd,struct file*filp,intmode)
  2. {
  3. struct scull_pipe*dev=filp->private_data;
  4. return fasync_helper(fd,filp,mode,&dev->async_queue);
  5. }

2)当数据到达时,需要实现异步通知,这时需要调用kill_fasync,当数据可读时,此时需要通知应用程序数据可读,如下是scullp设备提供的代码:

  1. if(dev->async_queue)
  2. kill_fasync(&dev->async_queue,SIGIO,POLL_IN);

如果是为写入提供异步信号,kill_fasync必为模式调用POLL_OUT。

3)在文件关闭时必须调用fasync方法,以便从活动的异步读取进程列表中删除该文件,所有在close方法中有如下调用:

  1. sucll_p_fasync(-1,filp,0);

四,llseeek实现

llseek方法对应lseek和llseek系统调用,该方法通过直接修改filp->f_pos执行定位操作,filp->f_pos记录的文件的读写位置,为了让lseek系统调用正确工作,read/write方法必须通过更新它们收到的偏移量参数来配合。在scull设备中的该方法实现如下:
  1. loff_t scull_llseek(struct file *filp, loff_t off, int whence)
    {
    struct scull_dev *dev = filp->private_data;
    loff_t newpos;
    
    switch(whence) {
    case 0: /* SEEK_SET */
    newpos = off;
    break;
    
    case 1: /* SEEK_CUR */
    newpos = filp->f_pos + off;
    break;
    
    case 2: /* SEEK_END */
    newpos = dev->size + off;
    break;
    
    default: /* can't happen */
    return -EINVAL;
    }
    if (newpos < 0) return -EINVAL;
    filp->f_pos = newpos;
    return newpos;
    }




    分享到:
    评论

    相关推荐

      Linux设备驱动详解第二版

      第6章 字符设备驱动 118 第7章 Linux设备驱动中的并发控制 139 第8章 Linux设备驱动中的阻塞与非阻塞I/O 161 第9章 Linux设备驱动中的异步通知与异步I/O 176 第10章 中断与时钟 193 第11章 内存与I/...

      华清远见驱动教程

      -第6章、字符设备驱动 -第7章、Linux设备驱动中的并发控制 -第8章、Linux设备驱动中的阻塞与非阻塞IO -第9章、Linux设备驱动中的异步通知与异步IO -第10章、中断与时钟 -第11章、内存与I-O访问 -第12章、Linux字符...

      嵌入式Linux应用开发完全手册有目录2

       第6章 存储器控制  第7章 内存管理单元MMU  第8章 NANDFlash控制器  第9章 中断体系结构  第10章 系统时钟和定时器  第11章 通用异步收发器UART  第12章 I*IC接口  第13章 LCD控制器  第...

      LINUX设备驱动第三版_588及代码.rar

      第六章 高级字符驱动程序操作 ioctl 阻塞型I/O poll和select 异步通知 定位设备 设备文件的访问控制 快速参考 第七章 时间、延迟及延缓操作 度量时间差 获取当前时间 延迟执行 内核定时器 tasklet ...

      韦东山Linux视频第1期_裸板_UBoot_文件系统_驱动初步

      也可去华为网盘下载! ... 第1课 环境搭建及工具、概念介绍 第2课 GPIO实验 第3课 存储管理器实验 第4课 MMU实验 ...第12课第6节 字符设备驱动程序之异步通知 第12课第7节 字符设备驱动程序之同步互斥阻塞

      linux设备驱动程序

      第六章 高级字符驱动程序操作 ioctl 阻塞型I/O poll和select 异步通知 定位设备 设备文件的访问控制 快速参考 ch07.第七章 时间、延迟及延缓操作 度量时间差 获取当前时间 延迟执行 内核定时器 tasklet 工作队列 ...

      嵌入式Linux应用开发完全手册

      第6章 存储器控制 第7章 内存管理单元MMU 第8章 NAND Flash控制器 第9章 中断体系结构 第10章 系统时钟和定时器 第11章 通用异步收发器UART 第12章 I*IC接口 第13章 LCD控制器 第14章 ADC和触摸屏接口 第3篇 嵌入式...

      韦东山视频目录+链接整合-1 视频目录

      韦东山视频目录+链接整合-1 : 第1课 环境搭建及工具、概念介绍 第2课 GPIO实验 第3课 存储管理器实验 ...第12课第6节 字符设备驱动程序之异步通知 第12课第7节 字符设备驱动程序之同步互斥阻塞

      嵌入式Linux应用开发完全手册有目录1(共2个)

       第6章 存储器控制  第7章 内存管理单元MMU  第8章 NANDFlash控制器  第9章 中断体系结构  第10章 系统时钟和定时器  第11章 通用异步收发器UART  第12章 I*IC接口  第13章 LCD控制器  第...

      linux设备驱动程序第三版

      1. Linux 设备驱动第三版 .................................................................................................................... 5 2. 第 1 章 设备驱动简介 ....................................

      Android驱动开发权威指南

      第6章Linux字符设备驱动 6.1 Linux字符设备驱动结构 6.1.1 cdev结构体 6.1.2分配和释放设备号 6.1.3 file_operations结构体 6.1.4 Linux字符设备驱动的组成 6.2一个字符设备驱动例子——virtualchar 6.2.1头文件、...

      嵌入式Linux应用开发完全手册.pdf

      第6章 存储器控制 第7章 内存管理单元MMU 第8章 NANDFlash控制器 第9章 中断体系结构 第10章 系统时钟和定时器 第11章 通用异步收发器UART 第12章 I*IC接口 第13章 LCD控制器 第14章 ADC和触摸屏...

      Linux DeviceDrivers 3rd Edition

      第六章 高级字符驱动程序操作 137 ioctl 137 阻塞型I/O 149 poll和select 163 异步通知 168 定位设备 172 设备文件的访问控制 173 快速参考 179 第七章 时间、延迟及延缓操作 183 度量时间差 183 获取当前...

      Understanding the Linux Kernel

       第六章定时测量  时钟和定时器电路  Linux计时体系结构  更新时间和日期  更新系统统计数  软定时器和延迟函数  与定时测量相关的系统调用  第七章进程调度  调度策略  调度算法  调度程序所使用的数据...

      Linux内核情景分析

      第6章 传统的Unix进程间通信 6.1 概述 6.2 管道和系统调用pipe() 6.3 命名管道 6.4 信号 6. 5 系统调用ptrace()和进程跟踪 6.6 报文传递 6.7 共享内存 6.8 信号量 《LINUX内核源代码情景分析(下册)》图书...

      Linux内核情景分析(非扫描版)

      第6章 传统的Unix进程间通信 6.1 概述 6.2 管道和系统调用pipe() 6.3 命名管道 6.4 信号 6. 5 系统调用ptrace()和进程跟踪 6.6 报文传递 6.7 共享内存 6.8 信号量 《LINUX内核源代码情景分析(下册)》图书...

      UNIX环境高级编程

      第6章 系统数据文件和信息 110 6.1 引言 110 6.2 口令文件 110 6.3 阴影口令 112 6.4 组文件 113 6.5 添加组ID 114 6.6 其他数据文件 115 6.7 登录会计 116 6.8 系统标识 116 6.9 时间和日期例程 117 6.10 小结 121 ...

      Linux内核源代码情景分析 (上下册 高清非扫描 )

      第6章 传统的Unix进程间通信 6.1 概述 6.2 管道和系统调用pipe() 6.3 命名管道 6.4 信号 6.5 系统调用ptrace()和进程跟踪 6.6 报文传递 6.7 共享内存 6.8 信号量 第7章基于socket的进程间通信 7.1系统调用...

    Global site tag (gtag.js) - Google Analytics