核心計時器
每當需要安排一項動作於稍後的時刻才發生,但是不想將當時行程阻擋到該時間點,就需要借助核心計時器(kernel timer),這些計時器可以安排函式於未來的特定時間點執行,還可以應用於各種工作。 在到達指定的時間之前,被排程的函式幾乎不會執行,也就是說該函式是以非同步(asynchrously)的方式運作。到目前為止,我們的驅動程式範例都是在發出系統呼叫的行程的環境裡運作。然而,當計時器開始跑,委託排程的行程就有可能休眠、被換到另一個處理器上執行、甚至可能結束執行。
Timer API
計時器是如此重要的資源,以致核心提供了一組API,用來宣告、註冊、移除核心計時器。
#include <linux/timer.h>
struct timer_list{
unsigned long expires;
void (*function)(unsigned long);
unsigned long data;
};
void init_timer(struct timer_list *timer);
struct timer_list TIMER_INITIALIZER(_function,_expires,_data);
void add_timer(struct timer_list *timer);
int del_timer(struct timer_list *timer);
expires欄位是預期要跑計時器函式的jiffies絕對值,也就是jiffies變化到該時刻,便會將data引數傳給function所指的函式,並執行該函式。 init_timer()函式初始化timer_list結構;或者可以指定TIMER_INITIALIZER給一個靜態結構。初始化完成後,可以修改它的三個欄位,最後才呼叫add_timer()來註冊計時器。對於會自我註冊的計時器,可以使用del_timer()來註銷他。 範例(LED閃爍):
static struct timer_list blink_timer;
init_timer(&blink_timer);
blink_timer.function = blink_timer_func;
blink_timer.data = 1; // initially turn LED on
blink_timer.expires = jiffies + (1*HZ); // 1 sec.
add_timer(&blink_timer);
其他函式有:
int mod_timer(struct timer_list *timer,unsigned long expires);
更新計時器的過期時間:通常用於計時器函式中來設定下次的觸發時間。
int del_timer_sync(struct timer_list *timer);
基本與del_timer()一樣,但他保證返回時,計時器函式沒在任何CPU上活動。
int timer_pending(const struct timer_list *timer);
傳回一個代表計時器函式是否已經準備好要被執行的布林值。