HZ值是一个与体系结构有关的常数。其值表示每秒有多少次时钟中断。
每次当时钟中断发生时,内核内部计数器的值就增加1,这个计数器的值在系统引导时被初始化为0,因此,它的值就是自上次操作系统引导以来的时钟滴答数,这个计数器是一个64位的变量(即使在32位架构上也是64位),称为“jiffies_64”,但是驱动程序开发者通常访问的是jiffies变量,它是unsigned long型变量,要么和jiffies_64相同,要么仅仅是jiffies_64的低32位,通常首选使用jiffies,因为它的访问很快,从而对64位jiffies_64值的访问并不需要在所有架构上都是原子的。jiffies和jiffies_64均应被看作只读变量。
点击(此处)折叠或打开
-
#include <linux/jiffies.h>
-
unsigned long j, stamp_1, stamp_half, stamp_n;
-
j = jiffies; //读取当前值
-
stamp_1 = j + HZ; //未来1秒
-
stamp_half = j + HZ / 2; //半秒
- stamp_n = j + n *HZ / 1000; //n毫秒
点击(此处)折叠或打开
-
#include <linux/jiffies.h>
-
int time_after(unsigned long a, unsigned long b);
-
int time_before(unsigned long a, unsigned long b);
-
int time_after_eq(unsigned long a, unsigned long b);
- int time_before_eq(unsigned long a, unsigned long b)
用等待队列实现延时:
点击(此处)折叠或打开
-
wait_queue_head_t wait;
-
init_waitqueue_head(&wait);
- wait_event_interruptible_timeout(wait, 0, delay);
点击(此处)折叠或打开
-
#include <linux/delay.h>
-
void ndelay(unsigned long nsecs);
-
void udelay(unsigned long usecs);
- void mdelay(unsigned long msecs);
三、定时器
3.1、内核timer定时器
首先需要定义一个timer_list变量timer
先初始化timer:
init_timer(&timer);
然后对timer的相关参数赋值:
timer.function = fun;
timer.expires = jiffies + TIMER_DELAY;
timer.data = (unsigned long)dev;
add_timer(&timer);
在定时器时间到的时候,会执行fun,如果继续定时,可以通过在fun中执行:
mod_timer(&timer, jiffies + TIMER_DELAY);
在不需要的时候通过调用:
del_timer(&timer);删除定时器。
这样一个简单的定时器就完成了。
内核定时器常常是作为“软件中断”的结果而运行的。在这种原子性的上下文中运行时,代码会受到许多限制,定时器函数必须以原子方式运行。任何通过定时器函数访问的数据结构都应该针对并发访问进行保护。
点击(此处)折叠或打开
-
include <linux/timer.>
-
-
struct timer_list {
-
struct list_head list;
-
unsigned long expires;
-
unsigned long data;
-
void (*function)(unsigned long);
- };
在第十章中讲述。