linux中斷的上半部和下半部

2021-06-09 23:29:45 字數 2298 閱讀 6096

本文**:

與linux中斷息息相關的乙個重要概念是linux中斷分為兩個半部:上半部(tophalf)和下半部(bottom half)。上半部的功能是"登記中斷",當乙個中斷發生時,它進行相應地硬體讀寫後就把中斷例程的下半部掛到該裝置的下半部執行佇列中去。因此,上半部執行的速度就會很快,可以服務更多的中斷請求。但是,僅有"登記中斷"是遠遠不夠的,因為中斷的事件可能很複雜。因此,linux引入了乙個下半部,來完成中斷事件的絕大多數使命。下半部和上半部最大的不同是下半部是可中斷的,而上半部是不可中斷的,下半部幾乎做了中斷處理程式所有的事情,而且可以被新的中斷打斷!下半部則相對來說並不是非常緊急的,通常還是比較耗時的,因此由系統自行安排執行時機,不在中斷服務上下文中執行。

linux實現下半部的機制主要有tasklet和工作佇列。 

tasklet基於linux softirq,其使用相當簡單,我們只需要定義tasklet及其處理函式並將二者關聯:

void my_tasklet_func(unsigned long); //定義乙個處理函式:

declare_tasklet(my_tasklet,my_tasklet_func,data); //定義乙個tasklet結構my_tasklet,與

my_tasklet_func(data)函式相關聯

然後,在需要排程tasklet的時候引用乙個簡單的api就能使系統在適當的時候進行排程執行:

tasklet_schedule(&my_tasklet);

此外,linux還提供了另外一些其它的控制tasklet排程與執行的api:

declare_tasklet_disabled(name,function,data); //與declare_tasklet類似,但等待tasklet被使能

tasklet_enable(struct tasklet_struct *); //使能tasklet 

tasklet_disble(struct tasklet_struct *); //禁用tasklet 

tasklet_init(struct tasklet_struct *,void (*func)(unsigned long),unsigned long); //類似

declare_tasklet() 

tasklet_kill(struct tasklet_struct *); // 清除指定tasklet的可排程位,即不允許排程該tasklet

我們先來看乙個tasklet的執行例項,這個例項沒有任何實際意義,僅僅為了演示。它的功能是:在globalvar被寫入一次後,就排程乙個tasklet,函式中輸出"tasklet is executing":

#include 

… //定義與繫結tasklet函式

void test_tasklet_action(unsigned long t);

declare_tasklet(test_tasklet, test_tasklet_action, 0);

void test_tasklet_action(unsigned long t)

…ssize_t globalvar_write(struct file *filp, const char *buf, size_t len, loff_t *off)

//排程tasklet執行

tasklet_schedule(&test_tasklet);

return sizeof(int);

}下半部分的任務就是執行與中斷處理密切相關但中斷處理程式本身不執行的工作。在linux2.6的核心中存在三種不同形式的下半部實現機制:軟中斷,tasklet和工作佇列。

下面將比較三種機制的差別與聯絡。

軟中斷: 1、軟中斷是在編譯期間靜態分配的。

2、最多可以有32個軟中斷。

3、軟中斷不會搶占另外乙個軟中斷,唯一可以搶占軟中斷的是中斷處理程式。

4、可以併發執行在多個cpu上(即使同一型別的也可以)。所以軟中斷必須設計為可重入的函式(允許多個cpu同時操作),

因此也需要使用自旋鎖來保護其資料結構。

5、目前只有兩個子系直接使用軟中斷:網路和scsi。

6、執行時間有:從硬體中斷**返回時、在ksoftirqd核心執行緒中和某些顯示檢查並執行軟中斷的**中。

tasklet: 1、tasklet是使用兩類軟中斷實現的:hi_softirq和tasklet_softirq。

2、可以動態增加減少,沒有數量限制。

3、同一類tasklet不能併發執行。

4、不同型別可以併發執行。

5、大部分情況使用tasklet。

工作佇列: 1、由核心執行緒去執行,換句話說總在程序上下文執行。

2、可以睡眠,阻塞。

Linux中斷上半部和下半部概念

前言 cpu在執行程式時,如果有外部中斷觸發時,如定時器中斷 序列匯流排中斷等,cpu停止當前任務從 而轉去響應中斷處理。對於中斷函式的處理,原則是盡快處理完事務並退出中斷,這一點也比較好 理解,盡快處理中斷並返回,保證正常任務的執行,並且能否響應其他事務的中斷,保證實時性和 併發性。其實,在微控制...

linux中斷處理的上半部和下半部

裝置的中斷會打斷核心中程序的正常排程和執行,系統對更高吞吐率的追求勢必 要求中斷服務程式盡可能地短小精悍。但是,這個良好的願望往往與現實並不吻合。在大多數真實的系統中,當中斷到來時,要完成的工作往往並不會是短小的,它可能 要進行較大量的耗時處理。為了在中斷執行時間盡可能短和中斷處理需完成大量工作之間...

中斷的上半部分與下半部分

為了讓核心能夠快速響應硬體裝置的訊息,引入了中斷機制。當硬體裝置需要被處理 比如網絡卡收到了包 會傳送乙個非同步的中斷請求給處理器,然後處理器陷入中斷上下文中,停止當前執行的程式,轉而執行預先設定好的中斷處理程式。完成中斷處理程式之後給硬體裝置乙個訊號再返回原先的工作繼續。在這套機制中,中斷處理程式...