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 };
View Code

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");
View Code

 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");
View Code

 

posted @ 2019-03-16 14:41  一枚小苦工  阅读(3553)  评论(0编辑  收藏  举报