本文转载自微信公众号《Osprey说说MCU》,作者Osprey。转载本文请联系Osprey谈MCU公众号。在某些情况下,我们可能需要知道程序本身的大小。一般来说,我们可以从编译结果(不包括ZI-data部分)看出我们的程序有多大:也可以用生成的bin文件的大小来看一下,这个bin文件是直接烧到flash上??的数据,没有任何转换,当然不包含ZI-data,因为它的初始化都是0,只需要在程序开始时清零即可(这个工作由库函数自动帮你完成),不需要将其保存在闪存中以浪费空间。bin文件生成方式(fromelf--bin!L--outputhello.bin):我们可以看一下这些数据的空间分布:一般来说,const声明的函数都会放在RO-data区。未初始化(或初始化为0)的全局(或局部静态)变量放在ZI-data区,当然栈(stack)也放在ZI-data区。MDK编译器为我们提供了一些内置变量。这些变量是在编译和链接后自动生成的。我们可以直接在程序中获取。那么有哪些变量,如何获取呢?根据Osprey的说法,MDK有以下内置变量://获取总大小Load$$LR$$LR_IROM1$$Limit;//这个同上Image$$ER_IROM1$$RO$$Limit;//这个同上Image$$RW_IRAM1$$基数;图像$$RW_IRAM1$$限制;图像$$RW_IRAM1$$长度;图像$$RW_IRAM1$$ZI$$基数;图像$$RW_IRAM1$$ZI$$限制;图像$$RW_IRAM1$$ZI$$长度;Image$$ER_IROM1$$Length对应Code+RODatasize,base和limit是这个空间的起始地址和结束地址。Image$$RW_IRAM1$$Length对应RW-Data的大小,base和limit是这个空间的起始地址和结束地址。Image$$RW_IRAM1$$ZI$$Length对应ZI-Data(包括STACK)的大小,base和limit是这个空间的起始地址和结束地址。那么我们如何使用这些变量呢?下面Osprey提供了C语言和汇编两种版本://C语言externintImage$$ER_IROM1$$Base;unsignedintbase=(uint32_t)&Image$$ER_IROM1$$Base;AssemblyIMPORT|Image$$ER_IROM1$$RO$$Base|IMPORT|Image$$ER_IROM1$$RO$$Limit|IMPORT|Image$$RW_IRAM1$$RW$$Base|IMPORT|Image$$RW_IRAM1$$RW$$Limit|IMPORT|Image$$RW_IRAM1$$ZI$$Base|IMPORT|Image$$RW_IRAM1$$ZI$$Limit|先用extern键声明这个外部变量,int类型。但是你会发现这个变量不能直接使用,你需要取它的地址,它的地址就是你要的数据。事实上,这些内置变量本身并不占用空间,这一点与用户声明的变量不同。我们可以理解为这些变量是存放在某个地址空间中的,这个地址就是它要表示的值(意思),但是由于它的特殊性,它并不占用空间,只能通过取地址来获取它代表。价值。通过这些内置变量,我们可以通过计算Code+RO-data+RW-Data的值得到bin文件的大小,但是查看bin文件大小时会发现bin文件是小于这个值。到底是怎么回事??通过分析map文件,我们可以看到如下信息:你会发现实际bin文件中包含的RW数据的大小不是372,而是56,也就是说bin文件中没有包含一些数据用于复制(可能与某些RW数据的初始值为0,被压缩有关)。Osprey没看懂具体原因,但是根据前面的变量,我们不能准确的得到bin文件的大小,只能说得到了一个比bin文件的大小稍大的数字。本来以为Osprey不可能获取到bin文件的准确大小。一次偶然的地图文件查看让Osprey看到了这样一个变量:好奇的Osprey对它进行了更深入的研究,找到了我需要的bin文件(程序)的大小。它就藏在这里。Osprey通过分析发现,这个地址包含的8个数据的含义如下:从图中的数据,减去flash的基地址,可以得到0x2FE8,也就是我们bin文件的实际大小。至于另外两个函数的地址,Osprey不知道这些值是干什么用的。通过分析map文件,最终确定是这两个函数的地址。至于它们是做什么用的,Osprey不是很清楚,但是看名字也知道应该和变量初始化有关。以上就是Osprey分享的关于程序本身获取自身大小的知识点。至于你用这些数据做什么,那是你的事。本来Osprey打算通过指定地址的方式获取bin的大小,在bin文件的末尾放一些数据,但这真的成了先有鸡还是先有蛋的问题。貌似使用内置变量的方式还是不行现在请教各位道友有没有什么好办法让编译器自动在bin文件末尾加上想要的数据(不是第三方工具)?
