1、内核定时器
时钟中断:由系统的定时硬件以周期性的时间间隔发生,这个间隔(也就是频率)由内核根据常数HZ来确定。
HZ常数:她是一个与体系结构无关的常数,可以配置50-1200之间,可以在内核中配置
tick:她是HZ的倒数,也就是每发生一次硬件定时器中断的事件间隔。如HZ为200,tick为5毫秒。
jiffies核心变数:它是linux核心变数(32位变数,unsigned long),它被用记录自开机以来,已经过多少个tick。每发生一次硬件定时器中断,jiffies变数会被加1。
定时器的作用:
内核定时器由用户控制某个函数(定时器函数)来特定的在未来某个时刻执行。
内核定时器注册的处理函数只执行一次(不是循环执行的)。
内核定时器定义:
在<linux/timer.h>中定义
struct timer_list { struct list_head entry;//内核使用 unsigned long expires;//超时时间jiffies的值 void (*function)(unsigned long);//超时处理函数 unsigned long data;//内核调用超时处理函数时传递给它的参数 struct tvec_base *base;//内核使用 };
定义定时器
DEFINE_TIMER(_name, _function, _expires, _data);
_name:待定义的内核定时器变量名称
_function:定时器处理函数
_expires:定时器超时jiffies值
_data:传递给定时器处理函数的参数
动态初始化
void init_timer(struct timer_list *timer);
timer:待初始化的内核定时器
添加定时器
void add_timer(struct timer_list *timer);
timer:待初始化的内核定时器
删除定时器
该函数是在定时器超时前将定时器删除
实际上,在定时器超时后,系统会自动将其删除
void del_timer(struct timer_list *timer);
timer:待初始化的内核定时器
修改定时器
该函数实际相当于del_timer(), timer->expires=expires, add_timer()三个步骤
int mod_timer(struct timer_list *timer, unsigned long expires);
timer:待修改的内核定时器
expires:待修改内核定时器的新超时值
返回:返回0表示定时器处于不活动状态,返回1表示定时器处于活动状态
2、实例代码:
/** *Copyright (c) 2013.TianYuan *All rights reserved. * *文件名称: kerneltimer.c *文件标识: 内核定时器 * *当前版本:1.0 *作者:wuyq * *取代版本:xxx *原作者:xxx *完成日期:2013-11-25 */ #include <linux/init.h> #include <linux/module.h> #include <linux/timer.h> MODULE_LICENSE("GPL"); /*定时器变量*/ struct timer_list bigdog_timer; #define BARK_TIMER 5/*定时器时间间隔*/ #define BARK_COUNTS 10/*次数*/ void bigdog_timer_handler(unsigned long data) { /*记录该函数被调用的次数*/ static int bark_count = 0; printk("wangwang~~~~~~~~~%ld!\n", data); if(bark_count < BARK_COUNTS){ bigdog_timer.expires = jiffies+HZ*BARK_TIMER; bigdog_timer.data++; add_timer(&bigdog_timer); bark_count++; } } int __init kerneltimer_init(void) { /*初始化定时器变量*/ init_timer(&bigdog_timer); bigdog_timer.expires = jiffies+HZ*BARK_TIMER;//超时时间.安装模块时间之后5秒 bigdog_timer.function = bigdog_timer_handler;//处理函数;函数指针:void (*fun)(unsigned long) bigdog_timer.data = 100; /*添加定时器到内核中去*/ add_timer(&bigdog_timer); printk("add_timer() Done!\n"); return 0; } void __exit kerneltimer_exit(void) { /*从内核中删除指定的定时器*/ del_timer(&bigdog_timer); printk("del_timer() done!\n"); } module_init(kerneltimer_init); module_exit(kerneltimer_exit);
KERNELDIR ?=/root/Desktop/work/ldd3/linux-2.6.31_TX2440A PWD := $(shell pwd) obj-m += kerneltimer.o default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean: @rm -f *.o *.ord* *.sy* *.mod.* *.ko