ARM Cortex-M內(nèi)核的復(fù)位啟動過程也被稱為復(fù)位序列(Reset sequence),下面就來簡要總結(jié)分析下這一過程。
ARM Cortex-M內(nèi)核的復(fù)位啟動過程與其他大部分CPU不同,也與之前的ARM架構(gòu)(ARM920T、ARM7TDMI等)不相同。大部分CPU復(fù)位后都是從0x0000_0000處取得第一條指令開始運(yùn)行的,然而在ARM Cortex-M內(nèi)核中并不是這樣的。其復(fù)位序列為:
1.從地址0x0000_0000處取出MSP的初始值;
2.從地址0x0000_0004處取出PC的初始值,然后從這個值對應(yīng)的地址處取指。
即下圖所示過程: ??
事實(shí)上,地址0x0000_0004開始存放的就是默認(rèn)中斷向量表(有些資料中將地址0x0000_0000處的MSP指針初始值也算作中斷向量表的一部分,這個說法似乎不太妥當(dāng)),ARM Cortex-M內(nèi)核的中斷向量表布局情況如下圖所示: ????
注意:中斷向量表的位置可以改變,此處是默認(rèn)情況下的設(shè)置。
值得注意的是,在ARM Cortex-M內(nèi)核中,發(fā)生異常后,并不是去執(zhí)行中斷向量表中對應(yīng)位置處的代碼,而是將對應(yīng)位置處的數(shù)據(jù)存入PC中,然后去此地址處進(jìn)行取指。簡而言之,在ARM Cortex-M的中斷向量表中不應(yīng)該放置跳轉(zhuǎn)指令,而是該放置ISR程序的入口地址。
有了上面的分析就很好理解復(fù)位序列了,復(fù)位其實(shí)就相當(dāng)于發(fā)生了一次Reset異常,而從圖中可以看到,地址0x0000_0004處存放的正是Reset異常對應(yīng)的中斷處理函數(shù)入口地址。
另外還有兩個細(xì)節(jié)問題需要注意:
1. 0x0000_0000處存放的MSP初始值最低三位需要是0;
2.0x0000_0004處存放的地址最低位必須是1。
第一個問題是因?yàn)锳RM AAPCS中對棧使用的約定是這樣的:
5.2.1.1
Universal stack constraints
At all times the following basic constraints must hold:
Stack-limit < SP <= stack-base. The stack pointer must lie within the extent of the stack.
SP mod 4 = 0. The stack must at all times be aligned to a word boundary.
5.2.1.2
Stack constraints at a public interface
The stack must also conform to the following constraint at a public interface:
SP mod 8 = 0. The stack must be double-word aligned.
簡而言之,規(guī)約規(guī)定,棧任何時(shí)候都必須4字節(jié)對齊,在調(diào)用入口需8字節(jié)對齊,而且SP的最低兩位在硬件上就被置為0了。
第二個問題與ARM模式與Thumb模式有關(guān)。ARM中PC中的地址必須是32位對齊的,其最低兩位也被硬件上置0了,故寫入PC中的數(shù)據(jù)最低兩位并不代表真實(shí)的取址地址。ARM中使用最低一位來判斷這條指令是ARM指令還是Thumb指令,若最低位為0,代表ARM指令;若最低位為1,代表Thumb指令。在Cortex-M內(nèi)核中,并不支持ARM模式,若強(qiáng)行切換到ARM模式會引發(fā)一個Hard Fault。
最后寫一段小程序來驗(yàn)證下以上分析。這段程序基于STM32F4系列單片機(jī),作用是讓PA0管腳輸出高電平。這應(yīng)該也是實(shí)現(xiàn)這一目的最精簡的寫法了。
rAHB1ENR EQU 0x40023830 AHB1ENRValue EQU 0x00000001 rMODER EQU 0x40020000 MODERValue EQU 0xA8000001 rODR EQU 0x40020014 ODRVaule EQU 0x00000001 AREA RESET, DATA, READONLY DCD 0x00000400 DCD Start AREA |.text|, CODE, READONLY ENTRY Start LDR R0, =rAHB1ENR LDR R1, =AHB1ENRValue STR R1, [R0] LDR R0, =rMODER LDR R1, =MODERValue STR R1, [R0] LDR R0, =rODR LDR R1, =ODRVaule STR R1, [R0] B . END
第11行使用DCD偽指令分配了4個字節(jié)的存儲空間,并將其值設(shè)置為0x0000_0400;第12行同理,將Start標(biāo)號處的地址放置在偏移量為4字節(jié)的位置處;第17行Start標(biāo)號之后的部分就是程序主體,依次完成了GPIOA端口RCC時(shí)鐘使能、PA0設(shè)置為輸出模式、PA0置高這三個步驟。
程序在鏈接時(shí)會將RESET段放置在目標(biāo)文件開頭,故相當(dāng)于在地址0x0000_0000處的數(shù)據(jù)為0x0000_0400,在地址0x0000_0004處的數(shù)據(jù)為Start部分的入口地址。
不過需要指出的是,實(shí)際上在STM32F4芯片中,內(nèi)部Flash的地址是從0x0800_0000處開始的,在BOOT管腳設(shè)置為Flash啟動的時(shí)候,芯片內(nèi)部會自動將0x0000_00000 0x000F_FFFF區(qū)域映射至0x0800_0000 0x080F_FFFF處,此時(shí)可以視為二者是等價(jià)的。
使用Debug模式進(jìn)行調(diào)試,復(fù)位后CPU寄存器的值如下所示:
![50ee5d76-c4c5-11ed-bfe3-dac502259ad0.png](https://file1.elecfans.com//web2/M00/99/D9/wKgaomTneNuAX-6aAAAUn8rLCPk703.png)
Flash中的數(shù)據(jù)如圖:
![5100dc1c-c4c5-11ed-bfe3-dac502259ad0.png](https://file1.elecfans.com//web2/M00/99/D9/wKgaomTneNuAMMexAAAsoqZEv6k325.png)
可以看到,編譯器很智能的將0x0800_0004處的數(shù)據(jù)設(shè)置為了0x0800_0009,而不是Start標(biāo)號真實(shí)的地址值,這說明了這是一條Thumb-2指令。復(fù)位后PC中的值是0x0800_0008,SP中的值是0x0000_0400,與預(yù)期結(jié)果完全相同。
最后順便提一下,上面那段簡單的程序有個問題,實(shí)際上Start部分的程序是占用了中斷向量表的空間,這在沒有異常發(fā)生的時(shí)候是沒有問題的,不過一旦有異常發(fā)生,顯然程序執(zhí)行是會出錯的。
審核編輯:湯梓紅
-
ARM
+關(guān)注
關(guān)注
134文章
9179瀏覽量
369426 -
內(nèi)核
+關(guān)注
關(guān)注
3文章
1383瀏覽量
40442 -
cpu
+關(guān)注
關(guān)注
68文章
10911瀏覽量
213141 -
中斷
+關(guān)注
關(guān)注
5文章
900瀏覽量
41792 -
Cortex-M
+關(guān)注
關(guān)注
2文章
229瀏覽量
29846
原文標(biāo)題:分析ARM Cortex-M內(nèi)核復(fù)位啟動過程
文章出處:【微信號:c-stm32,微信公眾號:STM32嵌入式開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
ARM Cortex-M0 DesignStart系列--4啟動過程分析
![<b class='flag-5'>ARM</b> <b class='flag-5'>Cortex-M</b>0 DesignStart系列--4<b class='flag-5'>啟動過程</b><b class='flag-5'>分析</b>](https://file.elecfans.com/web2/M00/79/7C/pYYBAGNrfgOACS4qAAFanBo5zHk452.png)
專家揭秘:STM32啟動過程全解
![專家揭秘:STM32<b class='flag-5'>啟動過程</b>全解](https://file1.elecfans.com//web2/M00/A6/51/wKgZomUMPOGAV3l7AAB574HaBVg441.jpg)
ARM Cortex-M內(nèi)核的相關(guān)資料推薦
ARM Cortex-M 系列微控制器(ST)
嵌入式uCLinux內(nèi)核啟動過程分析
傳統(tǒng)的單片機(jī)和ARM較量 助推MCU踏上高端Cortex-M市場
詳解bootloader的執(zhí)行流程與ARM Linux啟動過程分析
![詳解bootloader的執(zhí)行流程與<b class='flag-5'>ARM</b> Linux<b class='flag-5'>啟動過程</b><b class='flag-5'>分析</b>](https://file1.elecfans.com//web2/M00/A7/19/wKgZomUMQmGATJLlAABw36rp0a4271.png)
評論