軟件意義上的定時器最終依賴硬件定時器來實現, 內核在時鐘中斷發生后檢測各定時器是否到期 , 到期后的定時器處理函數將作為軟中斷在底半部執行 。實質上,時鐘中斷處理程序會 換起TIMER_SOFTIRQ軟中斷 ,運行當前處理器上到期的所有定時器。
總結起來還是軟中斷的流程
a.注冊軟中斷處理函數
1
2
3
|
/*/linux/kernel.timer.c*/ void __init init_timers( void ) -->open_softirq(TIMER_SOFTIRQ, run_timer_softirq, NULL); |
b.添加timer_list到某個鏈表
void add_timer (struct timer_list *timer);
c.觸發軟中斷處理函數
1
2
3
|
void irq_exit( void ) -->tick_nohz_stop_sched_tick(); -->raise_softirq_irqoff(TIMER_SOFTIRQ); |
d.調用軟中斷處理函數
static void run_timer_softirq(struct softirq_action *h)
-->__run_timers(base);
-->遍歷執行時間到達的timer_list中的定時器處理函數
在Linux設備驅動編程中,可以利用Linux內核中提供的一組函數和數據結構來完成定時觸發工作或者完成某種周期性的事務。這組函數和數據結構使得驅動程序師在多數情況下不用關心具體的軟件定時器究竟對應著怎樣的內核和硬件行為。
1) 一個timer_list 結構體的實例對應一個定時器,其定義如下:
1
2
3
4
5
6
7
8
9
10
|
struct timer_list { struct list_head entry, /*定時器列表*/ unsigned long expires, /*定時器到期時間*/ void (*function) (unsigned long ), /*定時器處理函數*/ unsigned long data, /*作為參數被傳入定時器處理函數*/ struct timer_base_s *base, ... }; |
實例化 struct timer_list my_timer;
2) 初始化定時器
1
2
3
4
5
6
7
|
void init_timer ( struct timer_list *timer); TIMER_INITIALIZER (_function, _expires, _data) DEFINE_TIMER (_name, _function, _expires, _data) setup_timer (); |
3) 增加定時器
void add_timer (struct timer_list *timer);
4) 刪除定時器
int del_timer (struct timer_list *timer);
5) 修改定時器的expire
int mod_timer (struct timer_list *timer, unsigned long expires);
原文鏈接:http://www.linuxidc.com/Linux/2017-10/147463.htm