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