STM32F1系列.map文件分析

一、概述

我们通过学习STM32F1知道,想要优化代码就必须知道工程的rom和ram的占用情况。所以,我们就要用到.map文件,通过分析.map文件,可以方便查看工程rom和ram的占用情况,包括单个源文件甚至每个函数的rom。

问:那.map到底可以分为几个部分呢?

答:通过仔细阅读.map文件,我们可以大致分为5个部分:

  • 列出不同函数的调用关系

  • 列出被MDK优化的冗余函数

  • 列出局部标签和全局标签

  • 列出映像文件的内存映射

  • 列出映像文件的组件大小

二、.map文件分析

1.基本概念

段(section):描述映像文件的代码和数据块。

RO:Read-Only的缩写,包括RO-data(只读数据)和RO-code(代码)。

RW:Read-Write的缩写,主要是RW-data,Rw-data由程序初始化初始值。

ZI:Zero-initialized的缩写,主要是ZI-data,由编程器初始化为0。

.text:与RO-code同义

.constdata:与RO-data同义

.bss:与ZI-data同义,通常是指存放未初始化的全局变量的区域

.data:与RW-data同义

2.实例分析

第一部分:

这部分代码反映出了各个函数的调用关系,比如箭头就表明了main文件代码段里就调用了led文件代码段里的LED_Init函数。

第二部分:

MDK里面有一个配置选项,假设没勾选可以看出编译器优化了3个冗余函数,大概50个字节。接着我们把选项打开,再全编译一下看看结果。

这时候就很明显可以看出编译器优化了很多没用到的代码了,节省了起码3258个字节的空间。所以个人建议以后大家创建工程的时候还是把选项选上吧。

第三部分:

问:什么是局部标签?什么是全局标签?

答:局部标签就是在函数内部用static声明的变量,还有用static声明的函数,基本上都是属于局部标签;全局标签就是不是用static声明的这种静态的变量和函数,是auto声明的全局变量和C文件函数就属于全局标签。还有就是汇编文件里面的变量如果作用域是本文件的就是局部标签,作用域是全工程的就是全局标签。

其实我觉得我们不用很会区分这些,反正就这两个标号,不在局部里就肯定在全局里,懂得在.map里面找就行了。

这个i.这个前缀就表示是在某个文件里面的某个函数,例如这里的stm32f10x_it文件里面的BusFault_Handler函数;这个SetSysClock要注意一下,为什么前面用i.前缀修饰过的函数,后面又出现一次呢?原来是因为这个函数是用static修饰的一个局部标签函数,用了8个字节的RAM大小,类型属于M3的Thumb指令代码。

第四部分:

这里主要有几个点,首先就是映像的入口地址0x8000131,然后可以知道加载域的起始地址,大小,最后知道执行域ROM和RAM的起始地址和大小。

还有要注意的是,在执行映像之前,必须将已初始化的RW数据从ROM中复制到RAM中的执行地址并创建ZI Section(初始化为0的变量区)。

问:为什么要这么做呢?谁来完成这一步骤呢?

答:因为我们的代码是存在Flash里面的,一上电代码并不会在ROM里面运行,我们得先把ROM里面的代码复制到RAM里面才能运行起来。这一步骤应该是由__main这个函数封装起来执行的。

总体来说,我们编译出来的代码,Code、RO-data和RW-data这几部分都是存在FLASH里面的,然后通过启动文件把RW数据复制到RAM中运行。

第五部分:

最后一部分就比较简单了,无非就是各个映像组件在各个文件中的代码大小,我们比较关心的是实际下载到FLASH中的大小,例如上面的Total ROM Size。

总结:

以上就是我对.map文件的简单分析,可能有些地方讲的不好,请各位大佬指出。谢谢!

猜你喜欢

转载自blog.csdn.net/SammySum/article/details/86485039