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…

python教程答案十九章_Python 编程从入门到实践 第19章 注销一节问题

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼现在网上的教程都是第1版的,很多代码都不能用,官网下了第2版的代码,一路用第1版教程修修改改好不容易到第19章 19.2.3 注销 这一节,现在遇到个问题,过不去了。。。求教大家…

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

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

我有个队友,叫悟空

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

go语言html css,html – 在Golang中加载图像和CSS

我在项目根目录的package main中的server.js中设置了一个路由http.HandleFunc( “/”,route.IndexHandler)IndexHandler在包路由中实现,如下所示:func IndexHandler(w http.ResponseWriter, r *http.Request) {data:struct{Name string}{"My name",}util.…

python队列只能一个个读取吗_python队列Queue的详解

QueueQueue是python标准库中的线程安全的队列(FIFO)实现,提供了一个适用于多线程编程的先进先出的数据结构,即队列,用来在生产者和消费者线程之间的信息传递基本FIFO队列class Queue.Queue(maxsize0)FIFO即First in First Out,先进先出。Queue提供了一个…

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

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

一个大神的Android成长之路

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

银联Apple Pay 总结

最近在空余的时间做了银联Apple Pay,是银联快捷支付,在手机钱包里面绑定银行卡,在购买商品的时候直接指纹支付就可以了. 首先你看一线Apple Pay的官方文档:Apple Pay Human Interface Guidelines. 因为按钮和界面的原因,苹果拒绝我2次了. 按钮要使用苹果自带的Apple Pay按钮,要…

jsp页面内引入静态html,JSP技术实现动态页面到静态页面的方法

本文是介绍了jsp技术实现动态页面到静态页面的方法,分享给大家,具体如下:对于JSP技术实现动态页面到静态页面的方案,我们从三个步骤来说明:JSP技术实现动态页面到静态页面的方案第一:为了能深入浅出的理解这…

python loads_python dumps和loads区别详解

这篇文章主要介绍了python dumps和loads区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下一.概念理解json是一种轻量级的数据交换格式,对象由花括号括起来的逗号分割的成员构成,成…

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

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

html分类代码查询,html标签元素分类(示例代码)

在CSS中,HTML中的标签元素可以被分成三种类型,分别是:块状元素、内联元素和内联块状元素。常用的块状元素有:、、(......标题)、、、、(长引用)、块状元素的特点:1、一个块状元素独占一行;2、块状元素的高度…

7月27

Ddl语句,数据定义表 ,创建删除。SQL 结构化查询语句 DML数据操控表:对数据进行操作,如增删查改 Grid control网络控制 control 像是一个集成的管理工具。Bi做数据仓库的应用。 Entity实体集 每个实体集是表,每个…

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

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

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

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

计算机应用技术专业课程改革方案,【计算机维护论文】计算机应用技术专业教学改革方案(共4015字)...

一、新课改背景下计算机应用技术专业教学创新型改革的必要性新课改背景下计算机应用技术专业教学创新新改革的必要性主要包括以下三点。第一,当前计算机应用技术专业教学存在教学计划单一且教学缺乏灵活性和创新性的问题,在一定程度上制约和影响计算机应…

多校第二场C题

水贪心 #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<queue> #include<set> using namespace std; typedef long long ll; typedef pair<int,int> pii; #define M…

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

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

python求解不等式组_解线性方程组和线性不等式组

你的问题是线性规划中的问题&#xff0c;你的等式和不等式是限制&#xff0c;你想最小化(然后最大化)表达式y。等式、不等式和表达式都是线性的&#xff0c;所以它是线性规划。使用scipy函数的scipy包可以进行这种线性规划。在这里是注释代码&#xff0c;可以做你想做的。注意&…