01啟動文件簡介
startup_stm32f429_439xx.s是STM32的啟動文件。
剛開始我一直認為STM32程序開始執(zhí)行是從main函數(shù)開始。后來網(wǎng)上查查不是。原來在執(zhí)行main函數(shù)之前,需要先執(zhí)行一段匯編程序和完成C語言資源硬件的初始化工作。就是以下幾個功能:
1--初始化棧指針MSP=_initial_sp。
2--初始化復(fù)位程序計數(shù)寄存器值=Reset_Handler。
3--初始化異常/ 中斷向量表。
4--系統(tǒng)時鐘配置。
5--C庫函數(shù)_main初始化用戶堆棧的調(diào)用 。
02文件啟動步驟
1-在啟動的時候,先對堆棧的大小定義,并在代碼區(qū)的起始位置建立異常中斷向量表。然后在復(fù)位中斷中服務(wù)程序中跳轉(zhuǎn)執(zhí)行C標準庫main函數(shù),以上這些完成后,跳轉(zhuǎn)到主程序中的main函數(shù)執(zhí)行相關(guān)函數(shù)應(yīng)用。但是假如STM32F429單片機被設(shè)置成從內(nèi)部flash啟動的,這時候,片內(nèi)Flash被映射到程序啟動空間,異常/中斷向量表實際的開始地址為0x8000000(查看STM32F4參考手冊可得到),則棧頂?shù)刂反娣旁?x8000000處,復(fù)位中斷存放在0x8000004處,若STM32F4遇到復(fù)位信號,則從0x8000004處取出復(fù)位中斷服務(wù)入口地址,繼而執(zhí)行中斷服務(wù)函數(shù),繞后跳轉(zhuǎn)到main函數(shù),最終進入main函數(shù)。由此我們可以得下面這個圖:
03啟動代碼講解
01棧(Stack)
我們可以在.s這個文件中看到堆棧信息如圖:
根據(jù)上面的圖片我們可以知道。
在startup_stm32f429_439xx.s文件中,將棧的大小設(shè)為0x00000400(1KB)F429是0x30000(192KB),Stack_Mem為棧名,不初始化可讀可寫,8字節(jié)對齊。Stack_Size是棧的大小,__initial_sp表示結(jié)束地址(棧頂?shù)刂罚瑮J怯筛咦止?jié)向低字節(jié)生長的)。
棧的主要作用是用于局部變量、函數(shù)調(diào)用、函數(shù)形參的開銷大小應(yīng)小于內(nèi)部RAM大小,考慮到局部變量的需求,防止棧溢出。
EQU:宏定義的偽指令,相當于等于,類似與 C 中的 define;
AREA:告訴匯編器匯編一個新的代碼段或者數(shù)據(jù)段;
SPACE:用于分配一定大小的內(nèi)存空間,單位為字節(jié);這里的大小等于Stack_Size。
DCD:數(shù)據(jù)定義( Data Definition )偽指令,單位是字(4字節(jié));
偽指令(Pseudo instruction):用于告訴匯編器如何進行匯編的指令,不生成可執(zhí)行代碼。
總結(jié)如下圖所示:
02堆(Heap)
在.s54行中如下圖這些代碼:
這些代碼中,堆的大小設(shè)為0x00000200(512B),其中Heap_ Mem是棧名,不初始化,可讀可寫,8(23)字節(jié)對齊。Heap_Size為堆的大小, heap_base為堆的起始地址,heap_limit為堆的結(jié)束地址,因為堆是由低地址向高地址生長的。
堆的作用是用于malloc()函數(shù)申請的動態(tài)內(nèi)存的分配。
04中斷向量表
PRESERVE8:指定當前文件的堆棧按照 8 字節(jié)對齊THUMB:表示后面指令為 THUMB 指令。THUBM 是 ARM 以前的指令集, 16bit,現(xiàn)在 Cortex-M 系列的都使用 THUMB-2 指令集, THUMB-2 是 32 位的,兼容 16 位和 32 位的指令,是 THUMB 的超級!
EXPORT:聲明一個標號具有全局屬性,可被外部的文件使用。如果是 IAR 編譯器,則使用的是 GLOBAL 這個指令。
——Vectors是異常/中斷向量表的起始位置,_Vectors_End是中斷向量表的結(jié)束位置,vectors__Size中斷向量表的大小。
TM32F42XX/STM32F43XX部分中斷向量表
在中斷向量表中的每一個位置存儲都是一個4字節(jié)服務(wù)程序入口地址,如果有中斷請求并且MCU進行了請求的響應(yīng),那么MCU就會找到向量表中找到對應(yīng)的中斷位置,找到中斷復(fù)位程序入口地址到程序計數(shù)寄存器,進而執(zhí)行中斷。
具體的詳細中斷向量表請參看數(shù)據(jù)手冊以及啟動文件。
05復(fù)位中斷服務(wù)程序
這句話的意思是定義一個名為.text代碼段,可讀
復(fù)位中斷服務(wù)程序是系統(tǒng)上電后第一個執(zhí)行的程序,調(diào)用Systemlnit函數(shù)初始化系統(tǒng)時鐘,然后調(diào)用C庫函數(shù)mian,最終調(diào)用 main 函數(shù)進入C程序的世界。
LDR:從存儲器加載字到一個寄存器。
BL:跳轉(zhuǎn)到由寄存器/標號給出的地址,并把跳轉(zhuǎn)前的下條指令地址保存到鏈接寄存器。
BLX:跳轉(zhuǎn)到由寄存器給出的地址,并根據(jù)寄存器的LSE確定處理器的狀態(tài),還要把跳轉(zhuǎn)前的下條指令地址保存到鏈接寄存器。
BX:跳轉(zhuǎn)到由寄存器/標號給出的地址,不用返回。
WEAK:表示弱定義,如果外部文件優(yōu)先定義了該標號,則首先引用該標號,可以在C語言中重新定義中斷服務(wù)程序;如果在啟動文件之外沒有重新定義中斷服務(wù)程序,則在對應(yīng)的異常/中斷向量表位置處存儲的是匯編文件定義的中斷服務(wù)程序入口地址。如果在啟動文件外,在另外一個C文件中重新定義了中斷服務(wù)程序,則在對應(yīng)的異常/中斷向量表位置處存儲的是C文件中的中斷服務(wù)程序入口地址。需要注意的是,啟動文件中的中斷服務(wù)程序的名稱和C文件中重新定義的中斷服務(wù)程序名稱必須保持一致。
IMPORT:表示該標號來自外部文件,跟C語言中的關(guān)鍵字EXTERN類似。這里表示Systemlnit 和main 這兩個函數(shù)均來自外部的文件。
Systemlnit是一個標準的庫函數(shù),在system_stm32f4xx.c這個庫文件中定義,主要作用是配置系統(tǒng)時鐘,在調(diào)用這個函數(shù)之后,STM32F429的系統(tǒng)時鐘被配置為180MHz。
main是一個標準的C庫函數(shù),主要作用是初始化用戶堆棧,最終調(diào)用main函數(shù)進入C程序的世界。在C應(yīng)用程序中,必須有一個main函數(shù)。需要注意的是,_main不是用戶C程序的main 函數(shù)。
異常和中斷服務(wù)程序
07用戶堆棧初始化
判斷是否定義了__MICROLIB,如果定義了則賦予標號__initial_sp(棧頂?shù)刂罚_heap_base(堆起始地址)、__heap_limit(堆結(jié)束地址)全局屬性,可供外部文件調(diào)用。如果沒有定義(實際的情況就是我們沒定義__MICROLIB),則使用默認的C庫函數(shù),然后初始化用戶堆棧大小,這部分由C庫函數(shù)__main來完成,當初始化完堆棧之后,就調(diào)用main函數(shù)去到C程序的世界。
IF、ELSE、ENDIF:匯編的條件分支語句,跟C語言的if、else類似。
-
STM32
+關(guān)注
關(guān)注
2293文章
11032瀏覽量
365001 -
C語言
+關(guān)注
關(guān)注
180文章
7632瀏覽量
141771 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4381瀏覽量
64890 -
啟動文件
+關(guān)注
關(guān)注
0文章
15瀏覽量
2379
發(fā)布評論請先 登錄
STM32Cube用法以及自動生成的代碼講解
STM32單片機的啟動文件簡介
STM32啟動文件內(nèi)容詳解

STM32啟動過程--啟動文件--分析

STM32啟動文件分析

3-STM32啟動文件詳解

評論