linux中斷處理原理分析

1、 中斷概念
       爲什麼需要中斷?
       1)外設的處理速度一般慢於CPU
       2)CPU不能一直等待外部事件
       所以設備必須有一種方法來通知CPU它的工作進度,這種方法就是中斷。

2、 中斷實現
       在Linux驅動程序中,爲設備實現一箇中斷包含兩個步驟:
       1)向內核註冊中斷
       2)實現中斷處理函數
3、 中斷註冊
       request_irq用於實現中斷的註冊功能:
       int request_irq(unsigned int irq, void (*handler)(int, void*, struct pt_regs *), unsigned long flags, const char *devname, void *dev_id)
      返回0表示成功,或者返回一個錯誤碼
      中斷註冊(參數)
      1) unsigned int irq  中斷號。
      2)void (*handler)(int,void *,struct pt_regs *)  中斷處理函數。
      3)unsigned long flags 與中斷管理有關的各種選項。
      4)const char * devname  設備名
      5)void *dev_id  共享中斷時使用。
      a)中斷註冊(中斷標誌)
      在flags參數中,可以選擇一些與中斷管理有關的選項,如:
      1)IRQF_DISABLED(SA_INTERRUPT)
            如果設置該位,表示是一個“快速”中斷處理程序;如果沒有設置這位,那麼是一個“慢速”中斷處理程序。
      2)IRQF_SHARED(SA_SHIRQ)
           該位表明中斷可以在設備間共享。
      b)快速/慢速中斷
      這兩種類型的中斷處理程序的主要區別在於:快速中斷保證中斷處理的原子性(不被打斷),而慢速中斷則不保證。換句話說,也就是“開啓中斷”標誌位(處理器IF)在運行快速中斷處理程序時是關閉的,因此在服務該中斷時,不會被其他類型的中斷打斷;而調用慢速中斷處理時,其它類型的中斷仍可以得到服務。
      c) 共享中斷
      共享中斷就是將不同的設備掛到同一個中斷信號線上。Linux對共享的支持主要是爲PCI設備服務。共享中斷也是通過request_irq函數來註冊的,但有三個特別之處:
      1)申請共享中斷時,必須在flags參數中指定 IRQF_SHARED位
      2)dev_id參數必須是唯一的。
      3)共享中斷的處理程序中,不能使用disable_irq(unsigned int irq)  爲什麼? 如果使用了這個函數,共享中斷信號線的其它設備將同樣無法使用中斷,也就無法正常工作了。
4、 中斷處理程序
       什麼是中斷處理程序,有何特別之處?中斷處理程序就是普通的C代碼。特別之處在於中斷處理程序是在中斷上下文中運行的,它的行爲受到某些限制:
       1) 不能向用戶空間發送或接受數據
       2) 不能使用可能引起阻塞的函數
       3) 不能使用可能引起調度的函數

5、 中斷處理函數流程
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);
/* 中斷處理,通常是數據接收 */
。。。。。。。。。
/* 喚醒等待數據的進程 */
wake_up_interruptible(&short_queue);

6、 釋放中斷
       當設備不再需要使用中斷時(通常在驅動卸載時), 應當把它們返還給系統,使用:void free_irq(unsigned int irq, void *dev_id)

發佈了21 篇原創文章 · 獲贊 3 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章