在 Linux 内核中很多函数是基于定时器进行驱动的,但是内核定时器的精度并不高,所以不能作为高精度定时器使用。并且内核定时器的运行没有周期性,到达计时终点后会自动关闭。如果要实现周期性定时,就要在定时处理函数中重新开启定时器。
Linux 内核中使用 timer_list 结构体表示内核定时器,该结构体定义在“内核源码/include/linux/timer.h”文件中,具体内容如下所示:
struct timer_list {
/*
* All fields that change during normal runtime grouped to the
* same cacheline
*/
struct hlist_node entry;
unsigned long expires;
void (*function)(struct timer_list *);
u32 flags;
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
ANDROID_KABI_RESERVE(1);
ANDROID_KABI_RESERVE(2);
};
使用以下宏对 timer_list 结构体进行定义,_name 为定义的结构体名称,_function为定时处理函数,该宏同样定义在文件 “内核源码/include/linux/timer.h”文件中,如下所示:
#define DEFINE_TIMER(_name, _function) \
struct timer_list _name = \
__TIMER_INITIALIZER(_function, 0)
例如可以使用以下代码对定时器和相应的定时处理函数进行定义
DEFINE_TIMER(timer_test,function_test);//定义一个定时器
定时器定义完成之后还需要通过一系列的 API 函数来初始化此定时器,部分函数说明如下
函数 | 作用 |
---|---|
void add_timer(struct timer_list *timer) | 向 Linux 内核注册定时器,使用add_timer 函数向内核注册定时器以后,定时器就会开始运行 |
int del_timer(struct timer_list * timer) | 删除一个定时器 |
int mod_timer(struct timer_list *timer,unsigned long expires) | 修改定时值,如果定时器还没 |
在使用 add_timer()函数向 Linux 内核注册定时器之前,还需要设置定时时间,定时时间由 timer_list 结构体中的 expires 参数所确定,单位为节拍数。
#include
#include
#include
static void function_test(struct timer_list *t);//定义function_test定时功能函数
DEFINE_TIMER(timer_test,function_test);//定义一个定时器
static void function_test(struct timer_list *t)
{
printk("this is function test \n");
mod_timer(&timer_test,jiffies_64 + msecs_to_jiffies(5000));//使用mod_timer函数将定时时间设置为五秒后
}
static int __init timer_mod_init(void) //驱动入口函数
{
timer_test.expires = jiffies_64 + msecs_to_jiffies(5000);//将定时时间设置为五秒后
add_timer(&timer_test);//添加一个定时器
return 0;
}
static void __exit timer_mod_exit(void) //驱动出口函数
{
del_timer(&timer_test);//删除一个定时器
printk("module exit \n");
}
module_init(timer_mod_init);
module_exit(timer_mod_exit);
DEFINE_TIMER(timer_test,function_test);//定义一个定时器
add_timer(&timer_test);//添加一个定时器
static void function_test(struct timer_list *t)
{
printk("this is function test \n");
mod_timer(&timer_test,jiffies_64 + msecs_to_jiffies(5000));//使用mod_timer函数将定时时间设置为五秒后
}