1、什么是ARM Cortex-M處理器
1.1、Cortex-M3和Cortex-M4處理器
Cortex-M3(2005年發(fā)布)和Cortex-M4(2010年發(fā)布)處理器是ARM公司設(shè)計的處理器。
Cortex-M3和Cortex-M4處理器使用32位架構(gòu),寄存器組中斷內(nèi)部寄存器、數(shù)據(jù)以及總線接口都是32位。Cortex-M處理器使用的指令集架構(gòu)(ISA)是Thumb ISA(是一種RISC(精簡指令集)),其基于Thumb-2技術(shù)并同時支持16位和32位指令。
主要有以下特點:
- 三級流水線:取指、譯碼、執(zhí)行。
- 哈佛總線架構(gòu),即具有統(tǒng)一的存儲器空間:指令和地址總線使用相同的地址空間。
- 32位尋址,支持4GB存儲器空間
- 有名為NVIC(嵌套向量中斷控制器)的中斷控制器,支持最多240個中斷請求和8-256個中斷優(yōu)先級。
- 支持多種OS特性,如節(jié)拍定時器(systick)、影子棧指針(雙棧指針:MSP/PSP)。
- 休眠模式和多種低功耗特性。
- 支持可選的MPU(存儲器保護(hù)單元),提供了存儲器的訪問權(quán)限控制。
- 支持兩個特定存儲區(qū)域的位段訪問
Cortex-M3和M4處理器提供了多種指令:
- 普通數(shù)據(jù)處理,包括硬件除法指令。
- 存儲器訪問指令,支持8位、16位、32位、64位數(shù)據(jù),以及其他可傳輸多個32位數(shù)據(jù)的指令。
- 位域處理指令。
- 乘累加(MAC)以及飽和指令。
- 用于跳轉(zhuǎn)、條件跳轉(zhuǎn)以及函數(shù)調(diào)用的指令
- 用于系統(tǒng)控制、支持OS等的指令。
另外,M4處理器還支持:
- 單指令多數(shù)據(jù)(SIMD)指令。
- 其他快速MAC和乘法指令。
- 飽和運算指令。
- 可選的單精度浮點指令。
1.2、Cortex-M處理器家族
Cortex-M3和Cortex-M4處理器基于ARMv7-M架構(gòu)。Cortex-M4處理器具有SIMD、快速MAC以及飽和指令,可以執(zhí)行一些數(shù)組信號處理程序。
Cortex-M0、Cortex-M0+和Cortex-M1基于ARMv6-M架構(gòu)。Cortex-M1是專門為FPGA應(yīng)用設(shè)計的。
Cortex-M33基于ARMv8-M架構(gòu)。添加了trustzone等安全組件。
1.3、處理器和微控制器的區(qū)別
在一個典型的微控制器設(shè)計中,處理器只會占芯片中的一小塊區(qū)域。其他部分為存儲器、時鐘生成(如PLL)和分配邏輯、系統(tǒng)總線以及外設(shè)等(I/O接口單元、通信接口、定時器、ADC、DAC等硬件單元)。微控制器供應(yīng)商(比如ST、TI、NXP)選擇Cortex-M處理器作為它們的CPU,添加上述的其他功能單元,最終成為一個微控制器。如下圖:
1.4、ARM處理器的發(fā)展
Cortex-M3處理器發(fā)布之前,ARM處理器已經(jīng)有了許多種,比如ARM7、ARM9、ARM11。它們支持兩套指令集:32位的ARM指令集和16位的Thumb指令集。
目前Cortex處理器系列包括三類:
- Cortex-A用于高性能的開發(fā)應(yīng)用平臺。
- Cortex-R用于需要實時性能的高端嵌入式系統(tǒng)。
- Cortex-M用于嵌入式微控制器系統(tǒng) 。
- Cortex-A :需要處理高端嵌入式系統(tǒng)(OS,如iOS、Android、Linux以及Windows)等復(fù)雜應(yīng)用的應(yīng)用處理器,需要強大的處理能力、支持存儲器管理單元(MMU)等虛擬存儲器系統(tǒng)、可選的增強Java支持和安全的程序運行環(huán)境。實際產(chǎn)品包括高端智能手機(jī)、平板電腦、電視以及服務(wù)器等。
- Cortex-R :實時、高性能的處理器,面向較高端的實時市場,其應(yīng)用包括硬盤控制器、移動通信的基帶控制器以及汽車系統(tǒng)。強大的處理能力和高可靠性非常關(guān)鍵,低中斷等待和確定性也非常重要。
- Cortex-M :面向微控制器和混合信號設(shè)計等小型應(yīng)用,注重低成本、低功耗、耗能效率和低中斷等。
1.5、Thumb ISA的架構(gòu)版本
2、軟件開發(fā)流程
3、技術(shù)綜述
3.1、Cortex-M3和M4處理器一般信息
3.1.1 處理器類型
Cortex-M3和M4為32位RISC(精簡指令集)處理器,其具有:
- 32位寄存器
- 32位內(nèi)部數(shù)據(jù)通路
- 32位總線接口
Cortex-M3和M4具有三級流水線,基于哈佛總線架構(gòu)(另一個是普林斯頓架構(gòu)),取指和數(shù)據(jù)訪問可以同時執(zhí)行。存儲器系統(tǒng)使用32位尋址,地址最大空間是4GB。存儲器空間包括程序代碼、數(shù)據(jù)、外設(shè)以及處理器內(nèi)部的調(diào)試支持部件。
Cortex-M刺激器基于一種加載—存儲架構(gòu)。比如要增加SRAM中存儲的數(shù)據(jù)值,處理器需要一條指令從SRAM中讀出數(shù)據(jù),將其放到處理器的寄存器中,然后使用第二條指令增加寄存器中的值,最后使用第三條指令將其寫回存儲器。
3.1.2 指令集
Cortex-M處理器使用的指令集為Thumb-2,它運行16位和32位指令的混合使用,以獲得更高的代碼密度和效率。
經(jīng)典的ARM處理器(比如ARM7)具有兩種操作狀態(tài):32位的ARM狀態(tài)和16位的Thumb狀態(tài)。在ARM狀態(tài),指令是32位的,內(nèi)核能夠以很高的性能執(zhí)行所有支持的指令;而對于Thumb狀態(tài),指令是16位的,可以得到很好地代碼密度,bugThumb指令不具有ARM指令所有功能,要完成特定的操作可能需要更多的指令。如下圖。對于經(jīng)典的ARM處理器,中斷處理會進(jìn)入ARM狀態(tài)。
隨著Thumb-2技術(shù)的引入,Thumb指令被擴(kuò)展為支持16位和32位兩種解碼方式,無需在兩個不同操作狀態(tài)切換就可以滿足所有的處理需求。
3.1.3 模塊框圖
3.1.4 存儲器系統(tǒng)
Cortex-M3和M4處理器本身不包含存儲器,它們具有通用的片上總線接口,供應(yīng)商可以將它們自己的存儲器系統(tǒng)添加到系統(tǒng)中。如下部件:
- 程序存儲器,一般是Flash
- 數(shù)據(jù)存儲器,一般是SRAM
- 外設(shè)
Cortex-M3和M4處理器主要使用的總線接口協(xié)議是AHB Lite(高級高性能總線),用于程序存儲器和系統(tǒng)總線接口。高級外設(shè)總線(APB)接口為處理器使用的另外一種總線協(xié)議。
3.1.5 中斷和異常支持
Cortex-M3和M4處理器中存在一個嵌套向量中斷控制器(NVIC)。它是可編程的且其寄存器經(jīng)過了存儲器映射。它的地址固定,編程模型對于所有的Cortex-M處理器都是一致的。
除了外設(shè)和其他外部輸入中斷,NVIC還支持多個系統(tǒng)異常,包括NMI(不可屏蔽中斷)等。供應(yīng)商決定實際支持的可編程中斷優(yōu)先級的數(shù)量。
4、架構(gòu)
4.1 編程模型
4.1.1 操作模式
圖4.1 操作狀態(tài)和模式
- 處理模式(Handler):執(zhí)行ISR等異常處理。此模式下,處理器總是具有特權(quán)訪問等級。
- 線程模式:在執(zhí)行普通的應(yīng)用程序代碼時,處理器可以處于特權(quán)訪問等級,也可處于非特權(quán)訪問等級。實際的訪問等級由特殊寄存器(CONTROL)控制。
軟件可以將處理器從特權(quán)線程模式切換到非特權(quán)線程模式,但無法將自身從非特權(quán)切換到特權(quán)模式,必須要借助異常機(jī)制才可以。
區(qū)分特權(quán)和非特權(quán)訪問等級,設(shè)計人員可以提供對關(guān)鍵區(qū)域訪問的保護(hù)機(jī)制及基本的安全模型,這樣有助于開發(fā)健壯的嵌入式系統(tǒng)。例如,系統(tǒng)中可能包含運行在特權(quán)訪問等級的OS內(nèi)核,以及運行在非特權(quán)訪問等級的應(yīng)用程序。還可以通過MPU設(shè)置存儲器訪問權(quán)限避免應(yīng)用任務(wù)破壞OS內(nèi)核以及其他任務(wù)使用的存儲器和外設(shè)。若應(yīng)用任務(wù)崩潰,剩下的任務(wù)和OS內(nèi)核可以繼續(xù)運行。
幾乎所有的NVIC寄存器支持特權(quán)訪問。
4.1.2 寄存器
寄存器組有16個寄存器,其中13個位32位通用目的寄存器,其他3個有特殊用途,如圖:
圖4.2 寄存器組中的寄存器
- R0 - R12
前8個(R0 - R7)是低寄存器。許多16位指令只能訪問低寄存器。高寄存器(R8 - R12)可以用于32位指令和幾個16位指令。R0 - R12初始值未定義。 - R13(SP)
R13為棧指針,可通過PUSH和POP指令實現(xiàn)棧存儲的訪問。存在2個棧指針:主棧指針(MSP)為默認(rèn)的棧指針,在復(fù)位或處理器在處理模式時使用;另一個為進(jìn)程棧指針(PSP),只能用于線程模式。棧指針的選擇由特殊寄存器(CONTROL)決定。MSP和PSP都是32位的,不過棧指針的最低兩位總是0。PUSH和POP總是32位的,32位字對齊。 - R14(LR)
R14配稱為鏈接寄存器,用于函數(shù)或子程序調(diào)用時返回地址的保存。在異常處理器件,LR會自動更新為特殊的EXC_RETURN(異常返回)數(shù)值,該值會在異常處理結(jié)束時觸發(fā)異常返回。有些跳轉(zhuǎn)/調(diào)用操作需要將LR(或正使用的任何寄存器)的第0位置1表示Thumb狀態(tài)。 - R15(PC)
R15是程序計數(shù)器。
4.1.3 特殊寄存器
除了寄存器組中的寄存器外,處理器還存在多個特殊寄存器,如下圖:
圖4.3 特殊功能寄存器
特殊寄存器未經(jīng)過存儲器映射,可以使用MSR和MRS等特殊寄存器訪問指令訪問。
MRS < reg >, < special_reg > ; 將特殊寄存器讀入寄存器
MSR < special_reg >, < reg > ; 寫入特殊寄存器
- 程序狀態(tài)寄存器
程序狀態(tài)寄存器包括以下三個狀態(tài)寄存器:
- 應(yīng)用PSR(APSR)
- 執(zhí)行PSR(EPSR)
- 中斷PSR(IPSR)
圖4.4 APSR、IPSR和EPSR
- PRIMASK、FAULTMASK和BASEPRI寄存器
PRIMASK、FAULTMASK和BASEPRI寄存器都用于異?;蛑袛嗥帘危總€異常都具有一個優(yōu)先級,數(shù)值小的優(yōu)先級高。這些特殊寄存器可基于優(yōu)先級屏蔽異常,只有在特權(quán)訪問等級才可對其訪問。這些寄存器編程模型如下:
圖4.5 PRIMASK、FAULTMASK和PRIMASK寄存器
- PRIMASK置位時,會阻止NMI和HardFault異常之外的所有異常。最常見用途是在時間要求很嚴(yán)格的進(jìn)程中禁止所有中斷,在該進(jìn)程完成后,需要將其清除重新使能中斷。
- FAULTMASK和PRIMASK非常類似,不過它還能屏蔽HardFault異常。錯誤處理代碼可以使用FAULTMASK以免在錯誤處理期間引發(fā)其他錯誤。FAULTMASK在異常返回自動清除。
- BASEPRI會根據(jù)優(yōu)先級屏蔽中斷。它的寬度取決于實際芯片實現(xiàn)的優(yōu)先級數(shù)量,大多數(shù)有8個或16個可編程優(yōu)先級,對應(yīng)的寬度為3位或4位。BASEPRI為0時不起作用,非0時,會屏蔽具有相同或更低優(yōu)先級的異常。
CMSIS-Core提供了多個C函數(shù)可以訪問它們。
x = _get_BASEPRI(); // 讀BASEPRI寄存器
x = _get_PRIMASK(); // 讀PRIMASK寄存器
x = _get_FAULTMASK(); // 讀FAULTMASK寄存器
_set_BASEPRI(x); // 設(shè)置BASEPRI寄存器的新值
_set_PRIMASK(x); // 設(shè)置PRIMASK寄存器的新值
_set_FAULTMASK(x); // 設(shè)置FAULTMASK寄存器的新值
_disable_irq(); // 設(shè)置PRIMASK,禁止IRQ
_ensable_irq(); // 清除PRIMASK,使能IRQ
還可以用匯編代碼訪問這些異常屏蔽寄存器:
MRS r0, BASEPRI; 將BASEPRI寄存器讀入 R0
MRS r0, PRIMASK; 將PRIMASK寄存器讀入 R0
MRS r0, FAULTMASK; 將FAULTMASK寄存器讀入 R0
MRS BASEPRI, r0 ; 將R0 寫入 BASEPRI寄存器
MRS PRIMASK, r0 ; 將R0 寫入 PRIMASK寄存器
MRS FAULTMASK, r0 ; 將R0 寫入 FAULTMASK寄存器
另外,還可以利用修改處理器狀態(tài)(CPS)指令:
CPSIE i ;使能中斷(清除PRIMASK)
CPSID i ;禁止中斷(設(shè)置PRIMASK)
CPSIE f ;使能中斷(清除FAULTMASK)
CPSID f ;禁止中斷(設(shè)置FAULTMASK)
- CONTROL寄存器
CONTROL寄存器(如下圖)定義了:
- 棧指針的選擇(MSP/PSP)
- 線程模式的訪問等級(特權(quán)/非特權(quán))
CONTROL寄存器只能在特權(quán)訪問等級修改,讀操作在特權(quán)和非特權(quán)都可以。
圖4.6 Cortex-M3、Cortex-M4和具有FPU的Cortex-M4中的CONTROL寄存器
表4.1 CONTROL寄存器中的位域
復(fù)位后,CONTROL寄存器默認(rèn)為0,意味著此時處理器處于特權(quán)訪問權(quán)限的線程模式并使用MSP。通過寫CONTROL寄存器,特權(quán)線程模式的程序可以切換棧指針或進(jìn)入非特權(quán)訪問等級。不過nPRIV置位后,運行在線程模式的程序不能訪問CONTROL寄存器了。即運行在非特權(quán)等級的程序無法切換回特權(quán)等級,這就提供了一個基本的安全模型;若有必要將處理器在線程模式切換回特權(quán)等級,則需要異常機(jī)制。在異常處理期間清除nPRIV位,回到線程模式后,處理器就會進(jìn)入特權(quán)等級。
圖4.7 棧指針選擇
圖4.8 特權(quán)線程模式和非特權(quán)線程模式間的切換
4.1.4 浮點寄存器
Cortex-M4有可選的浮點單元,提供了浮點數(shù)據(jù)處理用的一些寄存器以及浮點狀態(tài)和控制寄存器(FPSCR)
- S0 - S31和D0 - D15
- 浮點狀態(tài)和控制寄存器(FPSCR)
4.2 存儲器系統(tǒng)
4.2.1 存儲器映射
Cortex-M處理器的4GB地址空間被劃分了多個存儲器區(qū)域,如下圖。區(qū)域根據(jù)各自用法劃分,主要用于:
- 程序代碼訪問(如CODE區(qū)域)
- 數(shù)據(jù)訪問(如SRAM區(qū)域)
- 外設(shè)(如外設(shè)區(qū)域)
- 處理器的內(nèi)部控制和調(diào)試部件(如私有外設(shè)總線)
架構(gòu)的這種安排具有很大的靈活性,存儲器區(qū)域可用于其他目的。例如,程序即可以在CODE區(qū)域執(zhí)行,也可以在SRAM區(qū)域執(zhí)行,而且微控制器也可以在CODE區(qū)域加入SRAM。
圖4.9 存儲器映射
4.2.2 棧存儲
在棧這種存儲器機(jī)制中,存儲器的一部分可被用作后進(jìn)先出的數(shù)據(jù)存儲緩沖。ARM處理器將系統(tǒng)主存儲器用于??臻g操作,使用PUSH和POP。每次PUSH和POP操作后,棧指針會自動調(diào)整。
棧可用于:
- 當(dāng)正在執(zhí)行的函數(shù)需要使用寄存器進(jìn)行數(shù)據(jù)處理時,臨時存儲數(shù)據(jù)的初始值。這些數(shù)據(jù)在函數(shù)結(jié)束時可恢復(fù)回去
- 往函數(shù)或子程序傳遞信息,即函數(shù)調(diào)用的參數(shù)傳遞
- 用于存儲局部變量
- 在中斷等異常產(chǎn)生時保存處理器狀態(tài)和寄存器數(shù)值
Cortex-M處理器使用的棧模型是“滿遞減”。處理器啟動后,SP被設(shè)置為棧存儲空間最后的位置。每次PUSH操作,處理器先減小SP的值,然后將數(shù)據(jù)存儲在SP指向的存儲器位置。對于POP操作,SP指向的存儲器位置數(shù)據(jù)被讀出,然后SP的值自動減小。
PUSH和POP指令最常見的用法是,在執(zhí)行函數(shù)調(diào)用時保存寄存器組中的內(nèi)容,函數(shù)調(diào)用結(jié)束時通過POP恢復(fù)它們的值。
圖4.10 棧的PUSH和POP
若嵌入式系統(tǒng)中包含OS,通常會將應(yīng)用任務(wù)和內(nèi)核所用的??臻g分離開來,因此PSP會被用到,在異常入口和出口時會發(fā)生SP切換,如下圖。
圖4.11 SPSEL=1,線程等級使用進(jìn)程棧而異常處理使用主棧
盡管同一時間內(nèi)只有一個SP可見,如果當(dāng)前處于特權(quán)等級,可以用PSR和MRS指令訪問隱藏的SP。
4.3 異常和中斷
4.3.1 什么是異常
Cortex-M處理器有多個異常源,如圖:
圖4.12 各種異常源
- NVIC處理異常 。NVIC可以處理多個中斷請求(IRQ)和一個不可屏蔽中斷(NMI)請求,IRQ一般由片上外設(shè)或外部中斷輸入通過I/O端口產(chǎn)生,NMI可用于看門狗或掉電檢測。處理器內(nèi)部有個名為SysTick的定時器,可以產(chǎn)生周期性的定時中斷請求,可用于OS計時。
- 處理器自身也是一個異常事件源,包括表示系統(tǒng)錯誤狀態(tài)的錯誤事件以及軟件產(chǎn)生、支持OS操作的異常。異常類型如下表:
表4.2 異常類型
每個異常源都有一個異常編號,編號1-15為系統(tǒng)異常,16及其之上的則用于中斷。Cortex-M4和M4在設(shè)計上最多240個中斷輸入,不過實際實現(xiàn)的中斷數(shù)量要小得多,一般在16-100之間。
4.3.2 NVIC
NVIC處理異常和中斷配置、優(yōu)先級以及中斷屏蔽。NVIC具有以下特性:
- 靈活的異常和中斷管理
- 支持嵌套異常/中斷
- 向量化的異常/中斷入口
- 中斷屏蔽
4.3.3 向量表
當(dāng)異常事件產(chǎn)生且被處理器內(nèi)核接受后,相應(yīng)的異常處理就會執(zhí)行。向量表是可以重定位的,由NVIC中的名為向量表偏移寄存器(VTOR)控制。復(fù)位后默認(rèn)為0,向量表則位于地址0x0處。
圖4.13 異常類型(異常向量的最低位應(yīng)該置1,表示Thumb狀態(tài))
4.3.4 錯誤處理
Cortex-M3和M4處理器中有幾個異常為錯誤處理異常。處理器檢測到錯誤時,觸發(fā)錯誤異常,錯誤包括執(zhí)行未定義的指令以及總線錯誤、對存儲器訪問返回錯誤等。
圖4.14 錯誤異常的使用
總線錯誤、使用錯誤以及存儲器管理錯誤默認(rèn)是禁止的,且所有的錯誤事件都會觸發(fā)HardFault異常(總是使能)。但這些配置是可編程的。
4.4 復(fù)位和復(fù)位流程
對于典型的Cortex-M處理器,復(fù)位類型由三種:
- 上電復(fù)位。復(fù)位微控制器的所有部分,包括處理器、調(diào)試支持部件和外設(shè)等。
- 系統(tǒng)復(fù)位。只會復(fù)位處理器和外設(shè),不包括調(diào)試支持部件。
- 處理器復(fù)位。只復(fù)位處理器
在復(fù)位后以及處理器開始執(zhí)行程序之前,Cortex-M處理器會從存儲器中讀出頭兩個字,如下圖。向量表位于存儲器的開頭部分,它的頭兩個字為MSP的初始值和代表復(fù)位除了起始地址的復(fù)位向量。處理器讀出這兩個字會將其賦值給MSP和PC。
MSP的設(shè)置非常必要。因為在復(fù)位的很多時間內(nèi)有產(chǎn)生NMI或HardFault的可能,在異常處理前將處理器狀態(tài)壓棧時需要棧存儲和MSP。
圖4.15 復(fù)位流程
圖4.16 棧指針初始值和程序計數(shù)器初始值示例
5 存儲器系統(tǒng)
5.1 存儲器映射
圖5.1 Cortex-M3和Cortex-M4處理器預(yù)定義的存儲器映射(陰影部分的部件用于調(diào)試)
5.2 連接處理器到存儲器和外設(shè)
圖5.2 不同存儲區(qū)域的多個總線接口
圖5.3 基于Cortex-M3或Cortex-M4的簡單系統(tǒng)
圖5.4 STM32F4的Flash訪問加速器示意圖
圖5.5 多層AHB示例(NXP LPC1700)
5.3 位段操作
圖5.6 通過位段別名對位段區(qū)域進(jìn)行位訪問(SRAM區(qū)域)
5.4 存儲器屏障
存儲器屏障指令I(lǐng)SB、DSB、DMB
5.5 微控制器中的存儲器系統(tǒng)
許多微控制器設(shè)備,設(shè)計中還集成了其他存儲器系統(tǒng)特性。例如:
- BootLoader
- 存儲器重映射
- 存儲器別名
圖5.7 具有可配置存儲器映射的簡單存儲器系統(tǒng)
圖5.8 具有bootloader的系統(tǒng)的存儲器重映射示例
6 異常和中斷
6.1 異常和中斷簡介
典型的Cortex-M4微控制器中,NVIC接收多個中斷源產(chǎn)生的中斷請求,如圖
圖6.1 典型微控制器中的各種異常源
Cortex-M3和Cortex-M4的NVIC最多支持240個IRQ、1個NMI、1個SysTick及多個系統(tǒng)異常。多數(shù)中斷由定時器、I/O端口和通信接口(UART、I2C)等外設(shè)產(chǎn)生。中斷還可利用軟件生成。
為了繼續(xù)執(zhí)行被中斷的程序,異常流程需要利用一些手段保護(hù)被中斷程序的狀態(tài),這樣在異常處理完成后還可以恢復(fù)。一般這個過程可以由硬件機(jī)制實現(xiàn),也可以由硬件和軟件操作共同完成。對于Cortex-M4處理器,當(dāng)異常被接受后,有些寄存器被字段保存到棧中,返回時自動恢復(fù)。
6.2 異常類型
編號1-15的為系統(tǒng)異常,16及以上為中斷輸入。包括中斷在內(nèi)的多數(shù)異常,具有可編程的優(yōu)先級,一些系統(tǒng)異常則有固定的優(yōu)先級。
不同的Cortex-M4微控制器的中斷源編號(1-240)可能會不同,優(yōu)先級也可能有差異。
異常類型1-15為系統(tǒng)異常,如表7.1。類型16及以上為外部中斷輸入,如表7.2。
表6.1 系統(tǒng)異常列表
表6.2 中斷列表
CMSIS-Core定義了系統(tǒng)異常處理的名稱
表6.3 CMSIS-Core異常定義
優(yōu)先級的優(yōu)先級配置寄存器可被分為兩部分。上半部分(左邊的位)為搶占優(yōu)先級,下半部分(右邊的位)為子優(yōu)先級,如下
表6.4 常用的基本中斷控制CMSIS-Core函數(shù)
6.4 優(yōu)先級定義
圖6.2 3位優(yōu)先級寄存器(8個可編程優(yōu)先級)
圖6.3 4位優(yōu)先級寄存器(16個可編程優(yōu)先級)
8位寄存器被分為兩個部分:搶占優(yōu)先級和子優(yōu)先級。利用系統(tǒng)控制塊(SCB)中的一個名為優(yōu)先級分組的配置寄存器,每個具有可編程優(yōu)先級的優(yōu)先級配置寄存器可被分為兩部分。上半部分(左邊的位)為搶占優(yōu)先級,下半部分(右邊的位)為子優(yōu)先級,如下
表6.5 不同優(yōu)先級分組下優(yōu)先級寄存器中的搶占優(yōu)先級和子優(yōu)先級域定義
圖6.4 3位優(yōu)先級寄存器中優(yōu)先級分組為5時的域定義
圖6.5 3位優(yōu)先級寄存器中優(yōu)先級分組為1時的域定義
圖6.6 8位優(yōu)先級寄存器中優(yōu)先級分組為0時的域定義
6.5 向量表和向量表重定位
當(dāng)Cortex-M處理器接受某異常請求后,處理器要確定該異常處理的起始地址。該信息位于存儲器內(nèi)的向量表中,默認(rèn)從地址0開始,向量地址則為異常編號乘4,如圖
圖6.7 向量表
7 深入了解異常處理
7.1 C實現(xiàn)的異常處理
對于Cortex-M處理器,可以將異常處理或ISR實現(xiàn)為普通的C函數(shù)。為了詳細(xì)了解這種機(jī)制,看一下C函數(shù)在ARM架構(gòu)上如何工作。
用于ARM架構(gòu)的C編譯器遵循ARM的一個名為AAPCS(ARM架構(gòu)過程調(diào)用標(biāo)準(zhǔn))的規(guī)范。根據(jù)這份標(biāo)準(zhǔn),C函數(shù)可以修改R0-R3、R12、R14以及PSR。若C函數(shù)需要調(diào)用R4-R11,應(yīng)該將這些寄存器保存到棧中,且在函數(shù)結(jié)束前將他們恢復(fù),如圖。
R0-R3、R12、R14以及PSR被稱為“調(diào)用者保存寄存器”。R4-R11被稱為“被調(diào)用者保存寄存器”,被調(diào)用的子程序或函數(shù)需要確保這些寄存器在函數(shù)結(jié)束時不會發(fā)送變化。這些寄存器的值可能會在函數(shù)執(zhí)行過程中變化,不過需要在函數(shù)退出前將他們恢復(fù)。一般,函數(shù)調(diào)用R0-R3作為輸入?yún)?shù),R0用作返回結(jié)果。若返回值是64位,則R1也會用于返回結(jié)果。
圖7.1 AAPCS規(guī)定的函數(shù)調(diào)用中的寄存器使用
要使C函數(shù)可以用作異常處理,異常機(jī)制需要在異常入口處自動保存R0-R3、R12、R14以及PSR,并在異常退出時將他們恢復(fù),這些要由刺激器硬件控制。
圖7.2 在不需要或禁止雙字棧對齊時,Cortex-M3或Cortex-M4(無浮點)處理器的異常棧幀
7.1.1 EXC_RETURN
處理器進(jìn)入異常處理或ISR時,LR的值會被更新為EXC_RETURN的值。當(dāng)利用BX、POP或存儲器加載指令(LDR或LDM)被加載到PC中時,該數(shù)值用于觸發(fā)異常返回機(jī)制。
表7.1 EXC_RETURN的位域
表7.2 EXC_RETURN的合法值
7.2 異常流程
7.2.1 異常進(jìn)入和壓棧
圖7.3 壓棧和取向量
圖7.4 Cortex-M3處理器的AHB Lite總線上的壓棧流程
圖7.5 使用主棧的線程模式的異常棧幀
圖7.6 使用進(jìn)程棧的線程模式的異常棧幀,以及使用主棧的嵌套中斷壓棧
7.2.2 異常返回和出棧
圖7.7 LR在異常時被設(shè)置為EXC_RETURN(線程模式使用主棧)
圖7.8 LR在異常時被設(shè)置為EXC_RETURN(線程模式使用進(jìn)程棧)
圖7.9 出棧操作
7.3 中斷等待和異常處理優(yōu)化
7.3.1 什么是中斷等待
7.3.2 末尾連鎖
若某個異常產(chǎn)生時處理器正在處理另一個具有相同或更高優(yōu)先級的異常,該異常會進(jìn)入掛起狀態(tài)。在處理器執(zhí)行完當(dāng)前的異常處理后,它可以繼續(xù)執(zhí)行掛起的異常/中斷請求。處理器不會從棧中恢復(fù)寄存器(出棧)然后在將它們存入棧中(壓棧),而是跳過出棧和壓棧過程并盡快進(jìn)入掛起異常的中斷處理,如圖。對于無狀態(tài)等待的存儲器系統(tǒng),末尾連鎖的中斷等待時間僅為6個時鐘周期。
圖7.10 末尾連鎖
7.3.3 延遲到達(dá)
當(dāng)異常產(chǎn)生時,處理器會接受異常請求并開始壓棧操作。若壓棧期間產(chǎn)生了另外一個更高優(yōu)先級的異常,則更高優(yōu)先級的后到異常會先得到服務(wù)。
圖7.11 延遲到達(dá)異常行為
7.3.4 出棧搶占
若某個異常請求在另外一個剛完成的異常處理出棧期間產(chǎn)生,則處理器會舍棄出棧操作且開始取向量以及下一個異常服務(wù)的命令。該優(yōu)化成為出棧搶占。
圖7.12 出棧搶占行為
7.3.5 惰性壓棧
惰性壓棧是和浮點單元寄存器壓棧相關(guān)的一種特性。
8 OS支持特性
8.1 影子棧指針
圖8.1 每個任務(wù)的棧和其他的相獨立
8.2 SVC異常
圖8.2 上下文切換簡圖
圖8.3 SVC可作為OS系統(tǒng)服務(wù)的入口
圖8.4 利用匯編語言提取SVC服務(wù)編號
8.3 PendSV異常
圖8.5 PendSV上下文切換示例
- 第一部分對時間要求比較高,需要快速執(zhí)行,切優(yōu)先級較高。它位域普通的ISR內(nèi),在ISR結(jié)束時,PendSV的掛起狀態(tài)
- 第二部分包括中斷服務(wù)所需的剩余處理工作,它位于PendSV處理內(nèi)切具有較低的異常優(yōu)先級。
圖8.6 利用PendSV將中斷服務(wù)分為兩部分
8.4 實際的上下文切換
圖8.7 上下文切換
圖8.8 ucos-iii中的任務(wù)切換示例
評論
查看更多