曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 8323|回复: 4
打印 上一主题 下一主题

时间处理

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2009-9-28 00:19:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
概述
创建设备驱动程序的过程中会涉及到多种时间相关内容。内核中为了处理这些时间相关内容,把全局变量 jiffies_64 ( 2.6 内核 )作为时间的基准值 ( 2.4 内核中用 jiffies )。

设备驱动程序利用该基准值测定时间的流逝,并根据该时间控制硬件。为了进行时间的相关处理,内核提供了 Hz 、USER_Hz 等常数,以及处理年,月,日,时,分,秒的 do_gettimeofday() 、 do_settimeofday() 和 mktime() 等函数。

在控制硬件的过程中,偶尔会出现必须的延迟 (硬件的特性及时序上的要求) 。例如,为了访问一些芯片或设备的内部寄存器,需要较短的延迟时间,而同步数据输入输出时需要较长的时间。

通常,延迟较短时间时,会使用以 1ms 为单位的 mdelay() 函数或这是以 1us 为单位的 udelay() 函数等; 而对于延迟相对较长的时间,则会用 jiffies_64 ( 2.4 内核用 jiffies ) 全局变量。

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
沙发
 楼主| 发表于 2009-9-28 01:58:02 | 只看该作者

定时器中断 (timer interrupt)

操作系统的核心功能就是调度 ( scheduling ),为了实现调度,需要定时器中断,Linux 内核在初期就设置了称为 Hz 的常数,该常数设置了发生定时器中断的周期,内核利用该值,确定各个进程的运行时间 ( 进程分配到系统资源的时间 ),并进行调度。

为了处理相关的时间操作,设备驱动程序中使用了下列全局变量和函数:
      Hz : 每秒发生的定时器中断次数,2.4 内核中此值为 100 。
        
      USER_Hz : (2.6内核新增) 保证 Hz 值的数,在 2.6 内核中 i386 的这个值是 100 。(在 2.6 内核里,Hz 的值与处理器类型相关)
        
      jiffies : 2.4 内核以 Hz 值增加的全局变量,即以 0.01s 为间隔以 1 单位递增,即每秒增加 100 。
        
      jiffies_64 : (2.6 内核新增) 2.6 内核中以 Hz 值增加的全局变量,在 2.6 内核中 Hz 为 1000,即以 0.001s 为间隔以 1 为单位递增,即每秒增加 1000 。
      get_jiffies_64() : (2.6内核新增) 参照 jiffies_64 值的函数。
下图是 2.6 内核定时器中断更新 jiffies_64 值的过程:


下面根据内核版本求出 0.3s 后的时间方法和使用 USER_Hz 值的方法:
      2.4 内核中建议使用方法
#define DIFF_TIME ( 3*Hz/10 )
u32 aftertime;
aftertime = jiffies + DIFF_TIME;
这里 DIFF_TIME 的值为 30, 因为 2.4 内核是每 10ms 定时器中断一次,故秒数为 30 x 10 = 300ms 。

      2.4 内核中使用的常见方法
#define DIFF_TIME (30)
u32  aftertime;
aftertime = jiffies + DIFF_TIME;

      2.6 内核中使用上述例子时的补充方法
#define DIFF_TIME (30)
u64 aftertime;
aftertime = get_jiffies_64() + DIFF_TIME * (Hz / USER_Hz);

      2.6 内核中使用的常见方法
#define DIFF_TIME (3*Hz/10)
u64  aftertime;
aftertime = get_jiffies_64() + DIFF_TIME;

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
板凳
 楼主| 发表于 2009-9-28 13:29:17 | 只看该作者

处理较短的延迟时间

创建设备驱动程序的过程中会遇到需要处理短时间延迟的情况,这里的短时间指的是小于 1ms (0.001s) 的时间,或者是小于 1us (0.000001s) 的时间,此类短时间延迟多用于同步 (synchronization) 硬件,此时使用下列函数:

上面 3 个函数属于宏函数,需要包含头文件 <linux/delay.h> 。使用这些函数时,注意不能延迟过长的时间,这些函数在运行时,系统会终止,CPU 会闲置,调用该函数的例程如果出现形无限循环或者多次重复调用该函数,可能会造成系统中止的现象。

如果延迟时间超过 5ms ,就不能使用 mdelay() 函数。

如果延迟时间超过 1000us ,不能使用 udelay() 函数。

ndelay() 是 2.6 内核支持的函数。该函数在 1GHz 以上的快速系统中才有意义。在低于 GHz 的系统中使用该函数时,ndelay() 函数的作用和 udelay() 相同。

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
地板
 楼主| 发表于 2009-9-28 14:00:09 | 只看该作者

处理较长的延迟时间

设备驱动程序中,要尽量避免使用超过 1ms 的延迟时间。如果不得不使用长时间延迟,可以使用下列方法。对于控制硬件的设备驱动程序而言,该方法并不值得推荐,要尽可能避免。比如 300ms 的延迟方法:

1、对于 2.4 内核
#define DELAY_TIME_MSEC   (3*Hz/10)

unsigned long endtime = jiffies + DELAY_TIME_MSEC;

while (jiffies < endtimeschedule();

在时间 endtime 还未到达时,调用 schedule() 函数启动其他进程。这里需要注意,这个延迟可能并不是精确的时间延迟,往往可能会超时,所以这样的方式不能用在有精确时间延迟的终端处理程序上。

2、对于 2.6 内核
2.6 内核属于抢占型内核,这一点与 2.4 内核不同,可以使用下列结构:
#define DELAY_TIME_MSEC   (3*Hz/10)

u64 endtime = get_jiffies_64() + DELAY_TIME_MSEC;

while (jiffies < endtime); 
如果在 2.4 内核中使用该方法,会产生类似系统停止运行的效果,但 2.6 内核为抢占式内核,在循环语句的运行中调度被转换,所以没有必要调用 schedule() 函数。

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
5#
 楼主| 发表于 2009-9-28 16:51:44 | 只看该作者

设置系统时间

通常,设备驱动程序不需要设置年,月,日,时,分,秒形态的系统时间,但是也不能排除有这种可能性,系统还是为此提供了几个函数。下面是与系统时间相关的函数和结构体:

do_gettimeofday() ,  do_settimeofday() 函数与应用程序中使用的 gettimeofday() 函数或 settimeofday() 函数具有相同的功能。上述函数没有使用常用的时间格式,即其单位不是年,月,日,时,分,秒等,而是把当前时间换算为秒。

mktime() 是辅助函数,即输入年,月,日,时,分,秒后换算为秒。(详见:http://www.groad.net/bbs/read.php?tid-1224.html)

在 2.4 内核中,do_gettimeofday() 和 do_settimeofday() 函数的变量类型均使用 struct timeval 结构体;
在 2.6 内核中,do_gettimeofday() 函数的变量类型为 struct timeval ,而 do_settimeofday() 函数的变量类型为 struct timespec 。

系统时间的设定
设备驱动程序中设定系统时间时,系统整体的时间会改变,因此要特别注意。应用程序正在延迟时间,或者正在进行时间换算是,如果系统时间发生变化,就会处理错误信息。比如,在 2.6 内核中设置系统时间 2009年9月28日17 时 40 分 20 秒的方法。
timeval.tv_usec = 0;
timeval.tv_sec = (unsigned long) mktime (2009, 9, 28, 17, 40, 20);
do_settimeofday (&timeval);
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-3 13:27 , Processed in 0.093552 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表