Hi ALL!
最近在定位一個關于中斷的問題,以前看待這些問題是割裂的,要不是軟件怎么設計中斷,要不是硬件怎么設計中斷。
正好乘著這次機會,站在軟硬件交互的角度將中斷的知識來梳理一下。
對了,今天天氣不錯,周末快樂!
中斷是什么?
中斷是指計算機在執行期間,系統內發生任何非尋常的或非預期的急需處理事件,使得CPU暫時中斷當前正在執行的程序而轉去執行相應的中斷服務程序(Interrupt Service Routine, ISR)。這個事件可以是由硬件設備觸發(如硬盤讀寫錯誤、打印機沒有紙等),也可以是由軟件觸發(如用戶按下Ctrl+C)。
當發生中斷時,CPU會暫停當前正在執行的程序,并跳轉到相應的中斷處理程序(Interrupt Service Routine, ISR)去處理這個事件。中斷處理程序通常會保存當前任務的上下文信息(如CPU寄存器的狀態、內存中的數據等),然后執行相應的中斷處理操作(如讀取數據、發送響應等)。在中斷處理完畢后,CPU會恢復之前保存的上下文信息,并回到被中斷的任務繼續執行。
中斷是一種異步的事件處理機制,可以提高系統的并發處理能力。在現代計算機系統中,中斷被廣泛應用于處理各種硬件設備事件和軟件異常情況。
我們知道中斷的發生與處理是一個需要軟硬件交互的操作。
?關中斷:進入不可響應中斷請求的中斷,由硬件自動完成?保存斷點:把當前的程序計數器PC中的內容保存起來,用于中斷處理結束后能繼續執行主程序?識別中斷源:有多個中斷源同時請求時,只能響應最高優先級的,因此需進一步判斷中斷源?保存現場和屏蔽字:進入中斷服務程序后,要先保存現場?設置新的屏蔽字:用于改變中斷優先級和控制中斷的產生?開中斷:執行中斷程序時,打開中斷可實現更高優先級的中斷響應,實現中斷嵌套?執行中斷服務程序:執行中斷服務程序中的內容?再次關中斷:使得恢復現場和屏蔽字時不會被中斷打斷?恢復現場和屏蔽字:使現場和屏蔽字恢復到中斷之前的狀態?再次開中斷:中斷執行完,現場恢復完后,可以打開中斷?中斷返回:返回原程序繼續執行
處理過程,會經歷兩次的開/關中斷,也可用下圖描述
在之前我們在做嵌入式的時候,大多是關注了軟件層面,如何注冊中斷,如何設計中斷的參數,如何編寫中斷服務函數,如何將中斷服務綁定到中斷號。做linux中斷的話,這些都是定義好的,你可以去調用接口,當然也支持自定義添加新的中斷。
后面這部分可以好好展開學習一下,當然是在我的內存系列結束后。
但是既然是一個軟硬件交互的過程,那么這里就拉著硬件和軟件兩位伙伴來看看一個完整的中斷過程。
前置知識
在開始描述一個中斷的軟硬件流程之前,我們需要提前預備幾個前置知識點。
單重中斷與多重中斷
?單重中斷在CPU執行中斷服務程序的過程中不能被打斷。當有新的更高優先級的中斷發生時,正在執行的中斷服務程序會被暫停,轉而執行新的中斷服務程序。?多重中斷在執行某個中斷服務程序的過程中,CPU可以去響應更高的中斷請求。這被稱為中斷嵌套。比如,當一個中斷服務程序正在執行時,發生了另一個更高優先級的中斷,CPU會暫停當前的中斷服務程序,轉而執行新的中斷服務程序。一旦新的中斷服務程序執行完畢,CPU會返回到原來被暫停的中斷服務程序,繼續執行。
注意:單重中斷和多重中斷的區別在于“開中斷”的設置時間不同。對于單重中斷,開中斷指令設置在最后“中斷返回”之前,意味著在整個中斷服務處理過程中,不能再響應其他中斷源的請求。而對于多重中斷,開中斷指令提前至“保護現場”之后,意味著在保護現場之后,若有更高級別的中斷源提出請求,CPU也可以響應,從而實現中斷嵌套,這是二者的主要區別。
多重中斷與中斷屏蔽技術
上面我們知道了單重中斷和多重中斷的區別:
中斷的嵌套不能一直嵌套下去,為了保證正在執行的中斷服務程序的完整性和提高系統的效率和響應速度,有時候我們在執行種的時候不想新的中斷請求干擾正在執行的中斷服務程序來提高系統的效率和響應速度和保證正在執行的中斷服務程序的完整性。
那么這個時候就出現了中斷屏蔽技術。
1、中斷屏蔽技術:主要用于多重中斷
多重中斷:(中斷嵌套)當CPU正在執行某個中斷服務程序時,另一個中斷源又提出了新的中斷請求,而CPU又響應了這個新的請求,暫時停止正在運行的服務程序,轉去執行新的中斷服務程序,這稱為多重中斷,又稱中斷嵌套。
如果CPU對新的請求不予響應,待執行完當前的服務程序后再響應,即為單重中斷。
中斷系統若要具有處理多重中斷的功能,必須具備各項條件。
?1)提前設置“開中斷”指令:一般情況下,CPU進入中斷周期后,由中斷隱指令自動將EINT置“0”,即關中斷。
中斷隱指令指CPU響應中斷之后,經過某些操作,轉去執行中斷服務程序的一種操作。
這就意味著CPU在執行中斷服務程序中禁止響應新的中斷請求。CPU若想再次響應中斷請求,必須開中斷,
這一任務通常由中斷服務程序中的開中斷指令實現。
多重中斷示意圖如下:
?2)、優先級別高的中斷源有權中斷優先級別低的中斷源。
在滿足1的前提下,只有優先級別更高的中斷源請求才可以中斷比其級別低的中斷服務程序,反之則不然。
為了保證級別低的中斷源不干擾比其級別高的中斷源的中斷處理過程,可采用屏蔽技術。
例如,有A、B、C、D 4個中斷源,其優先級按A->B->C->D由高向低次序排列。在CPU執行主程序期間,同時出現了B和C的中斷請求,由于B級別高于C,故首先執行B的服務程序。
當B的服務程序執行完返回主程序后,由于C請求未撤銷,故CPU又再去執行C的中斷服務程序。若此時又出現了D的請求,因為D級別低于C,故CPU不響應。當C的服務程序執行完返回主程序后再去執行D的服務程序。
若此時又出現了A請求,因A級別高于D,故CPU暫停對D級中斷服務程序的執行,轉去執行A級中斷服務程序,等A級服務程序執行完后,再去執行D級中斷服務程序。上述中斷處理示意圖如下:
2、屏蔽技術
?1)屏蔽觸發器和屏蔽字:程序中斷接口電路中,完成觸發器D,中斷請求觸發器INTR和屏蔽觸發器MASK。
在程序中斷接口電路中,有三個重要的組成部分:完成觸發器D,中斷請求觸發器INTR和屏蔽觸發器MASK。這些組件都扮演著各自的角色,以實現程序中斷處理的功能。
完成觸發器D:當設備工作完成時,會將D置為1,這表示中斷源已經準備好向CPU發送中斷請求。
中斷請求觸發器INTR:當設備發出中斷請求時,INTR會被置為1。這個觸發器是用來向CPU發送中斷請求的。
屏蔽觸發器MASK:每個中斷源都有一個與之對應的屏蔽觸發器,如果該中斷源被屏蔽(即MASK=1),那么即使INTR被置為1,CPU也不會響應這個中斷請求。換句話說,屏蔽觸發器可以阻止特定的中斷源向CPU發送中斷請求。
所有的屏蔽觸發器組合在一起,構成了屏蔽寄存器。
?當中斷源被屏蔽時(MASK=1),此時即使D=1,中斷查詢信號到來時刻只能將INTR置“0”,CPU接收不到該中斷源的中斷請求,即它被屏蔽。?若該中斷源未被屏蔽(MASK=0),當設備工作已完成時(D=1),中斷查詢信號則將INTR置“1”,表示該中斷源向CPU發出中斷請求,?該信號送至排隊器進行優先級判斷。顯然,對于每個中斷請求觸發器就有一個屏蔽觸發器,將所有屏蔽觸發器組合在一起,便構成了一個屏蔽寄存器。屏蔽寄存器的內容稱為屏蔽字。屏蔽字與中斷源的優先級是一一對應的。
?2)屏蔽技術可改變優先等級:嚴格地說,優先級包含響應優先級和處理優先級。響應優先級是指CPU響應各中斷源請求的優先次序,這種次序往往是硬件線路已設置好的,不便于改動。處理優先級是指CPU實際對各中斷源請求的處理優先次序。如果不采用屏蔽技術,響應的優先次序就是處理的優先次序。采用了屏蔽技術后,可以改變CPU處理各中斷源的優先等級,從而改變CPU執行程序的軌跡。
例如,A、B、C、D 這4個中斷源的優先級別按A->B->C->D降序排列,根據這一次序,CPU執行程序的軌跡如下圖所示。當4個中斷源同時提出
在不改變CPU響應中斷的次序下,通過改變屏蔽字可以改變CPU處理中斷的次序。例如,更改上述4個中斷源的屏蔽字將其處理次序更改為:
CPU在運行程序的過程中,若A、B、C、D 4個中斷源同時提出請求,按照中斷級別的高低,CPU首先響應并處理A中斷源的請求,由于A的屏蔽字是1111,屏蔽了所有的中斷源,故A程序可以全部執行完,然后回到主程序。
由于B、C、D的中斷請求還未響應,而B的響應優先級高于其他,所以CPU響應B的請求,進入B的中斷服務程序。
在B的服務程序中,由于設置了新的屏蔽字0100,即A、C、D可打斷B,而A程序已執行完,C的響應優先級高于D,于是CPU響應C,進入C的服務程序。
在C的服務程序中,由于設置了的屏蔽字0110,即A、D可打斷C,A已執行于是CPU響應D,執行D的中斷服務程序。
D一直做完后回到C程序,C程序執行完后,回到B程序。
B程序做完后,回到主程序。
在中斷處理過程中,CPU首先會檢查INTR,如果INTR為1,那么CPU會進一步檢查對應的屏蔽觸發器(MASK),如果MASK也為1,那么該中斷源的中斷請求會被屏蔽,CPU不會響應;如果MASK為0,那么CPU會響應這個中斷請求,轉去執行對應的中斷服務程序。
這個過程是自動進行的,不需要程序員明確地編寫相關的指令。在硬件設計中,程序員需要根據實際需求來設置INTR、D和MASK的值,以實現正確的中斷處理。
你是軟件程序員還是硬件程序員呢?
3、屏蔽技術的意義
屏蔽技術還能給程序控制帶來更大的靈活性。例如,在浮點運算中,當程序員估計到執行某段程序時可能出現“階上溢”,但又不希望因“階上溢”而使機器停機,為此可設一屏蔽字,使對應“階上溢”的屏蔽位為“1”,這樣,即使出現“階上溢”,機器也不停機。
在某些情況下,程序員可能希望在執行某些操作之前禁止其他中斷,以防止這些中斷干擾正在進行的操作。通過將對應的中斷屏蔽觸發器設置為1(即屏蔽該中斷),程序員可以確保在執行這些操作期間,不會受到來自該中斷源的中斷請求干擾。
此外,屏蔽技術還可以用于實現優先級控制。例如,如果系統中有多個中斷源,并且程序員希望在某些操作完成之前不響應其他低優先級的中斷,那么可以通過調整屏蔽字的設置,改變CPU對不同中斷源的處理優先級。這樣,程序員可以更好地控制程序的執行流程和中斷處理順序,從而優化系統的性能和響應速度。
另外,屏蔽技術還可以用于調試程序。當程序中存在某些不可預見的錯誤時,程序員可以通過設置相應的屏蔽字,禁止某些中斷請求,以避免這些錯誤對程序執行造成干擾。同時,通過查看被屏蔽的中斷服務程序表,程序員可以及時發現錯誤并采取相應的措施進行修復。
屏蔽技術為程序員提供了一種強大的工具,可以更加靈活地控制程序的執行和中斷處理過程。通過合理使用屏蔽技術,可以提高系統的穩定性和性能,滿足各種復雜的應用需求。
一個中斷的一生
現在有了上述的基識,如何從軟件與硬件的角度去看一個中斷,一個中斷的完整流程應該是什么樣子?
?創建對應的中斷服務函數(軟件):在編寫操作系統或應用程序時,需要為每個中斷源創建一個對應的中斷服務函數(Interrupt Service Routine, ISR)。這個函數是用于處理特定中斷的程序,當發生中斷時,處理器會跳轉到這個函數執行相應的操作。?將中斷服務函數綁定到特定的中斷號,也叫中斷注冊(軟件):在操作系統或硬件系統中,需要將每個中斷源與相應的中斷號進行綁定。這個過程通常在初始化時完成,以確保當發生中斷時能夠正確地調用相應的中斷服務函數。這個綁定可以通過編程實現,例如在Linux系統中可以使用register_interrupt函數將中斷服務函數注冊到特定的中斷號。?模塊產生原始中斷(邏輯):當某個硬件設備需要中斷處理器服務時,它會向中斷控制器發送一個中斷請求。這個請求可能由硬件信號線或特定協議(如PCI Express)發送。例如,當硬盤讀寫錯誤時,硬盤控制器會向中斷控制器發送一個中斷請求。
原始中斷是指當某個設備或部件需要CPU的注意時,它會通過向CPU發送一個中斷信號來請求CPU的注意。這個中斷信號是由硬件電路產生的,是電信號,可以被CPU感知到。原始中斷通常是由硬件設備或系統自發產生的,例如鍵盤按鍵、定時器、打印機等。
?經過int_mask判斷后未被屏蔽從而中斷狀態拉高(邏輯):中斷控制器接收到中斷請求后,會根據int_mask判斷該中斷是否被屏蔽。如果未被屏蔽,則將中斷狀態拉高,以便處理器能夠感知到這個中斷請求。這個過程中斷控制器會根據int_mask中的位圖判斷當前的中斷是否被屏蔽,如果未被屏蔽則將對應的中斷狀態位拉高。
中斷的int_mask是中斷掩碼。它是一個只讀寄存器,用于顯示哪些位當前被屏蔽,哪些位未被屏蔽/啟用。通過設置int_mask,可以屏蔽或開啟某些中斷。
?模塊頂層信號 xxx_int拉高后,送給特定中斷號對應處理器(CPU&MCU等)的對應bit(邏輯):當中斷狀態被拉高后,模塊頂層信號 xxx_int 會被拉高,并將這個信號送給特定中斷號對應處理器的對應bit。這個過程是由硬件邏輯實現的,通常與處理器的架構和中斷控制器的設計有關。例如,在x86架構的計算機中,當某個中斷狀態被拉高后,對應的處理器會通過APIC總線將對應的中斷信號發送給處理器。?中斷信號拉高后,進入對應bit的中斷服務函數(邏輯):當處理器的對應bit接收到中斷信號后,處理器會跳轉到相應的中斷服務函數去處理這個中斷。這個過程是由硬件自動完成的,通常與處理器的架構和操作系統的設計有關。例如,在x86架構的計算機中,當處理器接收到一個中斷信號后,它會通過CSIP和IVT寄存器跳轉到對應的中斷服務函數執行相應的操作。
硬件層面,中斷系統需要硬件設備(如中斷控制器)來捕捉中斷信號,并將信號傳遞給CPU。在接收到中斷信號后,CPU會根據中斷號在中斷向量表中查找對應的入口地址,然后跳轉到這個地址執行對應的中斷服務程序。這個過程是由硬件自動執行的,不需要軟件的參與。
?執行中斷服務函數的內容(軟件):在中斷服務函數中,會根據設備的需求進行相應的操作,例如讀取數據、發送響應等。這個過程是由軟件實現的,通常與設備的驅動程序和操作系統的設計有關。例如,在Linux系統中,當執行完一個中斷服務函數后,它通常會通過調用handle_irq_event函數來處理設備的事件。
MORE
中斷向量表
在ARM處理器中,當一個中斷信號被觸發時,中斷控制器會發出一個中斷請求,并將該請求傳遞給CPU。 CPU接收到中斷請求后,會根據中斷號在中斷向量表中查找對應的中斷服務程序入口地址。 中斷向量表是一個預定義的表,其中每個條目都包含一個指向特定中斷服務程序的入口地址。 當CPU接收到中斷請求時,它會根據中斷號在表中查找對應的條目,獲取對應的入口地址,并跳轉到該地址執行相應的中斷服務程序。 在這個過程中,程序員可以通過設置中斷向量表中的條目來定義不同中斷源的中斷服務程序入口地址。 這樣可以實現自定義的中斷處理邏輯,根據不同的中斷事件執行相應的操作。 需要注意的是,在ARM處理器中,不同的工作模式(例如User、FIQ、IRQ、SVC等)使用不同的寄存器集和特權級別。 當中斷發生時,CPU會根據當前的工作模式和中斷向量表中的條目,確定要跳轉到的中斷服務程序的入口地址。 然后它會將CPU的狀態保存到相應的棧中,并跳轉到該地址執行中斷服務程序。 在ARM處理器中,中斷向量表是一個預定義的表,它通常在系統啟動時由引導加載器(Bootloader)或操作系統進行定義和初始化。 引導加載器在系統啟動時負責加載和啟動操作系統的內核。在這個過程中,它會讀取存儲器中的中斷向量表數據,并將其復制到指定的內存地址。 這個地址通常是在系統配置時確定的,以確保中斷向量表可以在正確的位置被CPU訪問。 操作系統在啟動后也會接管中斷向量表的管理和配置。它會根據系統中斷控制器和其他硬件設備的配置,將中斷向量表中的條目映射到相應的中斷服務程序入口地址。 這樣,當中斷發生時,CPU可以根據中斷號在中斷向量表中查找對應的條目,并跳轉到對應的地址執行相應的中斷服務程序。 需要注意的是,中斷向量表的定義方式和具體實現可能會因不同的ARM處理器架構和系統設計而有所不同。 因此,具體的定義位置和方式可能會因硬件平臺和操作系統而有所差異。 這部分又涉及到編譯與內存分布了,這里就不展開講了,有機會的一起看看。
Raw Interrupt和Masked Interrupt
Raw Interrupt和Masked Interrupt是兩種中斷類型,它們在ARM處理器中被用來處理中斷。
Raw Interrupt(原始中斷)是指外部中斷源的狀態,無論ARM芯片是否屏蔽該中斷源,這個中斷源的中斷狀態都會被寄存器存儲,從而可以通過相應的函數讀取。
Masked Interrupt(屏蔽中斷)是指是否屏蔽的狀態。在ARM處理器中,每個中斷源都有一個與之對應的屏蔽觸發器,如果該中斷源被屏蔽(即MASK=1),那么即使INTR被置為1,CPU也不會響應這個中斷請求。換句話說,屏蔽觸發器可以阻止特定的中斷源向CPU發送中斷請求。所有的屏蔽觸發器組合在一起,構成了屏蔽寄存器。
-
ARM
+關注
關注
134文章
9165瀏覽量
369190 -
寄存器
+關注
關注
31文章
5363瀏覽量
121158 -
觸發器
+關注
關注
14文章
2003瀏覽量
61347
原文標題:參考資料
文章出處:【微信號:處芯積律,微信公眾號:處芯積律】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論