一文看懂Stm32程序結構和啓動過程

Stm32程序啓動過程分析

程序在Flash的結構

使用Keil編譯程序後,程序分爲4部分:
在這裏插入圖片描述

  1. Code:代碼區,指程序中代碼即函數體的大小,注意程序中未使用的函數也會算在CODE中,也即會佔用FLASH空間,因此不用的函數最好刪除掉,以免佔用過多FLASH空間;
  2. RO-data:RO就是隻讀的意思,程序中只讀的變量(也就是帶Const的)和已初始化的字符串等;
  3. RW-data:特指已初始化的可讀可寫全局/靜態變量;
  4. ZI-data:未初始化的可讀可寫全局/靜態變量,注意初始化爲0也算做未初始化,用到的堆空間和棧空間也會被算入這裏面;

根據生成的*.map 文件:
在這裏插入圖片描述
可看出Load(下載後沒有運行)和 Execution(程序正常運行)下固件的內存映射:
其中Code和RO-data對應RO section,RW section爲RW-data,ZI section爲ZI-data。
在這裏插入圖片描述
各部分Size情況在*.map文件中有統計:
在這裏插入圖片描述

啓動過程

啓動方式

因爲固定的內存映射方式,代碼區域總是從0x00000000開始,數據區域(SRAM)總是從0x20000000開始,在STM32F4xx系列芯片中,有三種boot 模式,通過BOOT[1:0]引腳選擇:
在這裏插入圖片描述
同時,將0x00000000映射到相應的啓動位置的物理地址。例如從Flash memory啓動時,會將0x00000000映射到0x08000000。
在這裏插入圖片描述

啓動過程

  1. 根據BOOT[1:0]確定啓動方式,例如從Flash memory啓動;
  2. 取出0x0000_0000(0x0800_0000)的棧指針和0x0000_0004(0x0800_0004)處的PC指針;
    在這裏插入圖片描述
    棧頂地址可以在*.map 文件中找到 0x2000_0298 + 0x0000_0400。
    在這裏插入圖片描述
    Reset_Handle的入口地址可以在*.map中找到。
    在這裏插入圖片描述
  3. 根據Startup*.s文件定義的復位函數,執行SystemInit和__main函數。
; Reset handler
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main

                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP
  1. SystemInit函數可以在*.c文件中找到,不在贅述,比較重要的是__main()函數,該函數通過調用__scatterload_copy實現RW section的拷貝,__scatterload_zeroinit實現ZI section的初始化;
  2. 初始化堆和棧,而後SRAM結構如下圖所示:
    在這裏插入圖片描述
  3. 進入main函數,程序正常運行後,如下圖所示。
    在這裏插入圖片描述

參考:
https://blog.csdn.net/ybhuangfugui/article/details/75948282
https://www.cnblogs.com/39950436-myqq/p/11387179.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章