您的位置:首页 > 其它

内核定时器的简单应用

2015-12-20 16:00 253 查看
从离开大学到现在,接触linux内核也差不多有一个月了,基本上对于我来说只是了解一下理论知识,而并没有去用过,本篇主要是介绍了内核定时器的一个简单的应用,其实,内核定时器如果去深入的了解的话,当然是不简单,光从内核源码来看,它的数据结构就尤为复杂,但是今天这个例子, 会非常简单。

在Linux内核中,有这样的一个定时器,叫做内核定时器,内核定时器用于控制某个函数,也就是定时器将要处理的函数在未来的某个特定的时间内执行。内核定时器注册的处理函数只执行一次,即不是循环执行的。

如果对延迟的精度要求不高的话,最简单的实现方法如下---忙等待:

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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: