Linux中斷處理之共享中斷處理初探

2021-09-30 11:58:00 字數 1600 閱讀 2785

在看lkd(第二版)第六章(中斷和中斷處理程式)的時候,剛開始接觸到中斷線號和共享中斷線的時候半天愣是沒有想明白,原來理解的中斷和中斷和中斷處理程式就是通過中斷線號來進行關聯,硬體發生中斷,然後通過中斷線號查詢對應的中斷處理程式,最後中斷處理程式返回,此次中斷則處理完畢,沒想到冒出來個共享中斷線,呵呵,比較一下,感覺知識真的要及時更新,呵呵。

從個人的理解,linux2.6核心對中斷處理程式的現在的處理可以分為兩種模式,一種就是上面說的老的模式(非共享中斷線),一種屬於使用共享中斷線的新模式,從其使用的註冊中斷處理程式的函式中來分析,函式原型如下:

int request_irq(

unsigned int irq,

irqreturn_t (*handler)(int, void *, struct pt_regs *),

unsigned long irqflags,

const char * devname,

void * dev_id);

引數1:中斷線號

引數2:中斷處理程式函式指標

引數3:標誌掩碼(sa_interrupt, sa_sample_random, sa_shirq)

引數4:用於引數3為sa_shirq(共享中斷線)的時候,其他為null

原來對於計算機裝置比較少的時候,可能乙個中斷線好可以對應乙個中斷處理程式(非共享中斷線),這時候引數4為null,沒有任何用,但隨著計算機裝置的增加,乙個中斷線號對應乙個中斷處理程式已經不太現實,這個時候就使用了共享的中斷線號,多個裝置使用同乙個中斷線號,同乙個中斷裝置線號的所有處理程式鏈結成乙個鍊錶,這樣當在共享中斷線號的方式下乙個中斷產生的時候,就要遍歷其對應的處理程式鍊錶,但這個中斷是由使用同乙個中斷線號的多個裝置中間的乙個產生的,不可能鍊錶裡面的所有處理程式都呼叫一遍吧,呵呵,這個時候就該第四個引數派上用場了。

因為多個裝置共享同乙個中斷線號,當中斷產生的時候到底是那乙個裝置產生的中斷呢,這個就取決於第四個引數dev_id,這個引數必須是唯一的,也就是能區分到底是那個裝置產生的中斷,而且從第二個引數可以看出來,這個引數被傳入中斷處理程式(第二個引數),可以這麼理解,當中斷產生的時候,如果是共享的中斷線號,則對應鍊錶的所有中斷處理程式都被呼叫,不過在每個中斷處理程式的內部首先檢查(引數資訊以及裝置硬體的支援)是不是這個中斷處理程式對應的裝置產生的中斷,如果不是,立即返回,如果是,則處理完成,如果鍊錶中沒有乙個是,則說明出現錯誤。

下來說說中斷處理程式,先看看原型:

static irqreturn_t intr_handler(int irq, void * dev_id, struct pt_regs * regs);

引數1:中斷線號

引數2:裝置的資訊,唯一確定性

引數3:中斷之前的處理器暫存器的資訊和狀態

通過上面的分析,大概可以看到,引數1(中斷線號)貌似有點多餘,因為如果是非共享的中斷線,通過中斷線號直接呼叫處理程式,將這個引數傳進去好像沒什麼用,如果屬於共享的中斷線,則通過中斷線號直接找到對應的中斷處理程式鍊錶,挨個遍歷,都是乙個中斷線號,傳進去也沒用,該不該呼叫,通過第二個引數來區分,那為什麼要保留這個引數呢?答案是歷史遺留問題,往後可能越來越沒用了,至於為什麼是歷史遺留問題,可能在沒有第二個引數的時候才在第乙個上面做了點手腳,既然第二個引數已經新增進去了,第乙個的作用就越來越少了。

Linux如何處理共享中斷

linux可以讓多個裝置共享乙個中斷號,而且共享同一中斷的中斷處理程式形成乙個鍊錶,核心對每個中斷處理程式都要執行,那麼,沒有產生中斷的裝置本 該靠邊站的,它的中斷處理程式也被執行了?到底是怎麼會事?實際上 共享的處理程式與非共享的處理程式在註冊和執行方式上比較相似,但差異主要有以下三處 reque...

Linux中斷和中斷處理

眾所周知,處理器的速度跟外圍的硬體裝置的速度往往不在乙個數量級上,因此,如果核心採取讓處理器傳送乙個請求,然後專門等待回應的辦法,顯然差強人意。既然硬體處理的這麼慢,那麼核心就應該在這期間去處理其他事務,等待硬體真正完成了請求的操作後,再回過頭來對它進行處理。輪詢 polling 可能會是一種解決辦...

Linux中斷處理

裝置管理過程中,中斷號的申請是乙個非常重要的操作。當裝置發出中斷之後,硬體裝置根據intel cpu的通用處理過程,跳轉到了該中斷號對應的中斷相應函式處。在linux作業系統中,必定要跳到do irq函式處。在do irq 函式中,進行了一部分公共的中斷響應處理之後,根據已經入棧了的中斷號查詢裝置中...