天天看點

談談對中斷的了解

目錄

  • 一.中斷的了解
  • 二.單片機的中斷
  • 三.ARM的異常中斷
    • ARM工作模式&&異常中斷&&中斷向量表
    • 進入中斷和退出中斷的操作
    • 中斷異常服務程式
    • 中斷控制器
  • 四.Linux的中斷
    • 中斷、異常、系統調用
    • Kernel的中斷處理機制
    • 中斷下半部的實作
  • 五.中斷作為計算機系統中必要的存在

中斷是指CPU在執行過程中,出現了突發事件,CPU必須暫停目前程式的運作,保持現場,轉而處理突發事件,處理完畢之後,恢複現場繼續執行。

中斷按照來源可以分為:

  • 内部中斷:來自CPU内部,通常由軟體中斷指令和一些異常錯誤觸發
  • 外部中斷:來自CPU外部,通常由外設觸發,經由中斷控制器轉發請求到CPU,然後進行處理

在玩單片機的時候,中斷用的最多的就是外設觸發中斷了基本就是:

  1. 中斷源的優先級與打開使能中斷通道
  2. 綁定EXIT與GPIO,配置中斷觸發方式,引腳是浮空輸入
  3. 編寫中斷服務程式

這個階段對中斷的了解還停留在:外設觸發中斷、CPU響應中斷、執行中斷服務程式。

STM32-中斷詳解

在ARM的學習過程中,對異常中斷又有了更深入的了解,涉及到ARM的工作模式、異常中斷、中斷向量表、環境儲存與恢複等

ARM-異常中斷處理

從ARM的工作模式到異常中斷:

談談對中斷的了解
談談對中斷的了解

以及ARM的中斷向量表,一般是32Bytes,一個異常中斷占4Bytes,一般是一個跳轉指令:

談談對中斷的了解

其中,中斷優先級的劃分如下:

談談對中斷的了解

可以看出:

  • 複位就是直接去0x0000_0000位址執行
  • FIQ放在中斷向量表最後面,可以直接在中斷向量表後編寫FIQ處理程式,呼應了快速中斷
  • FIQ的優先級比IRQ高,可以打斷IRQ
  • 系統調用就是利用SWI(軟體中斷)進行處理的

談談對中斷的了解
  1. 将下一條指令位址儲存在lr寄存器中,具體是pc+4還是pc+8取決于異常的種類
  2. 将目前的CPSR拷貝到對應的SPSR
  3. 根據異常修改CPSR的值
  4. 根據向量表跳轉到中斷處理程式執行,在中斷處理程式中進行環境儲存與恢複
談談對中斷的了解

退出異常中斷時的情況:

談談對中斷的了解
  1. 将lr寄存器減去相應的偏移,指派給pc
  2. 将SPSR中的值指派給CPSR
  3. 清除中斷标志位(如果在進入中斷是設定了)

中斷中斷服務程式一般要做的是:

/* und異常處理,進入異常前,硬體完成的事情:将CPSR拷貝到SPSR,将被中斷指令的位址存儲在lr中 */
do_und:
    ldr sp, =0x34000000          /* und的棧指針,指向64M 的SDRAM的最高位址,為C函數配置設定空間 */
    stmdb sp!, {r0-r12,lr}      /* 儲存現場 */

    mrs r0, cpsr                /* mrs讀出寄存器的值,通過r0寄存器向下面的函數傳參 */
    bl Und_Process

    ldmia sp!, {r0-r12, pc}^     /* 恢複現場,注意:一定要加!來儲存sp的改變 */
           
  1. 設定棧,通過sp_und來設定
  2. 儲存現場,包括r0~r12寄存器、lr寄存器,儲存lr也是必須的,因為lr中的是異常處理完之後的傳回位址
  3. 調用C處理函數
  4. 恢複現場,利用ldmia sp!, {r0-r12,pc}^ 恢複各個寄存器的值,将lr寄存器的值指派給pc寄存器(有待考證,ia是先 後 ),^順便把SPSR中的值恢複到CPSR中

所謂保持現場與恢複現場就是對r0~r12寄存器進行入棧和出棧

ARM-und異常

談談對中斷的了解

在初始化中斷控制器的時候,主要是打開使能位即可,SRCPND和INTPND是在中斷處理函數裡使用的,判斷是哪一個中斷請求的

ARM-按鍵中斷

Linux中接觸作業系統之後,有了中斷、異常、系統調用的概念,

談談對中斷的了解

硬體上的處理:在CPU初始化的時候設定中斷使能标志,這個中斷使能标志對異常、中斷、系統調用都是等效的。然後根據内部或者外部事件設定中斷标志位,根據中斷向量表調用相應的中斷服務例程。

是以,無論是中斷、異常、系統調用,都會在中斷向量表中進行跳轉處理,接下來就是針對性的服務了。

如果是中斷,直接進入裝置驅動中,回報(滑鼠、鍵盤的輸入);

如果是異常,直接轉到異常服務例程來做處理;

如果是系統調用,由于系統調用的量很大,不同的系統調用在系統調用表中區分,選擇不同的系統調用實作;

當然,在處理異常中斷的時候,要注意保護現場和恢複現場,可以參考ARM來了解。

由于中斷會打斷程序的正常排程與運作,勢必要求中斷服務程式盡量短小精悍,然而大多數中斷處理程式中的工作量不會很小。

Linux核心的中斷處理架構是将中斷的處理分為了上半部和下半部:

談談對中斷的了解

當然,可以在/proc/interrupts中檢視系統中斷的統計資訊,包括每個中斷号上的中斷在CPU上發生的次數。

Linux裝置驅動中使用中斷的裝置需要申請和釋放中斷,使用核心提供的request_irq()和free_irq()接口。

Linux實作中斷下半部的機制主要有tasklet、工作隊列、軟中斷、線程化irq。

tasklet的執行上下文是軟中斷,執行的時機是上半部傳回的時候,隻需要定義tasklet及其處理函數,并關聯兩者就可以。關于tasklet的排程,在需要排程tasklet的時候引用一個tasklet_schedule()函數就可以。