CORTEX-M4知識(shí)點(diǎn)總結(jié)

上傳人:jun****875 文檔編號(hào):17745715 上傳時(shí)間:2020-12-04 格式:DOC 頁(yè)數(shù):41 大小:2.76MB
收藏 版權(quán)申訴 舉報(bào) 下載
CORTEX-M4知識(shí)點(diǎn)總結(jié)_第1頁(yè)
第1頁(yè) / 共41頁(yè)
CORTEX-M4知識(shí)點(diǎn)總結(jié)_第2頁(yè)
第2頁(yè) / 共41頁(yè)
CORTEX-M4知識(shí)點(diǎn)總結(jié)_第3頁(yè)
第3頁(yè) / 共41頁(yè)

下載文檔到電腦,查找使用更方便

9.9 積分

下載資源

還剩頁(yè)未讀,繼續(xù)閱讀

資源描述:

《CORTEX-M4知識(shí)點(diǎn)總結(jié)》由會(huì)員分享,可在線閱讀,更多相關(guān)《CORTEX-M4知識(shí)點(diǎn)總結(jié)(41頁(yè)珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。

1、 Cortex-M4內(nèi)核知識(shí)點(diǎn)總結(jié) 余 明 目錄 Cortex-M4內(nèi)核知識(shí)點(diǎn)總結(jié) 1 1 ARM處理器簡(jiǎn)介 4 2 架構(gòu) 5 2.1架構(gòu)簡(jiǎn)介 5 2.2編程模型 5 2.3存儲(chǔ)器系統(tǒng) 8 2.4復(fù)位和復(fù)位流程 11 3 指令集 13 3.1 CM4指令集特點(diǎn) 13 3.2 Cortex-M處理器間的指令集比較 13 3.3 匯編指令簡(jiǎn)要介紹 13 3.3.1 處理器內(nèi)傳送數(shù)據(jù) 13 3.3.2 存儲(chǔ)器訪問(wèn)指令 14 3.3.3 算數(shù)運(yùn)算 15 3.3.4 邏輯運(yùn)算 16 3.3.5 移位 16 3.3.6 異常相關(guān)指令 1

2、6 4 存儲(chǔ)器系統(tǒng) 17 4.1 存儲(chǔ)器外設(shè) 17 4.2 Bootloader 17 4.3位段操作 18 4.4 存儲(chǔ)器大小端 18 5 異常和中斷 20 5.1 中斷簡(jiǎn)介 20 5.2異常類型 20 5.3 中斷管理 21 5.4 異?;蛑袛嗥帘渭拇嫫?22 5.4.1 PRIMASK 22 5.4.2 FAULMASK (M0中無(wú)) 22 5.4.3 BASEPRI(M0中無(wú)) 22 5.5 中斷狀態(tài)及中斷行為 22 5.5.1 中斷狀態(tài) 22 5.5.2 中斷行為 23 5.6 各Cortex-M處理器NVIC差異 25 6 異常處理 27 6.

3、1 C實(shí)現(xiàn)的異常處理 27 6.2 棧幀 27 6.3 EXC_RETURN 28 6.4異常流程 29 6.4.1 異常進(jìn)入和壓棧 29 6.4.2 異常返回和出棧 30 7 低功耗和系統(tǒng)控制特性 31 7.1 低功耗模式 31 7.1 SysTick定時(shí)器 31 8 OS支持特性 33 8.1 OS支持特性簡(jiǎn)介 33 8.2 SVC和PendSV 33 8.3 實(shí)際的上下文切換 34 1 ARM處理器簡(jiǎn)介 ARM處理器的種類很多,從手機(jī)上的高端處理器芯片到面向微控制器的芯片,都有ARM的身影。2011年基于ARM處理器的芯片的出貨量已經(jīng)到達(dá)79億。這一

4、章首先對(duì)ARM處理器有個(gè)簡(jiǎn)單的了解。 在早期的時(shí)候,ARM處理器使用后綴表明特性。例如ARM7TDMI,T表示支持Thumb指令,D表示JTAG,M表示快速乘法器,I則表示嵌入式ICE模塊。 近幾年,ARM改變處理器的命名方式,統(tǒng)一使用了Cortex處理器的名稱。Cortex處理器下分為三類: Cortex-A系列:需要處理高端嵌入式系統(tǒng)等復(fù)雜應(yīng)用的應(yīng)用處理器 Cortex-R系列:實(shí)時(shí)、高性能的處理器,面向較高端的實(shí)時(shí)市場(chǎng) Cortex-M系列:面向微控制器和混合信號(hào)設(shè)計(jì)等小型應(yīng)用,注重低成本、低功耗。 不同系列的處理器使用不同版本的架構(gòu) Cortex-A系列 ARMv

5、7-A架構(gòu) Cortex-R系列 ARMv7-R架構(gòu) Cortex-M系列 ARMv7-M、ARMv6-M 在Cortex-M系列中,進(jìn)一步都處理器進(jìn)行了劃分 處理器 功能 架構(gòu) Cortex-M0、Cortex-M0+ 低功耗 ARMv6-M Cortex-M1 FPGA ARMv6-M Cortex-M3 微控制器 ARMv7-M Cortex-M4 增加DSP ARMv7E-M 2 架構(gòu) 2.1架構(gòu)簡(jiǎn)介 Cortex-M3和Cortex-M4處理器都是基于ARMv7-M架構(gòu)。最初ARMv-7M架構(gòu)是隨著Cortex-M3處理器一同引進(jìn)

6、的,而在Cortex-M4發(fā)布時(shí),架構(gòu)中又額外增加了新的指令和特性,改進(jìn)后的架構(gòu)有時(shí)也被稱為ARMv7E-M。 2.2編程模型 2.2.1操作模式和狀態(tài) Cortex-M4處理器包括兩種操作狀態(tài)和模式,還有兩種訪問(wèn)等級(jí)。 1. 操作狀態(tài) 調(diào)試狀態(tài):處理器被暫停后,就會(huì)進(jìn)入調(diào)試狀態(tài),比如利用調(diào)試器觸發(fā)斷點(diǎn),單步執(zhí)行等。 Thumb狀態(tài):處理器執(zhí)行程序代碼,它就是處在Thumb狀態(tài),因?yàn)镃ortex-M4用的是Thumb指令,所以稱為Thumb狀態(tài),并且在Cortex-M處理器中已經(jīng)不支持ARM指令,也就不存在ARM狀態(tài)。 2. 操作模式 處理模式:執(zhí)行中斷服務(wù)程序等異常處理。

7、在處理模式下,處理器總是具有特權(quán)訪問(wèn)等級(jí)。 線程模式:執(zhí)行普通的程序代碼。 3. 訪問(wèn)等級(jí) 特權(quán)訪問(wèn)等級(jí):可以訪問(wèn)處理器中的所有資源。 非特權(quán)訪問(wèn)等級(jí):有些存儲(chǔ)器區(qū)域無(wú)法訪問(wèn),有些操作也無(wú)法使用。 訪問(wèn)等級(jí)有特殊寄存器CONTROL控制。軟件可將處理器從特權(quán)訪問(wèn)等級(jí)轉(zhuǎn)換至非特權(quán)訪問(wèn)等級(jí),但反之無(wú)法直接轉(zhuǎn)換,需要借助異常機(jī)制。 處理器的操作模式和狀態(tài)可由圖1.1來(lái)表示,在上電后,默認(rèn)處于特權(quán)線程模式下的Thumb狀態(tài)。 2.2.2 寄存器 對(duì)于ARM架構(gòu)來(lái)講,處理存儲(chǔ)器中的數(shù)據(jù)時(shí),需將其從存儲(chǔ)器加載到寄存器中,處理完畢后,若有必要,還可以再寫(xiě)回存儲(chǔ)器。這種方式被稱

8、作“加載-存儲(chǔ)架構(gòu)”(LOAD-STORE)。 Cortex-M4處理器的寄存器組中有16個(gè)寄存器,其中包括13個(gè)通用寄存器和3個(gè)有特殊用途的寄存器。 1 通用寄存器R0-R12 R0-R7被稱作低寄存器,許多16位指令只能訪問(wèn)低寄存器。R8-R12稱作高寄存器,可用32位指令和幾個(gè)16位指令訪問(wèn)。R0-R12初始值未定義。 2 棧指針R13 R13為棧指針,可通過(guò)PUSH和POP操作實(shí)現(xiàn)棧存儲(chǔ)的訪問(wèn)。棧指針包括兩個(gè):主棧指針MSP和進(jìn)程棧指針PSP。MSP為默認(rèn)指針,復(fù)位后或處理模式時(shí)只能是MSP,而PSP只能在線程模式使用。棧指針的選擇有CONTROL寄存器控制。

9、MSP和PSP的最低兩位必須是0,也就是棧指針的地址操作必須4字節(jié)對(duì)齊。 3 鏈接寄存器(LR)R14 用于函數(shù)或子程序調(diào)用時(shí)返回地址的保存,在異常中則用來(lái)保存進(jìn)異常前狀態(tài)信息,包括系統(tǒng)模式、棧指針模式等。異常返回時(shí)參考LR中的信息返回到相應(yīng)狀態(tài)。 4 程序計(jì)數(shù)器(PC)R15 R15為程序計(jì)數(shù)器,讀操作返回當(dāng)前地址加4,寫(xiě)操作引起跳轉(zhuǎn)。 2.2.3 特殊寄存器 特殊寄存器有三類:程序狀態(tài)寄存器、中斷/異常屏蔽寄存器、處理器控制寄存器。 1 程序狀態(tài)寄存器:應(yīng)用PSR(APSR)、執(zhí)行PSR(EPSR)、中斷PSR(IPSR)。三個(gè)寄存器可以單獨(dú)訪問(wèn),也可以組合到

10、一個(gè)寄存器中訪問(wèn)。 在APSR中包含N(負(fù)標(biāo)志)、Z(零標(biāo)志)、C(進(jìn)位標(biāo)志)、V(溢出標(biāo)志)、Q(飽和標(biāo)志)和GE(大于或等于標(biāo)志,只在M4中有)。 IPSR中是中斷號(hào),只讀。 EPSR中,T為表示Thumb狀態(tài),由于M4支持Thumb狀態(tài),不支持ARM狀態(tài),T位始終為1。ICI是中斷繼續(xù)指令位,保存的是中斷被打斷時(shí)的信息。IT指令時(shí)IF-THEN指令,用于條件執(zhí)行。 2 PRIMASK、FAULTMASK、和BASEPRI寄存器:這三個(gè)寄存器只能在特權(quán)模式下使用。PRIMASK可屏蔽除NMI和HardFault之外的所有異常。FAULTMASK還可屏蔽HardFault。BAS

11、EPRI可以根據(jù)設(shè)置屏蔽低優(yōu)先級(jí)的中斷,可控制8個(gè)或16個(gè)中斷,相應(yīng)的改寄存器的寬度為3位或4位。 3 CONTROL寄存器 CONTROL寄存器主要有以下幾項(xiàng)作用: 線程模式下的訪問(wèn)等級(jí) 指針的選擇 當(dāng)前代碼是否使用了浮點(diǎn)單元 分別對(duì)應(yīng)了寄存器的低三位 位 功能 nPRIV(第0位) 0對(duì)應(yīng)特權(quán)等級(jí),1為非特權(quán)等級(jí) SPSEL(第1位) 0對(duì)應(yīng)主棧指針,1為進(jìn)程棧指針,處理模式下始終為0。 FPCA(第2位) 0未使用浮點(diǎn),1使用了浮點(diǎn) 2.2.4 浮點(diǎn)寄存器 1 S0-S31和D0-D15 S0-S31都為32位寄存器,也可以D0-D15的方式成

12、對(duì)訪問(wèn),但M4不支持雙精度浮點(diǎn)運(yùn)算,只是可以傳輸雙精度數(shù)據(jù)。 2 浮點(diǎn)狀態(tài)和控制寄存器(FPSCR) FPSCR兩個(gè)功能 提供浮點(diǎn)運(yùn)算結(jié)果的狀態(tài)信息,如負(fù)標(biāo)志、進(jìn)位標(biāo)志等。 定義一些浮點(diǎn)運(yùn)算動(dòng)作,如何舍入等 3 經(jīng)過(guò)存儲(chǔ)器映射的浮點(diǎn)單元控制寄存器(CPACR) 該寄存器經(jīng)過(guò)了映射,也就是說(shuō)需要通過(guò)通用寄存器加載進(jìn)行設(shè)置,寄存器的功能是可以設(shè)置浮點(diǎn)單元的訪問(wèn)權(quán)限,拒絕訪問(wèn)、特權(quán)訪問(wèn),全訪問(wèn)。 2.3存儲(chǔ)器系統(tǒng) 2.3.1 存儲(chǔ)器系統(tǒng)特性 4GB線性地址空間 架構(gòu)定義的存儲(chǔ)器映射。4GB的存儲(chǔ)器空間被劃分為多個(gè)區(qū)域,用于預(yù)定義的存儲(chǔ)器和外設(shè)。 支持大端和小端

13、的存儲(chǔ)器系統(tǒng)。 位段訪問(wèn)。 寫(xiě)緩沖 存儲(chǔ)器保護(hù)單元MPU 非對(duì)齊傳輸支持 2.3.2 存儲(chǔ)器映射 CORTEX-M處理器的4GB地址空間被分為了多個(gè)存儲(chǔ)器區(qū)域,如圖所示。區(qū)域根據(jù)各自典型用法進(jìn)行劃分,他們主要用于: 程序代碼訪問(wèn)(如CODE區(qū)域) 數(shù)據(jù)訪問(wèn)(如SRAM區(qū)域) 外設(shè)(如外設(shè)區(qū)域) 某款芯片的存儲(chǔ)器映射分配 一般Code放在Flash當(dāng)中,數(shù)據(jù)放在RAM中。數(shù)據(jù)在RAM存放有一定的順序,可以分為數(shù)據(jù)段,BSS段、堆和棧區(qū)域。 數(shù)據(jù)段,存儲(chǔ)在內(nèi)存的底部,包含初始化的全局變量和靜態(tài)變量。 BSS段,未初始化的數(shù)據(jù)。 堆,C函數(shù)自

14、動(dòng)分配存儲(chǔ)器區(qū)域,例如alloc()和malloc()。 棧,用于臨時(shí)數(shù)據(jù)存儲(chǔ),局部變量,函數(shù)調(diào)用 2.3.3 棧存儲(chǔ) 同幾乎所有的處理器架構(gòu)一樣,Cortex-M處理器在運(yùn)行時(shí)需要棧存儲(chǔ)和棧指針R13。ARM處理器將系統(tǒng)主存儲(chǔ)器用于??臻g操作,使用PUSH指令往棧中存儲(chǔ)數(shù)據(jù)以及POP指令從棧中提取數(shù)據(jù)。 處理器使用的是滿遞減的模型,棧指針是向下增長(zhǎng)的。處理器啟動(dòng)后,SP被設(shè)置為棧存儲(chǔ)空間的最后的位置,也就是最低位置,PUSH時(shí),SP指針首先減小,然后將數(shù)據(jù)壓入棧中。POP的時(shí)候相反,先將當(dāng)前SP所指的數(shù)據(jù)出棧,然后再修改SP,SP此時(shí)增大??捎孟旅鎯煞鶊D加以理解,

15、 棧中主要用于: 存儲(chǔ)局部變量 異常產(chǎn)生時(shí)保存處理器狀態(tài)(LR、xPSR)和寄存器數(shù)值 函數(shù)調(diào)用時(shí) 2.4復(fù)位和復(fù)位流程 對(duì)于典型的Cortex-M處理器,復(fù)位類型有三種: 上電復(fù)位。復(fù)位微控制器中所有部分。 系統(tǒng)復(fù)位。只會(huì)復(fù)位處理器和外設(shè),不包括處理的調(diào)試支持部件 處理器復(fù)位。只復(fù)位處理器。 在復(fù)位后以及處理器開(kāi)始執(zhí)行程序前,處理器會(huì)從存儲(chǔ)器中讀出頭兩個(gè)字節(jié)。第一個(gè)字表示主棧指針的初始值。第二個(gè)字代表復(fù)位處理起始地址的復(fù)位向量。處理器讀出這兩個(gè)自己后,就會(huì)將這些數(shù)值賦給MSP和PC。 之前在棧存儲(chǔ)時(shí)講到過(guò),Cortex-M處理器的棧操作時(shí)基于滿遞減的,所以S

16、P的初始值應(yīng)該設(shè)置在棧頂?shù)奈恢?。例如,若存?chǔ)器區(qū)域?yàn)?x20007C000~0x20007FFF(1KB),初始的棧指針就應(yīng)該為0x20008000。 另外,對(duì)于Cortex-M處理器,向量表中向量地址的最低位應(yīng)該為1,以代表他們?yōu)門humb狀態(tài)。對(duì)于下圖中的例子,復(fù)位向量為0x101,而啟動(dòng)代碼是從0x100開(kāi)始的。在取出復(fù)位向量后。Cortex-M處理器就可以從復(fù)位向量地址處執(zhí)行程序,并開(kāi)始正常操作。 3 指令集 CORTEX-M4使用的是Thumb-2指令集,不支持ARM指令集,Thumb指令集是ARM指令集的子集,但是Thumb-2技術(shù)已經(jīng)不再支持ARM狀態(tài)。 CORTEX

17、-M處理器間的一個(gè)區(qū)別就是指令集特性。為了將回路面積降到最低,CORTEXM0、CORTEXM0+、CORTEXM1處理器只支持多數(shù)16位指令和部分32位指令,CORTEX-M3支持的32位指令更多。CORTEX處理器支持剩下的SIMD(單指令多數(shù)據(jù))等DSP提升指令集可選的浮點(diǎn)指令。 3.1 CM4指令集特點(diǎn) CM4處理器使用ARMv7-M架構(gòu),指令集為Thumb指令集中的Thumb-2技術(shù),具有如下特點(diǎn) 16位與32位混合指令 加載/存儲(chǔ)指令集,不能直接操作存儲(chǔ)器。 指令長(zhǎng)度可變,使用16/32位由功能決定,優(yōu)先使用16位。 DSP指令,CM4中為單精度,CM7中可以雙

18、精度 3.2 Cortex-M處理器間的指令集比較 Cortex-M處理器的架構(gòu)有三類,ARMv6-M,ARMv7-M,ARMv7E-M。 內(nèi)核 性能 ARMv6-M M0/M0+/M1 一般數(shù)據(jù)處理,IO控制人物 ARMv7-M M3 高級(jí)數(shù)據(jù)處理、硬件除法 ARMv7E-M M4 SIMD、快速M(fèi)AC飽和運(yùn)算 3.3 匯編指令簡(jiǎn)要介紹 3.3.1 處理器內(nèi)傳送數(shù)據(jù) MOV < Rm源寄存器> 源寄存器處可以是立即數(shù),立即數(shù)為8位以下,9-16位用MOVW,32位的需要使用LDR偽指令。 使用浮點(diǎn)單元時(shí)可以使用VMOV指令。 3.

19、3.2 存儲(chǔ)器訪問(wèn)指令 訪問(wèn)可分為讀和寫(xiě)指令,另外根據(jù)讀寫(xiě)的大小還有其他的延伸。 數(shù)據(jù)類型 加載(讀) 存儲(chǔ)(寫(xiě)) 8位無(wú)符號(hào) LDRB STRB 8位有符號(hào) LDRSB STRB 16位無(wú)符號(hào) LDRH STRH 16位有符號(hào) LDRSH STRH 32位 LDR STR 多個(gè)32位 LDM STM 64位 LDRD STRD 棧操作 PUSH POP 介紹幾個(gè)較為重要的 1 LDR/STR LDR Rd,[Rn,#offset] 從存儲(chǔ)器Rn+offset處讀取字,讀取到Rd中 STR Rd,[Rn,#offset] 向存儲(chǔ)器

20、Rn+offset處存儲(chǔ)字,數(shù)據(jù)來(lái)自Rd。 LDR R0,[R1,#0X08] 從存儲(chǔ)器R1+0x08處讀取字,放到R0中 支持寫(xiě)回功能,加!即可,上面可以寫(xiě)成 LDR R0,[R1,#0X08]! 這樣表示存儲(chǔ)器位置的R1被更新為R1+0x08 2 LDM/STM 讀/寫(xiě)多個(gè)字 上述命令是為了從存儲(chǔ)器中讀寫(xiě)多個(gè)字。一般會(huì)加后綴配合使用 LDMIA Rn, Rn是存儲(chǔ)器位置,reg list是寄存器列表,從Rn所指的存儲(chǔ)器位置讀取數(shù)據(jù),放入寄存器中,每次讀取完成后,地址就會(huì)自動(dòng)加4。作用相當(dāng)于POP。另外要注意的是,先讀取的數(shù)據(jù)放置在低寄存器中,后讀取的

21、數(shù)據(jù)放置到高寄存器。 STMIA Rn, Rn是存儲(chǔ)器位置,reg list是寄存器列表, 向Rn所指的存儲(chǔ)器位置存儲(chǔ)數(shù)據(jù),每次存儲(chǔ)前,地址自動(dòng)減4。相當(dāng)于PUSH操作。另要注意的是,先存儲(chǔ)高寄存器的數(shù)據(jù),后存儲(chǔ)低寄存器的數(shù)據(jù)。 同樣,這兩個(gè)指令都可以通過(guò)!表示寫(xiě)回操作,更新寄存器所指的存儲(chǔ)器位置 3 壓棧與出棧 PUSH/POP PUSH和POP和上面的LDMIA和STMDB是相同的。 3.3.3 算數(shù)運(yùn)算 加:ADC 減:SUB 乘:MUL 除:DIV 對(duì)此不做詳細(xì)介紹 3.3.4 邏輯運(yùn)算 與:AND 或:ORR 位清除:BIC

22、 按位異或:EOR 按位或非:ORN 3.3.5 移位 算數(shù)右移:ASR 邏輯左移:LSL 邏輯右移:LSR 循環(huán)右移:ROR 3.3.6 異常相關(guān)指令 之前說(shuō)過(guò),M4可以有特權(quán)模式和非特權(quán)模式,并且非特權(quán)模式不能直接轉(zhuǎn)換到特權(quán)模式,只能在異常中修改CONTROL寄存器。這里就可以通過(guò)SVC指令來(lái)進(jìn)入異常。 SVC # 這樣就可以進(jìn)入SVC中斷中,然后修改CONTROL寄存器。要注意的是,調(diào)用SVC指令后,需盡快進(jìn)入中斷中,如果有其他高優(yōu)先級(jí)的中斷打斷了SVC,就會(huì)引起HardFault。 CPS指令使用時(shí)需要帶上后綴:IE(中斷使能),ID(中斷禁止),還

23、需指定要設(shè)置的中斷屏蔽寄存器,如之前講到的PRIMASK和FAULTMASK 指令 操作 CPSIE I 使能中斷(清除PRIMASK) CPSID I 禁止中斷(設(shè)置PRIMASK),除NMI和HardFault CPSIE F 使能中斷(清除FAULTMASK) CPSID F 禁止中斷(設(shè)置FAULTMASK),除NMI 4 存儲(chǔ)器系統(tǒng) 4.1 存儲(chǔ)器外設(shè) 哈佛結(jié)構(gòu),程序存儲(chǔ)器和數(shù)據(jù)存儲(chǔ)器分開(kāi),也就是指令和數(shù)據(jù)可以同時(shí)訪問(wèn)。 1、在第一章中的存儲(chǔ)器映射圖中,0-0.5G為代碼段,主要用于程序代碼,改區(qū)域一般也允許數(shù)據(jù)訪問(wèn)。一般此處為Flash。 在kei

24、l中,代碼編譯后,整個(gè)代碼分為幾部分:Code(代碼),RO-data(只讀數(shù)據(jù)),RW-data,(初始化的可讀寫(xiě)變量大?。?,ZI-data(Zero Initialize)未初始化的可讀寫(xiě)變量大小,它會(huì)被自動(dòng)初始化為0。ZI-data不會(huì)被算到代碼里,因?yàn)樗粫?huì)被初始化。 簡(jiǎn)單來(lái)說(shuō)呢就是在燒寫(xiě)的時(shí)候FLASH中的被占用的空間為:Code+RO-data+RW-data。 程序運(yùn)行的時(shí)候,芯片內(nèi)部RAM使用的空間為:RW-data+ZI-data 2、0.5G-1G范圍內(nèi)是SRAM,主要用于連接SRAM,其大都為片上SRAM,不過(guò)對(duì)存儲(chǔ)器的類型沒(méi)有什么限制。若支持可選的位段特性,則SR

25、AM區(qū)域的第一個(gè)1MB可位尋址,還可以在這塊區(qū)域中執(zhí)行程序代碼。 3、1G-1.5G是外設(shè)區(qū)域,多用于片上外設(shè),和SRAM區(qū)域類似,也可以放置程序代碼,若支持可選的位段特性,則外設(shè)區(qū)域的第一個(gè)1MB是可選的。 4、1.5G-2.5G空間為外部RAM空間 5、2G-3G空間為設(shè)備空間,用于片外外設(shè)。 6、3G-4G空間為系統(tǒng)空間。 4.2 Bootloader 芯片設(shè)計(jì)人員將Bootloader放入系統(tǒng)中的原因是多方面的。例如: 提供Flash編程功能,這樣就可以利用一個(gè)簡(jiǎn)單的UART接口來(lái)編程Flash,或者當(dāng)程序運(yùn)行時(shí),在自己的應(yīng)用程序中編程Flash存儲(chǔ)器的某些部分。

26、提供通信協(xié)議棧等額外的固件,可被軟件開(kāi)發(fā)人員通過(guò)API調(diào)用。 提供芯片內(nèi)置的自檢功能(BIST) 比如在1601中,提供一個(gè)4K的info區(qū),和128K的main區(qū),4K的info區(qū)就是一個(gè)bootloader,提供SPI下載功能,利用撥碼開(kāi)關(guān)可以設(shè)置從哪里啟動(dòng),mode=0時(shí)從info區(qū)啟動(dòng),mode=1時(shí)從main區(qū)啟動(dòng),并且main區(qū)分兩部分,軟件可設(shè)置從低64K啟動(dòng)還是從高64K啟動(dòng)。這里設(shè)計(jì)存儲(chǔ)器重映射的問(wèn)題,系統(tǒng)啟動(dòng)時(shí)是從0X00開(kāi)始的,不管是Boot loader還是用戶flash,都得從0x00開(kāi)始,然后0x04放的reset_handler的地址,mode=0,那inf

27、or區(qū)就被映射到了0x00,mode=1,main區(qū)就被映射到了0x00。 4.3位段操作 對(duì)存儲(chǔ)器中某一位操作是如何實(shí)現(xiàn)的呢?先來(lái)看看普通模式下, 寫(xiě)某一位: LDR R0,=0X200000000 ;設(shè)置地址 LDR R1,[R0] ;讀數(shù)據(jù) ORR.W R1,#0X04 ;修改第2位 STR R1,[R0] ;寫(xiě)回 讀某一位: LDR R0,=0X200000000 ;設(shè)置地址 LDR R1,[R0] ;讀數(shù)據(jù) UBFX.W R1, R1,#2,#1;提取第2位 這種操作無(wú)法保證

28、原子性,比如輸出端口的第0位被主程序使用,而第一位被中斷使用,這樣有可能出現(xiàn)數(shù)據(jù)沖突。位段操作模式下,這種現(xiàn)象可以避免,因?yàn)槲欢尾僮魇窃谟布燃?jí)下修改的。 位段操作只在兩個(gè)區(qū)域支持,SRAM的第1MB,外設(shè)區(qū)域的第1MB。每1MB會(huì)對(duì)應(yīng)一個(gè)32M的區(qū)域,只需操作這32M的某個(gè)字,就能對(duì)應(yīng)那1MB區(qū)域的某一位。例如寫(xiě)0x22000008為1,就設(shè)置了0x20000000第3位為1。在指令上也會(huì)更加簡(jiǎn)化。 位段寫(xiě)操作 LDR R0, =0X2200000 ;設(shè)置add MOV R1,#1 ;要寫(xiě)的數(shù)據(jù) STR R1 ,[R0] ;寫(xiě) 設(shè)置

29、了位段操作模式,對(duì)應(yīng)的32MB區(qū)域?qū)⒉荒茉偈褂谩? 4.4 存儲(chǔ)器大小端 大小端指的是數(shù)據(jù)存儲(chǔ)時(shí)的順序問(wèn)題。大端指的是高字節(jié)的數(shù)據(jù)放在低地址中,低字節(jié)放在高地址中,這種方式符合人類思維。小端則是低字節(jié)放在低地址中,高字節(jié)放在高地址中,這種方式更符合計(jì)算機(jī)思維。 例如將0x12345678放到存儲(chǔ)器0x2000-0x2003地址處 大端方式 地址 0x2003 0x2002 0x2001 0x2000 數(shù)據(jù) 0x78 0x56 0x34 0x12 小端方式 地址 0x2004 0x2003 0x2002 0x2001 數(shù)據(jù) 0x12 0x34 0x5

30、6 0x78 CM4處理器同時(shí)支持小端和大端的存儲(chǔ)器系統(tǒng)。CM的微控制器大多是小端的。 5 異常和中斷 5.1 中斷簡(jiǎn)介 所有的CORTEX-M處理器都會(huì)提供一個(gè)用于中斷處理的嵌套向量中斷控制器,也就是NVIC。中斷也屬于異常的一種,其他異常包括如錯(cuò)誤異常和其他用于OS支持的系統(tǒng)異常。 M4的NVIC支持最多240個(gè)IRQ(中斷請(qǐng)求),1個(gè)不可屏蔽中斷(NMI),1個(gè)SysTick(系統(tǒng)節(jié)拍)定時(shí)中斷及多個(gè)系統(tǒng)異常。 異常編號(hào) 異常類型 優(yōu)先級(jí) 描述 1 復(fù)位 -3 復(fù)位 2 NMI -2 不可屏蔽中斷 3 硬件錯(cuò)誤 -1 硬件錯(cuò)誤 4 MemM

31、anage錯(cuò)誤 可編程 存儲(chǔ)器管理錯(cuò)誤 5 總線錯(cuò)誤 可編程 總線錯(cuò)誤 6 使用錯(cuò)誤 可編程 程序錯(cuò)誤 7-10 保留 11 SVC 可編程 請(qǐng)求管理調(diào)用 12 調(diào)試監(jiān)控 可編程 調(diào)試監(jiān)控 13 保留 14 PendSV 可編程 一般用于上下文切換 15 SYSTICK 可編程 系統(tǒng)節(jié)拍定時(shí)器 16 外部中斷#0 可編程 片上外設(shè)或外部中斷源產(chǎn)生 17 外部中斷#1 可編程 … … … 255 外部中斷#239 可編程 除了前3個(gè)異常的優(yōu)先級(jí)是固定的,其余異常都可以修改優(yōu)先級(jí)。 5.2異常

32、類型 編號(hào)1-15為系統(tǒng)異常,16及以上的則為中斷輸入。 5.3 中斷管理 為了簡(jiǎn)化中斷和異常管理,CMSIS-Core提供了多個(gè)訪問(wèn)函數(shù)。 函數(shù) 用法 Void NVIC_EnableIRQ(IRQn_Type IRQn) 使能外部中斷 Void NVIC_DisableIRQ(IRQn_Type IRQn) 禁止外部中斷 Void NVIC_SetPriority(IRQn_Type IRQn,uint32_t priority) 設(shè)置中斷的優(yōu)先級(jí) Void _enable_irq(void) 清除PRIMASK使能中斷 Void _disable_irq(vo

33、id) 設(shè)置PRIMASK禁止所有中斷 Void NVIC_SetPriorityGrouping(uint32_t priorityGroup) 設(shè)置優(yōu)先級(jí)分組 復(fù)位后,所有中斷都處于禁止?fàn)顟B(tài),且默認(rèn)的優(yōu)先級(jí)為0。在使用任何一個(gè)中斷之前需要 設(shè)置所需中斷的優(yōu)先級(jí)(可選) 使能外設(shè)中的可以觸發(fā)中斷的中斷產(chǎn)生控制 使能NVIC中的中斷 在M4中,中斷優(yōu)先級(jí)共8位寬,但芯片廠商可進(jìn)行設(shè)置,范圍是3-8位。中斷優(yōu)先級(jí)分為兩個(gè)部分,分組優(yōu)先級(jí)(也叫搶占優(yōu)先級(jí))和子優(yōu)先級(jí)。處理器首先判斷的是分組優(yōu)先級(jí),分組優(yōu)先級(jí)高的會(huì)被首先處理,若分組優(yōu)先級(jí)相同,再比較子優(yōu)先級(jí)。8為寬的優(yōu)先級(jí)如何

34、分配搶占優(yōu)先級(jí)和分組優(yōu)先級(jí),可由寄存器設(shè)置。如下表 優(yōu)先級(jí)分組 搶占優(yōu)先級(jí)域 分組優(yōu)先級(jí)域 0(默認(rèn)) Bit[7:1] Bit[0] 1 Bit[7:2] Bit[1:0] 2 Bit[7:3] Bit[2:0] 3 Bit[7:4] Bit[3:0] 4 Bit[7:5] Bit[4:0] 5 Bit[7:6] Bit[5:0] 6 Bit[7] Bit[6:0] 7 無(wú) Bit[7:0] 這里要注意的是,異常編號(hào)和優(yōu)先級(jí)并不是一個(gè)意思,異常編號(hào)僅僅是一個(gè)編號(hào),就像是枚舉一樣,而優(yōu)先級(jí)則是需要手動(dòng)的進(jìn)行設(shè)置的。只有在分組優(yōu)先級(jí)和子優(yōu)先

35、級(jí)完全一致時(shí),異常編號(hào)才起作用,編號(hào)越小優(yōu)先級(jí)越高。 另外,在M4內(nèi)核中,還提供了中斷向量重定位功能。向量表重定位功能提供了一個(gè)名為向量表偏移寄存器(VTOR)的可編程寄存器。前面提到的Bootloder就可以使用此項(xiàng)功能來(lái)完成。 5.4 異?;蛑袛嗥帘渭拇嫫? 5.4.1 PRIMASK PRIMASK用于禁止除NMI和HardFault外的所有異常,只能在特權(quán)狀態(tài)訪問(wèn)如: CPSIE I ;清除PRIMASK(使能中斷) CPSID I;設(shè)置PRIMASK (禁止中斷) 5.4.2 FAULMASK (M0中無(wú)) FAULMASK用于禁止除NMI外的所有異常,只能在特權(quán)訪問(wèn),

36、如: CPSIE F ;清除FAULMASK COSID F;設(shè)置FAULMASK 5.4.3 BASEPRI(M0中無(wú)) BASEPRI可禁止優(yōu)先級(jí)低于某特定等級(jí)的中斷,只能在特權(quán)狀態(tài)訪問(wèn),如: _set_BASEPRI(0X60); //禁止優(yōu)先級(jí)在0x60-0xFF間的中斷 _set_BASEPRI(0X0); //取消BASEPRI屏蔽 5.5 中斷狀態(tài)及中斷行為 5.5.1 中斷狀態(tài) 中斷狀態(tài):inactive, pending, active,active and pending 中斷狀態(tài)之間的轉(zhuǎn)換: Inactive(非活躍):沒(méi)有掛起或激活的狀態(tài) P

37、ending(掛起):異常已經(jīng)被觸發(fā)但是處理還未處理。比如當(dāng)前中斷被觸發(fā),但是有高優(yōu)先級(jí)或同等優(yōu)先級(jí)的中斷正在執(zhí)行,或是中斷使能被禁止。 Active(活躍):中斷正在被處理 Active and pending(活躍并掛起) 異常被處理時(shí),同一個(gè)異常再次被觸發(fā)。 上述異常對(duì)應(yīng)的是每一個(gè)異常狀態(tài),不是整體的異常。 5.5.2 中斷行為 每個(gè)中斷都有多個(gè)屬性: 每個(gè)中斷都可以被禁止或使能 每個(gè)中斷都可以被掛起或解除掛起 每個(gè)中斷都可以處于活躍或非活躍狀態(tài) 這樣中斷就會(huì)產(chǎn)生多種行為,先來(lái)看一下最簡(jiǎn)單的中斷下中斷狀態(tài)的轉(zhuǎn)換 中斷的掛起狀態(tài)是可以手動(dòng)設(shè)置的,有一個(gè)

38、寄存器是中斷掛起狀態(tài)寄存器,例如上下文切換的PendSV異常,就是手動(dòng)設(shè)置PendSV掛起,然后進(jìn)入了PendSV異常中。同樣,掛起狀態(tài)是可以清除的。若中斷請(qǐng)求產(chǎn)生時(shí),處理器正在處理更高優(yōu)先級(jí)的請(qǐng)求,然后在處理器對(duì)該中斷請(qǐng)求作出相應(yīng)之前,掛起狀態(tài)被清除掉了,那么該中斷請(qǐng)求也就不會(huì)被處理了。 但是,如果外設(shè)保持某中斷為請(qǐng)求狀態(tài),那樣即使軟件清除掉掛起狀態(tài),掛起狀態(tài)仍會(huì)再次置位。 中斷處理完成后,如果中斷請(qǐng)求仍在繼續(xù)保持,中斷就再次進(jìn)入掛起狀態(tài),再次得到處理器的服務(wù) 對(duì)于脈沖中斷請(qǐng)求,若在處理器開(kāi)始處理前,中斷請(qǐng)求產(chǎn)生了多次,它只會(huì)被當(dāng)做一次請(qǐng)求 中斷的掛起狀態(tài)可以在其

39、正在被處理時(shí)再次置位,也就是之前所說(shuō)的active and pend狀態(tài)。中斷處理完成后會(huì)再次處理該中斷。 另外有一種情況需要注意,即使禁止了某中斷,中斷的掛起狀態(tài)仍然可以使用,只是無(wú)法轉(zhuǎn)化為活躍狀態(tài),并且,如果中斷被使能后,若沒(méi)有高優(yōu)先級(jí)中斷在執(zhí)行,掛起狀態(tài)就會(huì)被轉(zhuǎn)換為活躍狀態(tài),進(jìn)而進(jìn)入中斷處理,如果不希望此類狀況發(fā)生,那應(yīng)該在中斷使能之前清除掉中斷掛起狀態(tài)。 5.6 各Cortex-M處理器NVIC差異 Cortex-M處理器的中斷管理有一定區(qū)別 CM0 CM0+ CM1 CM3 CM4 中斷數(shù)量 1-32 1-32 1/8/16/32 1-240 1-

40、240 NMI Y Y Y Y Y 優(yōu)先級(jí)寬度 2 2 2 3-8 3-8 寄存器訪問(wèn) 字 字 字 字、半字、字節(jié) 字、半字、字節(jié) PRIMASK Y Y Y Y Y FAULTMASK N N N Y Y BASEPRI N N N Y Y 向量表偏移寄存器 N Y(可選) N Y Y 動(dòng)態(tài)修改優(yōu)先級(jí) N N N Y Y 中斷活躍狀態(tài) N N N Y Y 錯(cuò)誤處理 硬件錯(cuò)誤 硬件錯(cuò)誤 硬件錯(cuò)誤 硬件錯(cuò)誤+3個(gè)其他錯(cuò)誤異常 硬件錯(cuò)誤+3個(gè)其他錯(cuò)誤異常 調(diào)試監(jiān)控異常 N

41、N N Y Y 6 異常處理 6.1 C實(shí)現(xiàn)的異常處理 C函數(shù)在ARM架構(gòu)上是如何工作的,用于ARM架構(gòu)的C編譯器遵循ARM的一個(gè)名為AAPCS的規(guī)范。根據(jù)這份標(biāo)準(zhǔn),C函數(shù)可以修改R0-R3、R12、R14(LR)以及PSR。若C函數(shù)需要使用R4-R11,就應(yīng)該將這些寄存器保存到??臻g中,并且在函數(shù)結(jié)束前將他們恢復(fù)。 R0-R3、R12、R14、PSR被稱作“調(diào)用者保存寄存器”。 R4-R11為“被調(diào)用者保存寄存器”。 一般來(lái)說(shuō),函數(shù)調(diào)用將R0-R3作為輸入?yún)?shù),R0則用作返回結(jié)果。若返回值為64位,R1也會(huì)用于返回結(jié)果。 異常機(jī)制需要在異常入口處自動(dòng)保存R0-R3、R

42、12、R14、PSR,異常退出時(shí)將其恢復(fù),這些都要由處理器硬件控制。另外,與普通的C函數(shù)調(diào)用不同,返回地址PC并沒(méi)有存儲(chǔ)在LR中,進(jìn)入異常時(shí)LR存儲(chǔ)的是EXC_RETURN,異常返回時(shí)將會(huì)用到。因此,異常流程也需要將返回地址保存,所以,不算浮點(diǎn)單元,異常處理期間保存的寄存器為8個(gè)。對(duì)于帶浮點(diǎn)單元的Cortex-M4處理器,異常機(jī)制還會(huì)保存S0-S15以及FPSCR。 6.2 棧幀 在異常入口處被壓入??臻g的數(shù)據(jù)塊為棧幀。不具有浮點(diǎn)單元的M4處理器,棧幀是8個(gè)字大小。帶浮點(diǎn)的棧幀可能是8個(gè)或26個(gè)字大小。與上一個(gè)小節(jié)中所說(shuō)的異常處理期間保存的寄存器為8個(gè)是一個(gè)意思。 AAPCS要求棧指

43、針的數(shù)值在函數(shù)入口和出口處應(yīng)是雙字對(duì)齊的,雙字棧對(duì)齊特性可編程,該特性可以關(guān)閉。M0中不可設(shè)置。壓棧的xPSR的第9位表示棧指針的數(shù)值是否調(diào)整過(guò),0未調(diào)整,1調(diào)整過(guò),也就是會(huì)自動(dòng)插入一個(gè)字的空間。所以,棧幀最大為9或27個(gè)字。 6.3 EXC_RETURN 6.1小節(jié)中說(shuō)到過(guò),處理器進(jìn)入異常時(shí),LR存儲(chǔ)的是EXC_RETURN,這里說(shuō)明一下,EXC_RETURN的具體細(xì)節(jié)。 EXC_RETURN是一個(gè)字大小,位域表示如下 位 描述 數(shù)值 31:28 EXC_RETURN 指示 0xF 27:5 保留 全為1 0Xefffff 4 棧幀類型 (M0中無(wú)) 1:8字

44、 0:26字 3 返回模式 1:返回線程模式 0:返回處理模式 2 返回棧 1:返回線程棧 0:返回主棧 1 保留 0 0 保留 1 EXC_RETURN的合法值 浮點(diǎn)未使用FPCA=1 浮點(diǎn)使用FPCA=0 返回處理模式,總使用主棧 0XFFFFFFE1 0XFFFFFFF1 返回線程模式,返回后使用主棧 0XFFFFFFE9 0XFFFFFFF1 返回線程模式,返回后使用進(jìn)程棧 0XFFFFFFED 0XFFFFFFFD __asm void vPortSVCHandler( void ) { PRESERVE8 l

45、dr r3, =pxCurrentTCB /* Restore the context. */ ldr r1, [r3] ldr r0, [r1] ldmia r0!, {r4-r11} msr psp, r0 /* Restore the task stack pointer. */ isb mov r0, #0 msr basepri, r0 orr r14, #0xd /*或上0b1101,返回線程棧,線程模式*/ bx r14 } 6.4異常流程 6.4.1 異常進(jìn)入和壓棧 當(dāng)異常產(chǎn)生且被處理器接受時(shí)

46、,壓棧流程會(huì)將寄存器壓入棧中并組織棧幀。要注意的是,壓棧期間的棧訪問(wèn)順序和棧幀中的順序不同,首先壓棧的是PC和xPSR,這樣在取向量時(shí)會(huì)盡快更新PC。 這里再?gòu)?fù)習(xí)一下主棧與進(jìn)程棧的使用,在處理模式,必須使用主棧,在進(jìn)程模式,由CONTROL寄存器控制使用主棧還是進(jìn)程。 在處理器處于進(jìn)程模式并且使用進(jìn)程棧時(shí),壓棧操作使用進(jìn)程棧,然后就進(jìn)入了處理模式,直到異常返回之前,一直使用的是主棧,如異常嵌套的情況,在一個(gè)異常中又進(jìn)入了另一個(gè)異常,仍然使用的是主棧進(jìn)行壓棧。 另外,我們?cè)谑褂肙S的時(shí)候會(huì)有兩個(gè)棧空間,系統(tǒng)??臻g和任務(wù)??臻g,系統(tǒng)棧空間是在啟動(dòng)文件中進(jìn)行了設(shè)置,如圖6-1,這個(gè)棧空間是留給

47、異常使用的,也就是處理模式下的MSP;而在創(chuàng)建任務(wù)的時(shí)候都會(huì)有對(duì)棧空間的設(shè)置,我們稱為任務(wù)??臻g,也就是在線程模式下的PSP。 進(jìn)入異常時(shí),會(huì)將R0-R3,R12,LR和返回地址(帶浮點(diǎn)單元時(shí)包括S0-S15和FPSCR)硬件自動(dòng)壓棧保存,其他的(R4-R11)需要軟件保存。 6.4.2 異常返回和出棧 出棧時(shí)就是對(duì)EXC_RETURN數(shù)值的判斷,也就是EXC_RETURN中位域所表示的那幾項(xiàng),用什么棧進(jìn)行壓棧的仍返回什么棧,操作模式和棧幀類型也類似。出棧操作結(jié)束時(shí),還要檢查xPSR的第9位,若置1則去除壓棧時(shí)插入的額外空間。 對(duì)于棧空間中的數(shù)據(jù),同入棧一樣,R0-R3,R12,和

48、LR(帶浮點(diǎn)單元時(shí)包括S0-S15和FPSCR)是自動(dòng)出棧的,其余的需要軟件出棧。 7 低功耗和系統(tǒng)控制特性 7.1 低功耗模式 CORTEX-M系列處理器提供兩種休眠模式:休眠模式和深度休眠模式。由系統(tǒng)控制寄存器SCR控制。 處理器提供了兩個(gè)用于進(jìn)入休眠模式的指令:WFI,進(jìn)入休眠模式,等待中斷,可由中斷、調(diào)試、復(fù)位喚醒。WFE:等待事件,條件進(jìn)入休眠模式。內(nèi)部事件寄存器為0,進(jìn)入休眠,否則內(nèi)部事件寄存器被清除,處理器繼續(xù)執(zhí)行,除了中斷、調(diào)試、復(fù)位喚醒外,還能由事件喚醒。 WFE中的事件喚醒包括事件輸入信號(hào)脈沖(RXEV)。該信號(hào)屬于事件通信接口特性的一部分。處理器還存在一個(gè)名為T

49、XEV(發(fā)送事件)的輸出信號(hào),當(dāng)執(zhí)行SEV(發(fā)送事件)指令時(shí),TXEV會(huì)輸出一個(gè)周期的脈沖信號(hào)。 事件通信接口的主要設(shè)計(jì)目標(biāo)位,在一個(gè)特定事件發(fā)生前讓處理器一直處于休眠模式。例如: 允許外設(shè)和處理器之間的通信 允許多個(gè)處理器間的通信 7.1 SysTick定時(shí)器 Cortex-M處理器內(nèi)集成了一個(gè)小型的名為Systick的定時(shí)器,它屬于NVIC的一部分,可以產(chǎn)生Systick異常。Systick為簡(jiǎn)單的向下計(jì)數(shù)的24位計(jì)數(shù)器。 Systick的主要作用是用于在OS中任務(wù)管理和上下文切換,處理器可以在不同時(shí)間片內(nèi)處理不同任務(wù)。 設(shè)計(jì)這個(gè)定時(shí)器的目的是為了增加軟件的可移植性。所有

50、CORTEX-M系列的芯片都有相同的定時(shí)器。定時(shí)器的時(shí)鐘可以是處理器時(shí)鐘或者是外部參考時(shí)鐘(STCLK)。 定時(shí)器的使用很簡(jiǎn)單,只有四個(gè)寄存器 地址 寄存器 作用 0XE000E010 Systick控制和狀態(tài)寄存器 使能以及設(shè)置Systick 0XE000E014 Systick重裝載值寄存器 Systick計(jì)時(shí)周期 0XE000E018 Systick當(dāng)前值寄存器 Systick當(dāng)前數(shù)值 0XE000E01C Systick校準(zhǔn)值寄存器 校準(zhǔn)設(shè)置 使用CMSIS-Core中的函數(shù)就能方便地使用Systick,主要作用就是產(chǎn)生定時(shí)中斷,如下,產(chǎn)生1HZ的

51、定時(shí)中斷 配置正確的始終頻率數(shù),產(chǎn)生1khz的定時(shí)中斷 Sys_Config(SystemCoreClock/1000); SystemCoreClock為對(duì)應(yīng)芯片的時(shí)鐘頻率 SysTick定時(shí)器的寄存器只能在特權(quán)狀態(tài)下訪問(wèn)。 8 OS支持特性 8.1 OS支持特性簡(jiǎn)介 上下文切換是OS中很重要的一點(diǎn),經(jīng)過(guò)前面的學(xué)習(xí),我們知道一個(gè)OS的運(yùn)行就是在不同任務(wù)間頻繁的切換,而在切換時(shí),就需要對(duì)上一個(gè)任務(wù)的一些數(shù)據(jù)進(jìn)行保存,然后進(jìn)入下一個(gè)任務(wù),并取出這個(gè)任務(wù)保存的數(shù)據(jù)。可以手動(dòng)的實(shí)現(xiàn)一個(gè)系統(tǒng)的上下文切換。 處理器架構(gòu)實(shí)現(xiàn)了多個(gè)特性,保證了OS設(shè)計(jì)的方便和高效: 影子棧指針。有兩

52、個(gè)棧指針,MSP用于OS內(nèi)核以及中斷處理,PSP用于應(yīng)用任務(wù)。 Systick定時(shí)器。處理器內(nèi)部的簡(jiǎn)單的定時(shí)器??蓪?shí)現(xiàn)任務(wù)的定時(shí)器切換 SVC和PendSV異常。這兩種異常對(duì)于嵌入式OS的操作非常重要,如上下文的切換的實(shí)現(xiàn)等等。 非特權(quán)等級(jí)執(zhí)行,可以利用其實(shí)現(xiàn)一種基本安全模型 8.2 SVC和PendSV SVC稱作請(qǐng)求管理調(diào)用,它既是一條指令,也是一種異常。SVC指令就可以進(jìn)入SVC異常中,之前說(shuō)道過(guò)從非特權(quán)轉(zhuǎn)換到特權(quán)模式就可以使用SVC異常的方法。并且SVC異常通常是不能被打斷的,如果打斷就會(huì)出現(xiàn)硬件錯(cuò)誤。 PendSV異常是為完成OS的上下文切換,并且PendSV的異常

53、等級(jí)要設(shè)置為最低。這是因?yàn)槿绻鸓endSV的異常等級(jí)比較高的話,當(dāng)其他異常來(lái)臨或正在執(zhí)行時(shí),上下文切換就會(huì)打斷其他異常,上下文的切換較為復(fù)雜,就造成中斷延遲。這在實(shí)時(shí)系統(tǒng)中是不可以的。所以要把PendSV異常等級(jí)設(shè)置為最低,等待所有中斷執(zhí)行完畢后,再進(jìn)行上下文切換。下圖是兩種方式的對(duì)比。 任務(wù)切換一般有兩種方式,一種可以通過(guò)systick中斷觸發(fā)PendSV異常,比如在時(shí)間片式的任務(wù)中;對(duì)于手動(dòng)方式,可以通過(guò)SVC觸發(fā)PendSV異常,完成上下文切換。這里要說(shuō)明一下的是,下面兩幅圖中省略了觸發(fā)PendSV的過(guò)程,Systick異常優(yōu)先級(jí)是比較高的,它的作用簡(jiǎn)單,只是觸發(fā)PendSV異常,它對(duì)

54、IRQ的搶占影響很小。 8.3 實(shí)際的上下文切換 上下文切換操作由PendSV異常執(zhí)行處理,由于異常流程已經(jīng)保存了寄存器的R0-R3、R12、LR、xPSR和返回地址,PendSV只需將R4-R11保存到棧中。 具有四個(gè)任務(wù)的多任務(wù)系統(tǒng)實(shí)例: /*字訪問(wèn)的宏定義*/ #define HW32_REG(ADDRESS) (*(volatile unsigned long *)ADDRESS) /*以上宏定義相當(dāng)于 Int *p; p = (int*)0x60000000; *p = 0x01; 就是可以對(duì)ADDRESS地址處賦值,也就是訪問(wèn)這個(gè)字地址處的數(shù)據(jù)。*

55、/ Void task0(void); Void task1(void); Void task2(void); Void task3(void); //任務(wù)事件 Volatile uint32_t systick_count=0; //每個(gè)任務(wù)用的棧 8KB long long task0_stack[1024], task1_stack[1024], task2_stack[1024], task3_stack[1024]; //OS使用的數(shù)據(jù) uint32_t curr_task = 0; //當(dāng)前任務(wù) uint32_t next_task = 0;

56、//下一個(gè)任務(wù) uint32_t PSP_array[4]; //任務(wù)的進(jìn)程棧指針 //-------------------------------------------------------------------- // 主程序 int main(void) { //任務(wù)初始化 省略 //開(kāi)始任務(wù)調(diào)度 //創(chuàng)建任務(wù)0棧幀 PSP_array[0] = ((unsigned int) task0_stack) + (sizeof task0_stack) -16*4; /*初始化函數(shù)地址,14作為PC的位置,左移2位相當(dāng)于乘以4*/ HW32_REG(

57、PSP_array[0] + (14<<2)) = (unsigned long) task0; /*初始化程序計(jì)數(shù)器,15作為PSR位置*/ HW32_REG(PSP_array[0] + (15<<2)) = 0x01000000; /*初始化其他任務(wù)*/ …….. ……. ……. Curr_task = 0; //切換到任務(wù)0 /*設(shè)置PSP為任務(wù)0的棧頂*/ _set_PSP((PSP_array[curr_task] + 16*4)) NVIC_SetPriority(PendSV_IRQn,0xFF); //設(shè)置PendSV為最低優(yōu)先

58、級(jí) SysTick_Config(16800); _set_CONTROL(0X3); _ISB(); task0(); while(1); {stop_cpu;//不應(yīng)到此處} } Void task0(); { } Void task1(); { } Void task2(); { } Void task3(); { } _asm void PendSV_Handler() { //1保存當(dāng)前上下文 MRS R0,PSP //讀取當(dāng)前棧指針 STMDB R0!,{R4-R11}

59、 //將R4-R11保存到任務(wù)棧中 LDR R1, = _cpp(&curr_task) LDR R2, [R1] //當(dāng)前任務(wù)ID,也就是在PSP_array中的位置 LDR R3, = _cpp(&PSP_array) //PSP_array地址 STR R0,[R3,R2,LSL #2] //當(dāng)前任務(wù)棧PSP的位置存放到PSP_array中,上//文的保存完成 //2 加載下一個(gè)上下文 LDR R4 , =_cpp(&next_task) LDR R4,[R4] //得到下一個(gè)任務(wù)的ID,也就是在

60、PSP_array存放的//位置 STR R4,[R1] LDR R0,[R3,R4,LSL #2] //從PSP_array中取出這個(gè)任務(wù)的棧起始地址 LDMIA R0!,{R4-R11} //從任務(wù)棧中取出保存的R4-R11 MSR PSP, R0 //設(shè)置PSP為下一個(gè)任務(wù) BX LR ALIGN 4 } Void SysTick_Handler(void) { Systick_count++; //簡(jiǎn)單的任務(wù)調(diào)度器 Switch(curr_task) { Case 0: Next_task = 1;bre

61、ak; Case 1: Next_task = 2;break; Case 2: Next_task = 3;break; Case 3: Next_task = 0;break; Default: next_task = 0; Stop_cpu; Break;//不應(yīng)到此處 } If(curr_task!=next_task) { SCB->ICSR |=SCB_ICSR_PENDSVSET_Mask; }//在這里設(shè)置了PENDSV掛起,在PENDSV_HANDLER中完成上下文切換 Return; } 對(duì)于帶

62、浮點(diǎn)單元的上下文切換,基本流程是一致的。這里要了解帶浮點(diǎn)單元的一種壓棧機(jī)制,惰性壓棧。 帶浮點(diǎn)的情況下,處理器進(jìn)入異常時(shí),若要將每個(gè)異常所需的浮點(diǎn)單元寄存器壓棧(S0-S15,F(xiàn)PSCR),每次都需要額外執(zhí)行17次存儲(chǔ)器壓棧操作,會(huì)增加中斷等待時(shí)間。 為減少等待時(shí)間,M4處理器實(shí)現(xiàn)一種惰性壓棧的特性。默認(rèn)是使能的。若在浮點(diǎn)單元使能且使用的情況下產(chǎn)生了異常,則棧幀的長(zhǎng)度會(huì)增加。不過(guò),這些浮點(diǎn)寄存器的數(shù)值實(shí)際上是不會(huì)寫(xiě)入棧幀中的。惰性壓棧機(jī)制只會(huì)為這些寄存器保留一定的??臻g,不過(guò)只有R0-R3、R12、LR、返回地址和xPSR被壓棧。當(dāng)出現(xiàn)惰性壓棧時(shí),一個(gè)名為L(zhǎng)SPACT(惰性壓棧保持活躍)的寄存器會(huì)被置位,浮點(diǎn)單元上下文地址寄存器(FPCAR)存放浮點(diǎn)寄存器預(yù)留棧空間的地址。 在棧初始化時(shí),由于惰性壓棧的緣故,并不需要單獨(dú)考慮浮點(diǎn)單元的空間,但仍需要增加一個(gè)字的空間,這個(gè)用來(lái)保存LR(EXC_RETURN),它的第四位表示異常棧幀中是否包含浮點(diǎn)寄存器。上下文切換時(shí)通過(guò)檢查它來(lái)確認(rèn)是否需要壓入或彈出浮點(diǎn)寄存器的相關(guān)內(nèi)容。

展開(kāi)閱讀全文
溫馨提示:
1: 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

相關(guān)資源

更多
正為您匹配相似的精品文檔
關(guān)于我們 - 網(wǎng)站聲明 - 網(wǎng)站地圖 - 資源地圖 - 友情鏈接 - 網(wǎng)站客服 - 聯(lián)系我們

copyright@ 2023-2025  zhuangpeitu.com 裝配圖網(wǎng)版權(quán)所有   聯(lián)系電話:18123376007

備案號(hào):ICP2024067431號(hào)-1 川公網(wǎng)安備51140202000466號(hào)


本站為文檔C2C交易模式,即用戶上傳的文檔直接被用戶下載,本站只是中間服務(wù)平臺(tái),本站所有文檔下載所得的收益歸上傳人(含作者)所有。裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)上載內(nèi)容本身不做任何修改或編輯。若文檔所含內(nèi)容侵犯了您的版權(quán)或隱私,請(qǐng)立即通知裝配圖網(wǎng),我們立即給予刪除!