一、Linux 定时器介绍
在 Linux 内核中, 定时器叫做内核定时器, 内核定时器用于控制某个函数, 也就是定时器将要处理的函数在未来的某个特定的时间内执行。 内核定时器注册的处理函数只执行一次, 即不是循环执行的。 定时器的使用范围(延后执行某个操作, 定时查询某个状态; 前提是对时间要求不高的地方) 。
Hz: 系统时钟通过 CONFIG_HZ 来设置, 范围是 100-1000; HZ 决定使用中断发生的频率。 如果就没有定义的话, 默认是 100, 例: 1/200 = 5ms, 说明 4412 中是 5ms 产生一次时钟中断。内核的全局变量 jiffies: (记录内核自启动来的节拍数, 启动的时候初始化为 0, 内核之启动以来, 产生的中断数) 时钟中断, 每产生一个中断, jiffies 就加 1。 可以用来计算流逝时间和时间管理, jiffies 除以Hz 得到内核自启动以来的秒数。
二、数据类型:struct timer_list
struct timer_list {
/*
* All fields that change during normal runtime grouped to the
* same cacheline
*/
struct list_head entry;
unsigned long expires;
struct tvec_base *base;
void (*function)(unsigned long);
unsigned long data;
int slack;
#ifdef CONFIG_TIMER_STATS
int start_pid;
void *start_site;
char start_comm[16];
#endif
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
};
包含的主要成员:
-
struct list_head entry 双向链表
-
expires:定时器超时的时间,以linux的jiffies来衡量,记录什么时候产生时钟中断。
-
struct tvec_base *base: 管理时钟的结构体
-
void (*function)(unsigned long):定时器超时处理函数。
-
data:传递到超时处理函数的参数,主要在多个定时器同时使用时,区别是哪个timer超时。
三、主要相关的API函数
init_timer(struct timer_list*):定时器初始化函数;
add_timer(struct timer_list*):往系统添加定时器;
mod_timer(struct timer_list *, unsigned long jiffier_timerout):修改定时器的超时时间为jiffies_timerout;
timer_pending(struct timer_list *):定时器状态查询,如果在系统的定时器列表中则返回1,否则返回0;
del_timer(struct timer_list*):删除定时器。
四、使用简例
#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");
五、运行结果