工程能够正常链接,某块RAM的占用却突然升高,单看程序文件大小很难找出变化来自哪里。TASKING的链接MAP文件会列出内存用量、段位置和输入模块,可以沿着“内存区域—段—模块”逐步查找。以下以TriCore VX-toolset的Eclipse工程为例。
一、TASKING怎么生成MAP文件
TASKING可生成便于全文搜索的.map文本文件,以及用于工程内图形查看的.mapxml文件。分析前先选定构建配置,再确认报告包含内存用量和段定位结果。
1、选定构建配置
①在工程视图中右键点击目标工程,依次点击【Build Configurations】→【Set Active】,选择要检查的配置。
②右键点击工程并选择【Properties】,进入【C/C++Build】→【Settings】。
③核对【Configuration】中的配置名称,打开【Tool Settings】。
2、启用MAP文件
①在【Tool Settings】中依次点击【Linker】→【Map File】。
②勾选【Generate map file(.map)】,生成文本报告。
③勾选【Generate XML map file format(.mapxml)for map file viewer】,生成图形查看器使用的报告。
④点击【Apply and Close】,选中工程并执行【Project】→【Build Project】。
3、核对报告内容
①返回【Properties】→【C/C++Build】→【Settings】→【Tool Settings】→【Linker】→【Map File】。
②检查页面中的报告内容选项,确认内存用量、链接结果和段定位结果已启用。
③点击【Apply and Close】,再次执行【Project】→【Build Project】。
④在当前配置的输出目录中找到.map和.mapxml,核对文件修改时间。
4、打开报告
①双击输出目录中的.mapxml,打开MAP查看器。
②通过页面下拉列表或【Outline】切换到【Used Resources】。
③需要按段名搜索时,打开同目录的.map,按【Ctrl+F】查找。
二、TASKING MAP文件中的内存占用异常如何分析
先在Used Resources中确定是哪块内存、哪一列发生变化,再到Locate Result查找具体的段。Code、Data、Reserved的统计内容不同;Reserved还可能包含预留范围、栈、堆和对齐保护,不能直接当作代码或变量的大小。
1、确认报告对应本次构建
①打开当前配置目录中的.mapxml,切换到【Tool and Invocation】。
②核对链接器版本、调用参数和输出文件。
③打开【Console】,对照工程名与构建配置。
④若报告不是本次生成,点击【Project】→【Clean...】,勾选【Start a build immediately】,再点击【Clean】。
2、判断哪一列增大
①在【Used Resources】中找到异常内存区域,记录【Code】、【Data】、【Reserved】、【Free】和【Total】。
②查看【Largest gap】,记录最大连续空闲区域。
③打开上一版相同配置的MAP,逐列比较,标出变化最大的数值。
④若报告中没有内存用量,返回【Linker】→【Map File】检查报告内容选项,保存后重新构建。
3、追踪占用增大的段
①切换到【Locate Result:Sections】,找到异常内存对应的【Chip name】。
②查看【Section】、【Sect.size(dec)】及【Group】,找出明显增大的段。
③查看该行的【Defined in】,记录对象文件名;再切换到【Link Result】核对输入段与输出段。
④在工程视图中找到对应模块,检查近期加入的数组、常量或代码。
4、检查Reserved的来源
①在【Used Resources】中记录【Reserved】增大的内存区域。
②切换到【Locate Result:Sections】,查找预留段、栈、堆及对齐保护相关的段。
③打开工程使用的.lsl文件,搜索对应的group名称,以及reserved、blocksize等设置。
④与上一版MAP比较这些段的大小,确认变化发生在预留范围还是实际数据段。
5、核对初始化数据的ROM和RAM位置
①在文本.map中按【Ctrl+F】搜索异常数据段的名称。
②找到RAM中的目标段,再查找带方括号的同名ROM拷贝段。
③分别记录两处的内存区域、地址和大小。
④返回【Used Resources】,分别对照ROM与RAM的变化。初始化数据可能同时占用RAM空间和用于初始化的ROM空间。
6、检查段的定位规则
①在【Locate Result:Sections】中找到目标段,核对【Group】、【Address space】、【Chip name】和【Start address】。
②进入【Properties】→【C/C++Build】→【Settings】→【Tool Settings】→【Linker】→【Script File】,核对选用的链接脚本。
③打开该.lsl文件,搜索目标段的选择规则与分组名称。
④修改工程中的定位规则后,执行【Project】→【Clean...】重新构建,再核对段的位置。
三、对比MAP文件时还应注意什么
两份MAP只有在构建配置和链接选项一致时才便于比较。若表格中的内存数值难以解释,还可以从输入模块、被移除的段和地址空间入手,确认变化属于哪一步链接结果。
1、核对输入模块与被移除的段
①切换到【Processed Files】,查看本次链接加入的对象文件与库模块。
②切换到【Removed Sections】,记录发生变化的【Section】和【Reason】。
③返回【Tool and Invocation】,将本次链接选项与上一版报告对照。
2、区分内存区域与地址空间
①在【Used Resources】中分别查看按内存区域、按地址空间列出的表格。
②核对地址空间表中的【Native used】和【Foreign used】。
③比较同一物理内存的占用时,以对应内存区域的记录为准,不将重叠地址空间的数值直接相加。
3、留下可复查的记录
①在目标配置下点击【Project】→【Clean...】,勾选【Start a build immediately】,点击【Clean】。
②保存本次生成的.map、.mapxml,并记录所用.lsl文件的版本。
③记下变化最大的内存区域、段名、对象文件及处理后的占用数值。
总结
MAP文件的价值,是把笼统的“内存占用变大”落实到具体区域、字段和段。看到Reserved上升,或初始化数据同时出现在ROM、RAM时,先核对统计内容与定位结果,再决定是否调整代码或链接脚本。今后比较构建结果,也建议保留同一配置下的旧报告和链接脚本版本,避免凭印象判断数值变化。希望这些方法对大家分析TASKING MAP文件有所帮助;如有TASKING相关需求,欢迎联系我们咨询。