STM32 MAP文件

文章目录

  • 1 生成Map
  • 2 map中概念
  • 3 文件分析流程
    • 3.1 Section Cross References
    • 3.2 Removing Unused input sections from the image(移除未使用的段)
    • 3.3 Memory Map of the image(映像的内存分布)
      • 3.3.1 加载域
      • 3.3.2 运行域
  • 4 代码运行逻辑
  • 5 F103部分
    • 5.1 Image component sizes(映像组成大小)
    • 5.2 映像文件的总结说明

1 生成Map

Keil生成map文件,要设置:
在这里插入图片描述

2 map中概念

段(section) :描述映像文件的代码和数据块。
RO:Read-Only的缩写,包括RO-data(只读数据)和RO-code(代码)。
RW:Read-Write的缩写,主要是RW-data,RW-data由程序初始化初始值。
ZI:Zero-initialized的缩写,主要是ZI-data,由编译器初始化为0。
.text:与RO-code同义。
.constdata:与RO-data同义。
.bss: 与ZI-data同义。
.data:与RW-data同义

3 文件分析流程

3.1 Section Cross References

Section Cross References

    main.o(i.main) refers to misc.o(i.NVIC_PriorityGroupConfig) for NVIC_PriorityGroupConfig
    main.o(i.main) refers to delay.o(i.delay_init) for delay_init
    main.o(i.main) refers to usart.o(i.uart1_init) for uart1_init
    main.o(i.main) refers to led.o(i.LED_Init) for LED_Init
    main.o(i.main) refers to lcd.o(i.LCD_Init) for LCD_Init
    main.o(i.main) refers to key.o(i.KEY_Init) for KEY_Init

(模块、段的交叉引用关系)各个源文件生成的模块之间相互引用的关系。“refer to”是引用的意思,比如:

  • main.c和led.c会被编译成目标文件main.o和led.o。
  • i.main是main.c中main函数的入口(也是main函数编译出的段,函数编译后以段的形式存在,函数之间的引用,也就是段与段之间的引用)。
  • i.LED_Init是led.c中LED_Init函数的入口(也是LED_Init函数编译出的段)。

因此上面这句话意思就是main.c中的main函数引用了led.c中的LED_Init函数,剩下的基本都是这类的意思。

startup_stm32f40_41xxx.o(.text) refers to __main.o(!!!main) for __main

在启动代码中调用了_main.o模块中的_main函数。

3.2 Removing Unused input sections from the image(移除未使用的段)

将库中没有用到的函数从可执行映像中删除掉,减小程序的体积。

Removing Unused input sections from the image.

    Removing main.o(.rev16_text), (4 bytes).
    Removing main.o(.revsh_text), (4 bytes).
    Removing stm32f4xx_it.o(.rev16_text), (4 bytes).
    Removing stm32f4xx_it.o(.revsh_text), (4 bytes).
    Removing system_stm32f4xx.o(.rev16_text), (4 bytes).
    Removing system_stm32f4xx.o(.revsh_text), (4 bytes).
    Removing system_stm32f4xx.o(i.SystemCoreClockUpdate), (192 bytes).
    Removing system_stm32f4xx.o(.data), (20 bytes).

最后一栏有个总的统计结果:

2737 unused section(s) (total 289508 bytes) removed from the image.

总共移除了2737个未使用的段,共289508字节。

3.3 Memory Map of the image(映像的内存分布)

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

3.3.1 加载域

加载域反映了ARM可执行映像文件的各个段存放在存储器中的位置关系。

Memory Map of the image

  Image Entry point : 0x00000000

  Load Region LR_IROM1 (Base: 0x08000000, Size: 0x00008dac, Max: 0x00100000, ABSOLUTE)

    Execution Region ER_IROM1 (Base: 0x08000000, Size: 0x00008bd8, Max: 0x00100000, ABSOLUTE)

    Base Addr    Size         Type   Attr      Idx    E Section Name        Object

    0x08000000   0x00000188   Data   RO          302    RESET               startup_stm32f40_41xxx.o
    0x08000188   0x00000008   Code   RO         5804  * !!!main             c_w.l(__main.o)
    0x08000190   0x00000000   Code   RO         5799    .ARM.Collect$$_printf_percent$$00000000  c_w.l(_printf_percent.o)
    0x08000190   0x00000006   Code   RO         5798    .ARM.Collect$$_printf_percent$$00000009  c_w.l(_printf_d.o)
    0x08000196   0x00000006   Code   RO         5797    .ARM.Collect$$_printf_percent$$0000000C  c_w.l(_printf_x.o)
    0x0800019c   0x00000006   Code   RO         5796    .ARM.Collect$$_printf_percent$$00000014  c_w.l(_printf_s.o)
    0x080001a2   0x00000004   Code   RO         5832    .ARM.Collect$$_printf_percent$$00000017  c_w.l(_printf_percent_end.o)
    0x080001a6   0x00000002   Code   RO         5923    .ARM.Collect$$libinit$$00000000  c_w.l(libinit.o)

1、Exec Addr:运行域地址
2、Load Addr:加载域地址
3、Size:存储大小
4、Type:类型
Data:数据类型
Code:代码类型
Zero:未初始化变量类型
PAD:这个类型在map文件中放在这个位置,其实它不能算这里的类型。要翻译的话,只能说的“补充类型”。

ARM处理器是32位的,如果定义一个8位或者16位变量就会剩余一部分,这里就是指的“补充”的那部分,会发现后面的其他几个选项都没有对应的值。

3.3.2 运行域

运行域反映了ARM可执行映像文件各个段真正执行时在存储器中的位置关系:

Execution Region RW_IRAM1 (Base: 0x20000000, Size: 0x00002920, Max: 0x00020000, ABSOLUTE)

    Base Addr    Size         Type   Attr      Idx    E Section Name        Object

    0x20000000   0x00000028   Data   RW            7    .data               main.o
    0x20000028   0x00000180   Data   RW          347    .data               usart.o
    0x200001a8   0x00000008   Data   RW          501    .data               timer.o
    0x200001b0   0x00000004   Data   RW          565    .data               delay.o
    0x200001b4   0x00000001   Data   RW          694    .data               key.o
    0x200001b5   0x00000001   PAD
    0x200001b6   0x00000004   Data   RW          790    .data               lcd.o
    0x200001ba   0x00000002   PAD
    0x200001bc   0x00000008   Data   RW          979    .data               pwm.o
    0x200001c4   0x00000010   Data   RW         3651    .data               stm32f4xx_rcc.o
    0x200001d4   0x00002008   Zero   RW            5    .bss                main.o
    0x200021dc   0x000000c8   Zero   RW          346    .bss                usart.o
    0x200022a4   0x0000000e   Zero   RW          788    .bss                lcd.o
    0x200022b2   0x0000000a   Zero   RW          978    .bss                pwm.o
    0x200022bc   0x00000060   Zero   RW         5842    .bss                c_w.l(libspace.o)
    0x2000231c   0x00000004   PAD
    0x20002320   0x00000200   Zero   RW          301    HEAP                startup_stm32f40_41xxx.o
    0x20002520   0x00000400   Zero   RW          300    STACK               startup_stm32f40_41xxx.o
  Load Region LR$$.ARM.__AT_0x68000000 (Base: 0x68000000, Size: 0x00000000, Max: 0x000f4240, ABSOLUTE)

    Execution Region ER$$.ARM.__AT_0x68000000 (Base: 0x68000000, Size: 0x00000000, Max: 0x000f4240, ABSOLUTE, UNINIT)

4 代码运行逻辑

加载域就是程序在Flash中的实际存储,而运行域是芯片上电后的运行状态,因为MCU没上电时RAM中没有数据,所以此时所有的东西(包括代码、变量、初始值等)都是存放在flash中的,当上电后又要把变量等复制到RAM中才能正常运行。
在这里插入图片描述在执行映像之前,必须将已初始化的RW数据从ROM中复制到RAM中的执行地址并创建ZI Section(初始值为0的变量区),这样才算完成了MCU运行的准备。

5 F103部分

5.1 Image component sizes(映像组成大小)

在这里插入图片描述Code (inc. Data) :显示代码占用了多少字节。 在此映像中,有19442字节的代码, 其中包括1832字节的内联数据 (inc. data),例如文字池和短字符串。

RO Data :显示只读数据占用了多少字节(比如const char buf[] = “123456”)。这是除 Code (inc. data) 列中包括的内联数据之外的数据。

RW Data :显示读写数据占用了多少字节。

ZI Data :显示零初始化的数据占用了多少字节。

Debug :显示调试数据占用了多少字节,例如,调试输入节以及符号和字符串。

Object Totals :显示链接到一起以生成映像的对象占用了多少字节。

(incl. Generated):链接器会生成的映像内容,例如,交互操作中间代码。 如果 Object Totals 行包含此类型的数据,则会显示在该行中。本例中共有 1016 字节的 RO 数据,其中32字节是链接器生成的 RO 数据。

(incl. Padding) :链接器根据需要插入填充,以强制字节对齐。

下面的Library Totals显示已提取并作为单个对象添加到映像中的库成员占用了多少字节。

在这里插入图片描述

5.2 映像文件的总结说明

在这里插入图片描述Grand Totals:显示映像的真实大小。

ELF Image Totals:ELF(Executable and Linking Format)可执行链接格式映像文件大小。

ROM Totals:显示包含映像所需的 ROM的最小大小。这不包括 ZI数据和存储在ROM 中的调试信息。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

记录一次因内存不足而导致hiveserver2和namenode进程宕机的排查

背景 最近发现集群主节点总有进程宕机,定位了大半天才找到原因,分享一下 排查过程 查询hiveserver2和namenode日志,都是正常的,突然日志就不记录了,直到我重启之后又恢复工作了。 排查各种日志都是正常的&#xff0…

Doris 建表示例(七)

建表语法 使用 CREATE TABLE 命令建立一个表(Table)。更多详细参数可以查看: HELP CREATE TABLE; 建表语法: CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [database.]table_name(column_definition1[, column_definition2, ...][, index_definition1[, i…

ELK架构

经典的ELK 经典的ELK主要是由Filebeat Logstash Elasticsearch Kibana组成,如下图:(早期的ELK只有Logstash Elasticsearch Kibana) 此架构主要适用于数据量小的开发环境,存在数据丢失的危险。 整合消息队列Ngin…

【Spring Cloud实战】分布式系统控制与组件应用

在现代软件开发中,分布式系统已经成为一种常见的架构模式,被广泛应用于各种规模的企业和组织中。这种架构模式通过将应用程序拆分为独立的组件,并分布在不同的计算机节点上运行,使得系统能够应对高负载和大规模的数据处理需求&…

视频剪辑达人分享:高效减片头时长并调整播放速度的技巧,提升视频品质

在视频剪辑的过程中,许多初学者经常会遇到一些问题,如片头过长、播放速度不适当等,这些问题不仅会影响观众的观看体验,还会对视频品质产生负面影响。在调整播放速度时,要根据视频内容来进行调整。一般来说,…

双流网络论文精读笔记

精读视频:双流网络论文逐段精读【论文精读】_哔哩哔哩_bilibili Two-Stream Convolutional Networks for Action Recognition in Videos 传统的神经网络难以学习到物体的运动信息,双流网络则通过光流将物体运动信息抽取出来再传递给神经网络 给模型提供…

Qt 软件开发框架(主要部分)

目录 1、 一个软件基本要素 (1)UI模块 (2)网络模块 (3)业务逻辑模块 (4)中间层 (5)独立模块(守护进程、更新模块、日志收集模块…&#xff…

蓝桥杯物联网竞赛_STM32L071_3_Oled显示

地位: 对于任何一门编程语言的学习,print函数毫无疑问是一种最好的调试手段,调试者不仅能通过它获取程序变量的运行状态而且通过对其合理使用获取程序的运行流程,更能通过关键变量的输出帮你验证推理的正确与否,朴素的…

Rust开发——数据对象的内存布局

枚举与Sized 数据 一般数据类型的布局是其大小(size)、对齐方式(align)及其字段的相对偏移量。 1. 枚举(Enum)的布局: 枚举类型在内存中的布局通常是由编译器来确定的。不同的编译器可能有不…

如何使用springboot服务端接口公网远程调试——实现HTTP服务监听

🌈个人主页:聆风吟 🔥系列专栏:网络奇遇记、数据结构、算法模板 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 📋前言一. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 二. 内网穿透…

Java面试-微服务篇-SpringCloud

Java面试-微服务篇-SpringCloud SpringCloud 常见组件注册中心Eureka, Nacos负载均衡Ribbon服务雪崩, 熔断降级微服务的监控来源 SpringCloud 常见组件 通常情况下 Eureka: 注册中心Ribbon: 负载均衡Feign: 远程调用Hystrix: 服务熔断Zuul/Gateway: 网关 SpringCloudAlibaba…

C++程序中dump文件生成方法详解

最近项目中新作成了一个动态链接库,长时间运行后,偶尔会崩溃。根据log分析,被调用的动态库函数最外层catch到了这个异常,但是不能定位哪里出了问题。另外虽然上层exe是有dump文件输出处理的,但是在C中,如果…

Python requests请求响应以流stream的方式打印输出

如果你使用的请求库是requests,那么你必须了解的大模型里的请求怎么响应式的接收并打印出来的。 这里给大家写一下正式的书写方式: import requestsurl "http://localhost:8080/stream"payload {} headers {}response requests.request("GET&q…

创新洞察|展望2030 – 企业数字化转型的10大趋势(阿里研究院)

企业是否一定要 数字化创新 转型?究竟如何数字化转型?难点和坑又是什么?阿里研究院副院长针对未来十年中国的数字化转型提出十个方面需要关注的趋势:1.大国优势 2. 重构的消费者决策体系 3. 下一代数字原生企业 4. 所有企业都会成…

Endnote软件添加期刊引用格式

在下述网址中,找到你想要添加的期刊,下载引用格式文件(后缀为.ens格式) https://endnote.com/downloads/styles/?wpv_post_searchInformationfusion&wpv_aux_current_post_id12829&wpv_view_count12764-TCPID12829 下载…

ELK企业级日志分析平台——logstash

部署 新建一台虚拟机elk4部署logstash [rootelk4 ~]# yum install -y jdk-11.0.15_linux-x64_bin.rpm[rootelk4 ~]# yum install -y logstash-7.6.1.rpm 命令方式 [rootelk4 bin]# /usr/share/logstash/bin/logstash -e input { stdin { } } output { stdout {} } elasticsearc…

数仓成本下降近一半,StarRocks 存算分离助力云览科技业务出海

成都云览科技有限公司倾力打造了凤凰浏览器,专注于为海外用户提供服务,公司致力于构建一个全球性的数字内容连接入口,为用户带来更为优质、高效、个性化的浏览体验。 作为数据驱动的高科技公司,从数据中挖掘价值一直是公司核心任务…

【C++】——标准模板库STL作业(其一)

🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java基础:Java基础_IT闫的博客-CSDN博客 🐋c语言:c语言_IT闫的博客-CSDN博客 🐟MySQL&#xff1a…

Python-Django的“日志功能-日志模块(logging模块)-日志输出”的功能详解

01-综述 可以使用Python内置的logging模块来实现Django项目的日志记录。 所以与其说这篇文章在讲Django的“日志功能-日志模块-日志输出”,不如说是在讲Pthon的“日志功能-日志模块-日志输出”,即Python的logging模块。 下面用一个实例来进行讲解。 …

纯干货之阿里云云计算认证,赶紧收藏!

一、阿里云&云计算认证,引领未来 想必大家对阿里这个企业都很熟悉,我们平时常用的支付宝、淘宝、钉钉、飞猪等等都是阿里的产业,用在我们生活的各个方面。 但大家可能不知道的是,阿里云的云计算技术也是领先全国甚至全球的&…