长延迟

有些驱动程序需要延迟比较长的时间,即长于一个时钟滴答;

忙等待

如果想把执行延迟若干个时钟滴答,或者对延迟的精度要求不高,最简单的实现方法就是一个监视jiffies计数器的循环;这种忙等待的实现方法通常具有下面形式,其中j1是延迟终止的jiffies值:

 while (time_before(jiffies, j1))
cpu_relax();

对cpu_relax的调用将以架构相关的方式执行,其中不执行大量的处理器代码;在许多系统上,该函数根本不会做任何事情;而在SMP系统上,它可能将处理器让给其他线程;但是,只要可能,我们应该避免使用这种方式,这里提到它,只是因为可能偶尔需要运行这段代码,以便更好的理解其他延迟计数;

让出处理器

忙等待为系统整体增加了沉重的负担,因此有必要寻找更好的延迟计数,比如在不需要CPU时主动释放CPU,这可以通过调用shcedule函数实现;

 while (time_before(jiffies, j1)) {
schedule();
}

当进程使用schedule释放处理器之后,没有任何保证说进程可以再随后很快就能得到处理器;除了影响计算机系统整体性能之外,这种用法对驱动程序的需求并不安全,因为延迟可能远大于需求;

超时

通过监视jiffies计数器实现的延迟循环可以工作,但不是非常理想;存在两种构造基于jiffies超时的途径,使用哪个规则则依赖于驱动程序是否在等待其他事件;

如果驱动程序使用等待队列类等待其他一些事件,而我们同时希望在特定的时间段内运行,则可以使用wait_event_timeout或者wait_event_interruptible_timeout函数:

 #define wait_event_timeout(wq, condition, timeout)
#define wait_event_interruptible_timeout(wq, condition, timeout)

上述函数会在给定的等待队列上休眠,但是会在超时到期时返回;这样,这两个函数实现了一种有界的休眠,这种休眠不会永远继续;注意,这里的timeout标识要等待的jiffies值,而不是绝对时间值;如果超时到期,这个两个函数会返回零;如果进程由其他事件唤醒,则会返回剩余的延迟时间,并用jiffies表达;返回值不会是负数,及时因为系统负荷而导致真正的延迟时间超过预期;

上述两个函数需要有人在等待队列上调用wake_up函数,或者超时到期;而在没有人会在等待队列上调用wake_up的情况下,进程将始终会在超时到期时被唤醒;为了适应这种不等待任何事件而延迟的情况,内核提供了schedule_timeout函数;

 signed long __sched schedule_timeout(signed long timeout)

这里,timeout是用jiffies表示的延迟时间,正常返回值是0,除非在给定超时值之前函数返回(比如响应某个信号);schedule_timeout要求调用者首先设置当前进程的状态,典型的调用如下:

 set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(delay);

需要注意的是超时到期和真正呗调度执行之间,需要额外的时间;

短延迟

当设备驱动程序需要处理硬件的延迟时,这种延迟通常最多涉及到几十个毫秒;这种情况下,依赖于时钟滴答显然不是正确的方法;

ndelay,udelay和mdelay这几个内核函数很好的完成短延迟任务,它们分别延迟指定数量的纳秒、微秒和毫秒时间,它们的原型如下:

 #define mdelay(n)
#define udelay(n)
#define ndelay(n)

需要注意的是,这三个延迟函数均是忙等待函数,因而在延迟过程中无法运行其他任务;因为,我们只能在没有其他实用方法时使用这些函数;

实现毫秒级(或者更长)延迟还有另一种方法,这种方法不涉及忙等待;

 void msleep(unsigned int msecs)
unsigned long msleep_interruptible(unsigned int msecs)
void ssleep(unsigned int seconds)

通常,如果我们能够容忍比所请求更长的延迟,则应当使用schedule_timeout、sleep或者ssleep;

Linux设备驱动程序 之 延迟执行的更多相关文章

  1. linux设备驱动程序该添加哪些头文件以及驱动常用头文件介绍(转)

    原文链接:http://blog.chinaunix.net/uid-22609852-id-3506475.html 驱动常用头文件介绍 #include <linux/***.h> 是 ...

  2. 【转】linux设备驱动程序中的阻塞机制

    原文网址:http://www.cnblogs.com/geneil/archive/2011/12/04/2275272.html 阻塞与非阻塞是设备访问的两种方式.在写阻塞与非阻塞的驱动程序时,经 ...

  3. Linux设备驱动程序 第三版 读书笔记(一)

    Linux设备驱动程序 第三版 读书笔记(一) Bob Zhang 2017.08.25 编写基本的Hello World模块 #include <linux/init.h> #inclu ...

  4. Linux设备驱动程序学习之分配内存

    内核为设备驱动提供了一个统一的内存管理接口,所以模块无需涉及分段和分页等问题. 我已经在第一个scull模块中使用了 kmalloc 和 kfree 来分配和释放内存空间. kmalloc 函数内幕 ...

  5. Linux设备驱动程序学习----1.设备驱动程序简介

    设备驱动程序简介 更多内容请参考Linux设备驱动程序学习----目录 1. 简介   Linux系统的优点是,系统内部实现细节对所有人都是公开的.Linux内核由大量复杂的代码组成,设备驱动程序可以 ...

  6. Linux设备驱动程序学习----2.内核模块与应用程序的对比

    内核模块与应用程序的对比 更多内容请参考Linux设备驱动程序学习----目录 1. 内核模块与应用程序的对比 内核模块和应用程序之间的不同之处: 大多数中小规模的应用程序是从头到尾执行单个任务,而模 ...

  7. Linux设备驱动程序学习----3.模块的编译和装载

    模块的编译和装载 更多内容请参考Linux设备驱动程序学习----目录 1. 设置测试系统 第1步,要先从kernel.org的镜像网站上获取一个主线内核,并安装到自己的系统中,因为学习驱动程序的编写 ...

  8. linux设备驱动程序-设备树(1)-dtb转换成device_node

    linux设备驱动程序-设备树(1)-dtb转换成device_node 本设备树解析基于arm平台 从start_kernel开始 linux最底层的初始化部分在HEAD.s中,这是汇编代码,我们暂 ...

  9. linux设备驱动程序--在用户空间注册文件接口

    linux字符设备驱动程序--创建设备节点 基于4.14内核,运行在beagleBone green 在上一讲中,我们写了第一个linux设备驱动程序--hello_world,在驱动程序中,我们什么 ...

随机推荐

  1. 如何判断 Session是否存在

    相信很多人都跟我一样,在写网页中有些位置通过其他网页设置了 Session然后跳转到目标页面就需要要用 Session,但是那个位置如果是直接打开的就用不到 Session,那么问题就来了,例如:系统 ...

  2. vs-code 的常用插件

    最近编辑器转移至VS-Code上面了,为什么抛弃sublime呢,因为,sublime在项目逐渐变大的过程中(项目已上万行,还在不停继续变大),sublime会出现卡顿,反应缓慢,甚至未响应状态,基于 ...

  3. keras 切换后端 TensorFlow,cntk,theano

    参考 https://keras.io/#configuring-your-keras-backend https://keras.io/backend/ Switching from one bac ...

  4. LeetCode 【2】 Reverse Integer --007

    六月箴言 万物之中,希望最美:最美之物,永不凋零.—— 斯蒂芬·金 第二周算法记录 007 -- Reverse Integer (整数反转) 题干英文版: Given a 32-bit signed ...

  5. redis集群安装2

      概要:本文主要介绍如何在Centos7中单机搭建redis集群三主三从,按照本文绝对可以实现该需求,至于先搭建单机版主要为了方便理解redis集群,为下一步开发或生产上redis集群做铺垫.同时本 ...

  6. 使用.bat 批量将部分文件迁移到新的路径下

    1.建一个11.bat ,里面写  :   dir  /b /s  >1111.txt 保存后运行 即将所有的文件路径保存到1111.txt中 2.可以将获取的路径复制到execl中,找到自己需 ...

  7. DoD与TCP/IP

    DoD与TCP/IP都是协议栈. 什么是协议栈? 就是一套软件,默认安装完Windows就有,可以卸载再安装.把他卸载了,你就不能上网. 数据的封装以及解封装有网卡以及绑定的TCP/IP协议栈完成 A ...

  8. idou老师教你学Istio 07: 如何用istio实现请求超时管理

    在前面的文章中,大家都已经熟悉了Istio的故障注入和流量迁移.这两个方面的功能都是Istio流量治理的一部分.今天将继续带大家了解Istio的另一项功能,关于请求超时的管理. 首先我们可以通过一个简 ...

  9. flink相关

    flink一.简单实时计算方案 假如现在我们有一个电商平台,每天访问的流量巨大,主要访问流量都集中在衣服类.家电类页面,那么我们想实时看到这两类页面的访问量走势(十分钟出一个统计量),当做平台的重要指 ...

  10. [转]10分钟了解分布式CAP、BASE理论

    原文: https://www.cnblogs.com/chengtian/p/11278072.html ---------------------------------------------- ...