通过 map 文件,可以方便的查看工程 ROM/FLASH 和 RAM 的占用情况,包括单个源文件,甚至具
体到每个函数的 rom 大小都给出了,通过这些信息可以很好的进行代码优化。 MAP 文件的内容可分为如
下几部分:
- Section Cross References
- Removing Unused input sections from the image
- Image Symbol Table (Local Symbols Global Symbols)
- Memory Map of the image
-
配置 MDK 以生成 MAP 文件
要生成 MAP 文件, MDK 中如下选项要选上:
将工程全编译,且没有错误后,双击这里就可以看到生成的 map 文件了:
MAP 文件相关概念
认识 MAP 文件前先熟悉如下概念:
段(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 同义。
-
Section Cross References
这部分主要是不同文件中函数的调用关系(部分截图):
比如这句: main.o(i.main) refers to main.o(i.PrintfLogo) for PrintfLogo 表示 main.c 文件中的 main
函数调用了 PrintfLogo。Removing Unused input sections from the image
这部分主要是被删除的冗余函数,也就是添加到工程里面,但是没有调用到的, 下面是部分被删除冗
余函数的截图效果:
对于这个部分功能,用户最好将 MDK 中One ELF Section per Function
这个选项勾上,然后全编译工程,效果会比较好,有助于减小映像文件大小:
Image Symbol Table
Image Symbol Table 主要分为两类,分别是 Local Symbols 和 Global Symbols。
Local Symbols
Local Symbols 记录了用 static 声明的全局变量地址和大小, C 文件中函数的地址和用 static 声明的
函数代码大小,汇编文件中的标号地址(作用域限本文件),下面是部分截图:
Global Symbols
Global Symbols 记录了全局变量的地址和大小, C 文件中函数的地址及其代码大小,汇编文件中的
标号地址(作用域全工程) , 下面是部分截图:
Memory Map of the image
映像文件可以分为加载域(Load Region)和运行域(Execution Region): 加载域反映了 ARM 可
执行映像文件的各个段存放在存储器中的位置关系。 下面是部分截图, 另外映像中的入口点就是程序开始
执行的位置。
运行域反映了 ARM 可执行映像文件各个段真正执行时在存储器中的位置关系:
简单的说,加载域就是程序在 Flash 中的实际存储,而运行域是芯片上电后的运行状态,通过下面的框图
可以有一个感性的认识:
通过上面的框图可以看出, RW 区也是要存储到 ROM/Flash 里面的, 在执行映像之前,必须将已初始化
的 RW 数据从 ROM 中复制到 RAM 中的执行地址并创建 ZI Section(初始化为 0 的变量区) 。Image component sizes(映像组件大小)
Image component sizes 映像组件大小比较重要,比如下面内容代表的含义:
Code (inc. Data) :显示代码占用了多少字节。 在此映像中,有 19442 字节的代码, 其中包括 1832
字节的内联数据 (inc. data),例如文字池和短字符串。
- RO Data :显示只读数据占用了多少字节( 比如 const char buf[] = “123456”)。这是除 Code (inc.
data) 列中包括的内联数据之外的数据。
- RW Data :显示读写数据占用了多少字节。
- ZI Data :显示零初始化的数据占用了多少字节。
- Debug :显示调试数据占用了多少字节,例如,调试输入节以及符号和字符串。
- Object Totals :显示链接到一起以生成映像的对象占用了多少字节。
- (incl. Generated):链接器会生成的映像内容,例如,交互操作中间代码。 如果 Object Totals 行
包含此类型的数据,则会显示在该行中。本例中共有 1016 字节的 RO 数据,其中 32 字节是链接
器生成的 RO 数据。
- (incl. Padding) :链接器根据需要插入填充,以强制字节对齐。
下面的 Library Totals 显示已提取并作为单个对象添加到映像中的库成员占用了多少字节。
下面是我们经常要查看的内容:
- Grand Totals:显示映像的真实大小。
- ELF Image Totals: ELF(Executable and Linking Format)可执行链接格式映像文件大小。
- ROM Totals:显示包含映像所需的 ROM 的最小大小。这不包括 ZI 数据和存储在 ROM 中的调试
信息。