STM32的map文件学习笔记

前言

前几个月针对公司自己的芯片写了个程序,这个程序有个硬性要求,就是能用的FLASH空间只有4KB,之前已经写得差不多了,最终占用空间3.6KB。

这不,最近又得加需求,还剩一点点FLASH空间可以使用,这该如何是好。需求已经加过来了,不行也得行啊。所以就得去优化之前的代码了,这就得研究比较底层的东西了。

我们的芯片与其它的MCU芯片用起来都差不多一样。我们在用ST的时候,编译完成,会生成很多文件,其中有一个.map文件,里面包含的信息就是工程 ROM/FLASH 和 RAM 的占用情况 。

之前只是关心.map文件的最后几行的 ROM/FLASH占用信息,如:

这次就得认真的学习一下这个文件了,只有清楚的知道这些信息才可以很好的进行代码优化 。下面我们来一起学习一下STM32的.map文件。(以下内容来自野火及安富莱教程文档)

map文件

要生成 map 文件,MDK 中如下选项要选上:

将工程全编译,且没有错误后,双击这里就可以看到生成的 map 文件了:

map文件的内容可分为如下几部分:

1、节区的跨文件引用(Section Cross References)
2、删除无用节区(Removing Unused input ps from the image)
3、符号映像表(Image Symbol Table (Local Symbols Global Symbols)
4、存储器映像索引(Memory Map of the image)
5、映像组件大小(Image component sizes)

1、节区的跨文件引用

这部分主要是不同文件中函数的调用关系。  在这部分中,详细列出了各个.o 文件之间的符号引用。

由于.o 文件是由 asm 或 c/c++源文件编译后生成的,各个文件及文件内的节区间互相独立,链接器根据它们之间的互相引用链接起来,链接的详细信息在这个Section Cross References一一列出。

例如,开头部分说明的是 startup_stm32f429_439xx.o 文件中的“RESET”节区分为它使用的__initial_sp符号引用了同文件“STACK”节区。

也许我们对启动文件不熟悉,不清楚这究竟是什么,那我们继续浏览,可看到 main.o文件的引用说明,如说明 main.o 文件的 i.main 节区为它使用的 LED_GPIO_Config 符号引用了 bsp_led.o 文件的 i.LED_GPIO_Config 节区。

有时在构建工程的时候,编译器会输出 “Undefined symbol xxx (referred from xxx.o)” 这样的提示,该提示的原因就是在链接过程中,某个文件无法在外部找到它引用的标号,因而产生链接错误。

2、删除无用节区

map 文件的第二部分是删除无用节区的说明,见代码清单:

这部分列出了在链接过程它发现工程中未被引用的节区,这些未被引用的节区将会被删除(指不加入到*.axf 文件,不是指在*.o 文件删除),这样可以防止这些无用数据占用程序空间。

例如,上面的信息中说明 startup_stm32f429_439xx.o 中的 HEAP(在启动文件中定义的用于动态分配的“堆”区)以及 stm32f4xx_adc.o 的各个节区都被删除了,因为在我们这个工程中没有使用动态内存分配,也没有引用任何 stm32f4xx_adc.c 中的内容。

由此也可以知道,虽然我们把 STM32 标准库的各个外设对应的 c 库文件都添加到了工程,但不必担心这会使工程变得臃肿,因为未被引用的节区内容不会被加入到最终的机器码文件中

对于这个部分功能,用户最好将 MDK 中这个选项勾上,然后全编译工程,效果会比较好:

3、符号映像表

map 文件的第三部分是符号映像表(Image Symbol Table), 见代码清单 51-12。

这个表列出了被引用的各个符号在存储器中的具体地址、占据的空间大小等信息。

如我们可以查到LED_GPIO_Config 符号存储在 0x080002a5 地址,它属于 Thumb Code 类型,大小为 106 字节,它所在的节区为 bsp_led.o 文件的 i.LED_GPIO_Config 节区。

4、存储器映像索引

map 文件的第四部分是存储器映像索引(Memory Map of the image), 见代码清单:

映像文件可以分为加载域(Load Region)和运行域(Execution Region) 。

简单的说,加载域就是程序在 Flash 中的实际存储,而运行域是芯片上电后的运行状态,通过下面的框图可以有一个感性的认识:

通过上面的框图可以看出,RW 区也是要存储到 ROM/Flash 里面的,在执行映像之前,必须将已初始化的 RW 数据从 ROM 中复制到 RAM 中的执行地址并创建 ZI Section(初始化为 0 的变量区)。

本工程的存储器映像索引分为 ER_IROM1 及 RW_IRAM1 部分,它们分别对应 STM32内部 FLASH 及 SRAM 的空间。

相对于符号映像表,这个索引表描述的单位是节区,而且它描述的主要信息中包含了节区的类型及属性,由此可以区分 Code、 RO-data、 RW-data及 ZI-data。

例如,从上面的表中我们可以看到 i.LED_GPIO_Config 节区存储在内部 FLASH 的0x080002a4 地址,大小为 0x00000074,类型为 Code,属性为 RO。而程序的 STACK 节区(栈空间)存储在 SRAM 的 0x20000000 地址,大小为 0x00000400,类型为 Zero,属性为RW(即 RW-data) 。

5、映像组件大小

map 文件的最后一部分是包含映像组件大小的信息(Image component sizes),这也是最常查询的内容,见代码清单  :

这部分包含了各个使用到的*.o 文件的空间汇总信息、整个工程的空间汇总信息以及占用不同类型存储器的空间汇总信息,它们分类描述了具体占据的 Code、 RO-data、 RW-data及 ZI-data 的大小,并根据这些大小统计出占据的 ROM 总空间。

综合整个 map 文件的信息,可以分析出,当程序下载到 STM32 的内部 FLASH 时,需要使用的内部 FLASH 是从 0x0800 0000 地址开始的大小为 1456 字节的空间;当程序运行时,需要使用的内部 SRAM 是从 0x20000000 地址开始的大小为 1024 字节的空间。

总结

对照着这个map文件再看看我的程序,就可以知道哪里占的flash空间多了。硬件相关的部分已经用寄存器来操作,协议处理部分占用的flash空间最多。

最后,对于.map文件,我们一般只需要了解最后几行即可。如果想要深入学习,可以参照野火及安富莱的教程文档进行学习。


扫码或长按关注

回复「 篮球的大肚子」进入技术群聊

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/468055.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html网易云音乐图片轮播效果,Vue之网易云音乐PC版轮播图的实现

Github - program-learning-lists最近在刷网易云音乐歌单时发现首页的轮播图很有意思,正好自己想尝试做一个PC版的网易云音乐,于是就是使用Vue去做这个demo,废话少说,我要出招了,接招吧页面的DOM结构:style"slide…

深入理解mybatis原理, Mybatis初始化SqlSessionFactory机制详解(转)

文章转自http://blog.csdn.net/l454822901/article/details/51829785 对于任何框架而言,在使用前都要进行一系列的初始化,MyBatis也不例外。本章将通过以下几点详细介绍MyBatis的初始化过程。 1.MyBatis的初始化做了什么 2. MyBatis基于XML配置文件创建C…

我有个队友,叫悟空

昨晚,是我们篮球队年终聚会,好像也是第一次组织篮球队的聚会,之前就只知道在场上打球,场下就没有过这样的吃饭聚会。年终的时候,聚会特别多,该交流感情的交流感情,该年会抽奖的就年会抽奖&#…

C#基于LibUsbDotNet实现USB通信(一)

网上C#USB通信的资料比较少, 基本上都是基于LibUsbDotNet 和 CyUsb, 关于打印机设备的还有一个OPOS。 本篇文章基于LibUsbDotNet。 1. 下载并安装 LibUsbDotNet 安装文件。 2. 运行Filter Wizard, Install a device filter。 安装需要通信的usb设备。 3. 建一个简单…

一个大神的Android成长之路

这篇文章是我的一个朋友写的,总结了这些年的技术成长之路,我觉得对于很多技术人都有借鉴的作用,技术是相通的,不要整天想一口气吃成一个胖子,不积跬步无以至千里,既然选择了技术这条路,就不畏艰…

串口通讯你真的会了吗?不妨看看这些经验

平时使用串口打印出现乱码的绝大部分原因是串口波特率没对。那么我们怎么测量实际的波特率呢?在这之前,顺便一起回顾一下波特率的概念。什么是波特率、比特率? 比特率(Bitrate)表示每秒钟传输的二进制位数,单位为比特每秒(bit/s)。…

一些函数、变量命名法及代码规范

驼峰命名法 骆驼式命名法(Camel-Case)又称驼峰式命名法,也称小驼峰式命名法。骆驼式命名法就是当变量名或函数名是由一个或多个单词连结在一起时,第一个单词以小写字母开始;从第二个单词开始以后的每个单词的首字母都采…

linux 信号_[入门]谈一谈Linux中的信号

也许有一些同学有这样的疑问:kill -9 PID 中的 -9 到底是什么意思?Ctrl C 是为什么可以停止掉运行的程序?1. 什么是信号?在计算机科学中,信号是Unix、类Unix以及其他POSIX兼容的操作系统中进程间通讯的一种有限制的方…

终于讲透了,史上最详细的RS485串口通讯!

RS485接口组成的半双工网络,一般是两线制,多采用屏蔽双绞线传输,这种接线方式为总线式拓扑结构在同一总线上最多可以挂接32个结点。我们知道,最初数据是模拟信号输出简单过程量,后来仪表接口是RS232接口,这…

react 组件封装原则_我理解的React:React 到底是什么?

希望本文能帮助没接触过 React 的同学,对React有个大致的理解。最近要做一个“前端零基础的入门课程分享”,很多非前端同学可能只是知道 React 是个前端框架,整体对 React 的理解还是很模糊,借此机会,分享一下我对 Rea…

解引用NULL为什么会导致程序挂死?

来源:公众号【编程珠玑】作者:守望先生ID:shouwangxiansheng解引用NULL指针为什么会出错,导致程序挂死?或者说访问内存地址为0的位置为什么会视为非法?先了解NULL参考《NULL,0,\0有何区别?》。解…

关于主机的思维导图_送给孩子最好的思维导图课程

思维导图寒假班来了1关于思维导图思维导图是一种简单而有效的图形思维工具,主要元素包含图形、线条、关键字、颜色,配合下图,我们能理解思维导图利用了左脑和右脑的工作机理,能够充分调动大脑的分析推理和想象创新能力&#xff0c…

那年夏日我吃瓜

好吧,标题就是为了吸引读者进来增加阅读量的,作为一个公众号小编,我没有什么大量的墨水贡献给大家,但是就是想吹牛逼一下。我最近很懒,都有好几天没有更新新的文章了,然后大家也看到我自己写的东西没有什么…

未来计算机是否有意识或者人为的赋予意识,人工智能会有自我意识吗?

在西雅图的艾伦脑科学研究所,正在进行大规模的研究,以了解人脑中860亿个神经元是如何连接的。目的是产生所有连接的图:连接组。该研究所的科学家现在正在重建一立方毫米的老鼠大脑,这是有史以来最复杂的。绘制出大脑连接方式的映射…

别瞎找了,你要的C语言经典示例都在这~

大家周末好,这篇文章是从朋友的号那边看到的,确实不错,如果C语言还觉得没有胸有成熟的话,可以看看。里面的例子都很经典,有条件的同学实际操作一下。给大家找了一些C语言经典示例,github链接:ht…

广联达文件被锁怎么修复_事无巨细的绕过Apple id教程+修复蜂窝数据/电话

本次教程首发于Apple tech752大神,十分感谢他的nice job!通过这份教程你可以绕过Apple id激活锁,并且保留通话和移动数据和短信的功能,解决了由于基带锁导致绕过ID的机器不可以打电话的问题。写在前面:1.请勿用于捡到/…

计算机辅助翻译专业院校,2017年北大计算机辅助翻译考研经验分享

2017年北大计算机辅助翻译考研经验分享【摘要】笔者完美地将自身优势与兴趣相结合,最终成功折桂北大计算机辅助翻译。►择校(兴趣优势)其实我最开始考研的目标并不是北大的计算机作者hhhhhh1111次阅读2017-07-06【摘要】笔者完美地将自身优势与兴趣相结合&#xff0…

如何写出让同事无法维护的代码?

译文:http://coolshell.cn/articles/4758.html原文:http://mindprod.com/jgloss/unmain.html文章转自公众号 strongerHuang对,你没看错,本文就是教你怎么写出让同事无法维护的代码,因为只有这样,别人才不能…

调试,是一件有挑战的事情

如果你不是工程师,你应该享受不到加班调试的乐趣吧,我记得在大学的时候,我第一次调试I2C时序,当时用的芯片是24C02的RTC芯片,用51单片机模拟I2C时序,怎么整也整不出来,时序这个东西,…

make 命令_make考点总结(建议中、高考学生收藏)

考点一、“make宾语宾语补足语”结构1、这个结构表示“ 使…… 处于某种状态”“ 使……怎么样”。其中宾语的补足语,通常是表示情感的词(happy, sad)或者是表示状态的词(rich, strong, ill)。比如,Make your room clean.“使你的房间干净”,…