核心在時鐘中斷發生後檢測各定時器是否到期,在linux核心中提供了一組函式和資料結構來完成定時觸發工作/週期的事務。
struct timer_list ;
expires,定時器的到期時間,單位是jiffies
function,定時器到期,要執行的函式
data,傳入要執行的函式的引數
1.void init_timer(struct timer_list * timer);
功能是初始化 timer_list 結構體的 entry 的next 為 null,並給 base 指標賦值
2.timer_initializer(_function, _expires, _data)
功能是賦值 timer_list 結構體的 function、expires、data和 base 成員
函式原型是:
#define timer_initializer(_function, _expires, _data) , \
.function = (_function), \
.expires = (_expires), \
.data = (_data), \
.base = &boot_tvec_bases, \
}
3.define_timer(_name, _function, _expires, _data)
乙個給結構體賦值的快捷方式,
函式原型是:
#define define_timer(_name, _function, _expires, _data) \
struct timer_list _name = \
timer_initializer(_function, _expires, _data)
4.static inline void
setup_timer(struct timer_list * timer, void (*function)(unsigned long), unsigned long data)
這個函式也可以給 定時器 結構體成員賦值,
函式原型是:
static
inline
void setup_timer(struct timer_list * timer,
void (*function)(unsigned
long),
unsigned
long data)
void add_timer(struct timer_list * timer);
註冊核心定時器,將定時器加入到核心動態定時器鍊錶,即啟動定時器
int del_timer(struct timer_list * timer);
–> 直接刪除
int del_timer_sync(struct timer_list * timer);
–> 等待定時器處理完之後刪除,此函式不能出現在中斷上下文。一般用在多 cpu 場合,定時器被另乙個 cpu 使用的情況。
int mod_timer(struct timer_list *timer, unsigned long expires);
這個函式有啟動定時器的功能
open 函式中setup_timer,想要用定時器的地方mod_timer.
定義 timer_list 結構體,在想要呼叫的地方填充上 timer_list裡邊的成員,init_timer,add_timer
定時器的每次新增之後,執行完定時器後就會失效,要想迴圈使用,需要在定時函式中新增
del_timer 是刪除沒有發生的定時器,如果已經發生了,刪除不刪除應該無所謂
/**** 裝置結構體*/
struct ***_dev ;
/**** 驅動中的某函式*/
***_func1(…)
/**** 驅動中的某函式*/
***_func2(…)
/*定時器處理函式*/
static
void ***_do_timer(unsigned
long arg)
delayed_work是對於週期性的任務,linux提供的乙個封裝好的快捷方式
本質是利用定時器和工作佇列實現的,功能就是延時執行
struct delayed_work ;
struct work_struct ;
int schedule_delayed_work(struct delayed_work *work, unsigned long delay);
當delay(單位是jiffies)延時後,work成員中的work_func_t 型別成員 func() 會被執行
如果要週期性的執行任務,需要在 delayed_work 的工作函式中再次呼叫 schedule_delayed_work()
msecs_to_jiffies(const unsigned int m);
int cancel_delayed_work(struct delayed_work *work);
int cancel_delayed_work_sync(struct delayed_work *work);
void ndelay(unsigned long nsecs);
–> ns
void udelay(unsigned long usecs);
–> us
void mdelay(unsigned long msecs);
–> ms
void msleep(unsigned int millisecs);
–> 不可被打斷
unsigned long msleep_interruptible(unsigned int millisecs);
–> 可被打斷
void ssleep(unsigned int seconds);
–> 不可被打斷
乙個直觀的方式是比較當前 jiffies 和目標 jiffies。
time_after()
函式原型:
#define time_after(a,b) \
(typecheck(unsigned
long, a) && \
typecheck(unsigned
long, b) && \
((long)(b) - (long)(a) < 0))
time_before()
函式原型:
#define time_before(a,b) time_after(b,a)
乙個忙等待先延時 100 個jiffies 再延遲 2s 的例項:
/*延遲 100 個 jiffies*/
unsigned
long delay = jiffies + 100;
while (time_before(jiffies, delay));
/*再延遲 2s*/
unsigned
long delay = jiffies + 2*hz;
while (time_before(jiffies, delay));
schedule_timeout_uninterruptible()
–> 呼叫 schedule_timeout()之前置程序狀態為 task_
interruptible
schedule_timeout_interruptible()
–> 置程序狀態為task_uninterruptible
原始碼:
signed
long _ _sched schedule_timeout_interruptible(signed
long timeout)
signed
long _ _sched schedule_timeout_uninterruptible(signed
long timeout)
使用例項:
void msleep(unsigned
int msecs)
unsigned
long msleep_interruptible(unsigned
int msecs)
功能:
將當前程序新增到等待佇列中,在等待佇列中睡眠,當超時發生時,程序被喚醒
sleep_on_timeout(wait_queue_head_t *q, unsigned long timeout);
–> 不可被打斷
interruptible_sleep_on_timeout(wait_queue_head_t*q, unsigned long timeout);
–> 可被打斷
定時器和延時
interrupt 中斷優先順序 定時器和延時的區別 定時器,是指在做一件事情過程中,後台有個計時器,預定時間到後觸發另一項工作。延時,是指在做一件事情過程中,保持一種工作狀態的時間。利用迴圈處理的方式實現的延時,並不精確。1 當中斷發生時,cpu被打斷先執行中斷服務。導致執行時間變長。2 使用高階...
linux核心中如何使用定時器延時
0.包含標頭檔案 include 1.定義時間結構體變數 static struct timer list kbd timer 2.初始化時間結構體變數 init timer kbd timer 3.指定定時器超時服務函式 void kbd timer handler unsigned long k...
核心定時器
linux核心2.4版中去掉了老版本核心中的靜態定時器機制,而只留下動態定時器。相應地在timer bh 函式中也不再通過 run old timers 函式來執行老式的靜態定時器。動態定時器與靜態定時器這二個概念是相對於linux核心定時器機制的可擴充套件 功能而言的,動態定時器是指核心的定時器佇...