我們寫嵌入式程式,基本上採用c語言來編寫,以main( )作為程式的入口。但實際上,mian()並不是最先要執行的,在這之前需要做一些基本的工作,如堆、棧的定義;main函式的復位連線等,這些工作就需要乙個專門的啟動程
我們寫嵌入式程式,基本上採用c語言來編寫,以main( )作為程式的入口。但實際上,mian()並不是最先要執行的,在這之前需要做一些基本的工作,如堆、棧的定義;main函式的復位連線等,這些工作就需要乙個專門的啟動程式來完成,由於需要做的工作內容不多,並且需要更直接的管理記憶體,一般採用彙編編寫。
無論是stm32
、arm系列的微控制器,還是簡單的如51,pic等,都以為上述原因,需要啟動程式,只不過51,pic等微控制器的啟動程式已經在相應的ide編譯、鏈結的時候隱含的編譯了,故在寫微控制器程式的時候無需考慮。而
stm32
的啟動有相應的啟動檔案,本文將採用keil mdk自帶的啟動檔案stm32f10x.s進行分析。
1 啟動模式的選擇
stm32
晶元自帶的啟動方式有3種如下表
啟動模式選擇引腳
啟動模式
說明boot1
boot0x0
主快閃儲存器儲存器
主快閃儲存器儲存器作為啟動區域01
系統儲存器
系統儲存器作為啟動區域11
內建sram
內建sram作為啟動葡萄
stm32
就程式的啟動而言,採用以上3種方式啟動,但對於乙個嵌入式系統的程式來說,如果程式執行檔案很大,而
stm32
內建的儲存空間有限,就需要外接nand flash/nor flash 和sdram,即程式儲存在flash中,程式執行在sdram中,既節約了成本有提高了執行效率。如果採用外接的flash+sdram的方式,就需要乙個更加複雜的啟動檔案(bootloader),需要考慮flash的copy,flash的驅動,記憶體的管理,通訊機制等,本文暫不涉及此內容,以後有機會專門講述。
2 啟動檔案stm32f10x.s分析
關於stm32f10x.s的啟動檔案,主要做了3個工作:分配和初始化堆、棧;定義復位向量並初始化;中斷向量表及其相應的異常處理程式。
2.1 定義堆、棧及其初始化
堆和棧是能夠執行c語言的前提,如以下程式:
定義棧:
stack_size equ 0x00000200
area stack, noinit, readwrite, align=3
stack_mem space stack_size
__initial_sp
定義堆:
heap_size equ 0x00000000
area heap, noinit, readwrite, align=3
__heap_base
heap_mem space heap_size
__heap_limit
初始化堆、棧:
_user_initial_stackheap
ldr r0, = heap_mem
ldr r1, =(stack_mem + stack_size)
ldr r2, = (heap_mem + heap_size)
ldr r3, = stack_mem
bx lr
2.2 定義復位向量
boot引腳的設定不同,復位時,起始位址的位置不同,sram的起始位址為0x2000000, flash的起始位址為0x8000000。cortex-m3核心規定,起始位址必須存放堆定指標,而第二個位址必須存放復位中斷入口向量。在系統復位時,核心會自動從其實位址的下乙個位址(即32位)空間取出復位中斷入口向量,然後跳轉到復位中斷服務程式,該服務程式就會跳轉到main()執行程式。
中斷向量表(部分向量):
__vectors
dcd __initial_sp ; top of stack // 初始化堆跳轉
dcd reset_handler ; reset handler // 復位中斷向量跳轉
dcd nmi_handler ; nmi handler
dcd hardfault_handler ; hard fault handler
dcd memmanage_handler ; mpu fault handler
dcd busfault_handler ; bus fault handler
dcd usagefault_handler ; usage fault handler
dcd 0 ; reserved
dcd 0 ; reserved
dcd 0 ; reserved
dcd 0 ; reserved
dcd svc_handler ; svcall handler
dcd debugmon_handler ; debug monitor handler
dcd 0 ; reserved
dcd pendsv_handler ; pendsv handler
dcd systick_handler ; systick handler
復位中斷服務程式
; reset handler // 該程式會跳轉到main()
reset_handler proc
export reset_handler [weak]
import __main
ldr r0, =__main
bx r0
endp
3 其他中斷向量及服務子程式
在啟動檔案中,只定義了中斷向量,其相應的服務子程式跳轉到空操作。為以後擴充套件中斷服務程式做了準備。
在以上這些都勝利跑完之後,我們的微處理器(mcu)就開始main函式之旅……
STM32啟動流程
先闡述乙個問題,嵌入式應用程式以c語言為主,因此main函式成為程式執行的起點,但是我們忽略了乙個問題 mcu 微控制器 微控制器 上電之後,是如何尋找並執行main函式的呢?stm32晶元自帶的啟動方式有3種,通過設定boot1 boot0的引腳的高低電平即可選擇。系統儲存器啟動是將程式寫入到一塊...
stm32啟動檔案分析
這篇文章主要是分析stm32啟動檔案,啟動檔案是由彙編編寫的,檔名為startup stm32f40 41 s。啟動檔案最主要的功能就是初始化堆疊指標sp,執行復位程式進入c語言main函式 1.初始化堆疊空間大小,定義棧頂位置 堆起始位置等等 2.定義中斷向量表,初始化sp指標 3.reset h...
STM32啟動檔案分析
1.啟動檔案主要作用 a.初始化指標大小 b.初始化堆指標大小 c.初始化中斷向量表 d.初始化系統時鐘 e.呼叫 main,實現堆疊的初始化,最終跳轉到c的main當中 2.棧主要儲存程式的變數,當程式變數較多時,可以將棧分配的更大,但不能超過內部sram的大小 mdk中,全域性變數和區域性變數都...