Linux 驱动框架---驱动中的异步
异步IO是对阻塞和轮询IO的机制补充,所谓异步IO就是在设备数据就绪时主动通知所属进程进行处理的机制。之所以说是异步是相对与被通知进程的,因为进程不知道也无法知道什么时候会被通知;这一机制非常类似于硬件上的中断。异步IO的实现也依赖于Linux内核进程的信号机制,因为异步IO就是通过SIGIO信号通知的进程,而进程在收到信号后就会像中断一样直接跳转去执行之前就注册好的信号处理接口。
用户空间
注册信号接口函数有两个版本的接口signal(int signal,sighandler_t handler)其中signal为内核定义的信号类型目前支持30种信号,每种信号也有其缺省的处理方式如果当前进程未指定某一信号的处理方式,系统就会按系统缺省的方式处理。还有一个比较新接口他功能也更加强大是 int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact))他们的详细使用和定义内容如下:
//接口
typedef void (*sighandler_t)(int);
//原型
sighandler_t signal(int signum, sighandler_t handler));
//定义
void (*signal(int signum, void (*handler))(int)))(int);
第一个参数指定信号的值,第二个参数指定针对前面信号的处理方式或接口,可以设置为如下值:
忽略该信号(参数设为SIG_IGN)
采用系统默认方式处理信号(参数设为SIG_DFL)
可以自己实现处理方式(参数指定一个函数地址)signal()
调用成功,返回上一次为成功安装信号signum而调用signal()时的handler值,失败则返回SIG_ERR。
sigaction:
int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact)); //struct sigaction 结构体
struct sigaction {
union {
__sighandler_t _sa_handler;
void (*_sa_sigaction)(int, struct siginfo *, void *);
} _u;
sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
}; //__sighandler_t
void (*__sighandler_t)(int );
sigaction的第一个参数和signal相同,第二和第三个参数都是 struct sigaction类型的指针,第一个为给这个信号新安插的处理接口,而第三个用来接收之前给这个信号安插的处理接口的返回。这个结构体中的union 是信号处理接口函数,使用的是哪一种取决与flags变量的bit标志,而sa_mask则负责在信号处理过程中对指定信号的掩蔽类似避免中断嵌套。最后一个sa_restorer现在已经废弃不建议再使用最后就是siginfo_t 结构体他是sigaction接口高级于signal接口的另一个力证。其中主要的成员是意义使用起来比较复杂在专门的地方学习,今天主要学习驱动部分的异步IO实现机制。
内核空间
前面说了应用层的信号使用和异步IO的工作原理,接下来就是说明驱动也就是内核空间的异步IO实现机制了。在用户空间是负责接收信号那么内核空间肯定就是负责信号的释放,但是要能释放信号给指定的进程还要满足几个条件:
- 文件是异步方式打开的。
- 当前进程是文件的属主。
其中第一个条件可以同通过打开文件时指定FASYNC标志或通过fcntl(fd,F_SETFL,...)接口修改文件标志以支持异步通知。第二个则是通过使用接口fcntl(fd,F_SETOWN,getpid());进行设置。
而在内核部分的实现主要依赖一个数据结构和两个接口

struct fasync_struct {
spinlock_t fa_lock;
int magic;
int fa_fd;
struct fasync_struct *fa_next; /* singly linked list */
struct file *fa_file;
struct rcu_head fa_rcu;
};
//释放信号
void kill_fasync(struct fasync_struct **, int, int);
//处理文件FASYNC 状态变更的接口
int fasync_helper(int, struct file *, int, struct fasync_struct **);

文件操作接口中有一个fasync接口函数在文件ASYNC状态变更时会被调用所以需要实现它,的实现模版大致如下:

ststic int xxx_async(int fd,struct file* filp,int mode)
{
...
...
//async 为struct fasync_struct 的指针
return fasync_helper(fd,filp,mode,&async) }

然后就是释放信号的的操作,这一部分有可能发生在中断也有可能发生的其他的接口函数中,比如写接口中可以释放IO可以读的就绪信号给进程,而读接口可以释放可以写的接口给进程等,具体的使用就是:

ststic int xxx(int fd,struct file* filp,...)
{
...
...
//async 为struct fasync_struct 的指针
kill_fasync(&async,signum,POLL_IN);
...
...
}

kill_fasync 第一个接口参数为 异步结构体指针而 第二个参数为信号值一般为SIGIO,第三个为IO事件可为如下值或如下的值的或组合
//events可以是以下几个宏的:
EPOLLIN :表示对应的文件描述符可以读(包括对端SOCKET正常关闭);
EPOLLOUT:表示对应的文件描述符可以写;
EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);
EPOLLERR:表示对应的文件描述符发生错误;
EPOLLHUP:表示对应的文件描述符被挂断;
EPOLLET: 将EPOLL设为边缘触发(Edge Triggered)模式,这是相对于水平触发(Level Triggered)来说的。
EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里
最后需要注意的是,在通过xxx_async接口把文件加入到异步通知列表后如果关闭文件或取消异步时需要通过这个接口把FD文件描述符设置为-1,并把async_queue设为None将文件从异步通知列表中移除。

//如
static int xxx_release(struct inode* inode,struct file *filp)
{
...
xxx_fasync(-1,filp,0);
...
return 0;
}

参考:
https://blog.csdn.net/Fury97/article/details/83041810
Linux 驱动框架---驱动中的异步的更多相关文章
- Linux 驱动框架---驱动中的阻塞
描述和API 阻塞IO和非阻塞IO的应用编程时的处理机制是不同的,如果是非阻塞IO在访问资源未就绪时就直接返回-EAGAIN,反之阻塞IO则会使当前用户进程睡眠直到资源可用.从应用场景来说两种方式分别 ...
- Linux 驱动框架---驱动中的中断
在单片机开发中中断就是执行过程中发生了一些事件需要及时处理,所以需要停止当前正在运行的处理的事情转而去执行中断服务函数,已完成必要的事件的处理.在Linux中断一样是如此使用但是基于常见的中断控制器的 ...
- Linux 驱动框架---驱动中的时间相关
内核中的时间 Linux 系统内核对于时间的管理依赖于硬件,硬件按一定的周期产生中断,周期由内核的一个配置值HZ决定在系统启动时会将定时器配置为HZ值指定的频率产生中断:同时内核和维护一个64位(X8 ...
- Linux 驱动框架---驱动中的并发
并发指多个执行单元被同时.并行的执行,而并发执行的单元对共享资源的访问就容易导致竟态.并发产生的情况分为抢占和并行(多核)和硬抢占(中断).Linux为解决这一问题增加了一系列的接口来解决并发导致的竟 ...
- 驱动框架入门——以LED为例[【转】
本文转载自;http://blog.csdn.net/oqqHuTu12345678/article/details/72783903 以下内容源于朱有鹏<物联网大讲堂>课程的学习,如有侵 ...
- I2C驱动框架(四)
参考:I2C子系统之platform_driver初始化——I2C_adap_s3c_init() 在完成platform_device的添加之后,i2c子系统将进行platform_driver的注 ...
- Linux驱动框架之framebuffer驱动框架
1.什么是framebuffer? (1)framebuffer帧缓冲(一屏幕数据)(简称fb)是linux内核中虚拟出的一个设备,framebuffer向应用层提供一个统一标准接口的显示设备.帧缓冲 ...
- linux驱动基础系列--linux spi驱动框架分析
前言 主要是想对Linux 下spi驱动框架有一个整体的把控,因此会忽略某些细节,同时里面涉及到的一些驱动基础,比如平台驱动.设备模型等也不进行详细说明原理.如果有任何错误地方,请指出,谢谢! spi ...
- Linux下USB驱动框架分析【转】
转自:http://blog.csdn.net/brucexu1978/article/details/17583407 版权声明:本文为博主原创文章,未经博主允许不得转载. http://www.c ...
随机推荐
- 记一次压测问题定位:connection reset by peer,TCP三次握手后服务端发送RST_网络_c359719435的专栏-CSDN博客 https://blog.csdn.net/c359719435/article/details/80300433
记一次压测问题定位:connection reset by peer,TCP三次握手后服务端发送RST_网络_c359719435的专栏-CSDN博客 https://blog.csdn.net/c3 ...
- 加密填补 填充 pad padding
RFC 1423 - Privacy Enhancement for Internet Electronic Mail: Part III: Algorithms, Modes, and Identi ...
- LOJ10064黑暗城堡
题目描述你知道黑暗城堡有 N 个房间,M 条可以制造的双向通道,以及每条通道的长度. 城堡是树形的并且满足下面的条件: 设 Di 为如果所有的通道都被修建,第 i 号房间与第 1 号房间的最短路径长 ...
- WPF权限控制——【2】模块、菜单、按钮
周末没有工作,没有写博客,因为觉得休息很必要:曾听到一句话是这样说的:"你们得救在乎归回安息:你们得力在乎平静安稳".当我想到太阳没秒钟要燃烧420万吨的燃料时,想到的就是造物主的 ...
- 【LAMP】搭建Web网站过程中的记录【Ubuntu18.04+Apache2.4+PHP7.2+MySQL5.7】
全文使用的环境如题,主机使用的是腾讯云主机. 内容应该会是linux和apache这些所有部分都有一点,因为是遇见一个问题就记录一个. 配置LAMP环境 这部分可以参考这篇文章:https://www ...
- workflow定时任务部分失败
workflow遇到一个问题,每天定时任务导致部分失败,截图如下 目前这个问题现场出现过是重启wf解决的 ,但是也给研发排查了,根本原因不清楚,不确保现场还会再遇到.
- Hbase Java API包括协处理器统计行数
package com.zy; import java.io.IOException; import org.apache.commons.lang.time.StopWatch; import or ...
- Jcrop图片裁剪
一.引入js和css 二.实现 1.jsp页面 <%-- Created by IntelliJ IDEA. User: a Date: 2019/8/19 Time: 9:36 To chan ...
- 【算法】数据结构与算法基础总览(中)——刷Leetcode等算法题时一些很实用的jdk辅助方法锦集
最近重新学习数据结构与算法以及刷leetcode算法题时,发现不少jdk自带的方法可以提升刷题的效率.这些小技巧不仅仅对刷算法题带来便利,对我们平时开发也是很有帮助的.本文以java语言为基础,记录了 ...
- AtCoder Beginner Contest 172
比赛链接:https://atcoder.jp/contests/abc172/tasks A - Calc 题意 给出一个正整数 $a$,计算 $a + a^2 + a^3$ .($1 \le a ...