STM32编译过程

devtools/2025/2/28 8:01:33/

STM32编译过程

  • 1. 编译过程介绍
  • 2. 程序的组成、存储与运行
  • 3. 编译工具链
    • 3.1 armcc 工具
    • 3.2 armasm 工具
    • 3.3 armlink 工具
    • 3.4 armar 工具
    • 3.5 fromelf 工具
  • 4. MDK工程的文件类型

1. 编译过程介绍

在这里插入图片描述

编译MDK 软件使用的编译器是 armcc 和 armasm,它们根据每个 c/c++ 和汇编源文件编译成对应的以“.o”为后缀名的对象文件 (Object Code,也称目标文件),其内容主要是从源文件编译得到的机器码,包含了代码、数据以及调试使用的信息
链接链接器 armlink 把各个.o 文件及库文件链接成一个映像文件“.axf”或“.elf”
格式转换需要对链接器生成的 elf 映像文件利用格式转换器 fromelf 转换成“.bin”或“.hex”文件,交给下载器下载到芯片的 FLASH 或 ROM 中

在这里插入图片描述

构建过程调用的编译器。图中的编译器名字是“V5.06”,后面附带了该编译器所在的文件夹。在该路径,可看到编译工具中的各个编译工具,如 armar、armasm、armcc、armlink 及 fromelf, armar 是用于把.o 文件打包成 lib 文件的。
使用 armasm 编译汇编文件。图中列出了编译 startup 启动文件时的提示,编译后每个汇编源文件都对应有一个独立的.o 文件。
使用 armcc 编译 c/c++ 文件。图中列出了工程中所有的 c/c++ 文件的提示,同样地,编译后每个 c/c++ 源文件都对应有一个独立的.o 文件。
使用 armlink 链接对象文件,根据程序的调用把各个.o 文件的内容链接起来,最后生成程序的axf 映像文件,并附带程序各个域大小的说明,包括 Code、RO-data、RW-data 及 ZI-data 的大小。
使用 fromelf 生成下载格式文件,它根据 axf 映像文件转化成 hex 文件,并列出编译过程出现的错误 (Error) 和警告 (Warning) 数量。
提示给出了整个构建过程消耗的时间。

编译完成后,可以看到,每个 C 源文件都对应生成了.o、.d.crf 后缀的文件,还有一些额外的.dep、.hex、.axf、.htm、.lnp、.sct、.lst.map 文件。

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

程序组件所属类别描述
机器代码指令Code即代码域,指的是编译器生成的机器指令,这些内容被存储到ROM 区
常量RO-data即只读数据域,指程序中用到的只读数据,这些数据被存储在ROM 区因而程序不能修改
其内容。
例如 C 语言中 const 关键字定义的变量就是典型的 RO-data。
初值非0的全局变量RW-data即可读写数据域,指初始化为 “非 0 值” 的可读写数据,程序刚运行时,这些数据具有非 0 的
初始值,且运行的时候它们会常驻在 RAM 区因而应用程序可以修改其内容。
例如 C 语言中使用定义的全局变量,且定义时赋予“非 0 值”给该变量进行初始化。
初值为0的全局变量ZI-data即 0 初始化数据,指初始化为 “0 值” 的可读写数据域,它与 RW-data 的区别是程序刚运行时
这些数据初始值全都为 0,而后续运行过程与 RW-data 的性质一样,它们也常驻在RAM 区
因而应用程序可以更改其内容。
例如 C 语言中使用定义的全局变量,且定义时赋予“0 值”给该变量进行初始化 (若定义该变量时
没有赋予初始值,编译器会把它当 ZI-data 来对待,初始化为 0)
局部变量ZI-data
栈空间
在 C 语言中,函数内部定义的局部变量属于栈空间,进入函数的时候从栈空间申请内存给局部
变量,退出时释放局部变量,归还内存空间。此空间都会被初始值化为 0 值。
使用 malloc 动态分配的空间ZI-data
堆空间
使用 malloc 动态分配的变量属于堆空间。此空间都会被初始值化为 0 值。

应用程序的存储状态分为:静止状态运行状态

静止状态静止态的程序被存储在非易失存储器中,如 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 读取指令运行。计算机系统的应用程序运行过程很类似,不过计算机系统的程序在存储状态时位于硬盘,执行的时候甚至会把上述的 RO 区域 (代码、只读数据) 加载到内存,加快运行速度,还有虚拟内存管理单元 (MMU) 辅助加载数据,使得可以运行比物理内存还大的应用程序。而 STM32 没有 MMU,所以无法支持Linux 和 Windows 系统。

程序状态与区域组成
程序执行时的只读区域(RO)Code + RO data
程序执行时的可读写区域(RW)RW data + ZI data
程序存储时占用的 ROM 区Code + RO data + RW data

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

3. 编译工具链

点击 MDK 界面的“help->uVision Help” 可打开《ARM Development Tools》详解。
在这里插入图片描述


所有工具链的命令选项说明:
在这里插入图片描述

3.1 armcc 工具

armcc 用于把 c/c++ 文件编译成 ARM 指令代码,编译后会输出 ELF 格式的 O 文件 (对象、目标文件)

在这里插入图片描述

3.2 armasm 工具

armasm 是汇编器,它把汇编文件编译成 O 文件。
在这里插入图片描述

3.3 armlink 工具

  armlink 是链接器,它把各个 O 文件链接组合在一起生成 ELF 格式的 AXF 文件,AXF 文件是可执行的,下载器把该文件中的指令代码下载到芯片后,该芯片就能运行程序了。利用 armlink 还可以控制程序存储到指定的 ROM 或 RAM 地址
  链接器默认是根据芯片类型的存储器分布来生成程序的,该存储器分布被记录在工程里的 sct 后缀的文件中,有特殊需要的话可自行编辑该文件,改变链接器的链接方式。
在这里插入图片描述

3.4 armar 工具

armar 工具用于把工程打包成库文件。
在这里插入图片描述

3.5 fromelf 工具

fromelf 工具可根据 axf 文件生成 hex、bin 文件。
在这里插入图片描述

4. MDK工程的文件类型

< MDK 工程的文件类型介绍 >


http://www.ppmy.cn/devtools/163302.html

相关文章

MAC 安装Tensorflow简单方法

MacOS M1 pro安装tensorflow 1、环境配置&#xff08;必需&#xff09; PYTHON版本&#xff1a;3.11.0&#xff0c;python采用homebrew安装。&#xff08;已有python或更高版本可跳过&#xff0c;更高版本未经过测试&#xff0c;题主自认为可行&#xff09; brew install pyt…

AWS S3 如何设置公开访问权限?

1.让整个bucket都有公开访问权限 1.1关闭【阻止公共读】 1.2关闭ACL访问控制 1.3打开桶策略 这样桶内所有的图片就能访问了 2.只开放特定文件让其具有访问权限&#xff1f; 2.1关闭【阻止公共读】 如之前的图示 2.2打开ACL控制 2.3单个文件打开公共读

go 查看版本

个人学习笔记 1. 打开终端&#xff08;或命令提示符&#xff09; 在 Windows 上&#xff0c;使用 cmd 或 PowerShell。在 macOS 或 Linux 上&#xff0c;使用终端应用程序。 2. 运行以下命令 go version 3. 查看输出 命令执行后&#xff0c;终端会显示已安装的 Go 版本&…

VSCode+PlatformIO报错 找不到头文件

如图示&#xff0c;找不到目标头文件 demo工程运行正常&#xff0c;考虑在src文件夹内开辟自己的代码&#xff0c;添加后没有找到 找了些资料&#xff0c;大概记录如下&#xff1a; 1、c_cpp_properties.json 内记录 头文件配置 .vscode 中&#xff0c;此文件是自动生成的&a…

在线抽奖系统——管理员登录

目录 获取验证码 时序图 集成阿里云短信服务 SMSUtil 验证码生成 约定前后端交互接口 controller 层接口设计 Service 层接口设计 Redis sendVerificationCode getVerificationCode 接口测试 JWT JWTUtil 定义拦截器 配置拦截路径 用户登录 时序图 验证码登…

Ubuntu+deepseek+Dify本地部署

1.deepseek本地部署 在Ollama官网下载 需要魔法下载 curl -fsSL https://ollama.com/install.sh | sh 在官网找到需要下载的deepseek模型版本 复制命令到终端 ollama run deepseek-r1:7b 停止ollama服务 sudo systemctl stop ollama # sudo systemctl stop ollama.servi…

MySQL之解决表中存储类型为[1,2,3]这样的字符串中去除括号[]和逗号‘,‘的问题(FIND_IN_SET+replace)

bug&#xff1a;筛选条件时&#xff0c;筛选出了不符合电影类型的影片 问题如下&#xff1a; 数据库的film表中的字段type_ids类型是varchar&#xff0c;他用来存储电影的类型id&#xff0c;如&#xff1a;type_ids里面存的是[1,12,15]&#xff0c;说明他存的是电影类型中id为…

[Java基础] JVM常量池介绍(BeanUtils.copyProperties(source, target)中的属性值引用的是同一个对象吗)

文章目录 1. JVM内存模型2. 常量池中有什么类型&#xff1f;3. 常量池中真正存储的内容是什么4. 判断一个字符串(引用)是否在常量池中5. BeanUtils.copyProperties(source, target)中的属性值引用的是同一个对象吗&#xff1f;6. 获取堆内存使用情况、非堆内存使用情况 1. JVM内…