ARM 之 Cortex-M 內核中斷/異常系統詳解

問題

最近在使用STM32F3芯片的時候,遇到這樣一個問題:如果外部中斷來的頻率足夠快,上一個中斷沒有處理完成,新來的中斷如何處理? 在調試時,發現有中斷有 掛起、激活、失能等狀態,考慮這些狀態都是幹啥用的呢!他們是Cortex-M核所共有的,因此這裏不針對與具體用的STM32 MCU,直接上升到 Cortex-M內核來了解一下!

簡介

  中斷(也稱爲“異常”)是微控制器一個很常見的特性。中斷一般是由硬件(例如外設、外部引腳)產生,當中斷產生以後 CPU 就會中斷當前的程序執行流程轉而去處理中斷服務中指定的操作。
  所有的Cortex-M 內核都會系統一個用於中斷處理的組件:NVIC(Nested Vectored Interrupt Controller,嵌套向量中斷控制器)。它處理處理中斷,還處理其他需要服務的事件(例如 SVC 指令),通常稱爲“異常”。 ​ 按照 ARM 的說法,中斷也是一種異常
異常
Cortex-M3和 Cotex-M4 的 NVIC 最多支持 240 個 IRQ(中斷請求)、1 個不可屏蔽中斷(NMI)、1 個 Systick(滴答定時器)定時器中斷和多個系統異常。而 Cortex-M0 最多支持32個IRQ、1 個不可屏蔽中斷(NMI)、1 個 Systick(滴答定時器)定時器中斷和多個系統異常。

  • IRQ: 多數由定時器、IO端口、通信接口等外設產生
  • NMI: 通常由看門狗定時器或者掉電檢測器等外設產生
  • 其他: 主要來自系統內核

注意,本文所說的 Cortex-M 主要指定是 Cotex-M3和 Cotex-M4。
Cortex-M
Cortex-M0、Cortex-M0+、Cortex-M1 基於 ARMv6-M。與Cotex-M3和 Cotex-M4相比,他們的指令集較小。而且,Cortex-M1 是專門爲FPGA應用設計的,沒有獨立MCU。

異常類型

  Cortex-M 處理器的異常中,編號 1~15 的爲系統異常,16及以上的則爲中斷輸入。所有終端機部分系統異常都具有可編程的優先級。部分系統異常具有固定優先級。ARM給出了以下一張表:

類型 位置 優先級 描述
0 在復位時棧頂從向量表的第一個入口加載
Reset 復位 1 -3(最高) 在上電和熱復位(warm reset)時調用,在第一條指令上優先級降到最低(線程模式),異步的
Non-maskable Interrupt 不可屏蔽中斷(NMI) 2 -2 不能被除復位之外的任何異常停止或佔先。異步的。
Hard Fault 硬故障 3 -1 由於優先級的原因或可配置的故障處理被禁止而導致不能將故障激活時的所有類型故障,同步的
Memory Management 存儲器管理 4 可配置 MPU 不匹配,包括違反訪問規範以及不匹配,是同步的,即使MPU 被禁止或不存在,也可以用它來支持默認的存儲器映射的XN 區域
Bus Fault 總線故障 5 可配置 預取指故障,存儲器故障,以及其它相關的地址/存儲故障,精確時是同步,不精確時時異步
Usage Fault 使用故障 6 可配置 使用故障,例如,執行未定義的指令或嘗試不合法的狀態轉換,是同步的
7~10 保留
SVCall 系統服務調用 11 可配置 利用SVC 指令調用系統服務,是同步的
Debug Monitor 調試監控 12 可配置 調試監控,在處理器沒有停止時出現,是同步的,但只有在使能時是有效的,如果它的優先級比當前有效的異常的優先級低,則不能被激活
13 保留
PendSV 可掛起的系統服務請求 14 可配置 可掛起的系統服務請求,是異步的,只能由軟件來實現掛起
SysTick 系統節拍定時器 15 可配置 系統節拍定時器(System tick timer)已啓動,是異步的
External Interrupt 外部中斷 16 及以上 可配置 在內核的外部產生(外部設備),INTISR[239:0],通過NVIC(設置優先級)輸入,都是異步的

  針對 Cortex-M 系列的內核,ARM 提供了一套叫做 CMSIS 的東西。目前,所有的MCU均使用CMSIS 作爲編程基礎。在 CMSIS-Core 中,中斷標識有中斷枚舉實現,從數值 0 開始(代表中斷#0)。其中,系統異常的編號爲負數。具體如下:
CMSIS-Core
CMSIS-Core之所以使用另外一種編號系統,是因爲這樣可以稍微提高部分API的效率。中斷的編號和枚舉定義是同設備相關的,他們位於微控制器供應商提供的頭文件中,在一個名爲IRQn的typedef段中。

中斷處理(異常處理)

  當某種內部或外部事件發生時,MCU 的中斷系統將迫使 CPU 暫停正在執行的程序,轉而去進行中斷事件的處理,中斷處理完畢後,又返回被中斷的程序處,繼續執行下去。
  主程序正在執行,當遇到中斷請求(Interrupt Request)時,暫停主程序的執行轉而去執行中斷服務例程(Interrupt Service Routine,ISR),稱爲響應,中斷服務例程執行完畢後返回到主程序斷點處並繼續執行主程序。多箇中斷是可以進行嵌套的。正在執行的較低優先級中斷可以被較高優先級的中斷所打斷,在執行完高級中斷後返回到低級中斷裏繼續執行。
中斷執行

中斷管理

  管理中斷所使用的大部分寄存器都位於NVIC(Nested Vectored Interrupt Controller,嵌套向量中斷控制器)和SCB(System Control Block,系統控制塊)中。實際上,SCB是作爲NVIC的一部分來實現的,不過在CMSIS-Core中,將其定義在了獨立的結構體中。除此之外,處理器內核中還有用於中斷屏蔽寄存器:PRIMASK、FAULTMASK、BASEPRI。
NVIC和SCB位於系統控制空間,地址從0xE000E00開始,大小4KB。SCB中還有SysTick定時器,存儲器保護單元等。

優先級

中斷輸入和掛起

在Cortex-M內核中,每個中斷都具有多個屬性:

  • 每個中斷都可以被禁止(默認)或者使能
  • 每個中斷都可以別掛起或者解除掛起
  • 每個中斷都可以處於活躍或者非活躍

這些狀態屬性具有多種可能的組合。例如,在處理中斷時,可以將其禁止,若在中斷提出掐產生了同一個中斷的新請求,由於該活躍中斷被禁止了,那就會處於掛起狀態。
  NVIC在設計上既支持產生 脈衝中斷請求 的外設,也支持產生 高電平中斷請求 的外設。無需配置任何yigeNVIC寄存器以選擇其中一種中斷類型。對於脈衝中斷請求,脈衝寬度至少要爲一個時鐘週期;而對於電平觸發的請求,在ISR中的操作清湖請求之前,請求服務的外設要一直保持電平信號(如寫入寄存器以清除中斷請求)。儘管外部中斷請求在I/O引腳上的電平可能是低電平有效,但是NVIC收到的額請求信號爲高有效!
  中斷的掛起狀態被存儲在 NVIC 的可編程寄存器中,當 NVIC 的中斷輸入被確認後,它就會引發該中斷的掛狀態。即便中斷請求被取消,掛起狀態仍會爲高。這樣,NVIC 就可以處理脈衝中斷請求了。
  掛起狀態的意思是,中觀被置於一種等待處理器處理的狀態。有些情況下,處理器在終端掛起時就會進行處理。不過,若處理器已經在處理另外一個更高或同優先級的中斷,或者中斷被某個中斷屏蔽寄存器給屏蔽掉了,那麼在其他的中觀處理結束前或者中斷屏蔽被清除前,掛起請求會一直保持。
  當中斷開始處理中斷請求時,中斷的請求信號會被自動清除。當中斷正在被處理時,它就會處於活躍狀態。
掛起
當中斷處於活躍狀態時,處理器無法再中斷完成和異常返回前再次處理同一個中斷請求。
  中斷的掛起狀態位於中斷掛起狀態寄存器中,軟件可以方位這些寄存器。因此,可以手動清除或者設置中斷的掛起狀態。若中斷請求產生時處理器正在處理另一個具有更高優先級的中斷,而在處理器對該中斷請求做出響應之前,掛起狀態被清除掉了,則該中斷會被取消且不會再得到處理。
在這裏插入圖片描述
若持續保持某個中斷請求,那麼及時軟件嘗試清除該掛起狀態,掛起狀態還是會再次被置位的。
在這裏插入圖片描述
若中斷已經得到了處理,中斷源仍然在繼續保持中斷請求,那麼這個中斷就會再一次進入掛起狀態且再次得到處理
在這裏插入圖片描述
對於脈衝中斷請求,若在處理器開始處理前,中斷請求信號產生了多次,他們會被當做一次中斷請求處理
在這裏插入圖片描述
中斷掛起狀態可以在其正在被處理時再次置位。之前的中斷請求正在被處理時產生了新的請求,這樣機會引發新的掛起狀態。處理器在前一個ISR結束後需要再次處理這個中斷。
在這裏插入圖片描述
即使中斷被禁止了,他的掛起狀態仍然可置位。 這種情況下,若中斷稍後被使能了,它仍然可以被觸發並被得到處理。這種情況可能不是我們需要的,因此需要在使能NVIC中斷前手動清除掛起狀態。

參考

  1. The Definitive Guide to ARM Cortex-M3 and Cortex-M4 Processors, 3rd Edition
  2. The Definitive Guide to the Cortex-M0
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章