概述

内核通过定时器中断来跟踪事件流;

时钟中断由系统定时硬件以及周期性的间隔产生,这个间隔由内核根据HZ的值设定,HZ是一个细节结构有关的常数;作为一般性规则,即使知道对应平台上的确切HZ值,也不应该在编程时依赖该HZ值;

如果想改变系统时钟中断发生的频率,可以通过修改HZ值来进行,但是,如果修改了头文件中的HZ值,则必须使用新的值重新编译内核以及所有模块;

每当时钟中断发生时,内核内部计数器的值增加一;这个计数器的值在系统引导值初始化为0,因此,它的值就是上次操作系统引导以来的时钟滴答数;这个计数器是一个64位变量(即使在32位架构上也是64位),称为jiffies_64;但是驱动程序发开者通常访问的是jiffies变量,它是unsigned long类型的变量,要么和jiffies_64相同,要么仅仅是jiffies_64的低23位,根据架构是64位还是32位而定;通常首选使用jiffies,因为对它的访问很快,从而对于64位jiffies_64值的访问并不需要在所有架构上都是原子的;

使用jiffies计数器

该计数器和读取计数器的工具函数包含在<linux/jiffies.h>中,但是通常只需要包含<linux/sched.h>文件,后者会自动包含jiffies.h;

需要说明的是,jiffies和jiffies_64均应该被看成只读变量;

在代码中需要记录jiffies的当前值时,可简单的访问上面说的unsigned long变量;该变量被声明为volatile,这样可以避免编译器对访问该变量的语句的优化;在代码需要计算未来的时间戳时,必须读取当前的计数器;

  1. #incldue <linux/jiffies.h>
  2.  
  3. unsigned long j, stamp_1, stamp_half, stamp_n;
  4.  
  5. j = jiffies;
  6.  
  7. stamp_1 = j + HZ;
  8. stamp_half = j + HZ/;
  9. stamp_n = j + n * HZ / ;
时间比较

只要采用正确的方式来比较不同的值,上述代码不会因为jiffies的溢出而出现问题;比较缓存时间和当前时间,应该使用下面宏:

  1. #define time_after(a,b) \
  2. (typecheck(unsigned long, a) && \
  3. typecheck(unsigned long, b) && \
  4. ((long)((b) - (a)) < ))
  5. #define time_before(a,b) time_after(b,a)
  6.  
  7. #define time_after_eq(a,b) \
  8. (typecheck(unsigned long, a) && \
  9. typecheck(unsigned long, b) && \
  10. ((long)((a) - (b)) >= ))
  11. #define time_before_eq(a,b) time_after_eq(b,a)
用户空间时间与内核时间的转换

用户空间的时间使用struct timeval和struct timespec来表示,为了在用户空间时间和内核时间之间进行转换,内核提供了下面的四个辅助函数:包含在<linux/jiffies.h>中

  1. unsigned long timespec_to_jiffies(const struct timespec *value)
  2. void jiffies_to_timespec(const unsigned long jiffies,
  3. struct timespec *value)
  4.  
  5. unsigned long timeval_to_jiffies(const struct timeval *value)
  6. void jiffies_to_timeval(const unsigned long jiffies,
  7. struct timeval *value)
访问jiffies_64

对jiffies_64的访问不像对jiffies的访问那么直接,在64位架构上,两个变量其实是同一个变量;但是在32位架构上,对64位的访问不是原子的,必须借助一个辅助函数,该函数完成了适当的锁定:

  1. #if (BITS_PER_LONG < 64)
  2. u64 get_jiffies_64(void);
  3. #else
  4. static inline u64 get_jiffies_64(void)
  5. {
  6. return (u64)jiffies;
  7. }
  8. #endif

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设备驱动程序:一个简短的教程

    教你写Linux设备驱动程序:一个简短的教程 http://blog.chinaunix.net/uid-20799298-id-99675.html

  6. linux设备驱动程序_hello word 模块编译各种问题集锦

    在看楼经典书籍<linux设备驱动程序>后,第一个程序就是编写一个hello word 模块. 原以为非常easy,真正弄起来,发现问题不少啊.前两天编过一次,因为没有记录,今天看的时候又 ...

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

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

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

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

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

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

随机推荐

  1. Linux下定时任务的查看及取消

    crontab -l 表示列出所有的定时任务 crontab -r 表示删除用户的定时任务,当执行此命令后,所有用户下面的定时任务会被删除,执行crontab -l后会提示用户:“no crontab ...

  2. sip呼叫里SDP的一些字段的含义

    v=0 o=- 1 0 IN IP4 164.135.25.51 #local ip ,即本机SIP信令交互地址 s=SNS call #用于传递会话主题 c=IN IP4 164.135.25.51 ...

  3. xss part2

    0x01 xss challenge level 6-10 1.1 level 6 test with typical, notice the script has changed change sc ...

  4. Activiti使用总结

    工作流在我们日常的工作中用得可谓相当普及,尤其在企业内部管理系统,如考勤.财务.合同等系统中更是离不开它.在我们金融科技领域,工作流主要用于贷款审批.风控审核等环节.早期工作流在企业信息化发挥着很重要 ...

  5. element之input输入搜索联想框

    1. 模板代码 <el-autocomplete :minlength="2" v-model="searchName" :fetch-suggestio ...

  6. 【python+beautifulsoup4】Beautifulsoup4

    Beautiful soup将复杂HTML文档转换成一个复杂的属性结构,每个节点都是python对象,所有对象可归纳为4种Tag,NavigableString,BeautifulSoup,Comme ...

  7. java_实现Hello World

    1.新建项目 在空白处右击--New--java Project 2.项目文件结构 新建了项目之后项目文件在工作空间里面,(如果忘记工作空间的路径可以点击File---Switch Workspace ...

  8. ConcurrentDictionary源码概读

    ConcurrentDictionary的数据结构主要由Tables和Node组成,其中Tables包括桶(Node,节点)数组.局部锁(Local lock).每个锁保护的元素数量(PerLock) ...

  9. E - GCD HDU - 2588

    The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes written (a,b),is the ...

  10. [USACO15FEB]Superbull 超级牛

    题意概况 题目描述 \(Bessie\)和她的朋友们正在一年一度的\(Superbull\)锦标赛中打球,而\(Farmer John\)负责让比赛尽可能激动人心. 总共有 \(N\) 支队伍 \(1 ...