中斷的工作流程
中斷的運行并非 “瞬間完成”,而是遵循一套嚴謹?shù)挠布c軟件協(xié)同流程,從 “事件觸發(fā)” 到 “任務恢復” 可分為五個核心階段:中斷請求、中斷響應、現(xiàn)場保護、執(zhí)行 ISR、現(xiàn)場恢復與返回。每個階段都有明確的硬件邏輯與軟件規(guī)則,確保中斷處理的正確性與高效性。
(一)中斷請求:事件的 “信號傳遞”
中斷流程的起點是 “中斷請求(IRQ, Interrupt Request)”—— 當外設或內部模塊發(fā)生特定事件時(如按鍵按下導致 GPIO 引腳電平變化、定時器計數(shù)達到設定值、串口接收緩沖區(qū)有數(shù)據(jù)),會向 MCU 的 “中斷控制器” 發(fā)送一個硬件信號(通常是電平信號或脈沖信號),表明 “需要緊急處理”。
不同嵌入式芯片的中斷請求機制存在差異,但核心邏輯一致:首先,外設需具備 “中斷使能” 開關 —— 只有當外設自身的中斷使能位被置 1 時,事件發(fā)生才會觸發(fā) IRQ(例如,要讓串口接收數(shù)據(jù)觸發(fā)中斷,需先開啟串口的 “接收中斷使能位”);其次,中斷請求需經過 “同步電路”—— 由于外設時鐘與 MCU 核心時鐘可能不同步(如外設用 32kHz 時鐘,核心用 100MHz 時鐘),IRQ 信號需經過 1-2 個核心時鐘周期的同步,避免 metastability(亞穩(wěn)態(tài))導致的信號誤判;最后,中斷請求會被暫存在中斷控制器的 “掛起寄存器(Pending Register)” 中,等待 MCU 響應 —— 即使 MCU 暫時無法處理(如正在執(zhí)行更高優(yōu)先級任務),IRQ 信號也會被掛起保存,不會丟失。
(二)中斷響應:MCU 的 “優(yōu)先級判斷”
當 MCU 接收到中斷請求后,并非立即響應,而是先進行 “中斷響應條件判斷”,核心是 “是否允許中斷” 與 “中斷優(yōu)先級是否足夠高”。
首先是 “全局中斷使能” 判斷:MCU 有一個 “全局中斷使能位”(如 ARM Cortex-M 系列的 PRIMASK 寄存器),只有當該位為 0 時(全局中斷允許),MCU 才會響應中斷;若該位為 1(全局中斷禁止),則所有可屏蔽中斷都會被忽略,僅不可屏蔽中斷(NMI)能強制響應 —— 這一機制用于處理 “臨界區(qū)”(如主程序與 ISR 共享數(shù)據(jù)時,需禁止中斷避免數(shù)據(jù)混亂)。
其次是 “中斷優(yōu)先級判斷”:當多個中斷請求同時掛起時,中斷控制器會根據(jù)預設的 “中斷優(yōu)先級”,選擇優(yōu)先級最高的中斷進行響應。嵌入式系統(tǒng)的中斷優(yōu)先級通常分為 “搶占優(yōu)先級” 與 “子優(yōu)先級”(如 Cortex-M 的 NVIC 控制器):搶占優(yōu)先級高的中斷可打斷正在執(zhí)行的低搶占優(yōu)先級 ISR(即 “中斷嵌套”);若兩個中斷的搶占優(yōu)先級相同,則比較子優(yōu)先級,子優(yōu)先級高的先響應;若搶占優(yōu)先級與子優(yōu)先級均相同,則按 “中斷編號” 的默認順序響應(如編號小的優(yōu)先)。例如,“電機過載保護中斷”(搶占優(yōu)先級 1)可打斷正在執(zhí)行的 “按鍵掃描中斷”(搶占優(yōu)先級 2),而 “串口接收中斷” 與 “SPI 接收中斷”(均為搶占優(yōu)先級 2,子優(yōu)先級 1 與 2)則按子優(yōu)先級順序響應。
當滿足響應條件時,MCU 會啟動 “中斷響應序列”:首先,禁止同優(yōu)先級及更低優(yōu)先級的中斷(防止響應過程中被打斷);其次,自動保存 “上下文現(xiàn)場”—— 將當前的程序計數(shù)器(PC,記錄下一條要執(zhí)行的指令地址)、程序狀態(tài)寄存器(PSR,記錄 CPU 狀態(tài))、通用寄存器(R0-R3 等)的值壓入棧(Stack)中,確保后續(xù)能準確恢復常規(guī)任務;最后,根據(jù) “中斷向量表” 找到對應的 ISR 入口地址,將 PC 指向該地址,正式進入 ISR 執(zhí)行階段。
(三)現(xiàn)場保護與 ISR 執(zhí)行:事件的 “核心處理”
盡管 MCU 在中斷響應階段已自動保存部分寄存器(如 R0-R3、PC、PSR),但對于其他通用寄存器(如 R4-R11),若 ISR 中會修改這些寄存器的值,則需要在 ISR 開頭手動進行 “現(xiàn)場保護”—— 將這些寄存器的值壓入棧中;若 ISR 中不修改,則無需保護,以減少處理延遲。這一環(huán)節(jié)的核心原則是 “誰修改,誰保護”,避免 ISR 執(zhí)行后,常規(guī)任務的寄存器值被篡改,導致程序運行異常。
中斷服務程序(ISR)是中斷處理的 “核心邏輯”,其設計直接決定中斷處理的效率與可靠性。ISR 的核心要求是 “短小精悍”—— 僅處理與中斷事件直接相關的必要操作,避免執(zhí)行復雜運算、循環(huán)或調用耗時函數(shù)(如 printf、動態(tài)內存分配)。例如,按鍵中斷的 ISR 應僅做 “置位按鍵標志位” 或 “讀取按鍵值并緩存”,而將 “按鍵防抖處理”“執(zhí)行按鍵對應的功能(如開燈)” 交給主程序;串口接收中斷的 ISR 應僅做 “將接收數(shù)據(jù)存入緩沖區(qū)”,而將 “數(shù)據(jù)解析”“數(shù)據(jù)處理” 交給主程序。這樣設計的原因在于:ISR 執(zhí)行時間越長,中斷延遲與嵌套沖突的風險越高,甚至可能導致低優(yōu)先級中斷被長期阻塞,丟失重要事件。
此外,ISR 中還需注意 “中斷清除”—— 部分外設的中斷請求會在事件發(fā)生后持續(xù)有效(如定時器溢出中斷),若 ISR 中不手動清除 “中斷掛起位”,則 ISR 執(zhí)行完成后,中斷控制器會認為中斷請求仍存在,立即再次觸發(fā)中斷,導致 “中斷風暴”(ISR 無限循環(huán)執(zhí)行)。中斷清除的方式因外設而異:有的需要清除外設自身的中斷掛起位(如定時器的 SR 寄存器),有的需要通過讀取數(shù)據(jù)自動清除(如串口接收數(shù)據(jù)后,讀取 DR 寄存器即可清除接收中斷掛起位)。
(四)現(xiàn)場恢復與中斷返回:任務的 “無縫銜接”
ISR 執(zhí)行完成后,需要進行 “現(xiàn)場恢復” 與 “中斷返回”,確保常規(guī)任務能從被暫停的位置繼續(xù)執(zhí)行?,F(xiàn)場恢復與現(xiàn)場保護相對應:若 ISR 開頭手動保護了 R4-R11 等寄存器,則需在 ISR 結尾手動將這些寄存器的值從棧中彈出,恢復原值;若未保護,則無需操作。
中斷返回的核心是執(zhí)行 “中斷返回指令”(如 ARM Cortex-M 的 BX LR 指令,x86 的 IRET 指令)。當 MCU 執(zhí)行該指令時,會自動從棧中彈出之前保存的 PC、PSR、R0-R3 等寄存器的值,恢復 CPU 的狀態(tài)與程序計數(shù)器指向 ——PC 重新指向被中斷的常規(guī)任務的下一條指令,PSR 恢復中斷前的 CPU 狀態(tài)(如中斷屏蔽位、條件標志位),R0-R3 恢復原值。同時,中斷控制器會自動清除當前中斷的掛起位,并重新允許同優(yōu)先級及更低優(yōu)先級的中斷(若之前禁止),至此,整個中斷流程完成,常規(guī)任務無縫銜接繼續(xù)執(zhí)行。




