05-Linux硬件定时 jiffies

本系列文章主要讲Linux中的中断和时间管理,文章机构如下:
01 - 驱动中的中断处理
02 - 中断下半部 tasklet
03 - 中断的下半部 workqueue
04 - Linux中的延时操作函数
05 - Linux硬件定时 jiffies
06 - Linux 低分辨率定时器
07 - Linux高分辨率定时器

 本文内容参考正点原子《嵌入式 Linux驱动开发指南》一书,《嵌入式 Linux驱动开发指南》

1. 硬件时钟源的介绍和配置

在Linux中硬件定时器提供时钟源,时钟源的可以在内核源码目录下,执行 make menuconfig 进行配置,配置界面如下图所示:
在这里插入图片描述
 从上图可以看出,硬件时钟源一共可以选择100Hz、250Hz、300Hz和1000Hz四种,配置完内核之后,可以在内核源码目录下的 .config 文件中看到已经将配置的时钟频率写入到配置文件中,如下图所示:
在这里插入图片描述
 除此之外,还可以在 include\asm-generic\param.h 文件中找到设置的时钟频率,如下所示:
在这里插入图片描述
 采用不同的时钟频率可以获得不同的定时精度,高节拍率和低节拍率的优缺点如下:
 ①、高节拍率会提高系统时间精度,如果采用 100Hz 的节拍率,时间精度就是 10ms,采用1000Hz 的话时间精度就是 1ms,精度提高了 10 倍。高精度时钟的好处有很多,对于那些对时间要求严格的函数来说,能够以更高的精度运行,时间测量也更加准确。
②、高节拍率会带导致中断的产生更加频繁,频繁的中断会加剧系统的负担,1000Hz 的100Hz 的系统节拍率相比,系统要花费 10 倍的“精力”去处理中断。中断服务函数占用处理器的时间增加,但是现在的处理器性能都很强大,所以采用 1000Hz 的系统节拍率并不会增加太大的负载压力。根据自己的实际情况,选择合适的系统节拍率,本教程我们全部采用默认的100Hz 系统节拍率。

2. jiffies

 Linux 内核使用全局变量 jiffies 来记录系统从启动以来的系统节拍数,系统启动的时候会将 jiffies 初始化为 0,jiffies 定义在文include/linux/jiffies.h 中,定义如下:

extern u64 __jiffy_data jiffies_64;						// 64位的jiffies_64
extern unsigned long volatile __jiffy_data jiffies;		// 32位的jiffies

 当我们访问 jiffies 的时候其实访问的是 jiffies_64 的低 32 位,使用 get_jiffies_64 这个函数可以获取 jiffies_64 的值。在 32 位的系统上读取 jiffies 的值,在 64 位的系统上 jiffes 和 jiffies_64表示同一个变量,因此也可以直接读取 jiffies 的值。所以不管是 32 位的系统还是 64 位系统,都可以使用jiffies。前面说了 HZ 表示每秒的节拍数,jiffies 表示系统运行的 jiffies 节拍数,所以 jiffies/HZ 就是系统运行时间,单位为秒。不管是 32 位还是 64 位的 jiffies,都有溢出的风险,溢出以后会重新从 0 开始计数,相当于绕回来了,因此有些资料也将这个现象也叫做绕回。假如 HZ 为最大值 1000 的时候,32 位的 jiffies 只需要 4294967295(0xFFFFFFFF)/1000/3600/24 = 49.7 天就发生了绕回,对于 64 为的 jiffies 来说大概需要5.8 亿年才能绕回,因此 jiffies_64 的绕回忽略不计。处理 32 位 jiffies 的绕回显得尤为重要,

 Linux 内核提供了下面几个 API 函数来对jiffies进行处理(include\linux\jiffies.h)

u64 get_jiffies_64(void)	// 获取jiffies_64的值

time_after(a, b)			// a<b
time_before(a,b)			// a>b
time_after_eq(a,b)			// a<=b
time_before_eq(a,b)			// a>=b
time_in_range(a,b,c)		// b<=a<=c
time_in_range_open(a,b,c)	// b<=a<c

time_after64(a,b)			// a<b
time_before64(a,b)			// a>b
time_after_eq64(a,b)		// a<=b
time_before_eq64(a,b)		// a>=b
time_in_range64(a, b, c) 	// b<=a<=c

extern unsigned int jiffies_to_msecs(const unsigned long j)		// 将jiffies转换为对应的ms值
extern unsigned int jiffies_to_usecs(const unsigned long j)		// 将jiffies转换为对应的us值
static inline u64 jiffies_to_nsecs(const unsigned long j)		// 将jiffies转换为对应的ns值	
extern unsigned long __msecs_to_jiffies(const unsigned int m)	// 将ms转换为对应的jiffies值
extern unsigned long __usecs_to_jiffies(const unsigned int u)	// 将us转换为对应的jiffies值
extern unsigned long nsecs_to_jiffies(u64 n);					// 将ns转换为对应的jiffies值

 这节简单的对 jiffies 进行介绍,下面将在低分辨率定时器和高分辨率定时器中对 jiffies 进行实际的应用。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值