【STM32】MDK的编译过程及文件类型全解

1.编译过程简介

MDK编译过程

  1. 编译:MDK软件使用的编译器是armcc和armasm, 它们根据每个c/c++和汇编源文件编译成对应的以“.o”为后缀名的对象文件(Object Code,也称目标文件), 其内容主要是从源文件编译得到的机器码,包含了代码、数据以及调试使用的信息。
  2. 链接: 链接器armlink把各个.o文件及库文件链接成一个映像文件“.axf”或“.elf”。
  3. 格式转换:一般来说Windows或Linux系统使用链接器直接生成可执行映像文件elf后,内核根据该文件的信息加载后, 就可以运行程序了,但在单片机平台上,需要把该文件的内容加载到芯片上, 所以还需要对链接器生成的elf映像文件利用格式转换器fromelf转换成“.bin”或“.hex”文件,交给下载器下载到芯片的FLASH或ROM中。

MDK常见的文件类型

2.编译工具链

2.1环境变量

我们下载arm编译工具后,需要将目录添加到环境变了中。

在这里插入图片描述

  • armcc用于把c/c++文件编译成ARM指令代码,编译后会输出ELF格式的O文件(对象、目标文件)。
  • armasm是汇编器,它把汇编文件编译成O文件。
  • armlink是链接器,它把各个O文件链接组合在一起生成ELF格式的AXF文件,AXF文件是可执行的,下载器把该文件中的指令代码下载到芯片后, 该芯片就能运行程序了;利用armlink还可以控制程序存储到指定的ROM或RAM地址。
  • armar工具用于把工程打包成库文件。
  • fromelf可根据axf文件生成hex、bin文件,hex和bin文件是大多数下载器支持的下载文件格式。
2.2使用fromelf工具生成bin文件
  • HEX文件:这是一种ASCII编码的文件格式,它包含了以特定ASCII字符表示的十六进制数据。HEX文件通常较大,因为它们使用两个ASCII字符来表示一个字节的数据,并且包含了文件头、记录类型、地址字段等额外信息。
  • BIN文件:这是一种二进制文件格式,只包含实际的二进制数据,没有额外的文本信息。BIN文件通常比HEX文件小,因为它们不包含任何ASCII编码的开销。
fromelf --bin --output ..\Output\F407_Demo.bin ..\Output\F407_Demo.axf

在这里插入图片描述

Build started: Project: F407_Demo
*** Using Compiler 'V5.06 update 7 (build 960)', folder: 'D:\Keil_v5\ARM\ARM_Compiler_5.06u7\Bin'
Build target 'F407_Demo'
After Build - User command #1: fromelf --bin --output ..\Output\F407_Demo.bin ..\Output\F407_Demo.axf
"..\Output\F407_Demo.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed:  00:00:01

在这里插入图片描述

3.程序的组成、存储与运行

3.1CODE、RO、RW、ZI Data域及堆栈空间

程序组件所属的区域

在工程的编译提示输出信息中有一个语句“Program Size:Code=xx RO-data=xx RW-data=xx ZI-data=xx”, 它说明了程序各个域的大小,编译后,应用程序中所有具有同一性质的数据(包括代码)被归到一个域,程序在存储或运行的时候, 不同的域会呈现不同的状态,这些域的意义如下:

  • Code:即代码域,它指的是编译器生成的机器指令,这些内容被存储到ROM区
  • RO-data:Read Only data,即只读数据域,它指程序中用到的只读数据,这些数据被存储在ROM区,因而程序不能修改其内容。 例如C语言中const关键字定义的变量就是典型的RO-data。
  • RW-data:Read Write data,即可读写数据域,它指初始化为“非0值”的可读写数据,程序刚运行时,这些数据具有非0的初始值, 且运行的时候它们会常驻在RAM区,因而应用程序可以修改其内容。例如C语言中使用定义的全局变量,且定义时赋予“非0值”给该变量进行初始化。
  • ZI-data:Zero Initialie data,即0初始化数据,它指初始化为“0值”的可读写数据域, 它与RW-data的区别是程序刚运行时这些数据初始值全都为0, 而后续运行过程与RW-data的性质一样,它们也常驻在RAM区,因而应用程序可以更改其内容。例如C语言中使用定义的全局变量, 且定义时赋予“0值”给该变量进行初始化(若定义该变量时没有赋予初始值,编译器会把它当ZI-data来对待,初始化为0);
  • ZI-data的栈空间(Stack)及堆空间(Heap):在C语言中,函数内部定义的局部变量属于栈空间,进入函数的时候从向栈空间申请内存给局部变量, 退出时释放局部变量,归还内存空间。而使用malloc动态分配的变量属于堆空间。在程序中的栈空间和堆空间都是属于ZI-data区域的, 这些空间都会被初始值化为0值。编译器给出的ZI-data占用的空间值中包含了堆栈的大小(经实际测试,若程序中完全没有使用malloc动态申请堆空间, 编译器会优化,不把堆空间计算在内)。
3.2程序的存储与运行

RW-data和ZI-data它们仅仅是初始值不一样而已,为什么编译器非要把它们区分开?这就涉及到程序的存储状态了,应用程序具有静止状态和运行状态。 静止态的程序被存储在非易失存储器中,如STM32的内部FLASH,因而系统掉电后也能正常保存。但是当程序在运行状态的时候,程序常常需要修改一些暂存数据, 由于运行速度的要求,这些数据往往存放在内存中(RAM),掉电后这些数据会丢失。因此,程序在静止与运行的时候它在存储器中的表现是不一样的。

应用程序的加载视图与执行视图

图中的左侧是应用程序的存储状态,右侧是运行状态,而上方是RAM存储器区域,下方是ROM存储器区域。

  • 程序在存储状态时,RO节(RO section)及RW节都被保存在ROM区。
  • 当程序开始运行时,内核直接从ROM中读取代码,并且在执行主体代码前, 会先执行一段加载代码,它把RW节数据从ROM复制到RAM, 并且在RAM加入ZI节,ZI节的数据都被初始化为0。加载完后RAM区准备完毕,正式开始执行主体程序。

编译生成的RW-data的数据属于图中的RW节,ZI-data的数据属于图中的ZI节。是否需要掉电保存,这就是把RW-data与ZI-data区别开来的原因, 因为在RAM创建数据的时候,默认值为0,但如果有的数据要求初值非0,那就需要使用ROM记录该初始值,运行时再复制到RAM。

STM32的RO区域不需要加载到SRAM,内核直接从FLASH读取指令运行。

  • 当程序存储到STM32芯片的内部FLASH时(即ROM区),它占用的空间是Code、RO-data及RW-data的总和,所以如果这些内容比STM32芯片的FLASH空间大, 程序就无法被正常保存了。
  • 当程序在执行的时候,需要占用内部SRAM空间(即RAM区),占用的空间包括RW-data和ZI-data。

程序状态区域的组成

在MDK中,我们建立的工程一般会选择芯片型号,选择后就有确定的FLASH及SRAM大小,若代码超出了芯片的存储器的极限, 编译器会提示错误,这时就需要裁剪程序了,裁剪时可针对超出的区域来优化。

3.3配置RAM和ROM大小

STM32F407ZGT6微控制器的SRAM和Flash大小如下:

  • Flash:STM32F407ZGT6拥有最大1MB(1024KB)的Flash存储空间,用于存储程序代码和只读数据。Flash的地址范围从0x8000000开始。
  • SRAM:该微控制器具备总共192KB的SRAM,其中包括:
    • 112KB的主SRAM(SRAM1),地址从0x20000000开始,大小为0x20000即128KB。
    • 64KB的CCM(核心耦合存储器)数据RAM,地址从0x10000000开始,这部分内存仅CPU可以访问,不适用于DMA操作。
    • 备份SRAM,大小为4KB。

此外,STM32F407系列的芯片可以通过FSMC(灵活的静态存储控制器)扩展外部SRAM,例如使用型号为IS62WV51216的SRAM芯片,其容量为1MB(1024KB)。这为需要更多运行时数据存储空间的应用程序提供了扩展选项。

在这里插入图片描述

所以,

  • 程序存储状态时占用的ROM区=Code+RO_data+RW_data不能够超过1024KB。
  • 程序执行时占用RAM区=RW_data+ZI_data不能够超过128KB。

其中ZI_data包括初始值为0的全局变量、局部变量和动态分配的空间,局部变量属于栈空间,动态分配的空间属于堆空间。这两块空间也是可以单独配置的,在启动文件startup_stm32f40xx.s中。

在这里插入图片描述

4.map文件说明

在Listing目录下包含了*.map及*.lst文件,它们都是文本格式的。map文件是由链接器生成的,它主要包含交叉链接信息,查看该文件可以了解工程中各种符号之间的引用以及整个工程的Code、RO-data、 RW-data以及ZI-data的详细及汇总信息。它的内容中主要包含了“节区的跨文件引用”、“删除无用节区”、“符号映像表”、 “存储器映像索引”以及“映像组件大小”。

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

Image component sizes


      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Object Name

       140         56        128          0        128       1362   bsp_dma.o
        60         26          0          0          0        531   bsp_exti.o
        88         16          0          0          0       1389   bsp_led.o
        12          4          0          0          0        465   bsp_pwm2.o
       276         70          0         16          0        962   bsp_timer.o
       350         32          0         10          0       4498   bsp_usart.o
        16          0          0          0          0        506   bsp_wwdg.o
        64         28          0          0          0        531   main.o
       124         16          0          0          0       1887   misc.o
        36          8        392          0       1024        952   startup_stm32f40xx.o
       142         28          0          0          0       3647   stm32f4xx_dma.o
        32         10          0          0          0       1260   stm32f4xx_exti.o
       168          0          0          0          0       3286   stm32f4xx_gpio.o
        20          0          0          0          0       4082   stm32f4xx_it.o
       216         24          0         16          0       4626   stm32f4xx_rcc.o
        38          0          0          0          0       3354   stm32f4xx_tim.o
       308          8          0          0          0       5440   stm32f4xx_usart.o
        28         10          0          0          0       1107   stm32f4xx_wwdg.o
       276         34          0          0          0     306193   system_stm32f4xx.o

    ----------------------------------------------------------------------
      2410        370        552         44       1152     346078   Object Totals
         0          0         32          0          0          0   (incl. Generated)
        16          0          0          2          0          0   (incl. Padding)

    ----------------------------------------------------------------------

      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Library Member Name

         0          0          0          0          0          0   entry.o
         0          0          0          0          0          0   entry10a.o
         0          0          0          0          0          0   entry11a.o
         4          0          0          0          0          0   entry12b.o
         8          4          0          0          0          0   entry2.o
         4          0          0          0          0          0   entry5.o
         0          0          0          0          0          0   entry7b.o
         0          0          0          0          0          0   entry8b.o
         8          4          0          0          0          0   entry9a.o
        30          0          0          0          0          0   handlers.o
        36          8          0          0          0         68   init.o
         0          0          0          0          0          0   iusefp.o
        30          0          0          0          0         68   llshl.o
        36          0          0          0          0         68   llsshr.o
        32          0          0          0          0         68   llushr.o
        26          0          0          0          0         80   memcmp.o
      2218         90          0          0          0        464   printfa.o
         0          0          0          4          0          0   stdout.o
        44          0          0          0          0         80   uidiv.o
        98          0          0          0          0         92   uldiv.o
        48          0          0          0          0         68   cdrcmple.o
        56          0          0          0          0         88   d2f.o
       334          0          0          0          0        148   dadd.o
       222          0          0          0          0        100   ddiv.o
       186          0          0          0          0        176   depilogue.o
        48          0          0          0          0         68   dfixul.o
        26          0          0          0          0         76   dfltui.o
       228          0          0          0          0         96   dmul.o
        38          0          0          0          0         68   f2d.o
       110          0          0          0          0        168   fepilogue.o

    ----------------------------------------------------------------------
      3874        106          0          4          0       2044   Library Totals
         4          0          0          0          0          0   (incl. Padding)

    ----------------------------------------------------------------------

      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Library Name

      2574        106          0          4          0        988   mc_w.l
      1296          0          0          0          0       1056   mf_w.l

    ----------------------------------------------------------------------
      3874        106          0          4          0       2044   Library Totals

    ----------------------------------------------------------------------

==============================================================================


      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   

      6284        476        552         48       1152     342938   Grand Totals
      6284        476        552         48       1152     342938   ELF Image Totals
      6284        476        552         48          0          0   ROM Totals

==============================================================================

    Total RO  Size (Code + RO Data)                 6836 (   6.68kB)
    Total RW  Size (RW Data + ZI Data)              1200 (   1.17kB)
    Total ROM Size (Code + RO Data + RW Data)       6884 (   6.72kB)

==============================================================================

5.sct分散加载文件

当工程按默认配置构建时,MDK会根据我们选择的芯片型号,获知芯片的内部FLASH及内部SRAM存储器概况, 生成一个以工程名命名的后缀为*.sct的分散加载文件(Linker Control File,scatter loading), 链接器根据该文件的配置分配各个节区地址, 生成分散加载代码,因此我们通过修改该文件可以定制具体节区的存储位置。

在这里插入图片描述

文件内容如下:

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00100000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x20000000 0x00020000  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x10000000 0x00010000  {
   .ANY (+RW +ZI)
  }
}

我们的sct示例文件配置如下:程序的加载域为内部FLASH的0x08000000,最大空间为0x00100000;程序的执行基地址与加载基地址相同, 其中RESET节区定义的向量表要存储在内部FLASH的首地址,且所有o文件及lib文件的RO属性内容都存储在内部FLASH中; 程序执行时RW及ZI区域都存储在以0x20000000为基地址,大小为0x00020000的空间(128KB),这部分正好是STM32内部主SRAM的大小。

链接器根据sct文件链接,链接后各个节区、符号的具体地址信息可以在map文件中查看。

了解sct文件的格式后,可以手动编辑该文件控制整个工程的分散加载配置,但sct文件格式比较复杂,所以MDK提供了相应的配置选项可以方便地修改该文件, 这些选项配置能满足基本的使用需求,其实就是我们在上文中配置的RAM和ROM大小。

5.1控制文件分配到指定的存储空间

在这里插入图片描述

在弹出的对话框中有一个“Memory Assignment”区域(存储器分配),在该区域中可以针对文件的各种属性内容进行分配, 如Code/Const内容(RO)、Zero Initialized Data内容(ZI-data)以及Other Data内容(RW-data), 点击下拉菜单可以找到在前面Target页面配置的IROM1、IRAM1、IRAM2等存储器。 例如图中我们把这个bsp_led.c文件的OtherData属性的内容分配到了IRAM2存储器(在Target标签页中我们勾选了IRAM1及IRAM2), 当在bsp_led.c文件定义了一些RW-data内容时(如初值非0的全局变量),该变量将会被分配到IRAM2空间,配置完成后点击OK,然后编译工程, 查看到的sct文件。

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00100000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x20000000 0x00020000  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x10000000 0x00010000  {
    bsp_led.o (+RW)
   .ANY (+RW +ZI)
  }
}

虽然MDK的这些存储器配置选项很方便,但有很多高级的配置还是需要手动编写sct文件实现的, 例如MDK选项中的内部ROM选项最多只可以填充两个选项位置,若想把内部ROM分成多片地址管理就无法实现了; 另外MDK配置可控的最小粒度为文件,若想控制特定的节区也需要直接编辑sct文件。

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

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

相关文章

怎么压缩ppt?这几种压缩方法大家都在用!

怎么压缩ppt?当我们沉浸在PPT创作的海洋中,每一个精心的布局、每一个动人的动画,都仿佛是我们心血的结晶,然而,随着我们不断雕琢,PPT文件的大小也在悄然增长,如同一只隐形的巨兽,在不…

无线充电宝哪个牌子好?绿联、西圣、小米充电宝测评对比!

随着科技的不断进步和智能设备的普及,无线充电宝逐渐成为了现代人生活中的必需品。它们不仅方便了我们的日常充电需求,更减少了线缆的束缚,提高了使用的便捷性。在众多品牌中,绿联、西圣和小米作为市场上广受好评的无线充电宝品牌…

Windows下载、配置Java JDK开发环境的方法

本文介绍在Windows电脑中,安装JDK(Java Development Kit),也就是Java开发工具包的详细方法。 JDK是Java软件开发的基础,由Oracle公司提供,用于构建在Java平台上运行的应用程序与组件等;其已经包…

【windows】安装抓包工具Burp Suite 2024激活汉化

前言 在项目即将上线阶段,迈入生产环境之际,确保其安全性成为我们不可忽视的首要任务。为筑起一道坚不可摧的安全防线,我们借助业界公认的网络安全利器——Burp Suite,我们将展开一场全面的安全测试,旨在探查并消除任…

旗晟机器人AI智能算法有哪些?

在当今迅猛发展的工业4.0时代,智能制造和自动化运维已然成为工业发展至关重要的核心驱动力。伴随技术的持续进步,工业场景中的运维巡检已不再单纯地依赖于传统的人工运维方式,而是愈发多地融入了智能化的元素,其中智能巡检运维系统…

数据库MySQL---基础篇

存储和管理数据的仓库 MySQL概述 数据库相关概念 数据库(DataBase)---数据存储的仓库,数据是有组织的进行存储 数据库管理系统(DBMS)-----操纵和管理数据库的大型软件 SQL----操作关系型数据库的编程语言&#xff…

文华财经盘立方多空变色波段趋势线指标公式源码

文华财经盘立方多空变色波段趋势线指标公式源码&#xff1a; N1:20; N2:ROUND(N1/2,1); N3:ROUND(SQRT(N1),1); N4:2*EMA2(C,N2)-EMA2(C,N1); 尊重市场:EMA2(N4,N3),COLORRED,LINETHICK2; 尊重市场1:IF(尊重市场<REF(尊重市场,1), 尊重市场,NULL),COLORGREEN,LINETHIC…

gitlab-runner安装部署CI/CD

手动安装 卸载旧版&#xff1a; gitlab-runner --version gitlab-runner stop yum remove gitlab-runner下载gitlab对应版本的runner # https://docs.gitlab.com/runner/install/bleeding-edge.html#download-any-other-tagged-releasecurl -L --output /usr/bin/gitlab-run…

打开IDEA,程序员思考的永远只有两件事!!!

微信公众号&#xff1a;牛奶 Yoka 的小屋 有任何问题。欢迎来撩~ 最近更新&#xff1a;2024/07/09 [大家好&#xff0c;我是牛奶。] 当年面试时背了很多八股文&#xff0c;但在日渐重复的机械工作中&#xff08;产品业务开发&#xff09;&#xff0c;计算机网络、操作系统、算…

leetcode:LCR 018. 验证回文串(python3解法)

难度&#xff1a;简单 给定一个字符串 s &#xff0c;验证 s 是否是 回文串 &#xff0c;只考虑字母和数字字符&#xff0c;可以忽略字母的大小写。 本题中&#xff0c;将空字符串定义为有效的 回文串 。 示例 1: 输入: s "A man, a plan, a canal: Panama" 输出: t…

编辑器 goland 和 visual studio code

goland 编辑器做的真是太好了&#xff0c;面向 go 代码的定制设计&#xff0c;但它是收费软件&#xff0c;价格还贵的超出了自己的经济能力范围。有时候想打几行代码&#xff0c;却没有趁手的兵器&#xff0c;真是难受。但求助免费破解版吧&#xff0c;又需要关注公众号&#x…

Lab1 论文 MapReduce

目录 &#x1f339;前言 &#x1f985;2 Programming Model &#x1f33c;2.1 Example &#x1f33c;2.2 Types &#x1f33c;2.3 More Examples &#x1f985;3 Implementation(实现) &#x1f33c;3.1 ~ 3.3 &#x1f33c;3.4 ~ 3.6 &#x1f985;4 Refinemen…

Java-Redis-Clickhouse-Jenkins-MybatisPlus-Zookeeper-vscode-Docker-jdbc-xxljob

文章目录 Clickhouse基础实操windows docker desktop 下载clickhousespringboot项目配置clickhouse Redis谈下你对Redis的了解&#xff1f;Redis一般都有哪些使用的场景&#xff1f;Redis有哪些常见的功能&#xff1f;Redis支持的数据类型有哪些&#xff1f;Redis为什么这么快…

爬虫怎么实现抓取的

1.4爬虫工程师常用的库通过图1-3我们了解到&#xff0c;爬虫程序的完整链条包括整理需求、分析目标、发出网络请求、文本解析、数据入库和数据出库。其中与代码紧密相关的有&#xff1a;发出网络请求、文本解析、数据入库和数据出库&#xff0c;接下来我们将学习不同阶段中爬虫…

Proxmox VE 8虚拟机直通USB磁盘

作者&#xff1a;田逸&#xff08;fromyz&#xff09; 今天有个兄弟发消息&#xff0c;咨询怎么让插在服务器上的U盾被Proxmox VE上的虚拟机识别。在很久很久以前&#xff0c;我尝试过在Proxmox VE 5以前的版本创建windows虚拟机&#xff0c;并把插在Proxmox VE宿主机上的银行U…

[ TOOLS ] JFLASH 使用说明

一、使用everything查找JFLASH everything是指这个软件&#xff0c;使用这个方便查找想要的文件 二、创建一个工程并配置 创建完后进行配置&#xff1a; Target devic: 板子的芯片型号&#xff0c;比如R7FA6M4Target interface: 一般是SWDSpeed: 一般是4000kHz, 不能下载则将Sp…

快速将一个网址打包成一个exe可执行文件

一、电脑需要node环境 如果没有下面有安装教程&#xff1a; node.js安装及环境配置超详细教程【Windows系统安装包方式】 https://blog.csdn.net/weixin_44893902/article/details/121788104 我的版本是v16.13.1 二、安装nativefier 这是一个GitHub上的开源项目&#xff1a…

ROS2 分布式 及 ssh远程控制 和 上传下载文件或文件夹

问题1. 多台计算机连接同一wifi后 &#xff0c;运行ROS2的小乌龟案例&#xff0c;自己的计算机&#xff0c;无法控制其他电脑的小乌龟 按照正常的情况来说&#xff0c;ROS2是DDS的自发现通信机制&#xff0c;只要处在同一wifi网络中&#xff0c; A计算机执行启动小乌龟的命…

PHP验证日本免费电话号码格式

首先&#xff0c;您需要了解免费电话号码的格式。 日本免费电话也就那么几个号段&#xff1a;0120、0990、0180、0570、0800等开头的&#xff0c;0800稍微特殊点&#xff0c;在手机号里面有080 开头&#xff0c;但是后面不一样了。 关于免费电话号码的划分&#xff0c;全部写…

2024-07-09 Linux 使用gpio-keyboard标准方式获取按键事件实例代码

一、kernel dts 配置修改&#xff1a; diff --git a/sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-evb1-v11.dts b/sysdrv/source/kernel/arch/arm/boot/dts/rv1106g-evb1-v11.dts index d0d059a3b..584f3a00a 100755 --- a/sysdrv/source/kernel/arch/arm/boot/dts/rv110…