STM32 map 文件浅析

news/2024/9/28 17:15:24 标签: stm32, 单片机, 嵌入式

目录

  • 一、概述
  • 二、Section Cross References
  • 三、Removing Unused input sections from the image
  • 四、Memory Map of the image
    • 1、Local Symbols
    • 2、全局符号(Global Symbols)
  • 五、Image Symbol Table
  • 六、Image component sizes


一、概述

.map 文件是编译器链接时生成的一个文件,它主要包含了交叉链接信息。通过 .map 文件,我们可以知道整个工程的函数调用关系、FLASHRAM 占用情况及其详细汇总信息,能具体到单个源文件(.c/.s)的占用情况,根据这些信息,我们可以对代码进行优化。.map 文件可以分为以下 5 个组成部分:

  1. 程序段交叉引用关系(Section Cross References
  2. 删除映像未使用的程序段(Removing Unused input sections from the image
  3. 映像符号表(Image Symbol Table
  4. 映像内存分布图(Memory Map of the image
  5. 映像组件大小(Image component sizes

我们在 Keil 中最常见的就是在编译之后,编译窗口会显示类似如下一段关于程序和数据大小的信息:

这一段提示信息其实是汇总了程序和数据的信息,这些信息其实是单个模块汇总而成,在 .map 文件里有详细列表。

.map 文件输出信息的配置位于:Project -> Options for Target -> Listing,如下图:

主要包含配置:

  • Memory Map:内存映射
  • Callgraph:图像映射
  • Symbols:符号
  • Cross Reference:交叉引用
  • Size Info:大小信息
  • Totals Info:统计信息
  • Unused Section Info:未调用模块信息
  • Veneers Info:装饰信息

我们可根据自己情况,想要输出什么信息,勾选对应信息即可。

接下来将针对 .map 文件的五部分内容进行讲解。

二、Section Cross References

这部分内容描述了各个文件(.c/.s 等)之间函数(程序段)的调用关系,如下图所示:

比如下面这段:

board.o(i.board_lowlevel_init) refers to stm32f4xx_rcc.o(i.RCC_AHB1PeriphClockCmd) for RCC_AHB1PeriphClockCmd

表示的意思是:board.c 文件中的 board_lowlevel_init 函数调用了 stm32f4xx_rcc.c 文件中的 RCC_AHB1PeriphClockCmd 函数。

i.board_lowlevel_init 表示 board_lowlevel_init 函数的入口地址,同理 i.RCC_AHB1PeriphClockCmd 表示 RCC_AHB1PeriphClockCmd 的入口地址

board.oboard.c 源文件生成的目标文件模块

三、Removing Unused input sections from the image

这部分内容描述了工程中由于未被调用而被删除的冗余程序段(函数/数据):

在结尾还列出了一个统计数据,表示共移除l 849 个程序段,共 37144 字节。

四、Memory Map of the image

映像符号表(Image Symbol Table)描述了被引用的各个符号(程序段/数据)在存储器中的存储地址、类型、大小等信息。映像符号表分为两类:本地符号(Local Symbols)和全局符号(Global Symbols)。

1、Local Symbols

本地符号(Local Symbols)记录了用static 声明的全局变量地址和大小,c 文件中函数的地址和用static 声明的函数代码大小,汇编文件中的标号地址(作用域:限本文件),见下:

下面红框处,表示 stm32f4x_dma.c 文件中的 DMA_ClearFlag 函数的入口地址为 0x080001ec,类型为:Section(程序段)
,大小为 0。

因为:i.sys_stm32_clock_init 仅仅表示 sys_stm32_clock_init 函数入口地址,并不是指令,所以没有大小。在全局符号段,会列出sys_stm32_clock_init 函数的大小。

2、全局符号(Global Symbols)

全局符号(Global Symbols)记录了全局变量的地址和大小,C 文件中函数的地址及其代码大小,汇编文件中的标号地址(作用域:全工程),见下:

  1. Symbol Name:符号名称,名称命名及分类请看最后给出的官方参考文档。
  2. Value:存储对应的地址,大家会发现有 0x0800xxxx0x2000xxxx 这样的地址。0x0800xxxx 指存储在 FLASH 里面的代码、变量等。0x2000xxxx 指存储在内存 RAM 中的变量 Data 等。
  3. Ov Type:符号对应的类型。符号类型大概有几种:NumberSectionThumb CodeData等。
  4. Size:存储大小,就是当前行 Symbol 占用大小。
  5. Object(Section):段目标,这里一般指所在模块(源文件)。

图中红框框处部分,表示 stm32f4x_dma.c 文件中的 DMA_ClearFlag 函数的入口地址为:0x080001ed,类型为:Thumb Code(程序段)
,大小为 38 字节。

注意,此处的地址用的 0x08002bc9,和上一节的 0x080001ec 地址不符,这是因为 ARM 规定 Thumb 指令集的所有指令(Thumb 指令集更节省空间),其最低位必须为 1,0x080001ed = 0x080001ec + 1,所以才会有 2 个不同的地址,且总是差 1,实际上就是同一个函数。

五、Image Symbol Table

映像文件分为加载域(Load Region)和运行域(Execution Region),一个加载域必须有至少一个运行域(可以有多个运行域),而一个程序又可以有多个加载域。加载域为映像程序的实际存储区域,而运行域则是 MCU 上电后的运行状态。加载域和运行域的简化关系(这里仅表示一个加载域的情况)图如下图:

有关内存方面的内容可以参考:单片机内存区域划分

由图可知,RW 区也是存放在 ROM(FLASH)里面的,在执行 main 函数之前,RW(有初值且不为 0 的变量)数据会被拷贝到 RAM 区,同时还会在 RAM 里面创建 ZI 区(初始化为 0 的变量)。

Image Entry point : 0x08000189 表示映射入口地址。

Load Region LR_IROM1 (Base: 0x08000000, Size: 0x00001068, Max: 0x00080000, ABSOLUTE) 表示加载区域位于 LR_IROM1 开始地址0x08000000,大小有 0x00001068,这块区域最大为 0x00080000

执行区域有两段:

  1. Execution Region ER_IROM1:在内部 SRAM 运行域,所有 RAM(包括 RW 和 ZI)都是放在这个运行域里面
  2. Execution Region RW_IRAM1:在内部FLASH 运行域,所有需要放内部 FLASH 的代码,都应该放到这个运行域里面

这个区域,其实就是对应我们目标配置中的区域,如下所示:

  • Exec Addr:执行地址
  • Load Addr:加载地址
  • Size:存储大小
  • Type:类型
    1. Data:数据类型
    2. Code:代码类
    3. Zero:未初始化变量类型
    4. PAD:这个类型在 map 文件中放在这个位置,其实它不能算这里的类型。要翻译的话,只能说的“补充类型”。ARM 处理器是 32 位的,如果定义一个 8 位或者 16 位变量就会剩余一部分,这里就是指的“补充”的那部分,会发现后面的其他几个选项都没有对应的值。
  • Attr:属性
    1. RO:存储在 ROM 中的段
    2. RW:存储在 RAM 中的段
  • Section Name:段名。这里也可以说为入口分类名,大概包含:RESETARM.texti.data.bssHEAPSTACK 等。
  • Object:目标

六、Image component sizes

映像组件大小(Image component sizes)给出了整个映像所有代码(.o)占用空间的汇总信息,对我们比较有用,如图所示:

  • Code:指代码的大小;
  • RO-data:指除了内联数据(inline data)之外的常量数据;
  • RW-data:指可读写(RW)、已初始化的变量数据;
  • ZI-data:指未初始化(ZI)的变量数据;
  • Debug:表示调试数据所占的空间大小,如调试输入节及符号和字符串。
  • Object Totals:表示以上部分链接到一起后,所占映像空间的大小。
  • (incl.Generated):表示链接器生产的映像内容大小,它包含在 Object Totals 里面了,这里仅仅是单独列出,我们一般不需要关心。
  • (incl.Padding::表示链接器根据需要插入填充以保证字节对齐的数据所占空间的大小,它也包含在 Object Totals 里面了,这里单独列出,一般无需关心。
  • CodeRo-data:位于 FLASH 中;
  • RW-dataZI-data:位于 RAM 中;
  • RW-data 已初始化的数据会存储在 Flash 中,上电会从 FLASH 搬移至 RAM


    关系如下:
    R O S i z e = C o d e + R O D a t a R W S i z e = R W D a t a + Z I D a t a R O M S i z e = C o d e + R O D a t a + R W D a t a RO Size = Code + RO Data\\ RW Size = RW Data + ZI Data \\ ROM Size = Code + RO Data + RW Data ROSize=Code+RODataRWSize=RWData+ZIDataROMSize=Code+ROData+RWData

这里表示被提取的库成员(.lib 添加到映像中的部分所占空间大小。各项意义同前面提到的说明。我们一般只用看 Library Totals 来分析库所占空间的大小即可。

  • Grand Totals:表示整个映像所占空间大小。
  • ELF Image Totals:表示 ELF 可执行链接格式映像文件的大小,一般和 Grand Totals 一样大小。
  • ROM Totals:表示整个映像所需要的 ROM 空间大小,不含 ZIDebug 数据。
  • Total RO Size:表示 CodeRO 数据所占空间大小,本例程为:4172 字节。
  • Total RW Size:表示 RWZI 数据所占空间大小,即本映像所需 SRAM 空间的大小,本例程为:6816 字节。
  • Total ROM Size:表示 CodeRORW 数据所占空间大小,即本映像所需 FLASH 空间的大小,本例程为:4200 字节。

http://www.niftyadmin.cn/n/5681534.html

相关文章

Netty--第三章

Netty 进阶 1. 粘包与半包 1.1 粘包现象 服务端代码 public class HelloWorldServer { static final Logger log LoggerFactory.getLogger(HelloWorldServer.class); void start() { NioEventLoopGroup boss new NioEventLoopGroup(1); NioEventLoopGroup worker new Nio…

封装左侧抽屉可拖拽组件【可多个】

一、案例效果 二、案例代码 封装抽屉组件 <template><div class"drag-drawer"><div class"out-box" :style"style"><mtd-tooltip:content"collapse ? 展开面板 : 收起面板"class"tool-tip":placeme…

转做大模型开发,能不能挽救职业生涯?

大模型算是当之无愧最火的一个方向了&#xff0c;算是新时代的风口。有小伙伴觉得&#xff0c;既然是新领域、新方向&#xff0c;那么&#xff0c;人才需求肯定比较大&#xff0c;相应的人才缺乏&#xff0c;竞争也会更少&#xff0c;那转行去做大模型是不是一个更好的选择呢&a…

leetcode老问题新发现(更新ing)

重刷Leetcode [704. 二分查找](https://leetcode.cn/problems/binary-search/description/)[27. 移除元素](https://leetcode.cn/problems/remove-element/description/)977.有序数组的平方 前言&#xff1a;之前用C把代码随想录写的差不多了&#xff0c;近期在学Java&#xff…

Vue中对数组变化监听

在实际开发中&#xff0c;经常要对数组进行操作&#xff0c;最为常见的方法就是直接对数组中的某个元素进行赋值&#xff0c;比如下面这样的&#xff1a; <script>export default {data() {return {comments: [],isReply: [0, 0, 0, 0, 0]};},methods: {replyTo: functi…

基于Hive和Hadoop的招聘分析系统

本项目是一个基于大数据技术的招聘分析系统&#xff0c;旨在为用户提供全面的招聘信息和深入的职位市场分析。系统采用 Hadoop 平台进行大规模数据存储和处理&#xff0c;利用 MapReduce 进行数据分析和处理&#xff0c;通过 Sqoop 实现数据的导入导出&#xff0c;以 Spark 为核…

Pygame中Sprite实现逃亡游戏5

在《Pygame中Sprite实现逃亡游戏4》中通过碰撞检测实现了玩家、飞龙与飞火之间的碰撞处理&#xff0c;基本上实现了逃亡功能。最后&#xff0c;实现这个逃亡游戏中文字提示的功能。 1 操作提示 当进入游戏后&#xff0c;会在玩家下方的位置给出操作提示&#xff0c;如图1所示…

了解Webpack并处理样式文件

目录 引入定义安装和使用配置文件命令配置单独文件指定文件 处理样式css-loader使用 style-loaderless-loaderPostCSSpostcss-loaderpostcss-preset-env 引入 随着前端的快速发展&#xff0c;目前前端的开发已经变的越来越复杂了&#xff1a; 比如开发过程中我们需要通过模块化…