STM32 单片机启动流程
STM32 單片機啟動流程
剛接觸ARM的cortex-m系列單片機時,被告知一切都從main() 函數(shù)開始,要將程序?qū)懺趍ain()函數(shù)中。而仿真時也貌似是從main() 函數(shù)開始的,以STM32F103為例。
后來了解到全局變量是在main()函數(shù)之前初始化的。MDK默認情況下勾選下面選項,跳過了啟動的匯編部分代碼,直接進入了main() 函數(shù).
實際起始位置
在cortex-m系列中,中斷向量表存放在 Flash 開始部分,Flash中第一個字存放棧頂指針,第二個字存放復位中斷服務函數(shù)入口地址,其他中斷服務函數(shù)入口地址依次存放在Flash中。
MCU上電后,會將Flash中的第一個字加載到R13 MSP寄存器中,第二個字加載到R15 PC寄存器中。
從上圖可以看出ARM規(guī)定了M3,M4內(nèi)核要從地址0x0000 0000讀取中斷向量表,而STM32設置Flash地址到0x0800 0000怎么辦?
STM32將地址0x0800 0000開始的內(nèi)容重映射到首地址0x0000 0000中,這樣就解決了從0x0000 0000讀取中斷向量表的問題。
下圖可以看出STM32F105實際讀出的0x0000 0000和0x0800 0000內(nèi)容一樣
R13:棧頂指針寄存器SP
SP寄存器有兩個,MSP或者PSP,PSP是為了RTOS特意設置的,如果使用RTOS,則在RTOS的任務中就是使用的PSP,在中斷服務函數(shù)中則使用MSP。如果不使用RTOS,則默認一直使用MSP。
在MCU中,RAM只是負責暫存數(shù)據(jù),真正的運算是在寄存器中完成的,例如要對兩個變量進行加法運算,就需要將兩個變量的值從RAM中取出存入寄存器中,然后操作寄存器進行計算,最后將計算結(jié)果存入RAM中。因此常說的在進入子函數(shù)或者中斷服務函數(shù)時需要保存現(xiàn)場,其實也就是保存寄存器中的值,將寄存器值PUSH在棧中。
SP寄存器指向棧頂?shù)刂?#xff0c;因此隨著PUSH和POP,SP寄存器會跟著自動變化。
MSP寄存器存放棧頂指針,棧中存放局部變量、函數(shù)參數(shù)以及進入子函數(shù)、中斷服務函數(shù)前寄存器的值,當從子函數(shù)或者中斷服務函數(shù)中跳出時,會從棧中POP寄存器值,也就是恢復現(xiàn)場,確保程序可以正常執(zhí)行。平時盡量不讓使用遞歸就是為了防止多次調(diào)用自身,多次保存現(xiàn)場導致棧溢出。
入棧和出棧操作由編譯器自動生成代碼,但是入棧時默認只會將R0-R3入棧,如果中斷服務函數(shù)過于復雜,則編譯器也會將R4-R11入棧,這也就是為什么中斷服務函數(shù)盡量簡短的原因之一。
R15:程序計數(shù)寄存器PC
PC寄存器指向當前的程序地址。如果修改它的值,就能改變程序的執(zhí)行流(很多高級技巧就在這里面)
上電時將中斷向量表中的第二個字加載到PC寄存器中,也就是讓程序跳轉(zhuǎn)到復位中斷服務函數(shù)中。
不過復位中斷服務函數(shù)是一個匯編函數(shù)。
復位中斷服務函數(shù)中調(diào)用了SystemInit()函數(shù),該函數(shù)主要作用是設置中斷向量表的偏移地址。也就是說中斷向量表位置是可變的,當使用BOOT后,就需要在APP修改該偏移地址。
接著復位中斷服務函數(shù)跳轉(zhuǎn)到__main()函數(shù)中,__main()和我們平時說的main()函數(shù)是有區(qū)別的。
RAM掉電會丟失數(shù)據(jù),在上電后,RAM中的數(shù)據(jù)是不確定的,在運行main()函數(shù)之前需要將RAM中的數(shù)據(jù)初始化,也就是下圖左邊到右邊的過程,將flash中的RW數(shù)據(jù)加載到RAM中,并將RAM中的ZI段數(shù)據(jù)進行初始化操作。MDK中__main()函數(shù)幫我們自動完成了這個操作,也就是所謂的準備C語言環(huán)境,C語言環(huán)境準備好之后會跳到 main() 函數(shù)。
最后,其實還少說了一個,在上電后會根據(jù)boot0,boot1 的狀態(tài)確定自舉空間的位置,如果從系統(tǒng)存儲器自舉(系統(tǒng)bootLoad,出廠時,官方固化在單片機中的一段代碼,用戶無法修改的。在STM32中,常用的串口下載,DFU就是系統(tǒng)bootLoad中的功能),系統(tǒng)bootLoad執(zhí)行完畢后才是我們上面說的哪些,文章中的圖大部分來自《Cortex-M3 權(quán)威指南》
總結(jié)
以上是生活随笔為你收集整理的STM32 单片机启动流程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C# 学习笔记(19)操作SQL Ser
- 下一篇: FreeRtos学习笔记(11)查找就绪