Linux裝置驅動開發 核心定時器

2021-09-11 22:58:23 字數 2592 閱讀 8364

1. linux核心定時器是核心用來控制在未來某個時間點(基於jiffies)排程執行某個函式的一種機制,其實現位於  和 kernel/timer.c 檔案中。

2. 被排程的函式是非同步執行的,它類似於一種「軟體中斷」,而且是處於非程序的上下文中,所以排程函式必須遵守以下規則:

(1) 沒有 current 指標、不允許訪問使用者空間。因為沒有程序上下文,相關**和被中斷的程序沒有任何聯絡。

(2) 不能執行休眠(或可能引起休眠的函式)和排程。

(3) 任何被訪問的資料結構都應該針對併發訪問進行保護,以防止競爭條件。 

3. linux核心使用struct timer_list來描述乙個定時器

struct timer_list ;
(1)expires:表示期望定時器執行的 jiffies 值,到達該 jiffies 值時,將呼叫 function 函式,並傳遞 data 作為引數

(2)entry:連線該定時器到乙個核心鍊錶中

(3)base:核心內部使用

4. 定時器使用流程

(1)定義和初始化定時器

① 方法一:

define_timer(timer_name, function_name, expires_value, data);
define_timer為巨集定義,原始碼如下

#define define_timer(_name, _function, _expires, _data)        \

struct timer_list _name = \

timer_initializer(_function, _expires, _data)

② 方法二

struct timer_list my_timer;

init_timer(&my_timer);

my_timer.expires = jiffies + delay; 

my_timer.data = 0;     

my_timer.function = my_function;

注:以上巨集和函式定義於include/linux/timer.h。

(3)註冊定時器:add_timer

add_timer(&my_timer);
(4)啟動定時器:mod_timer

int mod_timer(struct timer_list *timer, unsigned long expires)
注:該函式負責修改核心定時器timer的超時欄位expires。該函式可以修改啟用和沒有啟用的核心定時器的超時時間,並把它們都設定為啟用狀態;返回值為0表示修改的核心定時器在修改之前處於未啟用狀態,返回值為1表示修改的核心定時器在修改之前處於已啟用狀態。

(5)刪除定時器:一但定時到期,核心會自動刪除定時器節點。但有時需要顯示的呼叫函式del_timer()來刪除定時器節點

int del_timer(struct timer_list *timer)
5. linux核心定時器組織架構

(1)與softirq、工作佇列兩種中斷下半部的處理方法類似,每乙個核心定時器節點與系統中的處理器通過乙個每處理器變數聯絡起來。核心在檔案 kernel/timer.c中使用下面的語句分配了乙個名稱為tvec_bases、型別為tvec_base_t的每處理器變數。

static define_per_cpu(struct tvec_base *, tvec_bases) = &boot_tvec_bases;
(2)資料結結struct tevc_base用來記錄系統中每乙個處理器上待處理核心定時器節點的相關資訊

struct tvec_base  ____cacheline_aligned;
①lock:用於保護每處理器變數tvec_bases的本地拷貝

②running_timer:記錄正在本地處理器上進行超時處理的核心定時器

③timer_jiffies:記錄該資料結構中所包含的定時器中最早超時時間,根據該變數可以計算出超時定時器節點所在鍊錶的表頭。

④tv1,tv2,tv3,tv4,tv5:

#define tvn_bits (config_base_small ? 4 : 6)

#define tvr_bits (config_base_small ? 6 : 8)

#define tvn_size (1 << tvn_bits)

#define tvr_size (1 << tvr_bits)

#define tvn_mask (tvn_size - 1)

#define tvr_mask (tvr_size - 1)

struct tvec ;

struct tvec_root ;

(3)核心定時器架構示意圖:

Linux裝置驅動 核心開發

linux裝置驅動需要使用核心api來實現,一般被包含在linux核心原始碼樹中。驅動可以編譯到核心,隨著核心一起在系統啟動的時候被載入。也可以編譯成核心模組,在系統執行起來之後動態地載入到核心中,使得除錯的時候無需重新編譯核心,也無需重啟系統,很大程度上方便了驅動 的除錯。但並不是只有裝置驅動才能...

《Linux裝置驅動開發詳解》 核心定時器

10.5.1 核心定時器程式設計 軟體意義上的定時器最終依賴硬體定時器來實現,核心在時鐘中斷發生後檢測各定時器是否到期,到期後的定時器處理函式將作為軟中斷在底半部執行。實質上,時鐘中斷處理程式執行 update process timers 函式,該函式呼叫run local timers 函式,這...

Linux裝置驅動 核心定時器

核心定時器使用 核心定時器是核心用來控制在未來某個時間點 基於jiffies 排程執行某個函式的一種機制,其實現位於 和 kernel timer.c 檔案中。被排程的函式肯定是非同步執行的,它類似於一種 軟體中斷 而且是處於非程序的上下文中,所以排程函式必須遵守以下規則 1 沒有 current ...