Cortex-M0中斷控制和系統控制(四)


轉載:https://aijishu.com/a/1060000000245247

Cortex-M0系統控制塊(SCB)是內核外設的主要模塊之一,提供系統控制以及系統執行信息,包括配置,控制,上報系統異常等。

image1.png

為了提高軟件效率,CMSIS簡化了SCB寄存器表示,在CMSIS中系統控制寄存器結構體:

typedef struct 
{    __IM  uint32_t CPUID; /*!< Offset: 0x000 (R/ )  CPUID Base Register */
    __IOM uint32_t ICSR;  /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
    uint32_t RESERVED0;
    __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
    __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W)  System Control Register */
    __IOM uint32_t CCR; /*!< Offset:0x014 (R/W) Configuration Control Register */
    uint32_t RESERVED1;
    __IOM uint32_t SHP[2U];/*!< Offset: 0x01C (R/W)  System Handlers Priority Registers. [0] is RESERVED */
    __IOM uint32_t SHCSR;  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
} SCB_Type;

1. CPUID

CPUID基地址寄存器包含處理器型號、版本等相關信息,是只讀的,可以通過應用軟件、調試器和燒錄器等獲取處理器的類型和版本信息。

Address: 0xE000ED00
Reset value: 0x410CC200

image2.png

這個地方CPUID與我們經常提到的MCU的96位UID不同,CPUID是處理器的ID號,由Arm提供並實現,通過CPUID可以知道內核型號及版本等信息。而96位UID是MCU產品ID,屬於MM32,由上海靈動微電子股份有限公司提供並按照一定的規則實現,96位的產品唯一身份標識所提供的參考號碼對任意一個系列微控制器,在任何情況下都是唯一的。用戶在何種情況下,都不能修改這個身份標識。

MCU還有一個DEV\_ID編碼,這個ID定義了MCU的器件號和硅片版本號,它是DBG\_MCU的一個組成部分,並且映射到外部APB總線上。SW 調試口(2個引腳) 或通過用戶代碼都可以訪問此編碼。

DEV\_ID地址:0x40013400 只支持32位訪問,只讀。

image4.png

在CMSIS驅動庫中,可以直接使用“ SCB->CPUID ” 獲取處理器ID。讀取MM32F0130的CPUID、UID和DEV\_ID如下所示:

image0.png

CPUID (0x410CC200)解析處理器信息:

image3.png

2. ICSR (Interrupt Control and State Register)

提供:

  • NMI異常的設置掛起位
  • 為PendSV和SysTick異常設置掛起和清除掛起位

表示:

  • 正在處理的異常的異常編號
  • 是否有被搶占的活動異常
  • 最高優先級未決異常的異常編號
  • 是否有任何中斷待處理
Address: 0xE000ED04
Reset value: 0x0000 0000

image5.png

ICSR中的某些控制位僅供調試使用,大多數情況下,應用程序只會用ICSR來控制或者檢查系統異常掛起狀態。

PendSV(可掛起的系統調用)異常對 OS 操作非常重要,其優先級可以通過編程設置。可以通過將中斷控制和壯態寄存器 ICSR 的 bit28掛起位置1來觸發PendSV中斷。與SVC異常不同,它是不精確的,因此它的掛起狀態可在更高優先級異常處理內設置,且會在高優先級處理完成后執行。利用該特性,若將PendSV設置為最低的異常優先級,可以讓PendSV異常處理在所有其他中斷處理完成后執行,這對於上下文切換非常有用,也是各種OS設計中的關鍵。在具有嵌入式OS的典型系統中,處理時間被划分為了多個時間片。

通過向中斷控制和狀態寄存器 ICSR 的 bit28 寫入1掛起PendSV來啟動PendSV中斷,如果中斷啟用且有編寫 PendSV 異常服務函數的話,則內核會響應 PendSV 異常,去執行PendSV 異常服務函數,這樣就可以在PendSV中斷服務函數中進行任務切換了。

3. AIRCR (Application Interrupt and Reset Control Register)

AIRCR為數據訪問和系統的復位控制提供字節序狀態。

要寫入該寄存器,您必須寫入0x05FA VECTKEY 字段,否則處理器將忽略寫入。

Address: 0xE000ED0C
Reset value: 0xFA05 0000

image6.png

任何對該寄存器的寫操作,都必須將0x05FA寫入到AIRCR[30:16],否則寫操作將無效,若需要半字讀取,需要寫入0xFA05。

應用程序中系統執行軟復位函數:

__STATIC_INLINE void NVIC_SystemReset(void)
{    __DSB();  //確保所有未完成的內存訪問包括緩沖寫入在重置之前完成
    SCB->AIRCR  = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
                   SCB_AIRCR_SYSRESETREQ_Msk);
    __DSB();    //確保完成內存訪問

    for(;;) /* wait until reset */
    {   
        __NOP();
    }
}

4. SCR (System Control Register)

SCR 控制進入和退出低功耗狀態的特性。

Address: 0xE000ED10
Reset value: 0x0000 0000

image7.png

SCR(系統控制)寄存器可以選擇使用立即休眠還是退出時休眠,當SCR寄存器的SLEEPONEXIT位為0的時候使用立即休眠,當為 1 的時候使用退出時休眠。

MM32F0130執行進入stop模式實現函數:

void PWR_EnterSTOPMode(u32 regulator, u8 stop_entry)
{    PWR->CR |= regulator;

    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

    (stop_entry == PWR_STOPEntry_WFI) ? __WFI() : __WFE();
}


5. CCR (Configuration and Control Register)

CCR 是只讀寄存器,指示 Cortex-M0 處理器行為的某些方面。

Address: 0xE000ED14
Reset value: 0x0000 0204

image8.png

SCB->CCR寄存器控制除數為零和未對齊內存訪問是否觸發用法HardFault。

6. SHPR (System Handler Priority Registers)

因為在ARMv7-M架構上才有SHPR1,所以 Cortex – M0使用系統優先級寄存器只有SHPR2和SHPR3,而沒有SHPR1。

SHPR2-SHPR3 寄存器設置具有可配置優先級的異常處理程序的優先級級別,從0到192。

SHPR2-SHPR3 是可字訪問的。

要使用 CMSIS 訪問系統異常優先級,可以使用CMSIS函數:

uint32_t NVIC_GetPriority(IRQn_Type IRQn)
void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

系統故障處理程序,以及每個處理程序的優先級字段和寄存器是:

image9.png

6.1 SHPR2 (System Handler Priority Register 2)
Address: 0xE000ED1C
Reset value: 0x0000 0000

image10.png

6.2 SHPR3 (System Handler Priority Register 3)

如果您的設備未實現 SysTick 計時器,則此字段為保留字段

Address: 0xE000 ED20
Reset value: 0x0000 0000

image11.png

SVCall、PendSV和SysTick可編程的中斷多用於在操作系統之上的軟件開發中。SVC用於產生系統函數的調用請求,例如,操作系統不讓用戶程序直接訪問硬件,而是通過提供一些系統服務函數,用戶程序使用SVC發出對系統服務函數的呼叫請求,以這種方法調用它們來間接訪問硬件。因此,當用戶程序想要控制特定的硬件時,它就會產生一個SVC異常,然后操作系統提供的SVC異常服務例程得到執行,它再調用相關的操作系統函數,后者完成用戶程序請求的服務。

另一個相關的異常是 PendSV,它和 SVC 協同使用。一方面, SVC異常是必須立即得到響應的(若因優先級不比當前正處理的高, 或是其它原因使之無法立即響應, 將上訪成Hardfault),應用程序執行 SVC 時都是希望所需的請求立即得到響應。另一方面,PendSV則不同,它是可以像普通的中斷一樣被掛起的(不像SVC那樣會上訪)。OS可以利用它“延期執行”一個異常——直到其它重要的任務完成后才執行動作。掛起 PendSV 的方法是:程序中往NVIC的PendSV掛起寄存器中寫 1。掛起后, 如果優先級不夠高,則將延期等待執行。PendSV 的典型使用場合是在上下文切換時(在不同任務之間切換)。有兩個就緒的任務,上下文切換被觸發的場合可以是:

執行一個系統調用
系統滴答定時器(SysTick)中斷,(輪轉調度中需要)

ARMv7-M和ARMv6-M都有的SCB寄存器名稱相同,但是ARMv7-M寄存器數量和有效控制bit位比ARMv6-M豐富了不少。一般來說,ARMv6-M向上兼容ARMv7-M,這意味着應用層和系統為ARMv6-M開發的級別軟件無需修改即可在 ARMv7-M 上執行,這也是Arm從一個平台切換到另一個平台可以很快速的完成切換的原因,有興趣深入研究可以參考《ARMv6-M Architecture Reference Manual》白皮書。


免責聲明!

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



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