HACK實驗室 發表於 2020-05-03 18:03:00
上一篇文章我寫了STM32的RAM和Flash,文章最後我建議大家來深入研究一下STM32上電啟動過程。同時有小夥伴留言說想讓我講一下IAP(在線升級程序)。其實如果搞懂STM32的上電啟動過程,那麼IAP就可以信手拈來了。下面我們一起來研究研究。
先說啟動文件
我們正常在操作一款單片機的時候,都是從main函數開始進行編程的,但是單片機上電是從main函數開始執行的嗎?答案當然是否定的,在main函數之前單片機最先執行的是硬體設置SP、PC然後是「啟動文件」,一般主要是項目文件裡面的startup_xxxxx.s文件。其實這個就是我們常說的Bootloader。
其實不光STM32系列單片機是這樣,我們接觸的NXP的微控制器、TI的MSP430以及51單片機等等其實都是有上述的啟動文件的。啟動文件負責的就是從單片機復位開始到main函數之前這段時間所需要進行的工作。我們一般很少接觸啟動文件的主要原因是開發環境往往給開發者自動的提供了這個啟動文件,不需要我們再去操心,直接從main函數開始進行設計就可以了。
STM32三種啟動方式
接觸過STM32系列單片機的朋友應該知道STM32有三種啟動模式,用戶可以通過設置BOOT0和BOOT1的引腳電平狀態,來選擇復位後的啟動模式。
需要注意的是STM32上電復位以後,代碼區都是從0x00000000開始的,三種啟動模式只是將各自存儲空間的地址映射到0x00000000中。
1)從Flash啟動,將Flash地址0x08000000映射到0x00000000,這樣啟動以後就相當於從0x08000000開始的,這是我們最常用的模式;
2)從SRAM啟動,將SRAM地址0x20000000映射到0x00000000,這樣啟動以後就相當於從0x20000000開始的,用於調試,筆者基本沒用過;
3)從系統存儲器啟動(可以看上篇文章裡的內存映射圖,System memory),將系統存儲器地址0x1FFFF000映射到0x00000000,這樣啟動以後就相當於從0x1FFFF000開始執行的,值得注意的是這個系統存儲器裡面存儲的其實是STM32自帶的Bootloader代碼,這其實是一個官方的IAP,它提供了可以通過UART1接口將用戶的代碼下載到Flash中的功能,下載完以後再切換到從Flash中啟動就可以正常運行了。打個比方這個官方的Bootloader就相當於我們玩路由器時的「不死breed」。筆者之前在調STM32低功耗的時候將下載口給復用了其他功能導致「變磚」,就是通過這種方式恢復的
切回正題
下面我們來具體看一下從用戶的Flash啟動STM32,從上電到main函數之間的這段時間都做了什麼。
1)第一步是硬體設置SP、PC
我們參考《Cortex-M3權威指南》向量表章節表7.6,如下圖所示:
前兩段地址主要是用來指定SP和PC的初值,上一節我們已經知道了映射關係,所以這時已自動從0x08000000位置處讀取數據賦值給了棧指針SP,從0x08000004位置處讀取數據賦值給了PC。需要注意的是這個復位向量初始值並不是固定的,可以通過一個叫「向量表偏移量寄存器」來修改定位。
下圖是我們那個開源OLED時鐘項目的HEX文件,用J-Flash打開就可以看到設置完的SP=0x20005B88,PC=0x0800282D。
2)第二步是設置系統時鐘
我們接著來追蹤系統的運行軌跡,上面我們已經知道了PC的地址為0x0800282D,但是這沒有遵循4位元組對齊,我們將其對齊為0x0800282C,這時我們打開項目文件裡面的.map文件,找到這個地址,如下圖示:
我們發現來到了第一節說的startup_xxxxx.s文件,我們打開startup文件找到:
我們發現運行到了SystemInit,C的世界我們就不陌生了,在項目文件的system_stm32f10x.c裡面可以找到SystemInit函數,也就是初始化系統時鐘了。
3)第三步是___main
到這裡大家可能會以為已經到了main函數了,其實不是這樣的。___main和main是不一樣的,我們尋找這個___main會發現找不到,startup文件裡面沒有,map文件裡面也沒有。其實它是在MDK自帶的庫裡面了,主要的功能是軟體設置SP、加載.data\.bss並初始化棧區。由於需要在線跟蹤才能看到,我在這裡就不給大家列出來了,感興趣的朋友可以深入研究一下。
4)最後來到C的世界
在執行到___main的最後就跳轉到了C文件的main函數了。
最後用一張圖來整體看一下流程:
總 結
到這裡STM32的存儲器以及上電啟動過程就完整的總結完了,希望對大家有所幫助,大家如果感興趣可以在調試STM32的時候一步一步的來跟蹤一下看看,每一款單片機的啟動文件其實都是很值得玩味的,對我們系統的來體會控制器的架構、指令集、中斷向量等內容是很有幫助的。大家如果將啟動過程了解清楚了對我們後面來進行IAP等有意思的操作是很有幫助的。
打開APP閱讀更多精彩內容聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容圖片侵權或者其他問題,請聯繫本站作侵刪。 侵權投訴