LINUX軟中斷處理如何與BH函式關聯的

2021-05-25 12:21:21 字數 2501 閱讀 7917

我們的重點是理解出這幾個陣列的關係,也就是說他們是怎麼關聯起來的,至於函式指標或者遮蔽位等內容可以參考linux核心情景分析書中的文字,他寫的比較清晰,唯一就是明確指出這三個陣列的關聯。讓我們開始理一下吧

首先我們先對bh_base這個陣列看一下,

這個陣列何時賦值的?

如果想對這個陣列賦值必須使用init_bh()函式,這個函式來完成對bh_base的賦值 ,書中借用sched_init()函式中呼叫的init_bh()為例說明了,是如何設定bh_base這個陣列的。現在明白了bh_base的賦值。

bh_base陣列是以前的老版本的乙個陣列,現在儘管已經賦值了函式,但是不會執行這個函式,因為還沒有與我們上面提到的其他陣列關聯起 來,如果想要使某乙個bh函式得到執行,必須使其與其他陣列關聯或者說掛上鉤才行。其實書中說「使bh_base陣列關聯到 bh_task_vec陣列的函式是mark_bh()」是錯誤的,mark_bh()這個函式呼叫了tasklet_hi_schedule()函 數,他其實將bh_task_vec與tasklet_hi_vec佇列頭陣列關聯起來,使bh_task_vec中的元素同時插入到 tasklet_hi_vec陣列中。tasklet_hi_vec這個佇列頭陣列是因不同的cpu個數為大小的,每個cpu有這樣的乙個佇列 頭。從中看出這個佇列頭是專門用於bh函式執行的。上面我們說使bh_base與bh_task_vec陣列關聯的原因是因為:在軟中斷初始化函 數中softirq_init(),它對bh_task_vec中的32個元素全部讓其執行bh_action()這個函式,而這個 bh_action()函式就是關聯bh_base陣列和bh_task_vec陣列中橋梁。如果用圖來看一下他們現在的關係

我們已經理清了tasklet_hi_vec陣列是bh_base函式陣列的關鍵,就來理它的脈搏

執行軟中斷處理時,會通過do_softirq()這個函式利用softirq_vec陣列來呼叫 task_hi_action()這個函式,task_hi_action()函式再通過tasklet_hi_vec佇列頭來呼叫 bh_task_vec中的bh_action()函式,進而再執行bh_base陣列中的bh函式。

那麼softirq_vec陣列是什麼時候賦值的,它是在soft_init()呼叫open_softirq()賦值的於是我們畫一圖

同樣我們可以看出另一條執行tasklet的路線

具體的tasklet的宣告和註冊可以參閱國防科技大學楊沙洲博士的文章《linux 2.4.x核心軟中斷機制》

他在文章中說到

declare_tasklet(my_tasklet,my_tasklet_func,data); /* 定義乙個tasklet結構my_tasklet,與my_tasklet_func(data)函式相關聯,相當於 declare_task_queue() */

tasklet_schedule(&my_tasklet); /* 登記my_tasklet,允許系統在適當的時候進行排程執行,相當於 queue_task(&my_task,&tq_immediate)和mark_bh(immediate_bh) */

另外還提到task queue

task我就列出了看楊博士的文章吧

下面我們用鍵盤的例項說一下建立tasklet的過程

首先必須在驅動中宣告乙個全域性的tasklet結構變數,這樣是為了在中斷處理中能夠獲得這個全域性的tasklet結構變數。

static struct tasklet_struct key_tasklet;

我們還需要乙個結構儲存鍵值

struct io_key ;

static struct io_key key;

然後我們需要乙個在後半部的處理程式,比如鍵盤為例

void key_tasklet(unsigned long arg)

{struct io_key *data = (struct io_key *)arg;

unsigned long j=0;

printk("/n**************key_tasklet_start*****************/n");

j = jiffies;

printk("time:%08lx  delta:%3li     inirq:%i    pid:%3i   cpu:%i   command:%s/n",

j, j - data->prevjiffies, in_interrupt() ? 1 : 0,

current->pid, smp_processor_id(), current->comm);

printk("/n**************key_tasklet_end*****************/n");

} tasklet_init(&keytask , key_tasklet , (unsigned long)&key);

這樣我們建立了鍵盤的後半部處理程式,可以用來轉譯鍵碼,而前半部中斷是為了查詢到具體哪個鍵產生了中斷。這樣就把比較費時的處理工作由tasklet來完成了。

from:

linux軟中斷與tasklet

軟中斷軟中斷由 struct softirq action void action struct softirq action 表示。並且當前核心中的軟中斷總數固定為32個,由陣列static struct softirq actionsoftirq vec nr softirqs 來表示。目前只用...

軟中斷與硬中斷

軟中斷 1.程式設計異常通常叫做軟中斷 2.軟中斷是通訊程序之間用來模擬硬中斷的 一種訊號通訊方式。3.中斷源發中斷請求或軟中斷訊號後,cpu或接收程序在適當的時機自動進行中斷處理或完成軟中斷訊號對應的功能 4.軟中斷是軟體實現的中斷,也就是程式執行時其他程式對它的中斷 而硬中斷是硬體實現的中斷,是...

軟中斷與硬中斷

軟中斷 1.程式設計異常通常叫做軟中斷 2.軟中斷是通訊程序之間用來模擬硬中斷的 一種訊號通訊方式。3.中斷源發中斷請求或軟中斷訊號後,cpu或接收程序在適當的時機自動進行中斷處理或完成軟中斷訊號對應的功能 4.軟中斷是軟體實現的中斷,也就是程式執行時其他程式對它的中斷 而硬中斷是硬體實現的中斷,是...