本文共 1833 字,大约阅读时间需要 6 分钟。
如果对延迟的精度要求不高的话,最简单的实现方法如下---忙等待:
Unsigned long j = jiffies + jit_delay * HZ;
While(jiffies < j)
{
……
}
jiffies:全局变量,用来记录自系统启动以来产生的节拍总数。启动时内核将该变量初始化为0;
此后每次时钟中断处理程序增加该变量的值。每一秒钟中断次数HZ,jiffies一秒内增加HZ。系统运行时间 = jiffie/HZ.
jiffies用途:计算流逝时间和时间管理
jiffies内部表示:
extern u64 jiffies_64;
extern unsigned long volatilejiffies; //位长更系统有关32/64
32位:497天后溢出
64位:……
在定时器中有这样一个概念,度量时间差:
时钟中断由系统的定时硬件以周期性的时间间隔产生,这个间隔说白了其实就是频率由内核根据HZ来确定,HZ是一个与体系结构无关的常数,可以配置为(50-1200),在X86平台,它的值被默认为1000 ;
定时器数据结构被组织成双向链表,如下:
Struct timer_list {
struct list_head entry;
//定时值基于jiffies
unsigned long expires;
//定时器内部值
struct tvec_base *base;
//定时器处理函数
void (*function)(unsigned long);
//定时器处理函数参数
unsigned long data;
……
};
对内核定时器操作有如下函数:
Void init_timer(struct timer_list *timer) ;
void add_timer(struct timer_list *timer);
int del_timer(struct timer_list *timer) ;
分别表示初始化定时器队列结构,启动定时器,在定时器超时前将它删除。当定时器超时后,系统会自动将它删除掉。
接下来我们来看一个例子:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/timer.h> /*timer*/
#include <asm/uaccess.h> /*jiffies*/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("yangyuanxin");
MODULE_DESCRIPTION("TimerModule");
MODULE_ALIAS("timer module");
struct timer_list timer;
//定时器超时执行函数
void timer_function(int para)
{
printk("<0>Timer Expired and para is %d !!\n",para);
}
int timer_init()
{
init_timer(&timer); //初始化内核定时器
timer.data= 5; //给执行的函数传参
timer.expires= jiffies + (5 * HZ); //当前jiffies的值加上5秒钟之后
timer.function= timer_function; //如果超时了就执行这个函数
add_timer(&timer); //启动定时器
return0;
}
void timer_exit()
{
del_timer(&timer );
}
module_init(timer_init);
module_exit(timer_exit);
转载地址:http://bokdo.baihongyu.com/