Linux裝置驅動編程之定時器2006-10-26 13:34
作者:
出處:Linux
責任編輯:方舟
相關專題:
Linux裝置驅動程式開發入門
Linux核心中定義了一個timer_list結構,我們在驅動程式中可以利用之:
struct timer_list { struct list_head list; unsigned long expires; //定時器到期時間 unsigned long data; //作為參數被傳入定時器處理函數 void (*function)(unsigned long); }; |
下面是關於timer的API函數:
增加定時器
| void add_timer(struct timer_list * timer); |
刪除定時器
| int del_timer(struct timer_list * timer); |
修改定時器的expire
| int mod_timer(struct timer_list *timer, unsigned long expires); |
使用定時器的一般流程為:
(1)timer、編寫function;
(2)為timer的expires、data、function賦值;
(3)調用add_timer將timer加入列表;
(4)在定時器到期時,function被執行;
(5)在程式中涉及timer控制的地方適當地調用del_timer、mod_timer刪除timer或修改timer的expires。
我們可以參考drivers/char/keyboard.c中鍵盤的驅動中關於timer的部分:
…
#include <linux/timer.h>
…
static struct timer_list key_autorepeat_timer =
{
function: key_callback
};
static void
kbd_processkeycode(unsigned char keycode, char up_flag, int autorepeat)
{
char raw_mode = (kbd->kbdmode == VC_RAW);
if (up_flag) {
rep = 0;
if(!test_and_clear_bit(keycode, key_down))
up_flag = kbd_unexpected_up(keycode);
} else {
rep = test_and_set_bit(keycode, key_down);
/* If the keyboard autorepeated for us, ignore it.
* We do our own autorepeat processing.
*/
if (rep && !autorepeat)
return;
}
if (kbd_repeatkeycode == keycode || !up_flag || raw_mode) {
kbd_repeatkeycode = -1;
del_timer(&key_autorepeat_timer);
}
…
/*
* Calculate the next time when we have to do some autorepeat
* processing. Note that we do not do autorepeat processing
* while in raw mode but we do do autorepeat processing in
* medium raw mode.
*/
if (!up_flag && !raw_mode) {
kbd_repeatkeycode = keycode;
if (vc_kbd_mode(kbd, VC_REPEAT)) {
if (rep)
key_autorepeat_timer.expires = jiffies + kbd_repeatinterval;
else
key_autorepeat_timer.expires = jiffies + kbd_repeattimeout;
add_timer(&key_autorepeat_timer);
}
}
…
}