在中斷的呼叫流程中講到linux中對中斷的處理最終會呼叫到在驅動程式中註冊的中斷處理函式。中斷處理函式(interrupt handle / interruptservice routine)是裝置驅動程式的一部分,核心通過它來回應特定的中斷。中斷處理函式同普通的函式並無太大的區別,但由於它是執行在中斷上下文(interrupt context)中的,所以他不能休眠和引起阻塞。
中斷處理函式的原型在linux/interrupt.h中:
typedef irqreturn_t (*irq_handler_t)(int, void *);
如我們可以定義乙個中斷處理函式:
static irqreturn_t m_key_irq_handle(int irq, void *dev)
其中第乙個引數是中斷號。第二個引數是我們註冊中斷時傳入的乙個指標通常我們傳入的是我們的裝置結構體。我們通過request_irq函式來註冊我們的中斷處理函式,他的原型是:
int request_irq(unsigned int irq, irq_handler_t handler,
unsigned long irqflags, const char *devname, void *dev_id);
irq是要申請的中斷號。
handler即使我們的中斷處理函式,dev_id即是要傳給中斷處理函式的第二個引數。
irqflags是中斷處理的屬性,可以指定中斷的出發方式及處理方式。這裡列出幾個比較重要的flag:
irqf_disabled-當該位被設定時在執行相應的中斷處理函式時核心會關掉所有中斷。
irqf_sample_random-會將產生該中斷的時間加入系統熵池,以便產生真正的隨機數。如果你的中斷時可預期或有規律的不要設定該項。
irqf_shared-表明多個裝置可以共享這個驅動。
另外還有一些處理方式的標誌位:irqf_trigger_rising/ irqf_trigger_falling/ irqf_trigger_high/ irqf_trigger_low等這些都是指定中斷的觸發方式的。
在函式request_irq中,會對action進行初始化:
int request_irq(unsigned int irq, irq_handler_t handler,
unsigned long irqflags, const char *devname, void *dev_id)
其中struct irqaction的定義如下:
struct irqaction ;
其中通過setup_irq(irq, action)將已經初始化好的action同irq聯絡起來:
int setup_irq(unsigned int irq, struct irqaction *new)
主要通過上面的語句,將request_irq中初始化好的action賦值給desc->action,通過desc的定義我們可以知道它指向irq_desc全域性陣列的第irq個元素。這個全域性陣列在handle.c中定義:
struct irq_desc irq_desc[nr_irqs] __cacheline_aligned_in_smp =
};
asmlinkage void __exception asm_do_irq(unsigned int irq, struct pt_regs *regs)
將我們此處的調註冊的資訊同中斷的呼叫資訊聯絡起來了。至此中斷的註冊流程就已經介紹完成了。 LINUX裝置驅動程式筆記
1.核心功能劃分 程序管理,記憶體管理,檔案系統,裝置控制,網路。裝置的分類 字元裝置,塊裝置,網路介面。單個原始檔編譯模組 obj m hello.o 多個原始檔編譯模組 obj m module.o module objs file1.o file2.o make c kernel 2.6 m ...
linux裝置驅動程式 字元裝置驅動程式
先留個 有一起學習驅動程式的加qq295699450 字元裝置驅動 這篇比較惱火。載入成功,但是讀不出來資料,有知道怎麼回事的,留個言,一起討論下 資料結構 struct scull mem struct scull dev dev 整個驅動程式 如下 include include include...
Linux裝置驅動程式 字元裝置驅動程式
1.檢視主裝置號,次裝置號 進入 dev目錄執行ls l,第四,五列分別為主次裝置號,10,180,1,5,這些是主裝置號,而60,63這些就是次裝置號 130 shell android dev ls l crw rw r system radio 10,60 1969 12 31 21 00 a...