长延迟

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

忙等待

如果想把执行延迟若干个时钟滴答,或者对延迟的精度要求不高,最简单的实现方法就是一个监视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. restTemplate源码解析(一)构造restTemplate的Bean实例

    所有文章 https://www.cnblogs.com/lay2017/p/11740855.html 正文 构造一个restTemplate的Bean实例很容易,只需这样配置 @Bean publ ...

  2. elementUI动态数据表格(带分页)

    index.vue <template> <div> <el-table ref="multipleTable" :data="tableD ...

  3. SpringBoot mysql出现The server time zone value '�й���׼ʱ��' is unrecogni

    MySql :8.0.18 引入的mysql驱动: SpringBoot整合Mybatis的框架,在访问Controller的时候 : ava.sql.SQLException: The server ...

  4. BeginInvoke异步线程

    this.BeginInvoke(new Action(() => { dataGridView1.DataSource = BLLBillConsume.BllGetClearMarketLo ...

  5. MyBatis-Spring 学习笔记一 SqlSessionFactoryBean以及映射器类

    MyBatis-Spring 是一个用来整合 MyBatis 和 Spring 框架的小类库,通过这个jar包可以将 MyBatis 代码地整合到 Spring 中. 使用这个类库中的类, Sprin ...

  6. 阿里P7告诉你什么是java并发包、线程池、锁

    并发包 java.util.concurrent从jdk1.5开始新加入的一个包,致力于解决并发编程的线程安全问题,使用户能够更为快捷方便的编写多线程情况下的并发程序. 同步容器 同步容器只有包括Ve ...

  7. win10关闭防火墙和其通知

    Win10电脑在关闭防火墙后,防火墙的通知会不定期提醒,如果误点后,防火墙就悄悄的开启了,导致好多功能就用不了了,所以比较有效的方法是:关闭防火墙,并关闭防火墙通知 1.关闭防火墙 在控制面板中,选择 ...

  8. C语言字符串格式化输出

    %ms:将字符串全部输出,如果字符串长度小于m,在左边用空格将输出宽度补齐为m: %.ns:如果n大于字符串长度,将字符串全部输出,否则,输出前n个字符: %m.ns:如果n不大于m,输出指定字符串的 ...

  9. 三星Q470c Logo界面无限掉电重启,变砖后的挽救过程

    背景 三星笔记本的部分型号如:NP530 Q470等 安装win8后再次重装系统(我弄了个Ubuntu18)会导致无法进入BIOS菜单页面的问题.启动显示logo页面后,能够听到明显啪的一声(硬盘掉电 ...

  10. FreeRTOS任务基础概念

    RTOS系统的核心就是任务管理: 任务的特性 在RTOS中每个任务都有自己的运行环境,不依赖于系统中其他的任务或者调度器,任何一个时间点只能有一个任务运行,具体运行哪个任务是由任务调度器来决定的,而任 ...