
本章为大家介绍编译器生成的map和htm文件进行解析,通过这两个文件可以让大家对工程代码的认识程度提升一个档次。 本章节以MDK为例进行说明,使用IAR同理。- U* y. K, p% g' n- [ MAP文件分析通过map文件,可以方便的查看工程ROM/FLASH和RAM的占用情况,包括单个源文件,甚至具体到每个函数的rom大小都给出了,通过这些信息可以很好的进行代码优化。MAP文件的内容可分为如下几部分:
下面将这个几个部分的含义逐一为大家做个说明。 1 MDK配置 要生成MAP文件,MDK中如下选项要选上: ![]() 将工程全编译,且没有错误后,双击这里就可以看到生成的map文件了: ![]() 认识MAP文件前先熟悉如下概念:
这部分主要是不同文件中函数的调用关系(部分截图) ![]() 比如这句:main.o(i.main) refers to main.o(i.PrintfLogo) for PrintfLogo表示main.c文件中的main函数调用了PrintfLogo。 4 Removing Unused input sections from the image这部分主要是被删除的冗余函数,也就是添加到工程里面,但是没有调用到的,下面是部分被删除冗余函数的截图效果: ![]() 对于这个部分功能,用户最好将MDK中这个选项勾上,然后全编译工程,效果会比较好: ![]() Image Symbol Table主要分为两类,分别是Local Symbols和Global Symbols。
Local Symbols记录了用static声明的全局变量地址和大小,C文件中函数的地址和用static声明的函数代码大小,汇编文件中的标号地址(作用域限本文件),下面是部分截图: ![]()
Global Symbols记录了全局变量的地址和大小,C文件中函数的地址及其代码大小,汇编文件中的标号地址(作用域全工程),下面是部分截图: ![]() 映像文件可以分为加载域(Load Region)和运行域(Execution Region):加载域反映了ARM可执行映像文件的各个段存放在存储器中的位置关系。下面是部分截图,另外映像中的入口点就是程序开始执行的位置。 ![]() 运行域反映了ARM可执行映像文件各个段真正执行时在存储器中的位置关系: ![]() 简单的说,加载域就是程序在Flash中的实际存储,而运行域是芯片上电后的运行状态,通过下面的框图可以有一个感性的认识: ![]() 通过上面的框图可以看出,RW区也是要存储到ROM/Flash里面的,在执行映像之前,必须将已初始化的RW数据从ROM中复制到RAM中的执行地址并创建ZI Section(初始化为0的变量区)。 7 Image component sizesImage component sizes映像组件大小比较重要,比如下面内容代表的含义: ![]()
下面的Library Totals显示已提取并作为单个对象添加到映像中的库成员占用了多少字节。 ![]() 下面是我们经常要查看的内容: ![]()
MDK将工程全编译,且没有错误后,就会生成此文件。以开发板配套例子为例,htm文件位于路径:\Project\MDK-ARM(uV5)\Objects。 此文件的最大作用就是基本统计了所有被调用函数的栈stack使用情况(不考虑中断嵌套)。下面是整个工程的最大栈需求: ![]() 具体到每个函数也给出最大的栈深度Max Depth,同时也给出函数本身的代码量大小和使用的栈大小,比如函数bsp_InitExtIO,最大栈深度是152字节。函数本身占用代码大小(Thumb指令集)28字节,使用栈8字节。 ![]() 通过这个文件,我们可以合理的配置启动文件里面的stack大小: ![]() 本章节的知识点比较重要,务必要熟练掌握。平时开发工程项目时,可以多关注map文件和htm文件。 版权归原作者所有,如有侵权,请联系删除。‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ # G) v( i4 x! U1 S/ w3 r |