上一篇文章我寫了STM32的RAM和Flash,文章最后我建議大家來深入研究一下STM32上電啟動(dòng)過程。同時(shí)有小伙伴留言說想讓我講一下IAP(在線升級(jí)程序)。其實(shí)如果搞懂STM32的上電啟動(dòng)過程,那么IAP就可以信手拈來了。下面我們一起來研究研究。
先說啟動(dòng)文件
我們正常在操作一款單片機(jī)的時(shí)候,都是從main函數(shù)開始進(jìn)行編程的,但是單片機(jī)上電是從main函數(shù)開始執(zhí)行的嗎?答案當(dāng)然是否定的,在main函數(shù)之前單片機(jī)最先執(zhí)行的是硬件設(shè)置SP、PC然后是“啟動(dòng)文件”,一般主要是項(xiàng)目文件里面的startup_xxxxx.s文件。其實(shí)這個(gè)就是我們常說的Bootloader。
其實(shí)不光STM32系列單片機(jī)是這樣,我們接觸的NXP的微控制器、TI的MSP430以及51單片機(jī)等等其實(shí)都是有上述的啟動(dòng)文件的。啟動(dòng)文件負(fù)責(zé)的就是從單片機(jī)復(fù)位開始到main函數(shù)之前這段時(shí)間所需要進(jìn)行的工作。我們一般很少接觸啟動(dòng)文件的主要原因是開發(fā)環(huán)境往往給開發(fā)者自動(dòng)的提供了這個(gè)啟動(dòng)文件,不需要我們?cè)偃ゲ傩模苯訌膍ain函數(shù)開始進(jìn)行設(shè)計(jì)就可以了。
STM32三種啟動(dòng)方式
接觸過STM32系列單片機(jī)的朋友應(yīng)該知道STM32有三種啟動(dòng)模式,用戶可以通過設(shè)置BOOT0和BOOT1的引腳電平狀態(tài),來選擇復(fù)位后的啟動(dòng)模式。
需要注意的是STM32上電復(fù)位以后,代碼區(qū)都是從0x00000000開始的,三種啟動(dòng)模式只是將各自存儲(chǔ)空間的地址映射到0x00000000中。
1)從Flash啟動(dòng),將Flash地址0x08000000映射到0x00000000,這樣啟動(dòng)以后就相當(dāng)于從0x08000000開始的,這是我們最常用的模式;
2)從SRAM啟動(dòng),將SRAM地址0x20000000映射到0x00000000,這樣啟動(dòng)以后就相當(dāng)于從0x20000000開始的,用于調(diào)試,筆者基本沒用過;
3)從系統(tǒng)存儲(chǔ)器啟動(dòng)(可以看上篇文章里的內(nèi)存映射圖,System memory),將系統(tǒng)存儲(chǔ)器地址0x1FFFF000映射到0x00000000,這樣啟動(dòng)以后就相當(dāng)于從0x1FFFF000開始執(zhí)行的,值得注意的是這個(gè)系統(tǒng)存儲(chǔ)器里面存儲(chǔ)的其實(shí)是STM32自帶的Bootloader代碼,這其實(shí)是一個(gè)官方的IAP,它提供了可以通過UART1接口將用戶的代碼下載到Flash中的功能,下載完以后再切換到從Flash中啟動(dòng)就可以正常運(yùn)行了。打個(gè)比方這個(gè)官方的Bootloader就相當(dāng)于我們玩路由器時(shí)的“不死breed”。筆者之前在調(diào)STM32低功耗的時(shí)候?qū)⑾螺d口給復(fù)用了其他功能導(dǎo)致“變磚”,就是通過這種方式恢復(fù)的
切回正題
下面我們來具體看一下從用戶的Flash啟動(dòng)STM32,從上電到main函數(shù)之間的這段時(shí)間都做了什么。
1)第一步是硬件設(shè)置SP、PC
我們參考《Cortex-M3權(quán)威指南》向量表章節(jié)表7.6,如下圖所示:
前兩段地址主要是用來指定SP和PC的初值,上一節(jié)我們已經(jīng)知道了映射關(guān)系,所以這時(shí)已自動(dòng)從0x08000000位置處讀取數(shù)據(jù)賦值給了棧指針SP,從0x08000004位置處讀取數(shù)據(jù)賦值給了PC。需要注意的是這個(gè)復(fù)位向量初始值并不是固定的,可以通過一個(gè)叫“向量表偏移量寄存器”來修改定位。
下圖是我們那個(gè)開源OLED時(shí)鐘項(xiàng)目的HEX文件,用J-Flash打開就可以看到設(shè)置完的SP=0x20005B88,PC=0x0800282D。
2)第二步是設(shè)置系統(tǒng)時(shí)鐘
我們接著來追蹤系統(tǒng)的運(yùn)行軌跡,上面我們已經(jīng)知道了PC的地址為0x0800282D,但是這沒有遵循4字節(jié)對(duì)齊,我們將其對(duì)齊為0x0800282C,這時(shí)我們打開項(xiàng)目文件里面的.map文件,找到這個(gè)地址,如下圖示:
我們發(fā)現(xiàn)來到了第一節(jié)說的startup_xxxxx.s文件,我們打開startup文件找到:
我們發(fā)現(xiàn)運(yùn)行到了SystemInit,C的世界我們就不陌生了,在項(xiàng)目文件的system_stm32f10x.c里面可以找到SystemInit函數(shù),也就是初始化系統(tǒng)時(shí)鐘了。
3)第三步是___main
到這里大家可能會(huì)以為已經(jīng)到了main函數(shù)了,其實(shí)不是這樣的。___main和main是不一樣的,我們尋找這個(gè)___main會(huì)發(fā)現(xiàn)找不到,startup文件里面沒有,map文件里面也沒有。其實(shí)它是在MDK自帶的庫里面了,主要的功能是軟件設(shè)置SP、加載.data.bss并初始化棧區(qū)。由于需要在線跟蹤才能看到,我在這里就不給大家列出來了,感興趣的朋友可以深入研究一下。
4)最后來到C的世界
在執(zhí)行到___main的最后就跳轉(zhuǎn)到了C文件的main函數(shù)了。
最后用一張圖來整體看一下流程:
總 結(jié)
到這里STM32的存儲(chǔ)器以及上電啟動(dòng)過程就完整的總結(jié)完了,希望對(duì)大家有所幫助,大家如果感興趣可以在調(diào)試STM32的時(shí)候一步一步的來跟蹤一下看看,每一款單片機(jī)的啟動(dòng)文件其實(shí)都是很值得玩味的,對(duì)我們系統(tǒng)的來體會(huì)控制器的架構(gòu)、指令集、中斷向量等內(nèi)容是很有幫助的。大家如果將啟動(dòng)過程了解清楚了對(duì)我們后面來進(jìn)行IAP等有意思的操作是很有幫助的。
-
STM32
+關(guān)注
關(guān)注
2293文章
11032瀏覽量
365089 -
IAP
+關(guān)注
關(guān)注
2文章
165瀏覽量
25054
發(fā)布評(píng)論請(qǐng)先 登錄
繞線轉(zhuǎn)子永磁電機(jī)啟動(dòng)過程準(zhǔn)時(shí)間最優(yōu)控制
晶閘管控制異步電機(jī)軟啟動(dòng)過程中振蕩現(xiàn)象研究
電機(jī)軟啟動(dòng)器無故障報(bào)警停機(jī)原因分析與控制系統(tǒng)改造
GaN、超級(jí)SI、SiC這三種MOS器件的用途區(qū)別
STM32F103做從站 上電過程,上位機(jī)不斷發(fā)送數(shù)據(jù)造成,通訊失敗怎么解決?
STM32的上電啟動(dòng)過程分享
干貨!!!開關(guān)電源的軟啟動(dòng)過程分析
BQ79600-Q1啟動(dòng)過程

AIC3254啟動(dòng)過程是怎樣的?需要功能調(diào)節(jié)延時(shí),請(qǐng)問怎么實(shí)現(xiàn)?
什么是PID調(diào)節(jié)器的三種模式
負(fù)載電容對(duì)電源轉(zhuǎn)換器啟動(dòng)過程的影響

評(píng)論