Linux設備驅動中中斷處理相關的首先是申請與釋放IRQ的API request_irq()和free_irq()函數
int request_irq(unsigned int irq, //irq是要申請的硬件中斷號 void (*handler)(int irq, void *dev_id, struct pt_regs *regs), unsigned long irqflags, const char * devname, //設備名 中斷屬於哪一個設備的 void *dev_id);
handler是向系統登記的中斷處理函數,是一個回調函數,中斷髮生時,系統調用這個函數
spa
irqflags是中斷處理的屬性,若設置IRQF_DISABLED,標明中斷處理程序是快速處理程序,快速處理程序被調用時屏蔽全部中斷,慢速處理程序不屏蔽;若設置IRQF_SHARED,則多個設備共享中斷,操作系統
dev_id在中斷共享時會用到,通常設置爲這個設備的device結構自己或者NULL。code
快速/慢速中斷區別orm
快速中斷保證中斷處理的原子性(不被打斷),而慢速中斷則不保證。換句話說,也就是「開啓中斷」標誌位(處理器IF)在運行快速中斷處理程序時是關閉的,所以在服務該中斷時,不會被其餘類型的中斷打斷;而調用慢速中斷處理時,其它類型的中斷仍能夠獲得服務,默認狀況是慢速中斷。進程
共享中斷ci
共享中斷就是將不一樣的設備掛到同一個中斷信號線上。Linux對共享的支持主要是爲PCI設備服務。共享中斷也是經過request_irq函數來註冊的,但有三個特別之處:回調函數
1)申請共享中斷時,必須在flags參數中指定 IRQF_SHARED位it
2)dev_id參數必須是惟一的。 //由於共享中斷 中斷號相同,因此須要dev_id來區別是哪一個設備中斷class
3)共享中斷的處理程序中,不能使用disable_irq(unsigned int irq) ,由於這個會關閉該中斷的全部設備
中斷處理程序void (*handler)
中斷處理程序。特別之處在於中斷處理程序是在中斷上下文中運行的,它的行爲受到某些限制:
1) 不能向用戶空間發送或接受數據 由於用戶空間和進程對應,進程變了用戶空間會變,中斷不對應任何進程,不屬於 進程
2) 不能使用可能引發阻塞的函數
3) 不能使用可能引發調度的函數 。防止用戶空間發生變化
五、 中斷處理函數流程
操做系統還有一個進程上下文,如驅動中的讀寫函數就是進程上下文
用戶的應用程序,fread 經過內核 調用 驅動中的.read操做。read是進程主動調用的,屬於進程上下文。中斷上下文是硬件發出的,不是進程主動調用的。
中斷處理函數的流程
void short_sh_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* 判斷是不是本設備產生了中斷 由於共享中斷產生中斷會調用該中斷號的全部設備 因此每一個設備須要判斷是否本身產生 中斷,不然處理會出錯*/ value = inb(short_base); if (!(value & 0x80)) return; //不是自己設備產生的中斷 返回 /* 清除中斷位(若是設備支持自動清除,則不須要這步) */ outb(value & 0x7F, short_base); /* 中斷處理,一般是數據接收 */ 。。。。。。。。。 /* 喚醒等待數據的進程 */ ake_up_interruptible(&short_queue); //接收數據 可能會阻塞別的進程,因此須要喚醒 }
卸載中斷
當設備再也不須要使用中斷時(一般在驅動卸載時), 應當把它們返還給系
void free_irq(unsigned int irq, void *dev_id)