當產生一個中斷時,會進入中斷處理程序。 但中斷處理程序必須快速、異步、簡單的對硬件做出迅速響應并完成那些時間要求很嚴格的操作。 因此,對于那些其他的、對時間要求相對寬松的任務,就應該推后到中斷被激活以后再去運行。 這樣,整個中斷處理流程就被分為了兩個部分: 下半部的任務主要是執行與中斷相關的工作,這些工作沒有被中斷服務程序本身完成。 下半部并不需要指明一個確切時間,只要把這些任務推遲一點,讓它們在系統不太繁忙并且中斷恢復后執行就可以了。 上半部和下半部的主要區別: 上半部指的是中斷處理程序,下半部則指的是一些雖然與中斷有相關性但是可以延后執行的任務。 上半部中斷不能被相同類型的中斷打斷,而下半部依然可以被中斷打斷。 通常下半部在中斷處理程序一返回就會馬上運行。 上半部分簡單快速,執行的時候禁止一些或者全部中斷。 下半部分稍后執行,而且執行期間可以響應所有的中斷。 每個軟中斷由 在 登錄后復制 數組的成員數由 新增一個軟中斷時,需要在文件 軟中斷使用的幾個要點: 相關接口 登錄后復制 即注冊對應類型的處理函數到全局數組 登錄后復制 實際上即以軟中斷類型 這也是同一類型軟中斷可以在多個 以一個按鍵驅動的中斷處理為例,將按鍵驅動的中斷處理分成上下兩部分: 軟中斷的注冊,在驅動的入口函數,注冊軟中斷: 添加的枚舉常量: 可以看到,使用軟中斷是需要修改內核,添加一個枚舉的,有些繁瑣。 所以,通常我們不建議擅自增加軟中斷的數量,如果需要新的軟中斷,盡可能把它們實現為基于軟中斷的 tasklet是利用軟中斷實現的一種下半部機制。 那是用軟中斷還是 選擇到底是用軟中斷還是 1、編寫 登錄后復制 2、聲明 登錄后復制 3、調度 登錄后復制 登記 以按鍵中斷驅動為例: 先使用 兩個要點: 工作隊列的相關接口函數: 在使用上,工作隊列與什么是中斷下半部
Linux
中,對中斷下半部的實現主要有三種:
softirq
softirq
即軟中斷,代碼位于kernel/softirq.c
文件中;softirq_action
結構表示:softirq.c
中定義了一個軟中斷向量數組softirq_vec
:static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;
enum
{
HI_SOFTIRQ=0, /*用于高優先級的tasklet*/
TIMER_SOFTIRQ, /*用于定時器的下半部*/
NET_TX_SOFTIRQ, /*用于網絡層發包*/
NET_RX_SOFTIRQ, /*用于網絡層收報*/
BLOCK_SOFTIRQ,
BLOCK_IOPOLL_SOFTIRQ,
TASKLET_SOFTIRQ, /*用于低優先級的tasklet*/
SCHED_SOFTIRQ,
HRTIMER_SOFTIRQ,
RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
NR_SOFTIRQS
};
NR_SOFTIRQS
決定,是一個枚舉常量。include/linux/interrupt.h
中添加一個枚舉常量。
void open_softirq(int nr, void (*action)(struct softirq_action *))
softirq_vec
中。
void raise_softirq(unsigned int nr)
nr
作為偏移量會置位irq_stat[cpu_id]
的成員變量__softirq_pending
.__softirq_pending
字段中的每一個bit
,對應著某一個軟中斷,某個bit
被置位,說明有相應的軟中斷等待處理。cpu
上并行運行的根本原因。軟中斷實例
tasklet
形式。tasklet
tasklet
好呢?tasklet
其實很簡單:
tasklet
。就像我們在前面看到的,軟中斷資源有限,也麻煩,而且軟中斷的使用者屈指可數。它只在那些執行頻率很高和連續性要求很高的情況下才需要。tasklet
效果都不錯,而且它們還非常容易使用。tasklet使用
tasklet
的使用步驟如下:tasklet
處理函數(下半部)void my_tasklet_fun (unsigned long data)
tasklet
//靜態
DECLARE_TASKLET(my_tasklet,my_tasklet_fun,data);
//動態
Struct tasklet_struct xxx;
tasklet_init(&xxx,tasklet_handler,dev)
tasklet
tasklet_schedule(&my_tasklet);
my_tasklet
, 然后允許系統在合適的時間調度它。tasklet實例
DECLARE_TASKLET
靜態聲明一個tasklet
,指定其下半部函數為btn_tasklet_func
,在中斷服務函數(上半部)獲取按鍵值后,調用tasklet_schedule
調度。work queue
work queue
即工作隊列,也是中斷下半部的一種。Work queue
將下半部工作推遲給一個內核線程去執行 ——work
總是運行于進程上下文.
work queues
。否則使用softirq
或tasklets
.Work queues
適用于需要分配大量的內存,獲得一個信號量,或者執行阻塞的I/O
的情況.tasklet
是類似的:
以上就是Linux驅動中斷下半部的三種方法的詳細內容,更多請關注www.92cms.cn其它相關文章!