Linux内核设备驱动之内核的时间管理笔记整理

2019-01-16 20:43:40丽君

unknown通常是指jiffies,known是需要对比的值(常常是一个jiffies加减后计算出的相对值)例:

unsigned long timeout = jiffies + HZ/2; /* 0.5秒后超时 */ ... if(time_before(jiffies, timeout)){ /* 没有超时,很好 */ }else{ /* 超时了,发生错误 */

time_before可以理解为如果在超时(timeout)之前(before)完成

*系统中还声明了一个64位的值jiffies_64,在64位系统中jiffies_64和jiffies是一个值。

可以通过get_jiffies_64()获得这个值。

*使用

u64 j2; j2 = get_jiffies_64();

(4)获得当前时间

驱动程序中一般不需要知道墙钟时间(也就是年月日的时间)。但驱动可能需要处理绝对时间。
为此,内核提供了两个结构体,都定义在<linux/time.h>:

struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ }; //较老,但很流行。采用秒和毫秒值,保存了1970年1月1日0点以来的秒数 struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ }; //较新,采用秒和纳秒值保存时间。

do_gettimeofday()该函数用通常的秒或微秒来填充一个指向struct timeval的指针变量,原型如下:

#include <linux/time.h> void do_gettimeofday(struct timeval *tv);

current_kernel_time()该函数可用于获得timespec

#include <linux/time.h> struct timespec current_kernel_time(void);
/******************** *确定时间的延迟执行 *******************/

设备驱动程序经常需要将某些特定代码延迟一段时间后执行,通常是为了让硬件能完成某些任务。

长于定时器周期(也称为时钟嘀嗒)的延迟可以通过使用系统时钟完成,而非常短的延时则通过软件循环的方式完成

(1)短延时

对于那些最多几十个毫秒的延迟,无法借助系统定时器。

系统通过软件循环提供了下面的延迟函数:

#include <linux/delay.h> /* 实际在<asm/delay.h> */ void ndelay(unsigned long nsecs); /*延迟纳秒 */ void udelay(unsigned long usecs); /*延迟微秒 */ void mdelay(unsigned long msecs); /*延迟毫秒 */

这三个延迟函数均是忙等待函数,在延迟过程中无法运行其他任务。

实际上,当前所有平台都无法达到纳秒精度。

(2)长延时

a.在延迟到期前让出处理器

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

在等待期间可以让出处理器,但系统无法进入空闲模式(因为这个进程始终在进行调度),不利于省电。

b.超时函数

#include <linux/sched.h> signed long schedule_timeout(signed long timeout);