1、總開關
每個CPU有一個中斷總開關。通過CPU中斷控制寄存器實現。Cortex-M的中斷控制寄存器包括:FAULTMASK、PRIMASK、BASEPRI、BASEPRI_MAX。總開關的本質是變更當前執行優先級,根據Cortex-M的架構設計,只有優先級高於當前執行優先級的中斷或異常才能搶占CPU。
FAULTMASK
設置為1后關閉所有中斷和異常,包括HardFault異常,只有NMI和Reset可以得到響應。
PRIMASK
設置為1后關閉所有中斷和除了HardFault異常外的所有其他異常,只有NMI、Reset和HardFault可以得到響應。
BASEPRI
設置為n后,屏蔽所有優先級數值大於等於n的中斷和異常。Cortex-M的優先級數值越大其優先級越低。
BASEPRI_MAX
和BASEPRI類似,但有個限制,即后寫入的優先級數值要比當前的BASEPRI值小才會起作用,否則不起作用。影響范圍最廣,影響CPU內的所有中斷源。
事實上BASEPRI_MAX和BASSEPRI是操作同一個寄存器,不過BASEPRI_MAX是一個條件寫指令,可以通過下列等效功能代碼理解:
// atomic related functions for unittest. extern uint8_t atomic_BASEPRI; // 用來模擬 BASEPRI 的值 // BASEPRI 設置 static inline uint8_t __set_BASEPRI(uint8_t prio) { atomic_BASEPRI = prio; } // BASEPRI_MAX 設置 static inline uint8_t __set_BASEPRI_MAX(uint8_t prio) { if(prio && (atomic_BASEPRI == 0 || atomic_BASEPRI > prio)) { atomic_BASEPRI = prio; } }
疑問:線程模式下,當前優先級和中斷優先級的搶占優先級相同,但中斷的子優先級比當前子優先級高,會怎么樣?當前優先級也分搶占優先級和子優先級嗎?
2、分開關
Cortex-M包括一個嵌套向量中斷控制器NVIC,每個外設在NVIC中都有一個對應的位,用來控制該外設的中斷。
- 寫NVIC->ISER寄存器中外設對應位為1打開中斷。
- 寫NVIC->ICER寄存器中外設對應位為1關閉中斷。
分開關只影響特定外設的中斷。
3、源開關
外設通常有多個中斷源,如接收到數據、發送完成、接收超時等等。外設通常提供中斷使能寄存器控制哪些中斷源產生時要向上匯報(向分開關匯報)。源開關與特定的外設相關,不同的外設會有不同的中斷,有不同的中斷控制寄存器。有些外設本身有總開關,該總開關控制該外設的所有中斷。
源開關影響范圍最窄,僅影響外設的某一種中斷源。