1.MAP文件浅析
1.1.MDK编译后生成的中间过程文件
1.2.Map文件构成:
- 程序段交叉引用关系(Section Cross References):描述各文件之间函数调用关系
- 删除映像未使用的程序段(Removing Unused input sections from the image):描述工程中未用到被删除的冗余程序段(函数/数据)
- 映像符号表(Image Symbol Table):描述各符号(程序段/数据)在存储器中的地址、类型、大小等
- 映像内存分布图(Memory Map of the image):描述各个程序段(函数)在存储器中的地址及占用大小
- 映像组件大小(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等内核复位后,做的第一件事:
- 从地址 0x0000 0000 处取出堆栈指针 MSP 的初始值,该值就是栈顶地址
- 从地址 0x0000 0004 处取出程序计数器指针 PC 的初始值,该值是复位向量
- 芯片厂商可以会把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作用