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

news2024/9/23 5:34:59

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文件。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Object方法重写

这篇文章大家随意看看就好,只是一点理解的东西,当然你也可以认真调查。 我们需要知道Obecj是java中的一个类,是所有类的父类,即超类。对,超级赛亚人的那个超。 我们需要关注其中的equals、tostring这两个方法。 例如&…

汇川Easy系列PLC使用本地脉冲5轴设置

根据官网手册可以看到,Easy302往上的系列都是支持本地5轴脉冲控制的 常规汇川PLC本地脉冲轴配置时,脉冲和方向的输出点都是成对出现的,但是easy如果要使用5轴的话,就需要自己定义方向 可以看到,Y0,Y1这两个点是单独…

接口测试课程结构

课程大纲 如图,接下来的阶段课程,依次专项讲解如下专题,能力级别为中级,进阶后基本为中高级: 1.接口基础知识; 2.抓包工具; 3.接口工具; 4.mock服务搭建(数据模拟服务&am…

国产PLC能否使用无线通讯终端来实现无线通讯?让我们一探究竟

在工业生产车间内,PLC被广泛应用于自动化控制的各个环节。随着智能化工厂的建设,许多PLC仍处于信息孤岛状态,现要将厂区内分散的PLC都建立通讯,如果重新布线工厂量大且不美观,此时就需要用到工业PLC无线通讯设备来解决…

Presto报错:[Presto requires an Oracle or OpenJDK JVM (found Red Hat, Inc.)]

启动前: 已经搭建了jdk环境hadoop的jdk环境配置没有问题 启动Presto时,报错 解决方案: 可能是presto自身变量配置没生效在presto路径下找到bin目录, 进入启动脚本launcher 在 exec "$(dirname “ 0 " ) / l a u n c h e r . p y " " 0"…

守护舌尖安全,破解EHS管理难题,食品加工企业的可持续发展之路

在当今社会,食品安全与环境保护已成为全球关注的热点,食品加工企业作为连接农业与消费者的关键环节,其环境、健康与安全(EHS)管理水平直接关系到产品的质量和企业的可持续发展。然而,食品加工企业在EHS管理…

面壁智能发布端侧 AI 应用开发平台;快手推出肖像动画技术 LivePortrait丨 RTE 开发者日报

开发者朋友们大家好: 这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「…

C# Winform自制多轴力臂(简单易懂,方便扩展)

WinForms框架广泛应用于上位机开发领域,其中对力臂的精准控制是常见需求之一。本文深入探讨了如何创建自定义的多轴力臂图形控件,不仅涵盖了力臂图形控件的角度调节机制,还详细展示了如何实现力臂运动的生动动态效果,为开发者提供…

AE-时间轴的基础操作

目录 预览(快捷键空格) 调整时间线显示比例(Alt鼠标滚轮) 控制预览长度(B/N) 逐帧移动(笔记本:按住fn上下方向键) 视频剪切(ctrlshiftD) 剪…

“El-Table二次封装“这样做【高级前端必备技能之一】

🔥 前言 这篇文章给大家分享一个高级自定义列表组件从0到1的开发过程,这个列表组件的主要功能有,列表拖拽排序,右侧操作按钮统一使用Tooltip展示,操作表头增加自定列表icon,点击icon可以对列表展示数据进行…

帮企建站包响应式建站源码系统 带完整的安装代码包以及搭建部署教程

系统概述 帮企建站包响应式建站源码系统是一款为企业和个人提供便捷、高效建站解决方案的工具。它融合了先进的技术和设计理念,旨在帮助用户轻松构建具有专业水准的网站,无论在桌面端还是移动端都能呈现出完美的展示效果。 该系统基于响应式设计原则&a…

怎么制作gif动图,视频制作GIF动画更简单

在社交媒体和网络交流中,GIF动画以其生动活泼的表现形式成为了表达情感、幽默和创意的热门媒介。无论是分享日常趣事,还是制作专业演示,一个恰到好处的GIF动图总能吸引目光,传递信息。 但你知道吗?即使没有专业的设计背…

有什么好的录屏软件?分享4款好评的软件!

在数字化时代,录屏软件已成为我们工作、学习和娱乐中不可或缺的工具。但面对市场上琳琅满目的录屏软件,我们该如何选择最适合自己的那一款呢?今天,就让我们一起来揭秘那些备受好评的录屏神器,帮助你轻松找到录屏的首选…

Stable Diffusion——如何把雪碧变成了一个小女孩?

引言 Stable Diffusion WebUI是一个基于深度学习的图像生成工具,它可以将一张图片转换成另一种模样。通过使用先进的稳定扩散算法,这个工具能够生成高质量、高分辨率的图像,同时保持原始图像的核心特征。无论您是想将照片转换成艺术作品&…

7成期刊下降!今年的影响因子为何如此凄惨?

2024年6月20日科睿唯安发布了JCR 2023,21800本期刊最新影响因子正式更新,附完整版EXCEL下载。 影响因子 影响因子(Journal Impact Factor,简称JIF或IF)是由科睿唯安每年发布的期刊引证报告(Journal Citati…

python——list

在Python中,list是一种非常灵活的数据结构,可以用来存储一系列的元素。这些元素可以是任何类型,包括数字、字符串、其他列表等,并且它们不需要是同一种类型。 列表特征: 以下是一些关于Python列表的基本操作&#xff…

书生大模型实战营(暑假场)-入门岛-第一关

书生大模型实战营暑假场重磅开启!,这场学习路线看起来很好玩呀,闯关学习既能学到知识又有免费算力可得,太良心啦。感兴趣的小伙伴赶快一起报名学习吧!!! 关卡任务 好的,我们废话不多…

论文总是写不好?这么向kimi提问再试试!【图文大全套】

学境思源,一键生成论文初稿: AcademicIdeas - 学境思源AI论文写作 你是否有这样的困惑:论文为什么总是达不到预期的高标准?写作过程中总感觉缺乏方向和灵感?在文献搜索和数据分析上耗费了大量时间却收获甚微&#xff…

老师怎样提高学生的听课效率?

在课堂上,我们常常面临一个问题:如何提高学生的听课效率?这是一个让无数教师头疼的问题。学生是否全神贯注,是否能够吸收和理解课堂上的知识,这直接关系到教学的成败。那么,作为教师,我们能做些…

敏捷的两种方式:Kanban和 Scrum

敏捷方法通过提供灵活、迭代的项目管理方法,改变了软件开发。敏捷方法中最著名的框架是 Kanban 和 Scrum。虽然这两种方法都旨在提高生产力和效率,但它们的运作原则和实践却截然不同。 在本文中,我们将深入探讨 Kanban 和 Scrum 的起源、主要…