历史上的今天
今天是:2025年07月26日(星期六)
2019年07月26日 | STM32经keil mdk编译产生的.map文件分析
2019-07-26 来源:eefocus
昨天遇到堆大小不足的问题,扩大Heap的size觉得有必要去分析下整个程序的内存占用的详细情况,仅仅从生成的Code + RO + RW +ZI提示太笼统,无法清楚的看见我写的每一个函数,定义的每一个全局变量、静态变量的具体位置、大小等等,经各路大神的提示,我去仔细研究了下.map文件,上网查阅了相关的资料,本文主要受博主 " 非著名码农" 的启示,原文地址 http://blog.csdn.net/ropai/article/details/7493168。
第一部分 Section Cross Reference 文件引用关系分析
主要是各个源文件生成的模块之间相互引用的关系
如第一句: startup_stm32f10x_hd.o(RESET) refers to startup_stm32f10x_hd.o(STACK) for __initial_sp
意思是说 startup_stm32f10x_hd.o(由startup_stm32f10x_hd.s文件生成的目标文件)文件里的RESET段 引用了 startup_stm32f10x_hd.o文件里的STACK段里的一个全局符号__initial_sp,可能是全局变量也可能是一个函数. 后面的文字打的都是此意。
第二部分 Removing Unused input sections from the image.
就是将库中没有用到的函数从可执行映像中删除掉,减小程序的体积。
第三部分 Image Symbol Table 映像中的所有符号组成的表
Local Symbol 局部符号 既有各模块的静态函数也有公开函数,没搞明白,有懂的兄台指点一二。
Global Symbol 全局符号 各个文件模块中的全局变量、公开函数。
其中最为重要的部分 是这两句
Region
Table
Table
Base 0x080002dc0 Number 0 anon
obj.o(Region
obj.o(Region
Table)
Region
Table
Table
Limit 0x080002de0 Number 0 anon
obj.o(Region
obj.o(Region
Table)
后面这两个符号我认为很重要,在运行库代码将可执行映像从加载视图转变为可执行视图的过程中起到了关键作用。Number是指它并不占据程序空间,而只是一个具有一定数值的符号,类似于程序中用define和EQU定义的。所以这里,我先放下map文件的分析,先通过仿真调试,看这两个数值在程序中怎么用。

果然,在刚开始执行程序时,R10和R11的值就已经被赋值成了这两个值。

很快就将0x08002dc0到0x08002dcf处的16个字节,4个双字加载到了R0-R3,我们可以分析一下里面的内容,R0就是程序加载视图的RW区的起始地址(0x08002de0),R1就是要输出的执行视图的RW区的地址(0x20000000),R2就是要复制的RW数据的个数,R3是复制函数(__scatterload_copy)的地址,类似于一个回调函数。接下来就要用了:0x0800011E 4718 BX r3这条指令去执行复制工作。

接下来又将0x08002dd0到0x08002ddf处的16个字节,4个双字加载到了R0-R3,我们可以分析一下里面的内容,R0就是程序加载视图的RW区的起始地址(0x08002de0+0x20=0x08002e00),R1就是要输出的执行视图的RW区的地址(0x20000020),R2就是要复制的RW数据的个数,R3是ZI区域建立函数(__scatterload_zeroinit )的地址。
执行完成后,程序就会进入BL.W __rt_entry处进行库的初始化工作。
经过这么一分析,现在我对于程序的加载映像和执行映像有了较深的理解:程序的RO_Code加上RO_Data总共是0x2dc0这么大,地址范围0x0800,0000到0x8000,2dbf。然后在0x0800,2dc0-2dcf共16个字节放了RW加载映像地址(0x0800,2de0)、执行映像地址(0x2000,0000)、RW长度(0x20)和将该段数据从加载映像复制到执行映像的函数地址。在0x0800,2dd0-2ddf共16个字节放了ZI加载映像地址(0x0800,2e00)、执行映像地址(0x2000,0020)、ZI长度(0x480)和建立ZI、HEAP和STACK执行映像的函数地址。
第五部分 Memory Map of the imag 内存映射
Execution Region ER_IROM1 (Base: 0x08000000, Size: 0x00046398, Max: 0x00080000, ABSOLUTE) 这一段指的是FLASH,size很明显是已用FLASH大小,包括Code + RO_data。下面列的就是每个目标文件所占FLASH的明细了。
Execution Region RW_IRAM1 (Base: 0x20000000, Size: 0x00008eb0, Max: 0x00010000, ABSOLUTE, COMPRESSED[0x00000350])这一段指的是片内SRAM,size就是RW_data + ZI_data所占用的片内SRAM的大小,则主堆栈指针MSP = 0x20000000 + 0x8eb0,程序开始运行时MSP就从这个地址开始为局部变量分配地址.
Execution Region ER$$.ARM.__AT_0x680830D0 (Base: 0x680830d0, Size: 0x00001024, Max: 0x00001024, ABSOLUTE, UNINIT)因为我为file结构变量定的地址是片外SRAM,所以map文件里也将片外SRAM的一些信息包括进来了,不过只有这个file结构体变量的大小哦0x1024
第六部分 Image component sizes 各目标文件的code ro rw zi的大小
显示列出工程中所有用的.c文件所生成的.o目标文件中各成分大小,然后是工程所添加的库文件所占的各成分大小。
从最后这一句看来
Code (inc. data) RO Data RW Data ZI Data Debug Library Name
91574 2618 16290 1296 680 81428 STemWin522_CM3_OS_Keil.lib
1538 64 133 16 0 1788 mc_w.l
818 0 0 0 0 1080 mf_w.l
----------------------------------------------------------------------
94120 2682 16432 1320 684 84296 Library Totals
STenWin522_CM3_OS_Keil.lib文件占用 (94120 + 16432 +1320)bytes的FLASH, (1320 + 684)bytes的SRAM,所以这就是为啥emWin移植需要至少2K内存的单片机!!!
史海拾趣
|
你是不是公司里的“好好人”?如果一味地讨好他人,你便会失去他人的尊重 每个公司都会有好好人,他们对于所有人都笑眯眯,对于所有人的要求都不会说“NO”。如果你是新进入公司的员工,可能刚开始要得到其他同事的信任,需要讨好别人,当然这 ...… 查看全部问答> |
|
第二次世界大战中英国发明的空中探测雷达对于探测飞机、火箭等目标所作出的重大贡献早已家喻户晓。但是近二十年来将雷达用于探测地下目标的技术获得了长足的发展。要探测的地下目标很多,包括金属、文物、地下水,天然气,尸体以及地下任何有断层或 ...… 查看全部问答> |
|
我刚学嵌入式不到一个月,遇到N多问题,一路百度过来的,现在这个实在是没办法解决了,故特来此地找大虾们帮帮忙啊。 我用的 VS2005 +WINCE6.0 ,系统定制时,用的是系统的BSP,步骤是:\"建立——下一步——下一步。。。。完成\"生成 ...… 查看全部问答> |
|
1, Caution! All external camera interface IOs must not be combined with any other GPIO or bi-directional ports. 上面这句话,好像是所有camera 外部IO接口不能与其他GPIO及双向口“结合”的意思,此处 ...… 查看全部问答> |
|
MODEL MR821 D ( + IS = 5.989e-09 + RS = 0.00477 + CJO = 1.139e-10 + VJ = 0.7174 + TT = 3.25e-08 + M = 0.2698 + BV = 100 + N = 2 + EG = 1.11 + XTI = 3 + KF = 0 + AF = 1 + FC = 0.5 + IBV = 0.0001 + TNOM ...… 查看全部问答> |
|
新建工程文件 仿真的时候出现 错误 target voltage seems to be below operating range for this device family. Make sure the target is powered on and try again 试过好几次啦 都是这样 望高人指点啊 … 查看全部问答> |




