CORTEX-M4知識(shí)點(diǎn)總結(jié)
《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
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,
21、數(shù)據(jù)放置到高寄存器。
STMIA Rn,
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 #
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)容。
- 溫馨提示:
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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 九年級(jí)數(shù)學(xué)上冊(cè) 第三章 概率的進(jìn)一步認(rèn)識(shí)復(fù)習(xí)課件 (新版)北師大版
- 九年級(jí)數(shù)學(xué)上冊(cè) 第23章 圖形的相似 23.5 位似圖形授課課件 (新版)華東師大版
- 九年級(jí)歷史下冊(cè) 第四單元 第8課 美國(guó)經(jīng)濟(jì)的發(fā)展課件 新人教版
- 危急值報(bào)告及處理制度課件
- 高考小說(shuō)閱讀-第三講:小說(shuō)的敘述方式課件
- 國(guó)內(nèi)管理學(xué)院評(píng)鑒現(xiàn)況及未來(lái)發(fā)展課件
- “圖形的認(rèn)識(shí)與測(cè)量”知識(shí)梳理及教學(xué)策略課件
- 新版近視科普講座ppt課件
- 課件--迎接本科教學(xué)工作水平評(píng)估
- 現(xiàn)在完成進(jìn)行時(shí)PPT幻燈片課件
- 高考語(yǔ)文大一輪總復(fù)習(xí)-散文閱讀-概括內(nèi)容要點(diǎn)和主旨題題組訓(xùn)練ppt課件-新人教版
- 工程材料計(jì)劃編制課件
- 工廠車間管理基礎(chǔ)知識(shí)課件
- 2015北師大版六年級(jí)數(shù)學(xué)總復(fù)習(xí)正比例與反比例課件
- 文明集會(huì)禮儀規(guī)范班會(huì)課件