一、时钟中断由系统的定时硬件以周期性的 时间间隔产生(1/HZ秒),这个间隔(频率)由 HZ决定,HZ是一个与硬件体系无关的常数,可配置(50-1200),在X86平台,默认是1000
每当时钟中断产生时,全局变量 jiffies 就+1,因此 jiffies 记录了自Linux启动后时钟中断发生的次数,驱动程序经常使用 jiffies 来计算 不同事件的时间间隔。
应用: 延时执行
如果对延时的精度要求不高,最简单的实现要求如下:-- 忙等待
unsigned long j = jiffies +jit_delay*HZ; while(jiffies < j) { //do nothing; }
二、内核定时器
定时器用于控制某个函数(定时器处理函数)在未来某个事件执行,内核定时器注册的函数只执行一次,不是重复执行的。
一般来说,定时器都在超时后马上就会执行超时处理函数,但是也有可能被推迟到下一个时钟节拍时才能执行,所以不能用定时器来实现任何硬实时任务。
struct timer_list{ struct list_head entry; //内核使用,内核定时器被组织成双线链表 unsigned long exoires; //设定的超时的jiffies值 void(*function)(unsigned long); //超时处理函数 unsigned long data; //超时处理函数参数 struct tvec_base *base; //内核使用 }
三、操作
初始化定时器 init_timer(struct timer_list *timer);
启动定时器 void add_timer(struct timer_list *timer);
删除定时器 (在生效前,超时后会自动删除)int del_timer(struct timer_list * timer);
#include "linux/module.h" #include "linux/timer.h" #include "linux/jiffies.h" struct timer_list demo_timer; static void time_func(unsigned long data) { printk("%s ,secs = %ld!\n",(char *)data,jiffies/HZ); mod_timer(&demo_timer,jiffies + 5*HZ); } static int __init mytimer_init(void) { printk("mytimer_init!\n"); setup_timer(&demo_timer,time_func,(unsigned long) "demo_timer!"); demo_timer.expires = jiffies + 1*HZ; add_timer(&demo_timer); return 0; } static void __exit mytimer_exit(void) { printk("mytimer_exit!\n"); del_timer(&demo_timer); } module_init(mytimer_init); module_exit(mytimer_exit); MODULE_LICENSE("Dual BSD/GPL");