本文分析STM32單片機(jī)從上電到運(yùn)行的過程,目的在于了解STM32單片機(jī)從啟動(dòng)到運(yùn)行的整個(gè)過程。
一般我們?cè)谑褂肧TM32單片機(jī)的時(shí)候,都是使用官方提供的驅(qū)動(dòng)文件,移植到自己即將要使用的工程中,移植完成之后再編寫自己的邏輯代碼,放到main( )函數(shù)中,就可以完美的運(yùn)行起來了。相信很多的人都沒有去關(guān)注過STM32從啟動(dòng)到運(yùn)行這個(gè)過程都發(fā)生了什么,現(xiàn)在就簡單分析一些這個(gè)過程。
本文以STM32F103為例進(jìn)行分析。在官方給我們提供的啟動(dòng)文件中,將整個(gè)單片機(jī)的啟動(dòng)過程要做的事情都已經(jīng)幫我們做好了,以至于我們?cè)谑褂眠@款單片機(jī)的時(shí)候,幾乎可以不會(huì)吹灰之力就可以運(yùn)行起來。STM32F103的啟動(dòng)文件形如:
根據(jù)不同的芯片容量,都有相對(duì)應(yīng)的啟動(dòng)文件可供選擇,實(shí)際使用根據(jù)芯片容量選擇合適的啟動(dòng)文件即可。
啟動(dòng)文件的主要作用有:
1)設(shè)置棧
2)初始化 SP 指針
3)設(shè)置堆
4)復(fù)位中斷服務(wù)函數(shù)
5)調(diào)用 SystemInit()函數(shù)來完成初始化工作
6)調(diào)用__main,該函數(shù)內(nèi)部會(huì)調(diào)用 main()函數(shù)
1、設(shè)置棧
從啟動(dòng)文件中可以看到:
上述代碼中: 1)35行,將棧的大小設(shè)為0x00000400(即1024 = 1KB)。 2)37行,棧名稱為STACK,不初始化,可讀可寫,8(2^3)字節(jié)對(duì)齊。 3)38行,分配一片連續(xù)的存儲(chǔ)區(qū)域并初始化為 0,大小為0x400個(gè)字節(jié)。 4)39行,__initial_sp表示棧的結(jié)束地址,即棧頂?shù)刂?,STM32中棧是由高地址向低地址生長。
2、設(shè)置堆
上述代碼中: 1)45行,將堆的大小設(shè)為0x00000200(即512B = 0.5KB)。 2)47行,棧名為HEAP,不初始化,可讀可寫,8(2^3)字節(jié)對(duì)齊。 3)48行,堆空間起始地址。 4)49行,堆空間:0x200個(gè)字節(jié)。 5)50行,堆空間結(jié)束地址。
3、對(duì)堆棧屬性進(jìn)行設(shè)置
1)PRESERVE8 指令指定當(dāng)前文件保持堆棧八字節(jié)對(duì)齊。 2)告訴匯編器下面是32位的Thumb指令,如果需要匯編器將插入位以保證對(duì)齊。
4、設(shè)置中斷向量表
1)57行,定義一塊數(shù)據(jù)段,只可讀,段名字是RESET。
2)58行,EXPORT:在程序中聲明一個(gè)全局的標(biāo)號(hào)__Vectors,該標(biāo)號(hào)可在其他的文件中引用。
3)59行,在程序中聲明一個(gè)全局的標(biāo)號(hào)__Vectors_End。
4)60行,在程序中聲明一個(gè)全局的標(biāo)號(hào)__Vectors_Size。
之后的是中斷的定義,可以分為兩部分:
一部分是系統(tǒng)內(nèi)部中斷:
另一部分是外部中斷:
在之后是中斷向量表的其他設(shè)置:
1)142行,得到向量表的大小。
2)144行,定義一個(gè)代碼段,可讀,段名字是.text。
5、中斷功能的定義
復(fù)位中斷:
1)149行,IMPORT:偽指令用于通知編譯器要使用的標(biāo)號(hào)在其他的源文件中定義。 2)150行,系統(tǒng)初始化。 3)151行,R0的值為SystemInit的地址。
4)152行,切換指令集,跳到SystemInit。 5)153行,R0的值為__main的地址。__main是庫提供的函數(shù)。用于完成堆棧,堆的初始化等工作,還會(huì)調(diào)用__user_initial_stackheap。 6)154行,切換指令集,跳到__main,并且最終會(huì)跳轉(zhuǎn)到main(),進(jìn)入C語言運(yùn)行環(huán)境。
6、用戶棧和堆初始化
1)333行,如果勾選了micro lib,使用微庫。 2)339行,沒有勾選微庫。
1)344,用戶堆棧初始化程序入口。 2)346,保存堆起始地址。 3)347行,保存棧結(jié)束地址。 4)348行,保存堆結(jié)束地址。 5)349行,保存棧起始地址。
7、中斷跳轉(zhuǎn)
中斷發(fā)生之后,是怎么實(shí)現(xiàn)跳轉(zhuǎn)到相應(yīng)的中斷服務(wù)函數(shù)里面的呢? 1)首先,前面
定義好了中斷的響應(yīng)函數(shù),即中斷向量表,標(biāo)號(hào)__Vectors,表示中斷向量表的入口地址。2)我們假設(shè)STM32從FLASH啟動(dòng),則中斷向量表起始地址為0x8000000,STM32上電后根據(jù)boot引腳來決定PC位置,即啟動(dòng)后PC跳到0x08000000。3)然后CPU會(huì)先取2個(gè)地址,第一個(gè)是棧頂?shù)刂?,第二個(gè)是復(fù)位異常地址(Reset_Handler),Reset_Handler最終會(huì)進(jìn)入到C語言的運(yùn)行環(huán)境,這個(gè)時(shí)候會(huì)先配置NVIC,使用NVIC_SetVectorTable()可以配置中斷向量表的起始地址和偏移,告訴CPU該向量表是位于Flash還是Ram,偏移是多少。 4)在發(fā)生中斷后,CPU找到中斷向量表地址,然后根據(jù)偏移(對(duì)號(hào)入座)再找到中斷地址,這樣就完成了跳轉(zhuǎn)了。
-
單片機(jī)
+關(guān)注
關(guān)注
6035文章
44554瀏覽量
634614 -
STM32
+關(guān)注
關(guān)注
2270文章
10895瀏覽量
355721 -
啟動(dòng)
+關(guān)注
關(guān)注
0文章
27瀏覽量
13903
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論