0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

STM32的map文件详细教程

汽车玩家 来源:嵌入式大杂烩 作者:嵌入式大杂烩 2020-04-04 17:19 次阅读

前几个月针对公司自己的芯片写了个程序,这个程序有个硬性要求,就是能用的FLASH空间只有4KB,之前已经写得差不多了,最终占用空间3.6KB。这不,最近又得加需求,还剩一点点FLASH空间可以使用,这该如何是好。需求已经加过来了,不行也得行啊。所以就得去优化之前的代码了,这就得研究比较底层的东西了。

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

STM32的map文件详细教程

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

map文件

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

STM32的map文件详细教程

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

STM32的map文件详细教程

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

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

1、节区的跨文件引用

STM32的map文件详细教程

这部分主要是不同文件中函数的调用关系。在这部分中,详细列出了各个.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 文件的第二部分是删除无用节区的说明,见代码清单 51-11。

STM32的map文件详细教程

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

例如,上面的信息中说明 startup_stm32f429_439xx.o 中的 HEAP(在启动文件中定义的用于动态分配的“堆”区)以及 stm32f4xx_adc.o 的各个节区都被删除了,因为在我们这个工程中没有使用动态内存分配,也没有引用任何 stm32f4xx_adc.c 中的内容。由此也可以知道,虽然我们把 STM32 标准库的各个外设对应的 c 库文件都添加到了工程,但不必担心这会使工程变得臃肿,因为未被引用的节区内容不会被加入到最终的机器码文件中。

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

STM32的map文件详细教程

3、符号映像表

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

STM32的map文件详细教程

这个表列出了被引用的各个符号在存储器中的具体地址、占据的空间大小等信息。如我们可以查到LED_GPIO_Config 符号存储在 0x080002a5 地址,它属于 Thumb Code 类型,大小为 106 字节,它所在的节区为 bsp_led.o 文件的 i.LED_GPIO_Config 节区。

4、存储器映像索引

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

STM32的map文件详细教程

映像文件可以分为加载域(Load Region)和运行域(Execution Region) 。简单的说,加载域就是程序在 Flash 中的实际存储,而运行域是芯片上电后的运行状态,通过下面的框图可以有一个感性的认识:

STM32的map文件详细教程

通过上面的框图可以看出,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),这也是最常查询的内容,见代码清单 :

STM32的map文件详细教程

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

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

总结

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

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

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FlaSh
    +关注

    关注

    10

    文章

    1621

    浏览量

    147736
  • STM32
    +关注

    关注

    2265

    文章

    10870

    浏览量

    354723
收藏 人收藏

    评论

    相关推荐

    深入解析Tricore的Tasking链接文件

    目录 1.链接文件有什么用? 2.文件结构和语法解析 2.1 文件结构 2.2 语法解析 3.小结 玩惯了ld文件,突然让搞lsl文件,被其
    的头像 发表于 11-12 16:31 232次阅读
    深入解析Tricore的Tasking链接<b class='flag-5'>文件</b>

    stm32单片机基于rt-thread 的 littlefs 文件系统 的使用

    作者:嵌入式学习和实践一、开发环境介绍硬件:基于野火stm32f407开发板软件:基于rt-threadv4.1.1版本的stm32f407-atk-explorerbsp工程。二、littlefs
    的头像 发表于 11-06 08:04 292次阅读
    <b class='flag-5'>stm32</b>单片机基于rt-thread 的 littlefs <b class='flag-5'>文件</b>系统 的使用

    bin文件怎么烧录到stm32

    烧录bin文件STM32微控制器是一个相对复杂的过程,涉及到硬件连接、软件配置和固件烧录等多个方面。 一、硬件准备 STM32开发板 STM32开发板是烧录bin
    的头像 发表于 08-22 09:38 1495次阅读

    第12章-ADC采集电压和显示 基于STM32的ADC—电压采集(详细讲解+HAL库)

    第12章-ADC采集电压和显示 基于STM32的ADC—电压采集(详细讲解+HAL库)
    的头像 发表于 08-21 16:31 2136次阅读
    第12章-ADC采集电压和显示 基于<b class='flag-5'>STM32</b>的ADC—电压采集(<b class='flag-5'>详细</b>讲解+HAL库)

    关于esp8266 fash map的相关问题求解答

    我的esp8266的flash map是4096KB,我在编译的第五步时选择4=4096KB(512KB+512KB)与6=4096KB(1024KB+1024KB)时,flash map 有什么区别
    发表于 07-08 07:49

    请问哪种型号的蓝牙或WIFI/bt组合支持A2DP、AVRCP、HFP、MAP 1.3.1或1.4.2配置文件

    请问哪种型号的蓝牙或 WIFI/bt 组合支持 A2DP、AVRCP、HFP、MAP 1.3.1 或 1.4.2 配置文件? 谢谢!
    发表于 07-05 06:28

    stvd无法生成map文件怎么解决?

    用stvd 4.3.12,为什么我新建的工程生活生成不了map文件(已经在project setting->linker->ouput里选择了General Map
    发表于 04-29 09:01

    鸿蒙TypeScript学习第12天【Map对象】

    Map 对象保存键值对,并且能够记住键的原始插入顺序。 任何值(对象或者原始值) 都可以作为一个键或一个值。
    的头像 发表于 04-10 15:47 1063次阅读
    鸿蒙TypeScript学习第12天【<b class='flag-5'>Map</b>对象】

    使用Tasking编译器生成的map文件中找不到静态全局变量的地址怎么解决 ?

    使用Tasking编译器生成的map文件中找不到静态全局变量的地址(变量在函数中已经使用),请问怎么解决
    发表于 02-06 07:21

    使用Tasking编译器生成的map文件中没有变量的字节长度,这个怎么解决?

    使用Tasking编译器生成的map文件中没有变量的字节长度,请问这个怎么解决?
    发表于 02-04 09:24

    如何查看GD32 Keil和IAR工程的map文件

    我们在设计调试程序时,往往需要知道一个函数或一个变量它在MCU中具体所在的地址以及所占用的空间大小,这时候就需要查看map文件。 那么什么是map文件呢?
    的头像 发表于 01-27 09:30 2504次阅读
    如何查看GD32 Keil和IAR工程的<b class='flag-5'>map</b><b class='flag-5'>文件</b>

    STM32CubeIDE找不到elf

    库(STM32Cube),提供了丰富的开发工具和功能,帮助开发者更快、更方便地开发嵌入式应用。 在使用STM32CubeIDE开发STM32应用程序时,有时会遇到找不到elf文件的问题
    的头像 发表于 01-02 16:32 1633次阅读

    stm32f1如何将外部中断关掉hal库

    Layer)来简化芯片和外设的驱动开发。在STM32F1中,外部中断的关闭是通过HAL库中的相应函数来实现的。下面我将详细介绍如何使用HAL库关闭外部中断。 引入必要的头文件 要使用外部中断功能,首先需要
    的头像 发表于 12-22 13:52 3190次阅读

    keil如何生成bin文件

    Keil是一种集成开发环境(IDE),专为ARM架构的嵌入式系统开发而设计。在Keil中生成bin文件是将代码编译并转换为可执行文件的过程。本文将详细介绍Keil生成bin文件的步骤和
    的头像 发表于 12-15 13:43 1.1w次阅读

    基于STM32F103CBT6最小系统板PCB图文件

    STM32F103CBT6最小系统板PCB图文件
    发表于 12-04 09:24 8次下载