赞
踩
所谓定时器,类似我们的闹钟,时间到后你就要做某件事。
因此,我们要做的有两件事:
1. 设置超时时间
2. 设置处理事件
Linux 内核使用全局变量 jiffies 来记录系统从启动以来的系统节拍数,也就是开机到现在总共的时钟中断次数。
系统启动的时候会将 jiffies 初始化为 0,时钟每中断一次,jiffies就增加一。
作用: Linux 内核使用 timer_list 结构体表示内核定时器
struct timer_list {
struct list_head entry;
unsigned long expires; /* 定时器超时时间,单位是节拍数 */
struct tvec_base *base;
void (*function)(unsigned long); /* 定时处理函数 */
unsigned long data; /* 要传递给 function 函数的参数 */
int slack;
};
void init_timer(struct timer_list *timer)
作用:初始化timer_list 变量
void add_timer(struct timer_list *timer)
作用:用于向 Linux 内核注册定时器
int del_timer(struct timer_list * timer)
作用:用于删除一个定时器
int del_timer_sync(struct timer_list *timer)
作用: del_timer 函数的同步版
区别:会等待其他处理器使用完定时器再删除
注意:del_timer_sync 不能使用在中断上下文中
int mod_timer(struct timer_list *timer, unsigned long expires)
作用:用于修改定时值
注意:如果定时器还没有激活的话,mod_timer 函数会激活定时器
内核定时器并不是周期性运行的,超时以后就会自动关闭。
因此如果想要实现周期性定时,就需要在定时处理函数中重新开启定时器。
/* 定义定时器 */
struct timer_list timer;
/**
* @brief 定时器回调函数
*
* @param data 定时器参数,在设置定时器时传入
*/
static void timer_function(unsigned long data)
{
/*
* 定时器处理代码
*/
/* 如果需要定时器周期性运行的话就使用 mod_timer */
mod_timer(&timer, jiffies + msecs_to_jiffies(超时时间(单位:ms)));
}
/**
* @brief 入口函数
*
*/
static int __init test_init(void)
{
/* 1、初始化定时器 */
init_timer(&timer);
/* 2、设置定时器 */
timer.function = function; // 设置定时器处理函数
timer.expires = jiffies + msecs_to_jiffies(超时时间); // 设置超时时间
timer.data = (要传入的参数); // 传给定时器处理函数的参数
/* 3、启动定时器 */
add_timer(&timer);
}
/**
* @brief 出口函数
*
*/
static void __exit test_exit(void)
{
/* 删除定时器 */
del_timer(&timer);
/* 或 */
del_timer_sync(&timer);
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。