时间差的度量
系统的定时器硬件以固定的频率产生时钟中断,产生始终中断的间隔以HZ 常量来决定,通常在50~1200之间,x86默认是1000,HZ可以根据不同的内核来配置。
Linux 采用jiffies (unsigned long)来对时钟中断进行计数,每当发生时钟中断时jiffies的值将+1,因此jiffies就记录了系统开机以来的时钟中断总次数。在驱动开发过程中经常会使用时钟中断来计算不同事件的时间间隔。
延迟执行
对于不精确的时间延迟要求,可以使用while 循环来计算延迟的时间。
//延迟10秒
unsigned long j = jiffies + 10 * HZ;
while(jiffies < j)
{
// do something.
}
内核定时器
内核定时器用于控制每个函数在未来的某个时间点执行。内核定时器被注册后只能执行一次,如果尚未到达执行目标函数的时间点就删除该定时器,那么目标函数将不能被执行。
内核定时器使用的数据结构(不同内核定时事件以双向链表的形式连接起来):
struct timer_list {
struct list_head entry; //链表头
unsigned long expires; //延迟的时间
struct tvec_base *base;
void (*function)(unsigned long); //目标函数,定时时间到达时会被调用
unsigned long data; //目标函数携带的数据
……
};
- init_timer(struct timer_list *timer) //初始化timer事件
- void add_timer(struct timer_list *timer) //添加定时事件
- int del_timer(struct timer_list *timer) //删除定时事件
范例:
#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jack Chen");
MODULE_DESCRIPTION("Hello World");
MODULE_ALIAS("A simple module");
MODULE_VERSION("V1.0");
struct timer_list timer;
static void _function(int data)
{
printk("<3> time is up data:%d
",data);
}
static int timer_init()
{
init_timer(&timer);
timer.expires = jiffies + 5*HZ;
timer.function = _function;
timer.data = 10;
add_timer(&timer);
return 0;
}
static void timer_exit()
{
del_timer(&timer);
}
module_init(timer_init);
module_exit(timer_exit);