問題
最近在使用 STM32F3 芯片的時候,遇到這樣一個問題:如果外部中斷來的頻率足夠快,上一個中斷沒有處理完成,新來的中斷如何處理?
在調(diào)試時,發(fā)現(xiàn)有中斷有 掛起、激活、失能等狀態(tài),考慮這些狀態(tài)都是干啥用的呢!他們是 Cortex-M 核所共有的,因此,這里不針對與具體用的 STM32 MCU,直接上升到 Cortex-M 內(nèi)核來了解一下!
簡介
中斷(也稱為“異?!?是微控制器一個很常見的特性。中斷一般是由硬件(例如外設、外部引腳)產(chǎn)生,當中斷產(chǎn)生以后 CPU 就會中斷當前的程序執(zhí)行流程轉而去處理中斷服務中指定的操作。
所有的 Cortex-M 內(nèi)核都會包含一個用于中斷處理的組件:NVIC(Nested Vectored Interrupt Controller,嵌套向量中斷控制器)。它處理處理中斷,還處理其他需要服務的事件(例如 SVC 指令),通常稱為異常(按照 ARM 的說法,中斷也是一種異常)。
Cortex-M3 和 Cotex-M4 的 NVIC 最多支持 240 個 IRQ(中斷請求)、1 個不可屏蔽中斷(NMI)、1 個 Systick(滴答定時器)定時器中斷和多個系統(tǒng)異常。而 Cortex-M0 最多支持 32 個 IRQ、1 個不可屏蔽中斷(NMI)、1 個 Systick(滴答定時器)定時器中斷和多個系統(tǒng)異常。
IRQ: 多數(shù)由定時器、IO 端口、通信接口等外設產(chǎn)生
NMI: 通常由看門狗定時器或者掉電檢測器等外設產(chǎn)生
其他: 主要來自系統(tǒng)內(nèi)核
注意,本文所說的 Cortex-M 主要指定是 Cotex-M3 和 Cotex-M4。
Cortex-M0、Cortex-M0+、Cortex-M1 基于 ARMv6-M。與 Cotex-M3 和 Cotex-M4 相比,他們的指令集較小。而且,Cortex-M1 是專門為FPGA 應用設計的,沒有獨立 MCU。
異常類型
Cortex-M 處理器的異常中,編號 1~15 的為系統(tǒng)異常,16 及以上的則為中斷輸入。所有中斷級別的異常都具有可編程的優(yōu)先級。部分系統(tǒng)異常具有固定優(yōu)先級。ARM 給出了以下一張表:
- | 0 | - | 在復位時棧頂從向量表的第一個入口加載 |
Reset 復位 | 1 | -3(最高) | 在上電和熱復位(warm reset)時調(diào)用,在第一條指令上優(yōu)先級降到最低(線程模式),異步的 |
Non-maskable Interrupt 不可屏蔽中斷(NMI) | 2 | -2 | 不能被除復位之外的任何異常停止或占先。異步的。 |
Hard Fault 硬故障 | 3 | -1 | 由于優(yōu)先級的原因或可配置的故障處理被禁止而導致不能將故障激活時的所有類型故障,同步的 |
Memory Management 存儲器管理 | 4 | 可配置 | MPU 不匹配,包括違反訪問規(guī)范以及不匹配,是同步的,即使MPU 被禁止或不存在,也可以用它來支持默認的存儲器映射的XN 區(qū)域 |
Bus Fault 總線故障 | 5 | 可配置 | 預取指故障,存儲器故障,以及其它相關的地址/存儲故障,精確時是同步,不精確時時異步 |
Usage Fault 使用故障 | 6 | 可配置 | 使用故障,例如,執(zhí)行未定義的指令或嘗試不合法的狀態(tài)轉換,是同步的 |
- | 7~10 | - | 保留 |
SVCall 系統(tǒng)服務調(diào)用 | 11 | 可配置 | 利用 SVC 指令調(diào)用系統(tǒng)服務,是同步的 |
Debug Monitor 調(diào)試監(jiān)控 | 12 | 可配置 | 調(diào)試監(jiān)控,在處理器沒有停止時出現(xiàn),是同步的,但只有在使能時是有效的,如果它的優(yōu)先級比當前有效的異常的優(yōu)先級低,則不能被激活 |
- | 13 | - | 保留 |
PendSV 可掛起的系統(tǒng)服務請求 | 14 | 可配置 | 可掛起的系統(tǒng)服務請求,是異步的,只能由軟件來實現(xiàn)掛起 |
SysTick 系統(tǒng)節(jié)拍定時器 | 15 | 可配置 | 系統(tǒng)節(jié)拍定時器(System tick timer)已啟動,是異步的 |
External Interrupt 外部中斷 | 16 及以上 | 可配置 | 在內(nèi)核的外部產(chǎn)生(外部設備),INTISR[239:0],通過 NVIC(設置優(yōu)先級)輸入,都是異步的 |
類型 | 位置 | 優(yōu)先級 | 描述 |
---|
針對 Cortex-M 系列的內(nèi)核,ARM 提供了一套叫做 CMSIS 的東西。目前,所有的 MCU 均使用 CMSIS 作為編程基礎。在 CMSIS-Core 中,中斷標識有中斷枚舉實現(xiàn),從數(shù)值 0 開始(代表中斷 #0)。其中,系統(tǒng)異常的編號為負數(shù)。具體如下:
CMSIS-Core 之所以使用另外一種編號系統(tǒng),是因為這樣可以稍微提高部分 API 的效率。中斷的編號和枚舉定義是同設備相關的,他們位于微控制器供應商提供的頭文件中,在一個名為 IRQn 的 typedef 段中。
中斷處理(異常處理)
當某種內(nèi)部或外部事件發(fā)生時,MCU 的中斷系統(tǒng)將迫使 CPU 暫停正在執(zhí)行的程序,轉而去進行中斷事件的處理,中斷處理完畢后,又返回被中斷的程序處,繼續(xù)執(zhí)行下去。
主程序正在執(zhí)行,當遇到中斷請求(Interrupt Request)時,暫停主程序的執(zhí)行轉而去執(zhí)行中斷服務例程(Interrupt Service Routine,ISR),稱為響應,中斷服務例程執(zhí)行完畢后返回到主程序斷點處并繼續(xù)執(zhí)行主程序。多個中斷是可以進行嵌套的。正在執(zhí)行的較低優(yōu)先級中斷可以被較高優(yōu)先級的中斷所打斷,在執(zhí)行完高級中斷后返回到低級中斷里繼續(xù)執(zhí)行。
中斷管理
管理中斷所使用的大部分寄存器都位于 NVIC(Nested Vectored Interrupt Controller,嵌套向量中斷控制器)和 SCB(System Control Block,系統(tǒng)控制塊)中。實際上,SCB 是作為 NVIC 的一部分來實現(xiàn)的,不過在 CMSIS-Core 中,將其定義在了獨立的結構體中。除此之外,處理器內(nèi)核中還有用于中斷屏蔽寄存器:PRIMASK、FAULTMASK、BASEPRI。
NVIC 和 SCB 位于系統(tǒng)控制空間,地址從 0xE000E00 開始,大小 4KB。SCB 中還有 SysTick 定時器,存儲器保護單元等。
優(yōu)先級
這部分暫且不說!
中斷輸入和掛起
在 Cortex-M 內(nèi)核中,每個中斷都具有多個屬性:
每個中斷都可以被禁止(默認)或者使能
每個中斷都可以別掛起或者解除掛起
每個中斷都可以處于活躍或者非活躍
這些狀態(tài)屬性具有多種可能的組合。例如,在處理中斷時,可以將其禁止,若在中斷退出前產(chǎn)生了同一個中斷的新請求,由于該活躍中斷被禁止了,那就會處于掛起狀態(tài)。
NVIC 在設計上既支持產(chǎn)生 脈沖中斷請求 的外設,也支持產(chǎn)生 高電平中斷請求 的外設。無需配置任何一個 NVIC 寄存器以選擇其中一種中斷類型。對于脈沖中斷請求,脈沖寬度至少要為一個時鐘周期;而對于電平觸發(fā)的請求,在 ISR 中的操作清除請求之前,請求服務的外設要一直保持電平信號(如寫入寄存器以清除中斷請求) 。盡管外部中斷請求在 I/O 引腳上的電平可能是低電平有效,但是 NVIC 收到的請求信號為高有效!
中斷的掛起狀態(tài)被存儲在 NVIC 的可編程寄存器中,當 NVIC 的中斷輸入被確認后,它就會引發(fā)該中斷的掛狀態(tài)。即便中斷請求被取消,掛起狀態(tài)仍會為高。這樣,NVIC 就可以處理脈沖中斷請求了。
掛起狀態(tài)的意思是,中斷被置于一種等待處理器處理的狀態(tài)。有些情況下,處理器在中斷掛起時就會進行處理。不過,若處理器已經(jīng)在處理另外一個更高或同優(yōu)先級的中斷,或者中斷被某個中斷屏蔽寄存器給屏蔽掉了,那么在其他的中斷處理結束前或者中斷屏蔽被清除前,掛起請求會一直保持。
在傳統(tǒng) ARM 處理器中,如果外設產(chǎn)生了中斷,那么它們得到處理前必須一直保持中斷請求信號。
當中斷開始處理中斷請求時,中斷的請求信號會被自動清除。當中斷正在被處理時,它就會處于活躍狀態(tài)。
當中斷處于活躍狀態(tài)時,處理器無法再中斷完成和異常返回前再次處理同一個中斷請求。
中斷的掛起狀態(tài)位于中斷掛起狀態(tài)寄存器中,軟件可以復位這些寄存器。因此,可以手動清除或者設置中斷的掛起狀態(tài)。若中斷請求產(chǎn)生時處理器正在處理另一個具有更高優(yōu)先級的中斷,而在處理器對該中斷請求做出響應之前,掛起狀態(tài)被清除掉了,則該中斷會被取消且不會再得到處理。
若持續(xù)保持某個中斷請求,那么及時軟件嘗試清除該掛起狀態(tài),掛起狀態(tài)還是會再次被置位的。
若中斷已經(jīng)得到了處理,中斷源仍然在繼續(xù)保持中斷請求,那么這個中斷就會再一次進入掛起狀態(tài)且再次得到處理
對于脈沖中斷請求,若在處理器開始處理前,中斷請求信號產(chǎn)生了多次,他們會被當做一次中斷請求處理
中斷掛起狀態(tài)可以在其正在被處理時再次置位。之前的中斷請求正在被處理時產(chǎn)生了新的請求,這樣機會引發(fā)新的掛起狀態(tài)。處理器在前一個 ISR 結束后需要再次處理這個中斷。
即使中斷被禁止了,他的掛起狀態(tài)仍然可置位。 這種情況下,若中斷稍后被使能了,它仍然可以被觸發(fā)并被得到處理。這種情況可能不是我們需要的,因此需要在使能 NVIC 中斷前手動清除掛起狀態(tài)。
總結
NVIC 中對于每個中斷需要設置 搶占優(yōu)先級 和 響應優(yōu)先級(又稱子優(yōu)先級)。多個中斷會先比較 搶占優(yōu)先級,搶占優(yōu)先級相同的比較響應優(yōu)先級。高搶占優(yōu)先級能夠打斷低搶占優(yōu)先級的,但是相同搶占優(yōu)先級的高響應優(yōu)先級不能打斷低響應優(yōu)先級。
高優(yōu)先級的搶占優(yōu)先級是可以打斷正在進行的低搶占優(yōu)先級中斷的。
搶占優(yōu)先級相同的中斷,高響應優(yōu)先級不可以打斷低響應優(yōu)先級的中斷。
搶占優(yōu)先級相同的中斷,當兩個中斷同時發(fā)生的情況下,哪個響應優(yōu)先級高,哪個先執(zhí)行。
如果兩個中斷的搶占優(yōu)先級和響應優(yōu)先級都是一樣的話,則看哪個中斷先發(fā)生就先執(zhí)行。
審核編輯:湯梓紅
-
微控制器
+關注
關注
48文章
7454瀏覽量
150855 -
mcu
+關注
關注
146文章
16885瀏覽量
349926 -
STM32
+關注
關注
2264文章
10854瀏覽量
354299 -
中斷
+關注
關注
5文章
895瀏覽量
41349 -
Cortex-M
+關注
關注
2文章
227瀏覽量
29708
原文標題:參考
文章出處:【微信號:技術讓夢想更偉大,微信公眾號:技術讓夢想更偉大】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
評論