主要參考:
startup_stm32f10x_hd.s, stm32f10x_exti.h, stm32f10x_exti.c,另外,這里說的外部中斷是相對於M3內核之外的,主要是外設中斷如:如I/O口相應的外接設備中斷,USART、Timer等其它本身固件中斷。
對於 cortex_m3 內核所支持的 240 個外部中斷,這里使用了“中斷通道”這個概念,因為盡管每個中斷對應一個外圍設備,但該外圍設備通常具備若干個可以引起中斷的中斷源或中斷事件。而該設備的所有的中斷都只能通過該指定的“中斷通道”向內核申請中斷。因此,關於中斷優先級的概念都是針對“中斷通道”的。當該中斷通道的優先級確定后,也就確定了該外圍設備的中斷優先級,並且該設備所能產生的所有類型的中斷,都享有相同的通道中斷優先級。至於該設備本身產生的多個中斷的執行順序,則取決於用戶的中斷服務程序。
STM32 可以支持的 68 個外部中斷通道,已經固定的分配給相應的外部設備。每個中斷通道都具備自己的中斷優先級控制字節 PRI_n(8 位,但在 STM32 中只使用 4 位,高 4 位有效) , 每 4 個通道的 8 位中斷優先級控制字 (PRI_n) 構成一個 32 位的優先級寄存器 (PriorityRegister) 。68 個通道的優先級控制字至少構成 17 個 32 位的優先級寄存器,它們是 NVIC寄存器中的一個重要部分(具體參考本組:嵌套的向量式中斷控制器(NVIC))。
比如:
如果在你的系統中使用了 TIME2(中斷通道 28)和 EXTI0(中斷通道 6)兩個中斷,而TIME2 中斷必須優先響應,而且當系統在執行 EXIT0 中斷服務時也必須打斷(搶先、嵌套) ,就必須設置 TIME2 的搶先優先級比 EXTI0 的搶先優先級要高(數目小) 。假定 EXTI0 為 2 號搶先優先級,那么 TIME2 就必須設置成 0 或 1 號搶先優先級。這些工作需要在 AIRC 中的PRIGROUP 設置完成,確定了整個系統所具有的優先級個數后,再分別對每個中斷通道(設備)進行設置。
這些中斷優先級的確定和嵌套規則,在ARM cortex_m3(STM32)有規定:
- 只能高搶先優先級的中斷可以打斷低搶先優先級的中斷服務,構成中斷嵌套。
- 當 2(n)個相同搶先優先級的中斷出現,它們之間不能構成中斷嵌套,但 STM32 首先響應子優先級高的中斷。
- 當 2(n)個相同搶先優先級和相同子優先級的中斷出現,STM32 首先響應中斷通道所對應的中斷向量地址低的那個中斷(當多個中斷出現后,則看它們的中斷向量地址:地址越低,中斷級別越高,STM32優先響應) 。
- 0 號搶先優先級的中斷,可以打斷任何中斷搶先優先級為非 0 號的中斷;1 號搶先優先級的中斷,可以打斷任何中斷搶先優先級為 2、3、4 號的中斷;……;構成中斷嵌套。
- 如果兩個中斷的搶先優先級相同,誰先出現,就先響應誰,不構成嵌套。如果一起出現(或掛在那里等待) ,就看它們 2 個誰的子優先級高了,如果子優先級也相同,就看它們的中斷向量位置了。
再比如:
上電 Reset 后,寄存器 AIRC 中 PRIGROUP[10:8]的值為 0(編號 0) ,因此此時系統使用 16 個搶先優先級,無子優先級。另外由於所有外部中斷通道的優先級控制字 PRI_n 也都是 0,所以根據上面的定義可以得出,此時 68 個外部中斷通道的搶先優先級都是 0 號,沒有子優先級的區分。 故此時不會發生任何的中斷嵌套行為, 誰也不能打斷當前正在執行的中斷服務。當多個中斷出現后,則看它們的中斷向量地址:地址越低,中斷級別越高,STM32優先響應(可在啟動文件里查找)。
PS: 此時內部中斷的搶先優先級也都是 0 號, 由於它們的中斷向量地址比外部中斷向量地址都低, 所以它們的優先級比外部中斷通道高, 但如果此時正在執行一個外部中斷服務,它們也必須排隊等待,只是可以插隊,當正在執行的中斷完成后,它們可以優先得到執行。