【異常/中斷響應】
Cortex-M3的異常/中斷響應序列包括:
- 入棧:把8個寄存器的值壓入棧。
- 取向量:從向量表中找出對應的服務程序入口地址。
- 更新寄存器:更新堆棧指針SP,更新連接寄存器LR,更新程序計數器PC
【入棧】
響應異常的第一個行動,就是自動保存現場的必要部分:依次把xPSR、PC、LR、R12以及R3~R0由硬件自動壓入適當的堆棧中:如果當響應異常時,當前的代碼正在使用PSP,則壓入PSP,也就是使用進程堆棧;否則就壓入MSP,使用主堆棧。
一旦進入了異常中斷服務例程,就將一直使用主堆棧。
假設入棧開始時,SP的值位N,則在入棧后,入棧順序以及入棧后堆棧中的內容變化如圖所示:

因為AHB接口上的流水線操作本性,地址和數據都是經過一個流水周期之后才進入。
在自動入棧的過程中,把寄存器寫入堆棧內存的時間順序,並不是與寫入的空間順序相對應的。但是,Cortex-M3內核會保證:正確的寄存器將被保存到正確的位置。
【取向量】
在數據總線執行入棧操作的時候,指令總線正在執行取向量操作:即從向量表中找出正確的中斷向量,然后在服務例程入口處預取指令。
取向量和入棧是同時進行的;
【更新寄存器】
在入棧和取向量操作完成之后,執行異常中斷服務程序之前,還要更新一系列的寄存器:
- 堆棧指針SP:在入棧后,會把堆棧指針(PSP或MSP)更新到新的位置。在執行異常中斷服務程序時,將由MSP負責對堆棧的訪問。
- 程序狀態寄存器PSR:更新IPSR位段的值為新響應的異常編號。
- 程序計數寄存器PC:在取向量完成后,PC將指向異常中斷服務程序的入口地址。
- 連接寄存器LR:在出入ISR的時候,LR的值將得到重新的詮釋,這種特殊的值稱為“EXC_RETURN”。在異常進入時由系統計算並賦給LR,並在異常返回時使用它。
另外,在NVIC中,也會更新若干個相關寄存器。例如,新響應異常的懸起位將被清除,同時其活動位將被置位。
【異常/中斷返回】
當異常中斷服務程序執行完畢之后,需要一個“異常返回”動作序列,從而恢復先前的系統狀態,使被中斷的程序繼續執行。
從形式上看,有3種途徑可以觸發異常返回序列,如:
不管使用哪一種返回指令,都需要用到先前存儲到LR中的EXX_RETURN,把EXC_RETURN送往PC。
在啟動了中斷返回序列后,將執行以下操作:
- 出棧:恢復先前壓入堆棧的寄存器的值。內部的出棧順序與入棧時的向對應。堆棧指針的值也恢復更新。
- 更新NVIC寄存器:異常返回,其將於的活動位將被硬件清除。對於外部中斷,如果中斷輸入再次被置為有效,懸起位也將再次置位,新的中斷響應序列也隨之再次執行。
參考摘錄:
《Cortex-M內核系列和STM32-講座2教程.pdf》
《ARM Cortex-M3權威指南.pdf》
