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