中斷處理是電腦系統的核心機制,允許硬體或軟體打斷 CPU 的正常執行流程,轉而處理緊急事件。理解中斷的運作原理對於嵌入式系統開發至關重要。本文從硬體層面出發,逐步解析中斷請求如何觸發、CPU 如何儲存當前執行狀態(上下文)、如何根據中斷向量表找到對應的中斷服務例程(ISR)並執行,以及最後如何還原到原來的執行狀態。除了基本流程,還會探討中斷優先順序的處理、中斷巢狀的機制、堆積疊在儲存上下文中的角色,以及系統延遲的影響。這些知識點將幫助開發者編寫更有效率、更穩定的中斷處理程式。

中斷的處理過程

中斷是電腦系統中的一種機制,允許硬體裝置或軟體程式暫時停止目前的執行流程,並轉而執行其他任務。這個過程涉及多個步驟,包括中斷請求、儲存上下文、尋找中斷服務例程(ISR)以及還原上下文。

中斷請求(IRQ)

當硬體裝置或軟體程式需要引發中斷時,會向處理器傳送中斷請求(IRQ)。這個請求會被處理器接收並處理。中斷請求可以由多種原因引發,例如按鍵按下、網路資料傳輸或計時器超時等。

儲存上下文

當處理器接收到中斷請求後,會立即儲存目前的執行上下文。這包括儲存目前的程式計數器(PC)、暫存器值等資訊。這樣做的目的是為了在中斷服務例程(ISR)執行完成後,可以還原到原來的執行狀態。

中斷服務例程(ISR)

處理器在儲存上下文後,會根據中斷請求找到對應的中斷服務例程(ISR)。ISR是一段專門用於處理中斷的程式碼,它會執行特定的任務以回應中斷請求。例如,當按鍵按下時,ISR可能會更新按鍵狀態或觸發其他動作。

還原上下文

在ISR執行完成後,處理器會還原原來的執行上下文。這包括還原原來的程式計數器(PC)、暫存器值等資訊。這樣做的目的是為了讓系統可以繼續執行原來的任務,而不會受到中斷的影響。

中斷優先順序

在某些情況下,可能會發生多個中斷請求同時到達處理器。在這種情況下,處理器需要根據中斷優先順序來決定哪個中斷請求先被處理。中斷優先順序可以根據硬體裝置或軟體程式的需求進行設定。

中斷巢狀

有些處理器允許中斷巢狀,也就是說,在一個中斷服務例程(ISR)正在執行時,可以接收另一個中斷請求並執行另一個ISR。這個功能可以提高系統的回應速度,但也可能增加系統的複雜度。

堆積疊和堆積

堆積疊(Stack)是一種資料結構,用於儲存資訊。堆積疊可以用於儲存函式呼叫的引數、區域性變數等資訊。在中斷處理過程中,堆積疊可以用於儲存原來的執行上下文,以便在ISR執行完成後還原原來的狀態。

堆積(Heap)是一種動態記憶體組態機制,用於儲存資料。堆積可以用於儲存動態組態的記憶體區塊,以便在程式執行過程中進行記憶體管理。

系統延遲

系統延遲(System Latency)是指從中斷事件發生到ISR開始執行的時間延遲。系統延遲包括處理器的中斷延遲和最大中斷停用時間。系統延遲越小,系統的回應速度越快。

中斷處理的第三步:從向量表中取出ISR

當中斷發生並儲存上下文後,處理中斷的第三步是根據向量表(IVT)確定要呼叫的ISR。這個表格位於處理器的特定記憶體區域。當中斷發生時,處理器會查詢這個表格以呼叫與中斷相關的函式。

向量表的初始化

啟動程式碼(可能隨編譯器或處理器廠商的HAL一起提供)會為您設定向量表,通常使用暫置的中斷處理器。在除錯時,您可能希望未處理的中斷進入無窮迴圈,以便您能夠找到它們並關閉中斷或正確地處理它們。但是當產品上市時,未處理的中斷處理器進入無窮迴圈將導致系統無回應。您可能希望未處理的中斷簡單地傳回到正常執行。這樣做浪費了處理器週期,仍然是一個錯誤,但至少對客戶的影響是一個輕微的速度減慢,而不是需要重新啟動的系統。

在某些情況下,如果您將處理器函式命名為與表中相同的名稱,一些工具的魔術將使聯結器使用您在IVT中的函式。然而,在其他處理器和編譯器中,您需要在中斷的正確插槽中手動將ISR插入函式表中。

查詢ISR

向量表位於記憶體中的特定地址,由玄貓設定。由於這通常是在啟動程式碼中為您完成的,因此您通常不需要知道如何做到這一點。然而,出於好奇,讓我們深入探討STM32F103xx的啟動程式碼:

__attribute__ ((section(".isr_vector")))
void (* const g_pfnVectors[])(void) = {
    // Core Level - CM3
    &_estack, // 初始堆積疊指標
    Reset_Handler, // 這是執行的開始
    NMI_Handler, // 非遮罩故障處理器
   ...
    TIM2_IRQHandler, // 28, TIM2 全域性中斷
    TIM3_IRQHandler, // 29,
    TIM4_IRQHandler, // 30, 
};

內容解密:

上述程式碼定義了一個向量表,該表格包含了與每個中斷相關的函式指標。當中斷發生時,處理器會查詢這個表格以呼叫相應的ISR。這個過程是由玄貓自動完成的,但瞭解其背後的原理對於開發人員來說是非常重要的。

圖表翻譯:

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 中斷處理機制與向量表應用

package "NumPy 陣列操作" {
    package "陣列建立" {
        component [ndarray] as arr
        component [zeros/ones] as init
        component [arange/linspace] as range
    }

    package "陣列操作" {
        component [索引切片] as slice
        component [形狀變換 reshape] as reshape
        component [堆疊 stack/concat] as stack
        component [廣播 broadcasting] as broadcast
    }

    package "數學運算" {
        component [元素運算] as element
        component [矩陣運算] as matrix
        component [統計函數] as stats
        component [線性代數] as linalg
    }
}

arr --> slice : 存取元素
arr --> reshape : 改變形狀
arr --> broadcast : 自動擴展
arr --> element : +, -, *, /
arr --> matrix : dot, matmul
arr --> stats : mean, std, sum
arr --> linalg : inv, eig, svd

note right of broadcast
  不同形狀陣列
  自動對齊運算
end note

@enduml

上述流程圖展示了中斷處理的過程。當中斷發生時,處理器會查詢向量表以呼叫相應的ISR。然後,ISR會被執行,最終傳回到正常執行。

中斷處理機制

中斷(Interrupt)是一種由硬體或軟體觸發的事件,需要CPU立即處理。中斷處理機制是指CPU如何回應和處理中斷的過程。

中斷號和中斷向量表

每個中斷都有一個唯一的中斷號(Interrupt Number),用於識別中斷的來源。中斷向量表(Vector Table)是一個儲存器中的表格,包含了每個中斷號對應的中斷處理程式(ISR)的地址。

當中斷發生時,CPU會將目前的執行狀態儲存起來,然後跳轉到中斷向量表中對應的ISR地址執行。ISR負責處理中斷事件,並在完成後傳回到原來的執行狀態。

可重入函式

可重入函式(Reentrant Function)是一種可以安全地多次呼叫而不會出現問題的函式。可重入函式必須滿足以下條件:

  • 不使用靜態或全域變數
  • 不呼叫非可重入函式
  • 不使用分享資源

中斷服務程式(ISR)

ISR是指處理中斷事件的程式。ISR應該盡可能地短小精悍,以減少系統延遲。ISR不應該呼叫非可重入函式或使用分享資源。

設定和清除位元

在某些情況下,需要設定或清除位元以控制中斷的行為。這可以透過設定和清除位元的暫存器來實作。

多個中斷源

在某些系統中,可能存在多個中斷源。這需要在ISR中進行額外的檢查,以確定哪個中斷源引發了中斷事件。

關閉中斷

可以透過關閉中斷來防止中斷事件的發生。這可以透過設定特定的旗標或暫存器來實作。

臨界區

臨界區(Critical Section)是指一段需要 atomically 執行的程式碼,以防止其他中斷事件的幹擾。可以透過關閉中斷或使用鎖機制來保護臨界區。

關閉中斷的方法

有兩種方法可以關閉中斷:

  • 使用 __disable_irq()__enable_irq()
  • 使用鎖機制

深入剖析中斷處理的底層機制後,可以發現從中斷請求、儲存上下文、查詢向量表到執行 ISR,整個流程環環相扣,確保系統能及時回應外部事件。多維度分析顯示,中斷優先順序和巢狀機制有效提升了系統的平行處理能力,但同時也增加了系統複雜度和除錯難度。技術限制深析指出,系統延遲、ISR 的執行效率以及堆積疊溢位等問題仍是中斷處理機制面臨的挑戰,尤其在實時性要求高的嵌入式系統中更需關注。從系統穩定性角度考量,ISR 應盡可能簡短高效,避免使用分享資源和非可重入函式,並妥善處理多個中斷源的競爭問題。玄貓認為,隨著硬體效能的提升和軟體設計的最佳化,中斷處理機制將在更精細的粒度上實作更靈活、更可靠的事件回應,進一步提升系統的實時效能和資源利用率。對於追求極致效能的系統,深入理解中斷處理機制並針對特定場景進行客製化最佳化至關重要。