STM32啟動過程分析

2021-09-02 03:33:33 字數 2978 閱讀 7133

硬體: stm32f1系列

軟體環境:keil 4.54

注:本文中提到的rtos以rt-thread為例,不涵蓋所有rtos的情況

在keil mdk中新建工程時會根據所選的device自動生成啟動**檔案startup.s,該檔案的作用可根據其頭部的注釋看出

this module performs:

;* - set the initial sp

;* - set the initial pc == reset_handler

;* - set the vector table entries with the exceptions isr address

;* - configure the clock system

;* - branches to __main in the c library (which eventually

;* calls main()).

;* after reset the cortexm3 processor is in thread mode,

;* priority is privileged, and the stack is set to main.

在startup.s中,完成了堆疊大小和中斷向量表的設定。預設的棧大小為400位元組,堆大小為200位元組,可自行更改。這個棧在bare-metal系統中為全域性所使用,在帶rtos的系統中被作業系統核心和中斷所使用,如果無多層函式巢狀呼叫,通常是夠用的。堆在使用malloc()的時候會被用到。堆疊的設定必須用組合語言完成,因為c語言通常會用到函式,而函式呼叫是依賴於堆疊的。關於startup.s的詳細分析請參考004:stm32啟動檔案詳解及systeminit函式分析一文

系統上電後,預設從位址為0的地方開始執行。在stm32中,若根據boot引腳選擇從主快閃儲存器儲存器啟動,則主快閃儲存器儲存器被對映到啟動空間(0x0000 0000),但仍然能夠在它原有的位址(0x0800 0000)訪問它。0x08000000開始的一段區域存放的是中斷向量表(即startup.s中__vectors開始的部分)

area reset, data, readonly

export __vectors

export __vectors_end

export __vectors_size

__vectors dcd __initial_sp ; top of stack

dcd reset_handler ; reset handler  先是執行__initial_sp設定主堆疊指標msp(相關概念請參考宋岩翻譯的《cortex-m3權威指南》),而後執行復位操作reset_handler

reset_handler    proc

export reset_handler [weak]

import __main

import systeminit

ldr r0, =systeminit

blx r0

ldr r0, =__main

bx r0

endp

reset_handler中首先執行systeminit()函式(在system_stm32f10x.c檔案中定義),該函式主要完成了rcc時鐘的設定。接著執行__main()處的**。在keil ide的工程視窗中,是無法搜尋到__main()的定義的,但在彙編**和工程map檔案中可以找到它的身影
__main                  0x08000121   thumb code     0  entry.o(.arm.collect$$$$00000000)
推測應該是在entry.c檔案中,而entry.c檔案應該是在keil自帶的library裡。 

參考mdk __main()**執行過程分析一文,__main()中主要通過

1. __scatterload()把rw/ro輸出段從裝載域位址複製到執行域位址,並完成zi執行域的初始化工作。

2. __rt_entry()初始化堆疊,完成庫函式的初始化,最後自動跳轉向main()函式。其中__user_initial_stackheap()是在startup.s中定義的

export  __user_initial_stackheap                 

__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

根據aapcs的規定,棧任何時候都得4位元組對齊,在呼叫入口得8位元組對齊。對於帶rtos的系統,該函式根據

area stack, noinit, readwrite, align=3

area heap, noinit, readwrite, align=3

preserve8

保證了主堆疊指標msp是遵守規定的,而執行緒堆疊指標psp全靠自己來保證每次進入c世界時是8位元組對齊,通常的做法是在程式中使用__attribute__((aligned(8)))來告知編譯器在分配空間時採用8位元組對齊。在發生中斷時,如果當前正在使用的棧指標不是8位元組對齊,則先把sp-4,調整為8位元組對齊,參考

cortex-m3 棧的8位元組對齊一文

補充:startup.s定義了中斷處理函式

nmi_handler     proc        ;過程的開始

export nmi_handler [weak]

b . ;原地跳轉(即無限迴圈),

endp ;過程的結束

其中weak作為若定義,意思是如果在別處也定義該symbol,在鏈結時用別處的位址,而stm3210x_it.c這個檔案通常會進行這些中斷處理函式的重新定義

stm32啟動過程

三 總結 這三種模式請看下列圖示 三個不同作用的空間在微控制器裡面佔了三個空間,微控制器引導哪個空間資源啟動,由boot1和boot0決定!正常來說一般是從flash啟動!啟動的程式是在sram上執行!有乙個很關鍵資料結構的知識點,執行時sram會分成以下四個部分 常量區,堆,棧,靜態儲存區!例如 ...

STM32的啟動過程

當執行main函式的時候,晶元不是直接執行main函式的,還有乙個啟動的過程 m3的啟動方式由boot0和boot1選擇,可以有三種啟動方式 最常用的應該是第一種,就是將程式儲存在片內的flash上,掉電後程式不會消失。boot引腳的設定不同,晶元復位後起始位址就不同,選擇從flash啟動的時候,其...

STM32 啟動過程簡述

根據啟動模式分析的結論 1 通過boot引腳設定可以將中斷向量表定位於sram區,即起始位址為0x02000000,同時復位後pc指標位於0x02000000處 2 通過boot引腳設定可以將中斷向量表定位於flash區,即起始位址為0x08000000,同時復位後pc指標位於0x08000000處...