20135327郭皓--讀書筆記四

第七章 中斷和中斷處理

7.1 中斷

  • 中斷使得硬件得以發出通知給處理器。
  • 不一樣的設備對應的中斷不一樣,而每一箇中斷都經過一個惟一的數字標誌。
  • 這些中斷值一般被稱爲中斷請求(IRQ)線.每一個 IRQ線都會被關聯二個數值量一一例如, 在經典的 PC 機上, IRQ0是時鐘中斷,而 IRQ1是鍵盤中斷。但並不是全部的中斷號都是這樣嚴格定義的。

異常linux

  • 在操做系統中,討論中斷就不能不說起異常。異常與中斷不一樣,它在產生時必須考慮與 處理器時鐘同步。實際上,異常也經常稱爲同步中斷。

7.2 中斷處理程序

  • 在響應一個特定中斷的時候,內核會執行一個函數,該函數叫作中斷處理程序(interrupt handler)或中斷服務例程(interrupt service routine, ISR)。產生中斷的每一個設備都有一個。相應的中斷處理程序。
  • 在 Linux 中,中斷處理程序就是普普統統的C 函數.只不過這些函數必須按照特定的類型 聲明,以便內核可以以標準的方式傳遞處理程序的信息,在其餘方面,它們與通常的函數別無二致。
  • 中斷處理程序與其餘內核函數的真正區別在於,中斷處理程序是被內核調用來響應中斷的, 而它們運行於咱們稱之爲中斷上下文的特殊上下文中。
  • 中斷上下文偶爾也稱做原子上下文,由於正如咱們看到的,該上下文中的執行代碼不可阻塞。
  • 中斷可能隨時發生,所以中斷處理程序也就隨時可能執行。因此必須保證中斷處理程序可以 快速執行,這樣才能保證儘量快地恢復中斷代碼的執行。

7.3 上半部與下半部的對比

  

咱們通常把中斷處理切爲兩個部分或兩半。中斷處理程序是上半部(top half) 一一接收到一箇中斷,它就當即開始執行,但只作有嚴格時限的工做,例如對接收的中斷進行應答或復位硬件,這些工做都是在全部中斷被禁止的狀況下完成的。可以被容許稍後完成的工做會推遲到下半部(bottom half)去。此後,在合適的時機,下半部會被開中斷執行。 

 

7.4 註冊中斷處理程序

  • 中斷處理程序是管理硬件的驅動程序的組成部分。
  • 驅動程序能夠經過 request_irq()函數註冊-箇中斷處理程序(它被聲明在文件<linux/interrupt.h> 中〉, 而且激活給定的中斷線,以處理中斷
1 /* request_irq:分配一條給定的中斷線 */
2  int request_irq(unsigned int irq,
3      irq_handler_t handler,
4      unsigned long flags, 
5      const char *name, 
6     void *dev) 

第一個參數irq表示要分配的中斷號.異步

第二個參數handler是一個指針,指向處理這個中斷的實際中斷處理程序。函數

7.4.1 中斷處理程序標誌 

第三個參數flags能夠爲0,也多是下列一個或多個標誌的位掩碼。其定義在文件<linux/ interrupt.h>。在這些標誌中最重要的是:spa

    •  IRQF _DISABLED-一該標誌被設置後,意味着內核在處理中斷處理程序自己期間,要禁止全部的其餘中斷。
    •  IRQF_SAMPLE_RANOOM一--此標誌代表這個設備產生的中斷對內核熵池(entropy pool) 有貢獻。內核熵池負責提供從各類隨機事件導出的真正的隨機數。
    •  IRQF _TIMER -一該標誌是特別爲系統定時器的中斷處理而準備的。 
    •  IRQF _SHARED-一此標誌代表能夠在多箇中斷處理程序之間共享中斷線。

第四個參數 name 是與中斷相關的設備的 ASCII 文本表示。操作系統

第五個參數 dev 用於共享中斷線。指針

request_ irq()成功執行會返回 0。 若是返回非0值,就表示有錯誤發生,在這種狀況下,指定的中斷處理程序不會被註冊。code

注意, request_irq()函數可能會睡眠,所以,不能在中斷上下文或其餘不容許阻塞的代碼中調用該函數blog

7.4.3 釋放中斷處理程序

  • 卸載驅動程序時,須要註銷相應的中斷處理程序,並釋放中斷線。
  • 若是指定的中斷線不是共享的,那麼,該函數刪除處理程序的同時將禁用這條中斷線.若是中斷線是共享的,則僅刪除dev所對應的處理程序,而這條中斷線自己只有在刪除了最後一個處理程序時纔會被禁用。

7.5 編寫中斷處理程序

重入和中斷處理程序 
        Linux 中的中斷處理程序是無須重入的。當一個給定的中斷處理程序正在執行時,相應的中斷線在全部處理器上都會被屏蔽掉,以防止在同一中斷線上接收另外一個新的中斷。一般狀況下,全部其餘的中斷都是打開的,因此這些不一樣中斷線上的其餘中斷都能被處理,但當前中斷線老是被禁止的。 由此能夠看出,同一個中斷處理程序絕對不會被同時調用以處理嵌套的中斷。這極大地簡化了中斷處理程序的編寫。
    

 

7.5.1 共事的中斷處理程序

  • 共享的處理程序與非共享的處理程序在註冊和運行方式上比較類似,但差別主要有如下三處:
    • request_irq()的參數 flags 必須設置 IRQF_SHARED 標誌。 
    • 對於每一個註冊的中斷處理程序來講,dev參數必須惟一。 
    • 中斷處理程序必須可以區分它的設備是否真的產生了中斷。

 

7.6 中斷上下文

  • 當執行一箇中斷處理程序時,內核處於中斷上下文( interrput context)中。
  • 進程上下文能夠睡眠,也能夠調用調度程序。
  • 中斷上下文和進程並無什麼瓜葛。與 current 宏也是不相干的
  • 中斷上下文具備較爲嚴格的時間限制,由於它打斷了其餘代碼。

 

7.7 中斷處理機制的實現

在內核中,中斷的旅程開始於預約義入口點,這相似於系統調用經過預約義的異常句柄進入內核。接口

ret_from_intr()例程相似於初始入口代碼進程

 

7 .8 /proc/interrupts 

procfs是一個虛擬文件系統,它只存在於內核內存,通常安裝於/proc目錄。在procfs中讀寫文件都要調用內核函數,這些函數模擬從真實文件中讀或寫。與此相關的例子是/proc/interrupts文件,該文件存放的是系統中與中斷相關的統計信息

 

  

第1列是中斷線。 在這個系統中,現有的中斷號爲0 ~ 二、 四、 五、 12 及 15。這裏沒有顯示沒有安裝處理程序的中斷線。

第2列是一個接收中斷數目的計數器。

第3列是處理這個中斷的中斷控制器。 

7.9 中斷控制

    Linux 內核提供了一組接口用於操做機器上的中斷狀態。這些接口爲咱們提供了可以禁止當 前處理器的中斷系統,或屏蔽掉整個機器的一條中斷線的能力,這些例程都是與體系結構相關 的,能夠在 <asm/system.h> 和 <asm/irq.h>中找到。 

 

  通常來講, 控制中斷系統的緣由歸根結底是須要提供同步。

7.9.1 禁止和激活中斷

 

 

7.9.2 禁止指定中斷線

在某些狀況下,只禁止整個系統中一條特定的中斷錢就夠了。 這就是所謂的屏蔽掉(masking out)一條中斷線。做爲例子,你可能想在對中斷的狀態操做以前禁止設備中斷的傳遞。爲此,Linux 提供了四個接口:

1 void disable_irq(unsigned int irql;
2 void disable_irq_nosync(unsigned int irq) ;
3 void enable_irq(unsigned int irq) ; 
4 void synchronize_irq(unsigned int irq); 

前兩個函數禁止中斷控制器上指定的中斷線,即禁止給定中斷向系統中全部處理器的傳遞。 

全部這三個函數能夠從中斷或進程上下文中調用,並且不會睡眠。 

禁止多箇中斷處理程序共享的中斷線是不合適的。

7.9.3 中斷系統的狀態

 

7.10 小結

本章介紹了中斷,它是一種由設備使用的硬件資源異步向處理器發信號。實際上,中斷就是由硬件來打斷操做系統。

大多數現代硬件都經過中斷與操做系統通訊。

內核提供的接口包括註冊和註銷中斷處理程序、禁止中斷、屏蔽中斷線以及檢查中斷系統的狀態。

相關文章
相關標籤/搜索