Linux内核定时器
1.新旧差异
旧的Linux内核使用init_timer()
来初始化一个定时器,新的内核不再使用该函数,改为使用timer_setup()
。
timer结构体也有变化,旧的结构体类型成员:
struct timer_list {
14 /*
15 * All fields that change during normal runtime grouped to the
16 * same cacheline
17 */
18 struct hlist_node entry;
19 unsigned long expires;
20 void (*function)(unsigned long);
21 unsigned long data;
22 u32 flags;
23
24#ifdef CONFIG_LOCKDEP
25 struct lockdep_map lockdep_map;
26#endif
27};
新的结构体类型成员:
struct timer_list {
12 /*
13 * All fields that change during normal runtime grouped to the
14 * same cacheline
15 */
16 struct hlist_node entry;
17 unsigned long expires;
18 void (*function)(struct timer_list *);
19 u32 flags;
20
21#ifdef CONFIG_LOCKDEP
22 struct lockdep_map lockdep_map;
23#endif
24};
不再使用成员data
,而且回调函数的参数也发生变化,需要传入struct timer_list
类型的指针,导致不能向回调函数传递数据参数。
2.使用内核定时器
#include <linux/module.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
struct timer_list g_timer;//定义全局timer变量
void timer_func(struct timer_list* timer)//回调函数
{
printk("%s:current jiffies is %ld\n",__func__,jiffies);
timer->expires=jiffies+HZ;//修改到期时间为1秒之后
mod_timer(timer,timer->expires);
}
static int __init timer_init(void)
{
printk("enter: %s\n",__func__);
timer_setup(&g_timer,timer_func,0);初始化定时器
printk("current jiffies is %ld\n",jiffies);
g_timer.expires=jiffies+2*HZ;初始化定时器时间
add_timer(&g_timer);//添加定时器
return 0;
}
static void __exit timer_exit(void)
{
printk("enter:%s\n",__func__);
del_timer(&g_timer);//删除定时器
}
module_init(timer_init);
module_exit(timer_exit);
MODULE_LICENSE("GPL");
在内核加载函数中初始化一个定时器,jiffies记录系统自从启动以来的滴答数,HZ代表系统在1s中发生时钟中断的次数。在定时器回调函数中调用mod_timer(),用以触发下一次计数在一秒之后,最后要在模块卸载函数中删除定时器。
3.程序验证
将定时器加载到设备后,打印设备内容。
cat /dev/timer
查看设备信息
dmesg
可以看到绿色字体数值在不断加一,实现了定时器的功能。