Cortex-M3的異常/中斷屏蔽寄存器組


轉自

1. Cortex-M3的異常/中斷屏蔽寄存器組

注:只有在特權級下,才允許訪問這3個寄存器。

 

 

 

名 字

功能描述

PRIMASK

只有單一比特的寄存器。置為1后,就關掉所有可屏蔽異常,只剩下NMI和硬Fault可以響應。默認值是0,表示沒有關閉中斷。

FAULTMASK

只有單一比特的寄存器。置為1后,只有NMI可以響應。默認值為0,表示沒有關異常。

 

BASEPRI

該寄存器最多有9位(由表達優先級的位數決定)。定義了被屏蔽優先級的閾值。當它被設置為某個值后,所有優先級號大於等於此值的中斷都被關。若設置成0,則不關斷任何中斷,0為默認值。

注:寄存器BASEPRI的有效位數受系統中表達優先級的位數影響,如果系統中只使用3個位來表達優先級,則BASEPRI有意義的值僅為0x00、0x20、0x40、0x60、0x80、0xA0、0xC0和0xE0

使用MRS/MSR指令訪問這三個寄存器,比如:

  MRS    R0, BASEPRI            ;讀取BASEPRI到R0中
  MSR    BASEPRI, R0            ;將R0數據寫入到BASEPRI中

為了快速的開關中斷,CM3還專門設置了一條CPS指令,有四種用法:

  CPSID    I    ;PRIMASK=1,關中斷
  CPSIE    I    ;PRIMASK=0,開中斷
  CPSID    F    ;FAULTMASK=1,關異常    
  CPSIE    F    ;FAULTMASK=0,開異常

CMSIS-M3微控制器軟件接口標准中的core_cm3.h給出了開關中斷或異常的函數:

1.1 開/關中斷

   1: /**
   2:  * @brief  Set the Priority Mask value
   3:  *
   4:  * @param  priMask  PriMask
   5:  *
   6:  * Set the priority mask bit in the priority mask register
   7:  */
   8: static __INLINE void __set_PRIMASK(uint32_t priMask)
   9: {
  10:   register uint32_t __regPriMask         __ASM("primask");
  11:   __regPriMask = (priMask);
  12: }

       使用__set_PRIMASK(1)關閉中斷;__setPRIMASK(0)開啟中斷。

       一些說明:__INLINE是宏定義,對應__inline,這是keil編譯器自定義關鍵字,表示這個函數是內聯函數,但並不是強制性內聯,編譯器最終決定是否內聯。

       __ASM(“primask”): __ASM也是一個宏,對應__asm,這是keil編譯器自定義關鍵字,關於這個關鍵字,有相當多的用法,可以在C中內嵌匯編語言、內嵌匯編函數、指定匯編標號以及本代碼中的聲明一個已命名寄存器變量。這里,已命名的寄存器是("primask"),也就是說寄存器變量__regPriMask等同於編譯器已命名的primask。語法為:

        register type var-name __asm(reg);

keil編譯器已命名的寄存器變量為:

 

 

 

寄存器

__asm修飾的字符串

處理器

APSR

"apsr"

All processors

CPSR

"cpsr"

All processors

BASEPRI

"basepri"

Cortex-M3, Cortex-M4

BASEPRI_MAX

"basepri_max"

Cortex-M3, Cortex-M4

CONTROL

"control"

Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4

DSP

"dsp"

Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4

EAPSR

"eapsr"

Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4

EPSR

"epsr"

Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4

FAULTMASK

"faultmask"

Cortex-M3, Cortex-M4

IAPSR

"iapsr"

Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4

IEPSR

"iepsr"

Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4

IPSR

"ipsr"

Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4

MSP

"msp"

Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4

PRIMASK

"primask"

Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4

PSP

"psp"

Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4

PSR

"psr"

Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4

r0 to r12

"r0" to "r12"

All processors

r14 or lr

"r14" or "lr"

All processors

r13 or sp

"r13" or "sp"

All processors

r15 or pc

"r15" or "pc"

All processors

SPSR

"spsr"

All processors, apart from Cortex-M series processors.

XPSR

"xpsr"

Cortex-M0, Cortex-M1, Cortex-M3, Cortex-M4

1.2 開/關異常

   1: /**
   2:  * @brief  Set the Fault Mask value
   3:  *
   4:  * @param  faultMask  faultMask value
   5:  *
   6:  * Set the fault mask register
   7:  */
   8: static __INLINE void __set_FAULTMASK(uint32_t faultMask)
   9: {
  10:   register uint32_t __regFaultMask       __ASM("faultmask");
  11:   __regFaultMask = (faultMask & 1);
  12: }

使用__set_FAULTMASK(1)來關閉中斷和異常;使用__set_FAULTMASK(0)開啟中斷和異常.

1.3 更精確的優先級屏蔽

   1: /**
   2:  * @brief  Set the Base Priority value
   3:  *
   4:  * @param  basePri  BasePriority
   5:  *
   6:  * Set the base priority register
   7:  */
   8: static __INLINE void __set_BASEPRI(uint32_t basePri)
   9: {
  10:   register uint32_t __regBasePri         __ASM("basepri");
  11:   __regBasePri = (basePri & 0xff);
  12: }

比如想屏蔽優先級不高於0x60的中斷,則使用代碼:__set_BASEPRI(0x60);如果想取消中斷屏蔽,則使用__set_BASEPRI(0)即可。

 

2.異常/中斷和優先級

       Cortex-M3的異常包括系統異常和外設中斷,系統異常是Cortex-M3內核自帶的一些異常,比如復位、總線Fault和SysTick等等(見表2-1),外設中斷是指制造CPU的廠家加入的,比如串口、定時器中斷等等(見表2-2)。

注:關於異常和中斷,想要分個清清楚楚實在有點困難。異常和中斷都可以“中斷”正常執行的代碼流,區別在於,異常是Cortex-M3內核產生的“中斷”信號,而中斷是Cortex-M3內核外部(片上外設或外部中斷信號)產生的“中斷”信號。希望你看懂了,有時候你心里明白,但要講的清清楚楚着實難!

表2-1:系統異常

 

 

 

編號

類型

優先級

簡介

0

N/A

N/A

1

復位

-3(最高)

復位

2

NMI

-2

不可屏蔽中斷(來自外部NMI輸入腳)

3

硬Fault

-1

只要FAULTMASK沒有置位,硬Fault服務例程會被強制執行

4

存儲器管理Fault

可編程

MPU訪問違例以及訪問非法位置均可引發。企圖在“非執行區”取址也會引發此Fault。

5

總線Fault

可編程

總線收到了錯誤響應,原因可以使預取流產或數據流產,企圖訪問協處理器也會引發此Fault

6

用法Fault

可編程

由於程序錯誤導致的異常。通常是使用了一條無效指令,或者是非法的狀態轉換,例如嘗試切換到ARM狀態

7~10

保留

保留

保留

11

SVCall

可編程

執行系統服務調用指令(SVC)引發的異常

12

調試監視器

可編程

調試器(斷點、數據觀察點,或者是外部調試請求)

13

保留

保留

保留

14

PendSV

可編程

為系統設備而設的“可掛起請求”

15

SysTick

可編程

系統節拍時鍾定時器(SysTick)

表2-2:外設中斷

編號 類型 優先級 簡介
16

IRQ #0

可編程

外設中斷#0

17

IRQ #1

可編程

外設中斷#1

...

...

可編程

...

255

IRQ #239

可編程

外設中斷#239

注:表2-1和2-2中的“編號”有着特殊的意義,一是特殊功能寄存器IPSR中會記錄當前正在服務的異常並給出了它的編號;二是優先級完全相同的多個異常同時掛起時,則先響應異常編號最小的那一個。

        一個發生的異常如果不能被立即響應,就稱它被“掛起”,值得一提的是,對於被掛起的中斷/異常,中斷/異常信號不必由其產生者保持,NVIC的掛起狀態寄存器會來保持這個信號。所以哪怕后來掛起的中斷源釋放了中斷請求信號,曾經的中斷請求也不會丟失。

        除了復位、NMI和硬Fault三個異常具有固定的優先級外,其它所有異常和中斷的優先級都是可以編程的。這就涉及到優先級配置寄存器。Cortex-M3優先級配置寄存器共8位,所以可以有256級的可編程優先級。但是大多數Cortex-M3芯片都會精簡設計。

        LPC177x/8x使用了優先級配置寄存器的5位,所以有32級可編程優先級。復位后,對於所有優先級可編程的異常,其優先級都被初始化為0(最高優先級)

2.1 設置異常/中斷的優先級

2.1.1 系統異常優先級設置

        SHPR1-SHPR3寄存器用於設置有可編程優先級的系統異常,可設置的優先級為0到31。SHPR1-SHPR3可按字節訪問。為了提高軟件效率,CMSIS簡化了SCB寄存器的表述。在CMSIS中,字節數組SHP[0] 到SHP[12]對應於寄存器SHPR1至SHPR3。

表2-3:SHPR1寄存器的位分配

名稱

功能

[31:24]

PRI_7

保留

[23:16]

PRI_6

系統處理程序6的優先級,用法Fault

[15:8]

PRI_5

系統處理程序5的優先級,總線Fault

[7:0]

PRI_4

系統處理程序4的優先級,存儲器管理Fault

表2-3:SHPR2寄存器的位分配

名稱

功能

[31:24]

PRI_11

系統處理程序11的優先級,SVCall

[23:0]

-

保留

表2-4:SHPR3寄存器的位分配

名稱

功能

[31:24]

PRI_15

系統處理程序15的優先級,SysTick 異常

[23:16]

PRI_14

系統處理程序14的優先級,PendSV

[15:0]

-

保留

注:每個PRI_N域為8位寬,但是處理器僅實現每個域的位[7:3],位[2:0]讀取值為零並忽略寫入值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM