《Linux核心設計與實現》讀書筆記(七)- 中斷處理

來源:互聯網
上載者:User

中斷處理一般不是純軟體來實現的,需要硬體的支援。通過對中斷的學習有助於更深入的瞭解系統的一些底層原理,特別是驅動程式的開發。

主要內容:

  • 什麼是中斷
  • 中斷類型
  • 中斷相關函數
  • 中斷處理機制
  • 中斷控制方法
  • 總結

 

1. 什麼是中斷

為了提高CPU和外圍硬體(硬碟,鍵盤,滑鼠等等)之間協同工作的效能,引入了中斷的機制。

沒有中斷的話,CPU和外圍裝置之間協同工作可能只有輪詢這個方法:CPU定期檢查硬體狀態,需要處理時就處理,否則就跳過。

當硬體忙碌的時候,CPU很可能會做許多無用功(每次輪詢都是跳過不處理)。

 

中斷機制是硬體在需要的時候向CPU發出訊號,CPU暫時停止進行中的工作,來處理硬體請求的一種機制。

 

2. 中斷類型

中斷一般分為非同步中斷(一般由硬體引起)和同步中斷(一般由處理器本身引起)。

非同步中斷:CPU處理中斷的時間過長,所以先將硬體複位,使硬體可以繼續自己的工作,然後在適當時候處理插斷要求中耗時的部分。

舉個例子:網卡的工作原理

  1.     網卡收到資料包後,向CPU發出中斷訊號,請求處理接收到的資料包
  2.     CPU將收到的資料包拷貝到記憶體後,即通知網卡繼續工作
  3.     至於資料包拷貝至記憶體後的處理會在適當的時候進行

 

這樣做避免了處理資料包時間過長導致網卡接收資料包速度變慢。

 

同步中斷:CPU處理完插斷要求的所有工作後才反饋硬體

舉個例子:系統異常處理(比如運算中的除0操作)

  1.     應用程式出現異常後,需要核心來處理
  2.     核心調用相應的異常處理函數來處理異常
  3.     處理完後終了應用程式或者給出message

 

同步中斷應該處理能很快完成的一種中斷。

 

3. 中斷相關函數

實現一個中斷,主要需要知道3個函數:

  • 註冊中斷的函數
  • 釋放中斷的函數
  • 中斷處理常式的聲明

 

3.1 註冊中斷的函數

    位置:<linux/interrupt.h>  include/linux/interrupt.h

 

定義如下:

/* * irg     - 表示要分配的中斷號 * handler - 實際的中斷處理常式 * flags   - 標誌位,表示此中斷的具有特性 * name    - 中斷裝置名稱的ASCII 表示,這些會被/proc/irq和/proc/interrupts檔案使用 * dev     - 用於共用中斷線,多個中斷程式共用一個中斷線時(共用一個中斷號),依靠dev來區別各個中斷程式 * 傳回值: * 執行成功:0 * 執行失敗:非0 */int request_irq(unsigned int irq,                irq_handler_t handler,                unsigned long flags,                const char* name,                void *dev)

 

3.2 釋放中斷的函數

定義比較簡單:

void free_irq(unsigned int irq, void *dev)

如果不是共用中斷線,則直接刪除irq對應的中斷線。

如果是共用中斷線,則判斷此中斷處理常式是否中斷線上的最後一個中斷處理常式,

    是最後一個中斷處理常式 -> 刪除中斷線和中斷處理常式

    不是最後一個中斷處理常式 -> 刪除中斷處理常式

 

3.3 中斷處理常式的聲明

聲明格式如下:

/*  * 中斷處理常式的聲明 * @irp  - 中斷處理常式(即request_irq()中handler)關聯的中斷號 * @dev  - 與 request_irq()中的dev一樣,表示一個裝置的結構體 * 傳回值: * irqreturn_t -  執行成功:IRQ_HANDLED  執行失敗:IRQ_NONE */static irqreturn_t intr_handler(int, irq, void *dev)

 

4. 中斷處理機制

中斷處理的過程主要涉及3函數:

  • do_IRQ 與體繫結構有關,對所接收的中斷進行應答
  • handle_IRQ_event 調用中斷線上所有中斷處理
  • ret_from_intr 恢複寄存器,將核心恢複到中斷前的狀態

 

處理流程可以參見書中的圖,如下:

 

5. 中斷控制方法

常用的中斷控制方法見下表:

函數

說明

local_irq_disable() 禁止本地中斷傳遞
local_irq_enable() 啟用本地中斷傳遞
local_irq_save() 儲存本地中斷傳遞的目前狀態,然後禁止本地中斷傳遞
local_irq_restore() 恢複本地中斷傳遞到給定的狀態
disable_irq() 禁止給定中斷線,並確保該函數返回之前在該中斷線上沒有處理常式在運行
disable_irq_nosync() 禁止給定中斷線
enable_irq() 啟用給定中斷線
irqs_disabled() 如果本地中斷傳遞被禁止,則返回非0;否則返回0
in_interrupt() 如果在中斷上下文中,則返回非0;如果在進程上下文中,則返回0
in_irq() 如果當前正在執行中斷處理常式,則返回非0;否則返回0

 

總結

中斷處理對處理時間的要求很高,如果一個中斷要花費較長時間,那麼中斷處理一般分為2部分。

上半部只做一些必要的工作後,立即通知硬體繼續自己的工作。

中斷處理中耗時的部分,也就是下半部的工作,CPU會在適當的時候去完成。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.