在linux驱动中经常需要使用定时器,常见的使用为启动某项检查获取检测log等,此时会在proc/下增加相应的检测开关和时间域。如/proc/ctcwifi/diag_enable和/proc/ctcwifi/diag_duration,此时需支持diag_enable的读写,diag_duration的读写,当diag_enable写1时开始检测,检测时间为diag_duration,在检测时间内,或将检测日志保存到log,或将检测关键直接输出到串口。此时就需要使用linux定时器。
linux内核专门提供了定时器的实现机制主要涉及一下几个函数:
1、初始化定时器:
void init_timer(struct timer_list * timer);
2、添加定时器:
void add_timer(struct timer_list * timer);
3、删除定时器:
int del_timer(struct timer_list * timer);
上面的定时器函数中都使用了struct timer_list,该结构体的定义在#include<linux/timer.h>中,如下:
struct timer_list
{
struct list_head list; //linux中对所有定时器实行链表管理,此为链表头结点
unsigned long expires; //定时器到期时间
unsigned long data; //此参数最后传入定时处理函数,类似于线程中的arg
void (*function)(unsigned long); //定时器超时执行函数
};
下面提供一段代码实例(由于原有检测时间域和检测开关实现及检测处理方法不便于给出,现给出一般用法):
#include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/sched.h> //提供jiffies的定义
#include <linux/init.h> #include <linux/timer.h>
struct timer_list ctcwifi_timer; //定义一个定时器
void ctcwifi_diag_timeout(unsigned long arg)
{
printk("enter ctcwifi_diag_timeout function,
recv data %d from timer\n",arg);
del_timer(&ctcwifi_timer); //也可在exit函数中删除,两处选择一处
}
static int __init ctcwifi_diag_init(void) //驱动insmod时执行
{
ptintk("enter ctcwifi_diag_init function\n"); //初始化定时器
ctcwifi_timer.expires = jiffies + (100 * HZ); //设定超时时间,100s
ctcwifi_timer.data = 300; //传递给定时器超时函数的值
ctcwifi_timer.function = ctcwifi_diag_timeout; //定时器超时执行函数
add_timer(&ctcwifi_timer); //添加定时器
return 0;
}
static void __exit ctcwifi_diag_exit(void) //驱动rmmod时执行
{
del_timer(&ctcwifi_timer); //卸载模块时,删除定时器,也可在超时函数中删除
printk("enter ctcwifi_diag_exit function\n");
}
module_init(ctcwifi_diag_init);
module_exit(ctcwifi_diag_exit);
MODULE_AUTHOR("ZC");
MODULE_LICENSE("Dual BAD/GPL");