讀書筆記(七)-中斷處理

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

主要內容:

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

1.什麼是中斷

爲了提高CPU和外圍硬件(硬盤,鍵盤,鼠標等等)之間協同工作的性能,引入了中斷的機制.

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

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


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


2.中斷類型

中斷一般分爲異步中斷(一般由硬件引起)和同步中斷(一般由處理器本身引起).

異步中斷:CPU處理中斷的時間過長,所以先將硬件復位,使硬件可以繼續自己的工作,然後在適當的時候處理中斷請求中耗時的部分.

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

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

這樣做避免了處理數據包時間過長導致網卡接收數據包速度變慢.


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

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

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

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


3.中斷相關函數

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

  • 註冊中斷的函數
  • 釋放中斷的函數
  • 中斷處理程序的聲明

3.1 註冊中斷的函數

位置:

/*
 * 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會在適當的時候去完成.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章