嵌入式学习笔记:深入解析STM32启动过程

1.MAP文件浅析

1.1.MDK编译后生成的中间过程文件

1.2.Map文件构成:

  1. 程序段交叉引用关系(Section Cross References):描述各文件之间函数调用关系
  2. 删除映像未使用的程序段(Removing Unused input sections from the image):描述工程中未用到被删除的冗余程序段(函数/数据)
  3. 映像符号表(Image Symbol Table):描述各符号(程序段/数据)在存储器中的地址、类型、大小等
  4. 映像内存分布图(Memory Map of the image):描述各个程序段(函数)在存储器中的地址及占用大小
  5. 映像组件大小(Image component sizes):给出整个映像代码(.o)占用空间汇总信息

1.3.与MAP相关的概念

名词 别称 解释 内存
Section / 程序段 /
RO(Read Only) data .constdata 只读数据 Flash(ROM)
RO(Read Only) code .text 只读代码 Flash(ROM)
RW(Read Write) .data 可写数据(定义了且初始化不为0) Flash(ROM)/SRAM
ZI(Zero initialized) .bss 定义了但没初始化(初始化为0) SRAM

总结:MAP文件是MDK编译代码后,产生的集程序、数据及IO空间的一种映射列表文件,简单说就是包括了:各种.c文件、函数、符号等的地址、大小、引用关系等信息。MAP的主要作用是分析各.c文件占用FLASH 和 RAM的大小,方便优化代码

2.STM32启动过程

2.1.STM32STM32启动模式(自举模式)

M3/M4/M7等内核复位后,做的第一件事:

  1. 从地址 0x0000 0000 处取出堆栈指针 MSP 的初始值,该值就是栈顶地址
  2. 从地址 0x0000 0004 处取出程序计数器指针 PC 的初始值,该值是复位向量
  3. 芯片厂商可以会把0x0000 0000和0x0000 0004地址映射到其它的地址(如0x0800 0000和0x0800 0004

    启动模式选择表(STM32F1)
    (F4与其类似,FSMC可重映射到外部SRAM,F7/H7只有一个BOOT)

2.2.STM32启动过程(以Flash为例)

  • 初始化MSP,从0x0800 0000获取堆栈指针 MSP,此时会设置堆(Heap_Size)和栈(Stack_Size)的大小
  • 初始化PC,从0x0800 0004获取程序计数器指针PC,此时PC指向中断向量表(Reset Vector,既__Vector),在中断向量表中,第一条指令即是Reset_Handler
  • 在Reset_Handler函数中,会调用SystemInit函数(可选),并调用标准C库函数__mian()执行一系列设置,调用main函数
  • __main()函数的细节
    __scatterload():把RW/RO输出段从装载域地址复制到运行域地址,并完成了ZI运行域的初始化工作
    __rt_entry():完成库函数的初始化
    __user_setup_stackheap():初始化堆栈
  • 请添加图片描述

    栈(Stack):编译器自动分配和释放,存放函数参数、函数调用、局部变量等
    堆(Heap):程序分配和释放,如malloc、calloc、realloc等
    函数局部变量较多,嵌套关系复杂时,需加大栈大小(Stack_Size)

    Reset_Handler函数如下:

    Reset_Handler   PROC								//PROC:定义子程序
    													//WEAK:弱定义
                    EXPORT  Reset_Handler   [WEAK]		//EXPORT:标明全局属性,可被外部调用
                    IMPORT  __main						//IMPORT:申明来自外部文件,类extern
                    IMPORT  SystemInit
                    LDR   R0, =SystemInit
                    BLX   R0               
                    LDR   R0, =__main
                    BX      R0
                    ENDP								//ENDP:表示子程序结束
    

    【注】Reset_Handler的作用:外部存储器配置;中断向量表地址配置。

    __main()参考链接:
    【1】STM32 启动解析__main main
    【2】MDK __main()代码执行过程分析
    【3】【stm32】stm32深入思考(1) 之 系统启动流程 main之前的过程,__main作用,start.s作用

    物联沃分享整理
    物联沃-IOTWORD物联网 » 嵌入式学习笔记:深入解析STM32启动过程

    发表评论