内核时钟基础知识:
HZ:(系统时钟通过CONFIG_HZ来设置,范围是100-1000;HZ决定时钟中断发生的频率)
内核的全局变量jiffies:(记录内核自启动来的节拍数,内核之启动以来,产生的中断数)
jiffies/HZ :内核自启动以来的秒数
使用 vi config_for_linux_scp_elite 命令,在配置文件中查看,搜索CONFIG_HZ可以获知HZ时钟频率。
jiffies参数的头文件 #include "linux/jiffies.h"
内核定时器编程
1.timer_list结构体
在 Linux 内核中,timer_list 结构体的一个实例对应一个定时器
1
2
3
4
5
6
7
8
9 1struct timer_list {
2 struct list_head entry;
3 unsigned long expires;
4 struct tvec_base *base;
5 void (*function)(unsigned long);
6 unsigned long data;
7 ...
8};
9
timer_list 结构体内的参数:
- struct list_head entry 双向链表。
- unsigned long expires;超时时间。记录什么时候产生时钟中断。
- struct tvec_base *base;管理时钟的结构体
- void (*function)(unsigned long);时钟中断产生之后的动作
- unsigned long data;传递的参数
2.初始化定时器
1
2 1init_timer(timer)
2
上述 init_timer()函数初始化 timer_list 的 entry 的 next 为 NULL,并给 base 指针赋
值。
TIMER_INITIALIZER(_function, _expires, _data)宏用于赋值定时器结构体的function、expires、data 和 base 成员
1
2 1setup_timer(timer, fn, data)
2
setup_timer也用于初始化定时器,同时赋值其成员
参数:
- struct timer_list * timer
- void (*function)(unsigned long)
- unsigned long data
3.增加定时器
1
2 1extern void add_timer(struct timer_list *timer);
2
4.删除定时器
1
2 1extern int del_timer(struct timer_list * timer);
2
5.修改定时器的expires
1
2 1extern int mod_timer(struct timer_list *timer, unsigned long expires);
2
上述函数用于修改定时器的到期时间,在新的被传入的 expires 到来后才会执行定时器函数。
mod_timer = del_timer(timer);timer->expires = expires; add_timer(timer);
简单驱动代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 1#include "linux/module.h"
2#include "linux/timer.h"
3#include "linux/jiffies.h"
4
5struct timer_list demo_timer;
6
7static void time_func(unsigned long data)
8{
9 printk("%s ,secs = %ld!\n",(char *)data,jiffies/HZ);
10
11 mod_timer(&demo_timer,jiffies + 5*HZ);
12}
13
14static int __init mytimer_init(void)
15{
16 printk("mytimer_init!\n");
17 setup_timer(&demo_timer,time_func,(unsigned long) "demo_timer!");
18 demo_timer.expires = jiffies + 1*HZ;
19 add_timer(&demo_timer);
20
21 return 0;
22}
23
24static void __exit mytimer_exit(void)
25{
26 printk("mytimer_exit!\n");
27 del_timer(&demo_timer);
28}
29
30module_init(mytimer_init);
31module_exit(mytimer_exit);
32
33MODULE_LICENSE("Dual BSD/GPL");
34