9.3时间管理之timer
内核定时器:
涉及头文件:
#include <linux/timer.h>
一个内核定时器对应如下一个结构体变量:
struct timer_list {
	struct list_head entry;
	unsigned long expires;   //定时的未来时间点,以jiffies为参考点。
	struct tvec_base *base;
	void (*function)(unsigned long); //定时处理函数
	unsigned long data;	//定时处理函数需要的点心
int slack;
#ifdef CONFIG_TIMER_STATS
	int start_pid;
	void *start_site;
	char start_comm[16];
#endif
#ifdef CONFIG_LOCKDEP
	struct lockdep_map lockdep_map;
#endif
};
a. 定时对象的实例化
<1> 
	struct timer_list timer;
	init_timer(&timer);
	timer.function = do_timer_hehe;
	timer.expires  = jiffies + n*HZ;
	timer.data     = (unsigned long)&val; 	 
<2>
struct timer_list timer;
	setup_timer(&timer, do_timer_hehe, (unsigned long)&val);
	timer.expires = jiffies + n*HZ;	
<3> 
	DEFINE_TIMER(timer, do_timer_hehe, jiffies+n*HZ, (unsigned long)&val);
b. 定时器的注册及启动
add_timer(&timer);
c. 当希望周期性产生定时的时候,需要在定时处理函数中调用如下函数再次启动下一次
   的定时:
mod_timer(&timer, jiffies + n*HZ);
d. 在驱动模块的出口移除曾经注册的定时器
	del_timer(&timer);
	del_timer_sync(&timer);
timer目录:
1 obj-m := demo.o 2 3 KERNEL := /linux-3.5/ 4 5 all: 6 make -C $(KERNEL) M=`pwd` 7 clean: 8 make -C $(KERNEL) M=`pwd` clean 9
1 #ifndef _LINUX_TIMER_H 2 #define _LINUX_TIMER_H 3 4 #include <linux/list.h> 5 #include <linux/ktime.h> 6 #include <linux/stddef.h> 7 #include <linux/debugobjects.h> 8 #include <linux/stringify.h> 9 10 struct tvec_base; 11 12 struct timer_list { 13 /* 14 * All fields that change during normal runtime grouped to the 15 * same cacheline 16 */ 17 struct list_head entry; 18 unsigned long expires; 19 struct tvec_base *base; 20 21 void (*function)(unsigned long); 22 unsigned long data; 23 24 int slack; 25 26 #ifdef CONFIG_TIMER_STATS 27 int start_pid; 28 void *start_site; 29 char start_comm[16]; 30 #endif 31 #ifdef CONFIG_LOCKDEP 32 struct lockdep_map lockdep_map; 33 #endif 34 }; 35 36 extern struct tvec_base boot_tvec_bases; 37 38 #ifdef CONFIG_LOCKDEP 39 /* 40 * NB: because we have to copy the lockdep_map, setting the lockdep_map key 41 * (second argument) here is required, otherwise it could be initialised to 42 * the copy of the lockdep_map later! We use the pointer to and the string 43 * "<file>:<line>" as the key resp. the name of the lockdep_map. 44 */ 45 #define __TIMER_LOCKDEP_MAP_INITIALIZER(_kn) \ 46 .lockdep_map = STATIC_LOCKDEP_MAP_INIT(_kn, &_kn), 47 #else 48 #define __TIMER_LOCKDEP_MAP_INITIALIZER(_kn) 49 #endif 50 51 /* 52 * Note that all tvec_bases are 2 byte aligned and lower bit of 53 * base in timer_list is guaranteed to be zero. Use the LSB to 54 * indicate whether the timer is deferrable. 55 * 56 * A deferrable timer will work normally when the system is busy, but 57 * will not cause a CPU to come out of idle just to service it; instead, 58 * the timer will be serviced when the CPU eventually wakes up with a 59 * subsequent non-deferrable timer. 60 */ 61 #define TBASE_DEFERRABLE_FLAG (0x1) 62 63 #define TIMER_INITIALIZER(_function, _expires, _data) { \ 64 .entry = { .prev = TIMER_ENTRY_STATIC }, \ 65 .function = (_function), \ 66 .expires = (_expires), \ 67 .data = (_data), \ 68 .base = &boot_tvec_bases, \ 69 .slack = -1, \ 70 __TIMER_LOCKDEP_MAP_INITIALIZER( \ 71 __FILE__ ":" __stringify(__LINE__)) \ 72 } 73 74 #define TBASE_MAKE_DEFERRED(ptr) ((struct tvec_base *) \ 75 ((unsigned char *)(ptr) + TBASE_DEFERRABLE_FLAG)) 76 77 #define TIMER_DEFERRED_INITIALIZER(_function, _expires, _data) {\ 78 .entry = { .prev = TIMER_ENTRY_STATIC }, \ 79 .function = (_function), \ 80 .expires = (_expires), \ 81 .data = (_data), \ 82 .base = TBASE_MAKE_DEFERRED(&boot_tvec_bases), \ 83 __TIMER_LOCKDEP_MAP_INITIALIZER( \ 84 __FILE__ ":" __stringify(__LINE__)) \ 85 } 86 87 #define DEFINE_TIMER(_name, _function, _expires, _data) \ 88 struct timer_list _name = \ 89 TIMER_INITIALIZER(_function, _expires, _data) 90 91 void init_timer_key(struct timer_list *timer, 92 const char *name, 93 struct lock_class_key *key); 94 void init_timer_deferrable_key(struct timer_list *timer, 95 const char *name, 96 struct lock_class_key *key); 97 98 #ifdef CONFIG_LOCKDEP 99 #define init_timer(timer) \ 100 do { \ 101 static struct lock_class_key __key; \ 102 init_timer_key((timer), #timer, &__key); \ 103 } while (0) 104 105 #define init_timer_deferrable(timer) \ 106 do { \ 107 static struct lock_class_key __key; \ 108 init_timer_deferrable_key((timer), #timer, &__key); \ 109 } while (0) 110 111 #define init_timer_on_stack(timer) \ 112 do { \ 113 static struct lock_class_key __key; \ 114 init_timer_on_stack_key((timer), #timer, &__key); \ 115 } while (0) 116 117 #define setup_timer(timer, fn, data) \ 118 do { \ 119 static struct lock_class_key __key; \ 120 setup_timer_key((timer), #timer, &__key, (fn), (data));\ 121 } while (0) 122 123 #define setup_timer_on_stack(timer, fn, data) \ 124 do { \ 125 static struct lock_class_key __key; \ 126 setup_timer_on_stack_key((timer), #timer, &__key, \ 127 (fn), (data)); \ 128 } while (0) 129 #define setup_deferrable_timer_on_stack(timer, fn, data) \ 130 do { \ 131 static struct lock_class_key __key; \ 132 setup_deferrable_timer_on_stack_key((timer), #timer, \ 133 &__key, (fn), \ 134 (data)); \ 135 } while (0) 136 #else 137 #define init_timer(timer)\ 138 init_timer_key((timer), NULL, NULL) 139 #define init_timer_deferrable(timer)\ 140 init_timer_deferrable_key((timer), NULL, NULL) 141 #define init_timer_on_stack(timer)\ 142 init_timer_on_stack_key((timer), NULL, NULL) 143 #define setup_timer(timer, fn, data)\ 144 setup_timer_key((timer), NULL, NULL, (fn), (data)) 145 #define setup_timer_on_stack(timer, fn, data)\ 146 setup_timer_on_stack_key((timer), NULL, NULL, (fn), (data)) 147 #define setup_deferrable_timer_on_stack(timer, fn, data)\ 148 setup_deferrable_timer_on_stack_key((timer), NULL, NULL, (fn), (data)) 149 #endif 150 151 #ifdef CONFIG_DEBUG_OBJECTS_TIMERS 152 extern void init_timer_on_stack_key(struct timer_list *timer, 153 const char *name, 154 struct lock_class_key *key); 155 extern void destroy_timer_on_stack(struct timer_list *timer); 156 #else 157 static inline void destroy_timer_on_stack(struct timer_list *timer) { } 158 static inline void init_timer_on_stack_key(struct timer_list *timer, 159 const char *name, 160 struct lock_class_key *key) 161 { 162 init_timer_key(timer, name, key); 163 } 164 #endif 165 166 static inline void setup_timer_key(struct timer_list * timer, 167 const char *name, 168 struct lock_class_key *key, 169 void (*function)(unsigned long), 170 unsigned long data) 171 { 172 timer->function = function; 173 timer->data = data; 174 init_timer_key(timer, name, key); 175 } 176 177 static inline void setup_timer_on_stack_key(struct timer_list *timer, 178 const char *name, 179 struct lock_class_key *key, 180 void (*function)(unsigned long), 181 unsigned long data) 182 { 183 timer->function = function; 184 timer->data = data; 185 init_timer_on_stack_key(timer, name, key); 186 } 187 188 extern void setup_deferrable_timer_on_stack_key(struct timer_list *timer, 189 const char *name, 190 struct lock_class_key *key, 191 void (*function)(unsigned long), 192 unsigned long data); 193 194 /** 195 * timer_pending - is a timer pending? 196 * @timer: the timer in question 197 * 198 * timer_pending will tell whether a given timer is currently pending, 199 * or not. Callers must ensure serialization wrt. other operations done 200 * to this timer, eg. interrupt contexts, or other CPUs on SMP. 201 * 202 * return value: 1 if the timer is pending, 0 if not. 203 */ 204 static inline int timer_pending(const struct timer_list * timer) 205 { 206 return timer->entry.next != NULL; 207 } 208 209 extern void add_timer_on(struct timer_list *timer, int cpu); 210 extern int del_timer(struct timer_list * timer); 211 extern int mod_timer(struct timer_list *timer, unsigned long expires); 212 extern int mod_timer_pending(struct timer_list *timer, unsigned long expires); 213 extern int mod_timer_pinned(struct timer_list *timer, unsigned long expires); 214 215 extern void set_timer_slack(struct timer_list *time, int slack_hz); 216 217 #define TIMER_NOT_PINNED 0 218 #define TIMER_PINNED 1 219 /* 220 * The jiffies value which is added to now, when there is no timer 221 * in the timer wheel: 222 */ 223 #define NEXT_TIMER_MAX_DELTA ((1UL << 30) - 1) 224 225 /* 226 * Return when the next timer-wheel timeout occurs (in absolute jiffies), 227 * locks the timer base and does the comparison against the given 228 * jiffie. 229 */ 230 extern unsigned long get_next_timer_interrupt(unsigned long now); 231 232 /* 233 * Timer-statistics info: 234 */ 235 #ifdef CONFIG_TIMER_STATS 236 237 extern int timer_stats_active; 238 239 #define TIMER_STATS_FLAG_DEFERRABLE 0x1 240 241 extern void init_timer_stats(void); 242 243 extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf, 244 void *timerf, char *comm, 245 unsigned int timer_flag); 246 247 extern void __timer_stats_timer_set_start_info(struct timer_list *timer, 248 void *addr); 249 250 static inline void timer_stats_timer_set_start_info(struct timer_list *timer) 251 { 252 if (likely(!timer_stats_active)) 253 return; 254 __timer_stats_timer_set_start_info(timer, __builtin_return_address(0)); 255 } 256 257 static inline void timer_stats_timer_clear_start_info(struct timer_list *timer) 258 { 259 timer->start_site = NULL; 260 } 261 #else 262 static inline void init_timer_stats(void) 263 { 264 } 265 266 static inline void timer_stats_timer_set_start_info(struct timer_list *timer) 267 { 268 } 269 270 static inline void timer_stats_timer_clear_start_info(struct timer_list *timer) 271 { 272 } 273 #endif 274 275 extern void add_timer(struct timer_list *timer); 276 277 extern int try_to_del_timer_sync(struct timer_list *timer); 278 279 #ifdef CONFIG_SMP 280 extern int del_timer_sync(struct timer_list *timer); 281 #else 282 # define del_timer_sync(t) del_timer(t) 283 #endif 284 285 #define del_singleshot_timer_sync(t) del_timer_sync(t) 286 287 extern void init_timers(void); 288 extern void run_local_timers(void); 289 struct hrtimer; 290 extern enum hrtimer_restart it_real_fn(struct hrtimer *); 291 292 unsigned long __round_jiffies(unsigned long j, int cpu); 293 unsigned long __round_jiffies_relative(unsigned long j, int cpu); 294 unsigned long round_jiffies(unsigned long j); 295 unsigned long round_jiffies_relative(unsigned long j); 296 297 unsigned long __round_jiffies_up(unsigned long j, int cpu); 298 unsigned long __round_jiffies_up_relative(unsigned long j, int cpu); 299 unsigned long round_jiffies_up(unsigned long j); 300 unsigned long round_jiffies_up_relative(unsigned long j); 301 302 #endif
1 /* head file */ 2 #include <linux/init.h> 3 #include <linux/module.h> 4 #include <linux/sched.h> 5 6 #include <linux/timer.h> 7 8 #include <linux/delay.h> 9 10 #define PERIORD 2 11 12 static struct timer_list timer;//1.定义一个定时对象 13 14 static void do_timer_hehe (unsigned long data)//定时处理函数/data接收的就是定时处理函数需要的参数(点心) 15 { 16 printk("In %s: %s\n", __func__, (char *)data); 17 18 mod_timer(&timer, jiffies+HZ*PERIORD);//3.周期性产生定时 19 } 20 21 /* driver module entry */ 22 static int __init demo_init(void) 23 { 24 setup_timer(&timer, do_timer_hehe, (unsigned long)"hehe");//1.定时对象的实例化/第三个参数为定时处理函数要传递的参数(准备的点心) 25 timer.expires = PERIORD*HZ + jiffies;//1.以jiffies为参考点,定时的未来时间点 26 27 add_timer(&timer);//2.定时器的注册及启动 28 29 return 0; 30 } 31 32 module_init(demo_init); 33 34 35 /* driver module exit */ 36 static void __exit demo_exit(void) 37 { 38 del_timer_sync(&timer);//4.在驱动模块出口移除曾经注册的定时器。 39 } 40 module_exit(demo_exit); 41 42 /* driver module description */ 43 MODULE_LICENSE("GPL"); 44 45 MODULE_AUTHOR("crmn"); 46 MODULE_VERSION("crmn1.0"); 47 MODULE_DESCRIPTION("example for driver module arch");

 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号