本文转载自《安富莱STM32-V7开发板用户手册,含BSP驱动包设计(V3.0)》

通过 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
  • Image component sizes

    配置 MDK 以生成 MAP 文件

    要生成 MAP 文件, MDK 中如下选项要选上:
    image.png
    将工程全编译,且没有错误后,双击这里就可以看到生成的 map 文件了:
    image.png

    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 同义。
  • .data:与 RW-data 同义

    Section Cross References

    这部分主要是不同文件中函数的调用关系(部分截图):
    image.png
    比如这句: main.o(i.main) refers to main.o(i.PrintfLogo) for PrintfLogo 表示 main.c 文件中的 main
    函数调用了 PrintfLogo。

    Removing Unused input sections from the image

    这部分主要是被删除的冗余函数,也就是添加到工程里面,但是没有调用到的, 下面是部分被删除冗
    余函数的截图效果:
    image.png
    对于这个部分功能,用户最好将 MDK 中 One ELF Section per Function 这个选项勾上,然后全编译工程,效果会比较好,有助于减小映像文件大小:
    image.png

    Image Symbol Table

    Image Symbol Table 主要分为两类,分别是 Local Symbols 和 Global Symbols。

    Local Symbols

    Local Symbols 记录了用 static 声明的全局变量地址和大小, C 文件中函数的地址和用 static 声明的
    函数代码大小,汇编文件中的标号地址(作用域限本文件),下面是部分截图:
    image.png

    Global Symbols

    Global Symbols 记录了全局变量的地址和大小, C 文件中函数的地址及其代码大小,汇编文件中的
    标号地址(作用域全工程) , 下面是部分截图:
    image.png

    Memory Map of the image

    映像文件可以分为加载域(Load Region)和运行域(Execution Region): 加载域反映了 ARM 可
    执行映像文件的各个段存放在存储器中的位置关系。 下面是部分截图, 另外映像中的入口点就是程序开始
    执行的位置。
    image.png
    运行域反映了 ARM 可执行映像文件各个段真正执行时在存储器中的位置关系:
    image.png
    简单的说,加载域就是程序在 Flash 中的实际存储,而运行域是芯片上电后的运行状态,通过下面的框图
    可以有一个感性的认识:
    image.png
    通过上面的框图可以看出, RW 区也是要存储到 ROM/Flash 里面的, 在执行映像之前,必须将已初始化
    的 RW 数据从 ROM 中复制到 RAM 中的执行地址并创建 ZI Section(初始化为 0 的变量区) 。

    Image component sizes(映像组件大小)

    Image component sizes 映像组件大小比较重要,比如下面内容代表的含义:
    image.png

  • 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 显示已提取并作为单个对象添加到映像中的库成员占用了多少字节。
image.png
下面是我们经常要查看的内容:
image.png

  • Grand Totals:显示映像的真实大小。
  • ELF Image Totals: ELF(Executable and Linking Format)可执行链接格式映像文件大小。
  • ROM Totals:显示包含映像所需的 ROM 的最小大小。这不包括 ZI 数据和存储在 ROM 中的调试

信息。