stm32之Map文件分析
总结 stm32 编译过程中生成的 Map 文件的各个部分的作用。
前言
事实上,在 MDK 编译过程生成的文件种类数量达到了 11 种类型:.axf、.crf、.d、.dep、.hex、.lnp、.lst、.o、.htm、bulild_log.htm 和.map。
对于我们来说重要的是 Map
文件,它是用来显示程序的内存布局的。我们用来调试程序是有益的。
在 Keil 种打卡 Map 文件的方法:
- 双击工程名可以直接打开 Map 文件。
- 在 Output 文件夹种找到 Map 文件。
Map 文件分析
首先,我们确定 Mao 文件包含的信息:
- 各个段之间的指向关系
- 各个段之间的处于哪个内存区域
- 符号表
- 删除程序没有使用的符号
- 大小
分析前的准备
Map 文件中的基本概念
i.main这个符号表示 main 的入口函数,其他的 i. 同理
前面我们提到了,Map 文件主要是有五个部分组成的。下面我们主要对于这五个部分进行分析。
Section Cross References 各个段之间的指向关系
打开 MAP 文件所看到的第一部分就是各个段之间的指向关系。
前面我们提到了,这里的 i
所表示的是 input
即函数入口地址的意思。如,i. sys_stm32_clock_init
仅仅表示sys_stm32_clock_init
函数入口地址
for
后面就表示这个文件中所使用的文件。如 main.c
中调用了函数 led_gpio_config
gpio_bit_write
等等。
所以通过这个文件,我们可以知道哪个文件使用了哪些函数。
Removing Unused input sections from the image. 删除程序没有使用的符号
第二部分告诉我们,删除程序没有使用的符号。
Image Symbol Table 符号表
第三部分是符号表。
符号表中包含了本地符号和全局符号。
图中红框框处部分,表示 sys.c 文件中的 sys_stm32_clock_init 函数的入口地址为:0x08002bc9,类型为:Thumb Code(程序段),大小为 344 字节。
注意,此处的地址用的 0x08002bc9,和 2.1.3.1 节的 0x08002bc8 地址不符,这是因为ARM 规定 Thumb 指令集的所有指令,其最低位必须为 1,0x08002bc9 = 0x08002bc8 + 1,所以才会有 2 个不同的地址,且总是差 1,实际上就是同一个函数。
Memory Map of the image 各个段之间的处于哪个内存区域
第四部分就是内存映射了。
映像文件分为加载域(Load Region)和运行域(Execution Region),一个加载域必须有至少一个运行域(可以有多个运行域),而一个程序又可以有多个加载域。加载域为映像程序的实际存储区域,而运行域则是 MCU 上电后的运行状态。加载域和运行域的简化关系(这里仅表示一个加载域的情况)图如图 2.1.4.1 所示:
由图可知,RW 区也是存放在 ROM(FLASH)里面的,在执行 main 函数之前,RW(有初值且不为 0 的变量)数据会被拷贝到 RAM 区,同时还会在 RAM 里面创建 ZI 区(初始化为 0 的变量)
Image component sizes 大小
最后一部分是映像文件的大小。
映像组件大小(Image component sizes)给出了整个映像所有代码(.o)占用空间的汇总信息,对我们比较有用。
其中,Debug 那一列不需关心