Linux内核定时器
一、Linux定时器主要调用接口
1、定时器数据结构
1 struct timer_list { 2 /* 3 * All fields that change during normal runtime grouped to 4 * the same cacheline 5 */ 6 struct hlist_node entry; 7 unsigned long expires; 8 void (*function)(unsigned long); 9 unsigned long data; 10 u32 flags; 11 int slack; 12 13 #ifdef CONFIG_TIMER_STATS 14 int start_pid; 15 void *start_site; 16 char start_comm[16]; 17 #endif 18 #ifdef CONFIG_LOCKDEP 19 struct lockdep_map lockdep_map; 20 #endif 21 };
2、定时器初始化接口
(1)、init_timer
原型:#define init_timer(timer)
用法:
i、声明定时器
ii、调用init_timer
iii、初始timer字段 :
(2)、TIMER_INITIALIZER
原型:#define TIMER_INITIALIZER(_function, _expires, _data)
用法:
i、初始化定时器
注意:使用TIMER_INITIALIZER初始化定时器,必须在声明定时器变量的同时初始化。
ii、初始化timer字段
使用该方法初始化定时器,因为在调用接口的同时,已经将回调函数等参数传入,可以不用初始化timer字段。但是,在开启定时器的时候,定时器会立即执行。如需要开启定时器后延时一段时间执行,需重新对expires字段赋值。
(3)、DEFINE_TIMER
原型:#define DEFINE_TIMER(_name, _function, _expires, _data)
用法:
i、初始化定时器
ii、初始化timer字段
使用该方法初始化定时器,因为在调用接口的同时,已经将回调函数等参数传入,可以不用初始化timer字段。但是,在开启定时器的时候,定时器会立即执行。如需要开启定时器后延时一段时间执行,需重新对expires字段赋值。
_name字段,不可以是字符串。
(4)、setup_timer
原型:#define setup_timer(timer, fn, data)
用法:
i、初始化定时器
ii、调用setup_timer
ii、初始化timer字段
使用该方法初始化定时器,因为在调用接口的同时,已经将回调函数等参数传入,可以不用初始化timer字段。但是,在开启定时器的时候,定时器会立即执行。如需要开启定时器后延时一段时间执行,需重新对expires字段赋值。
3、定时器开启接口
(1)、add_timer
原型:void add_timer(struct timer_list *timer)
用法:
i、保证定时器的主要字段已经被初始化:expires、function、data等等
ii、add_timer(&MYTIMER);
iii、定时器被激活,根据expires参数执行
(2)、mod_timer
原型:int mod_timer(struct timer_list *timer, unsigned long expires)
用法:
i、保证定时器的主要字段已经被初始化:function、data等等
ii、mod_timer(&MYTIMER,jiffies + TIME_SECOND*HZ);
iii、定时器被激活,根据expires参数执行
iiii、如果timer此时已经被激活,返回1
3、定时器销毁接口
(1)、del_timer.
原型:int del_timer(struct timer_list *timer)
用法:
(2)、del_timer_sync
原型:int del_timer_sync(struct timer_list *timer)
用法:
与 del_timer 相比,此函数会等待定时器服务函数执行完毕,然后删除定时器。
4、完整测试代码
1 #include <linux/init.h> 2 #include <linux/module.h> 3 #include <linux/timer.h> 4 5 #define RUN_TIMES_VALUE 5 //timer func run RUN_TIMES_VALUE times,then exit 6 7 #define TIME_SECOND 5 //restart time 8 9 static void timer_start(void); 10 static void timer_restart(void); 11 static void timer_func(unsigned long param); 12 static void timer_destroy(void); 13 14 /**** init type include 4 kinds ****/ 15 16 //#define TIMER_INIT_TYPE_1 17 #define TIMER_INIT_TYPE_2 18 //#define TIMER_INIT_TYPE_3 19 //#define TIMER_INIT_TYPE_4 20 21 22 #ifdef TIMER_INIT_TYPE_1 23 #define TIMER1_PRINT "This is timer 1 func" 24 #define THE_TIMER_NAME1 my_timer1 25 #define MYTIMER THE_TIMER_NAME1 26 #define MY_PRINT TIMER1_PRINT 27 static struct timer_list THE_TIMER_NAME1; 28 #endif 29 30 #ifdef TIMER_INIT_TYPE_2 31 #define TIMER2_PRINT "This is timer 2 func" 32 #define THE_TIMER_NAME2 my_timer2 33 #define MYTIMER THE_TIMER_NAME2 34 #define MY_PRINT TIMER2_PRINT 35 static struct timer_list THE_TIMER_NAME2 = TIMER_INITIALIZER(timer_func,0,((unsigned long)TIMER2_PRINT)); 36 #endif 37 38 #ifdef TIMER_INIT_TYPE_3 39 #define TIMER3_PRINT "This is timer 3 func" 40 #define THE_TIMER_NAME3 my_timer3 //不可以是字符串 41 #define MYTIMER THE_TIMER_NAME3 42 #define MY_PRINT TIMER3_PRINT 43 DEFINE_TIMER(THE_TIMER_NAME3,timer_func,0,((unsigned long)TIMER3_PRINT)); 44 #endif 45 46 #ifdef TIMER_INIT_TYPE_4 47 #define TIMER4_PRINT "This is timer 4 func" 48 #define THE_TIMER_NAME4 my_timer4 49 #define MYTIMER THE_TIMER_NAME4 50 #define MY_PRINT TIMER4_PRINT 51 static struct timer_list THE_TIMER_NAME4; 52 #endif 53 54 55 /**** destroy type,include 2 kinds ****/ 56 57 #define TIMER_DESTROY_TYPE_1 58 //#define TIMER_DESTROY_TYPE_2 59 60 /**** activate timer, include 2 kinds ****/ 61 #define TIMER_ACTIVATE_TYPE_1 62 //#define TIMER_ACTIVATE_TYPE_2 63 64 65 66 static void timer_start(void) 67 { 68 int ret = 0; 69 #ifdef TIMER_ACTIVATE_TYPE_1 70 printk("Timer start in type 1 -- add_timer\r\n"); 71 add_timer(&MYTIMER); 72 ret = mod_timer(&MYTIMER,jiffies + TIME_SECOND*HZ); 73 printk(KERN_INFO"start -- Ret of mod_timer is %d\n",ret); 74 #endif 75 #ifdef TIMER_ACTIVATE_TYPE_2 76 printk("Timer start in type 2 -- mod_timer\r\n"); 77 ret = mod_timer(&MYTIMER,jiffies + TIME_SECOND*HZ); 78 printk(KERN_INFO"start -- Ret of mod_timer is %d\n",ret); 79 #endif 80 } 81 static void timer_restart(void) 82 { 83 int ret = 0; 84 #ifdef TIMER_ACTIVATE_TYPE_1 85 printk("Timer restart in type 1 -- add_timer\r\n"); 86 MYTIMER.expires = jiffies + TIME_SECOND*HZ; 87 add_timer(&MYTIMER); 88 #endif 89 #ifdef TIMER_ACTIVATE_TYPE_2 90 printk("Timer restart in type 2 -- mod_timer\r\n"); 91 ret = mod_timer(&MYTIMER,jiffies + TIME_SECOND*HZ); 92 printk(KERN_INFO"restart -- Ret of mod_timer is %d\n",ret); 93 #endif 94 } 95 96 static void timer_func(unsigned long param) 97 { 98 static unsigned int counter = 0; 99 char* p_print = (char*)param; 100 101 printk(KERN_INFO"\r\n"); 102 if(counter < RUN_TIMES_VALUE) 103 { 104 printk(KERN_INFO"%s %d\r\n",p_print,counter); 105 counter++; 106 timer_restart(); 107 } 108 else 109 { 110 printk(KERN_INFO"Run times run out of\r\n"); 111 } 112 } 113 114 static void timer_init(void) 115 { 116 printk(KERN_INFO"Alloc a timer\r\n"); 117 118 #ifdef TIMER_INIT_TYPE_1 119 printk(KERN_INFO"Select type 1 to init the timer -- init_timer\r\n"); 120 init_timer(&MYTIMER); 121 #endif 122 123 #ifdef TIMER_INIT_TYPE_2 124 printk(KERN_INFO"Select type 2 to init the timer -- TIMER_INITIALIZER\r\n"); 125 #endif 126 127 #ifdef TIMER_INIT_TYPE_3 128 printk(KERN_INFO"Select type 3 to init the timer -- DEFINE_TIMERr\r\n"); 129 #endif 130 131 #ifdef TIMER_INIT_TYPE_4 132 setup_timer(&MYTIMER,timer_func,(unsigned long )MY_PRINT); 133 printk(KERN_INFO"Select type 4 to init the timer -- setup_timer\r\n"); 134 #endif 135 136 MYTIMER.expires = jiffies + TIME_SECOND*HZ; 137 MYTIMER.function = timer_func; 138 MYTIMER.data = (unsigned long )MY_PRINT; 139 140 141 } 142 static void timer_destroy(void) 143 { 144 145 #ifdef TIMER_DESTROY_TYPE_1 146 printk(KERN_INFO"Destroy the timer in destroy type 1 -- del_timer\r\n"); 147 del_timer(&MYTIMER); 148 #endif 149 150 #ifdef TIMER_DESTROY_TYPE_2 151 printk(KERN_INFO"Destroy the timer in destroy type 2 -- del_timer_sync\r\n"); 152 del_timer_sync(&MYTIMER); 153 #endif 154 } 155 156 157 static int __init timer_test_init(void) 158 { 159 printk(KERN_INFO"Enter timer test\r\n"); 160 timer_init(); 161 timer_start(); 162 return 0; 163 } 164 165 static void __exit timer_test_exit(void) 166 { 167 timer_destroy(); 168 169 printk(KERN_INFO"Exit timer test\r\n"); 170 } 171 172 module_init(timer_test_init); 173 module_exit(timer_test_exit); 174 175 MODULE_LICENSE("GPL"); 176 MODULE_AUTHOR("Marvin.xin"); 177 MODULE_DESCRIPTION("A Test Module for Timer");
5、同一个定时器函数,服务4个timer
根据定时器函数参数区分不同的定时器
1 #include <linux/init.h> 2 #include <linux/module.h> 3 #include <linux/timer.h> 4 5 #define RUN_TIMES_VALUE 5 //timer func run RUN_TIMES_VALUE times,then exit 6 7 #define TIME_SECOND 5 //restart time 8 9 #define TIMER_STR_1 "This is timer 1 coming" 10 #define TIMER_STR_2 "This is timer 2 coming" 11 #define TIMER_STR_3 "This is timer 3 coming" 12 #define TIMER_STR_4 "This is timer 4 coming" 13 14 15 16 17 static void timer_start(int timer_index); 18 static void timer_restart(int timer_index); 19 static void timer_func(unsigned long param); 20 static void timer_destroy(int timer_index); 21 22 23 24 25 static struct timer_list my_timer1; 26 static struct timer_list my_timer2 = TIMER_INITIALIZER(NULL,0,0); 27 DEFINE_TIMER(my_timer3,NULL,0,0); 28 static struct timer_list my_timer4; 29 30 31 #define TIMER_TOTAL_NUM 4 32 enum { 33 timer_num_0 = 0, 34 timer_num_1, 35 timer_num_2, 36 timer_num_3, 37 timer_num_total, 38 }; 39 typedef struct timer_data{ 40 unsigned char timer_id; 41 unsigned char second; 42 struct timer_list* ptimer; 43 unsigned char counter; 44 char* print_str; 45 }timer_s; 46 47 timer_s my_timer[TIMER_TOTAL_NUM]; 48 49 50 /**** destroy type,include 2 kinds ****/ 51 52 //#define TIMER_DESTROY_TYPE_1 53 #define TIMER_DESTROY_TYPE_2 54 55 /**** activate timer, include 2 kinds ****/ 56 //#define TIMER_ACTIVATE_TYPE_1 57 #define TIMER_ACTIVATE_TYPE_2 58 59 60 61 static void timer_start(int timer_index) 62 { 63 if(timer_index < timer_num_total) 64 { 65 #ifdef TIMER_ACTIVATE_TYPE_1 66 printk("Timer %d start in type 1 -- add_timer\r\n",timer_index+1); 67 add_timer(my_timer[timer_index].ptimer); 68 #endif 69 70 #ifdef TIMER_ACTIVATE_TYPE_2 71 printk("Timer %d start in type 2 -- mod_timer\r\n",timer_index+1); 72 mod_timer(my_timer[timer_index].ptimer,jiffies + my_timer[timer_index].second*HZ); 73 #endif 74 } 75 else 76 { 77 printk("timer_index error\r\n"); 78 } 79 80 } 81 static void timer_restart(int timer_index) 82 { 83 if(timer_index < timer_num_total) 84 { 85 #ifdef TIMER_ACTIVATE_TYPE_1 86 //printk("Timer %d restart in type 1 -- add_timer\r\n",timer_index+1); 87 my_timer[timer_index].ptimer->expires = jiffies + my_timer[timer_index].second*HZ; 88 add_timer(my_timer[timer_index].ptimer); 89 #endif 90 #ifdef TIMER_ACTIVATE_TYPE_2 91 printk("Timer %d restart in type 2 -- mod_timer\r\n",timer_index+1); 92 mod_timer(my_timer[timer_index].ptimer,jiffies + my_timer[timer_index].second*HZ); 93 #endif 94 } 95 else 96 { 97 printk("timer_index error\r\n"); 98 } 99 100 } 101 102 static void timer_func(unsigned long param) 103 { 104 timer_s* ptimer = (timer_s*)param; 105 106 if(ptimer->timer_id < timer_num_total) 107 { 108 109 if(ptimer->counter < RUN_TIMES_VALUE) 110 { 111 printk("%s -- Timer %d counter %d\r\n",ptimer->print_str,ptimer->timer_id+1,ptimer->counter); 112 ptimer->counter++; 113 timer_restart(ptimer->timer_id); 114 } 115 else 116 { 117 printk(KERN_INFO"Timer %d Run times run out of\r\n",ptimer->timer_id+1); 118 } 119 } 120 else 121 { 122 printk("Something error\r\n"); 123 } 124 } 125 126 static void timer_init(void) 127 { 128 129 my_timer[timer_num_0].timer_id = timer_num_0; 130 my_timer[timer_num_0].ptimer = &my_timer1; 131 my_timer[timer_num_0].print_str = TIMER_STR_1; 132 my_timer[timer_num_0].second = 1; 133 my_timer[timer_num_0].counter = 0; 134 135 my_timer[timer_num_1].timer_id = timer_num_1; 136 my_timer[timer_num_1].ptimer = &my_timer2; 137 my_timer[timer_num_1].print_str = TIMER_STR_2; 138 my_timer[timer_num_1].second = 2; 139 my_timer[timer_num_1].counter = 0; 140 141 my_timer[timer_num_2].timer_id = timer_num_2; 142 my_timer[timer_num_2].ptimer = &my_timer3; 143 my_timer[timer_num_2].print_str = TIMER_STR_3; 144 my_timer[timer_num_2].second = 3; 145 my_timer[timer_num_2].counter = 0; 146 147 my_timer[timer_num_3].timer_id = timer_num_3; 148 my_timer[timer_num_3].ptimer = &my_timer4; 149 my_timer[timer_num_3].print_str = TIMER_STR_4; 150 my_timer[timer_num_3].second = 4; 151 my_timer[timer_num_3].counter = 0; 152 153 //init timer 1 154 init_timer(&my_timer1); 155 my_timer[timer_num_0].ptimer->expires = my_timer[timer_num_0].second*HZ + jiffies; 156 my_timer[timer_num_0].ptimer->data = (unsigned long)(&my_timer[timer_num_0]); 157 my_timer[timer_num_0].ptimer->function = timer_func; 158 159 //init timer 2 160 my_timer[timer_num_1].ptimer->expires = my_timer[timer_num_1].second*HZ + jiffies; 161 my_timer[timer_num_1].ptimer->data = (unsigned long)(&my_timer[timer_num_1]); 162 my_timer[timer_num_1].ptimer->function = timer_func; 163 164 //init timer 3 165 my_timer[timer_num_2].ptimer->expires = my_timer[timer_num_2].second*HZ + jiffies; 166 my_timer[timer_num_2].ptimer->data = (unsigned long)(&my_timer[timer_num_2]); 167 my_timer[timer_num_2].ptimer->function = timer_func; 168 169 //init timer 4 170 setup_timer(&my_timer4,NULL,0); 171 my_timer[timer_num_3].ptimer->expires = my_timer[timer_num_3].second*HZ + jiffies; 172 my_timer[timer_num_3].ptimer->data = (unsigned long)(&my_timer[timer_num_3]); 173 my_timer[timer_num_3].ptimer->function = timer_func; 174 175 } 176 static void timer_destroy(int timer_index) 177 { 178 if(timer_index < timer_num_total) 179 { 180 #ifdef TIMER_DESTROY_TYPE_1 181 printk(KERN_INFO"Destroy the timer %d in destroy type 1 -- del_timer\r\n",timer_index+1); 182 del_timer(my_timer[timer_index].ptimer); 183 #endif 184 185 #ifdef TIMER_DESTROY_TYPE_2 186 printk(KERN_INFO"Destroy the timer %d in destroy type 2 -- del_timer_sync\r\n",timer_index+1); 187 del_timer_sync(my_timer[timer_index].ptimer); 188 #endif 189 } 190 else 191 { 192 printk("timer_index error\r\n"); 193 } 194 } 195 196 197 static int __init timer_test_init(void) 198 { 199 printk(KERN_INFO"Enter timer test\r\n"); 200 timer_init(); 201 timer_start(timer_num_0); 202 timer_start(timer_num_1); 203 timer_start(timer_num_2); 204 timer_start(timer_num_3); 205 return 0; 206 } 207 208 static void __exit timer_test_exit(void) 209 { 210 timer_destroy(timer_num_0); 211 timer_destroy(timer_num_1); 212 timer_destroy(timer_num_2); 213 timer_destroy(timer_num_3); 214 printk(KERN_INFO"Exit timer test\r\n"); 215 } 216 217 module_init(timer_test_init); 218 module_exit(timer_test_exit); 219 220 MODULE_LICENSE("GPL"); 221 MODULE_AUTHOR("Marvin.xin"); 222 MODULE_DESCRIPTION("A Test Module for Timer");