一文看懂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

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