linux驱动开发学习三:异步操作

前面的队列以及锁都是基于阻塞是的操作。要实现同步,还可以通过信号也就是异步的方式来进行。例如在往文件的写入字符后,发送一个信号。捕捉到信号后执行动作。这样就不会造成阻塞,之前的阻塞性IO和POLL,是调用函数进去检查,条件不满足是造成阻塞。

应用层启动异步通知机制就三个步骤:

1 调用signal函数,让指定的信号SIGIO与处理函数sig_handle对应

2 指定一个进程作为文件的”属主(filp-owner)”, 这样内核才知道信号要发给哪个进程

3 在设备文件中添加FASYNC标志,驱动中就会调用xxx_fasync函数。

流程图如下:

在这里,命名为globalfifo_fasync

static const struct file_operations globalmem_fops={

.owner=THIS_MODULE,

.llseek=globalmem_llseek,

.read=globalmem_read_queue,

.write=globalmem_write_queue,

.unlocked_ioctl=globalmem_ioctl,

.open=globalmem_open,

.release=globalmem_release,

.fasync=globalfifo_fasync,

};

globalfifo_fasync函数实现如下,当文件的模式被设置成FASYNC的时候,将会调用这个函数

static int globalfifo_fasync(int fd,struct file *filp,int mode)

{

struct globalmem_dev *dev=filp->private_data;

return fasync_helper(fd,filp,mode,&dev->async_queue);

}

在 globalfifo_fasync中实际调用的是fasync_add_entry。

(1)     申请一个fasync_struct结构体。可以看到这个结构体手链表形式。fa_fd关联了设备文件fd参数

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;

};

(2)     调用fasync_insert_entry将新分配的fasync_struct插入到fasync列表中去。代码如下,如果能在fasync列表中找到对应的filp文件。则直接返回。如果没有找到,则将new插入到fapp的最前面。插入方法new->fa_fd = fd; new->fa_next = *fapp; 和前面介绍的列表插入方法是一样的。

4 等操作完成后,比如写完成,此时可以读取数据了,则通过kill_fasync释放一个信号。代码如下

实际起作用的是kill_fasync_rcu函数,在这个里面,遍历列表中所有的数据,找到owner以及fd。然后发送相应的信号

5 等操作完后fasync_remove_entry将异步队列清空

原文地址:https://www.cnblogs.com/zhanghongfeng/p/12286298.html

时间: 2024-10-09 09:12:31

linux驱动开发学习三:异步操作的相关文章

Linux驱动开发之 三 (那些必须要了解的硬件知识 之 存储器篇)

Linux驱动开发之 三 (那些必须要了解的硬件知识 之 存储器篇) 本文重点学习存储器相关的基本知识,网络上对RAM,ROM,FLASH等有非常详细的介绍,老谢将这些知识点摘抄整理并加以注释如下.这个整理的过程也是加深记忆的过程. 1.什么是内存 在计算机的组成结构中,有一个很重要的部分,就是存储器.存储器是用来存储程序和数据的部件,对于计算机来说,有了存储器,才有记忆功能,才能保证正常工作.存储器的种类很多,按其用途可分为主存储器和辅助存储器,主存储器又称内存储器(简称内存),辅助存储器又称

linux驱动开发学习路线

这篇文章是和大四学弟交流的文章,贴出来,和大家学习讨论 需要掌握的基本技能: C/C++/ python shell makefile linux基本操作 以android手机为例,我通俗的介绍下市场上产品的软件结构. 手机---> 硬件:cpu(arm架构单片机)+各种传感器(显示屏.距离传感器.温度传感器.gms模块 gprs模块等等).本质上手机就是一个单片机加上一堆传感器,单片机控制各个传感器与人进行负责的交互.(驱动工程师就是在linux底层让传感器可以工作,然后提供控制硬件的接口交给

Linux驱动开发学习的一些必要步骤

1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, lsmod, rmmod. 在驱动的init函数里打印hello world, insmod后应该能够通过dmesg看到输出. 5. 写一完整驱动, 加上read, write, ioctl, polling等各种函数的驱动实现. 在ioctl里完成从用户空间向内核空间传递结构体的实现. 6. 写一bl

linux驱动开发(三) 字符设备驱动框架

还是老规矩先上代码 demo.c #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/cdev.h> #include <linux/fs.h> int demo_major = 250; int demo_minor = 0; int demo_count = 1; struct cdev cdev; int de

linux驱动开发(三) 字符设备驱动框架(自动创建设备节点)

代码如下 #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/cdev.h> #include <linux/fs.h> #include <linux/device.h> int demo_major = 250; int demo_minor = 0; int demo_count = 1; stru

Hasen的linux设备驱动开发学习之旅--异步通知

/** * Author:hasen * 参考 :<linux设备驱动开发详解> * 简介:android小菜鸟的linux * 设备驱动开发学习之旅 * 主题:异步通知 * Date:2014-11-05 */ 一.异步通知的概念和作用 阻塞和非阻塞访问.poll()函数提供了较好地解决设备访问的机制,但是如果有了异步通知整套机制就更 加完整了. 异步通知的意思是:一旦设备就绪,则主动通知应用程序,这样应用程序根本就不需要查询设备状态,这 一点非常类似于硬件上"中断"的概

Hasen的linux设备驱动开发学习之旅--异步I/O

/** * Author:hasen * 参考 :<linux设备驱动开发详解> * 简介:android小菜鸟的linux * 设备驱动开发学习之旅 * 主题:异步I/O * Date:2014-11-11 */ linux中最常用的输入/输出(I/O)模型是同步I/O.在这个模型中,请求发出后,应用就会阻塞,知道请求满足 为止.但是在某些情况下,I/O请求可能需要与其他的进程进行交叠.可移植操作系统接口(POSIX)异步I/O(AIO) 应用程序接口(API)就提供了这种功能. AIO基本

Hasen的linux设备驱动开发学习之旅--中断

/** * Author:hasen * 参考 :<linux设备驱动开发详解> * 简介:android小菜鸟的linux * 设备驱动开发学习之旅 * 主题:中断 * Date:2014-11-13 */ 一.中断和定时器 所谓中断是指CPU在执行程序的过程中,出现了某些突发事件急待处理,CPU必须暂停执行当前的程序, 转而去处理突发事件,处理完毕后CPU又返回原程序被中断的位置并继续执行. 下图是中断的分类 嵌入式系统以及X86 PC中大多包含可编程中断控制器(PIC),许多MCU内部就

Hasen的linux设备驱动开发学习之旅--阻塞与非阻塞I/O

/** * Author:hasen * 参考 :<linux设备驱动开发详解> * 简介:android小菜鸟的linux * 设备驱动开发学习之旅 * 主题:阻塞与非阻塞I/O * Date:2014-11-05 */ 阻塞操作是指在执行设备操作时,若不能获得资源,则挂起进程直到满足可操作的条件后再进行操作.被 挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足.而非阻塞操作的进程在不能 进行设备操作时,并不挂起,它或者放弃,或者不停地查询,直到条件满足以进行操作为止.