#stm32整理(二)关于MDK的编译过程及文件类型全解

news2024/12/23 17:51:48

参考野火开发指南如有侵权即刻删除,只是为了学习交流使用

1、编译

1、编译过程简介

在这里插入图片描述

(1)编译,MDK 软件使用的编译器是 armcc 和 armasm,它们根据每个 c/c++ 和汇编源文件编译
成对应的以“.o”为后缀名的对象文件 (Object Code,也称目标文件),其内容主要是从源文
件编译得到的机器码,包含了代码、数据以及调试使用的信息;

将C/C++和汇编等文件编译成为,o文件 ,o文件是对象文件(目标文件)
(2)链接,链接器 armlink 把各个.o 文件及库文件链接成一个映像文件“.axf”或“.elf”;

(3) 格式转换,一般来说 Windows 或 Linux 系统使用链接器直接生成可执行映像文件 elf 后,内
核根据该文件的信息加载后,就可以运行程序了,但在单片机平台上,需要把该文件的内
容加载到芯片上,所以还需要对链接器生成的 elf 映像文件利用格式转换器 fromelf 转换成
“.bin”或“.hex”文件,交给下载器下载到芯片的 FLASH 或 ROM 中。

编译c到o 链接o生成.axf .elf文件 通过转换器转换成.bin文件或.hex文件。

2、编译具体过程分析

在这里插入图片描述
(1) 提示信息的第一部分说明构建过程调用的编译器。图中的编译器名字是“V5.06(build 20)”,
后面附带了该编译器所在的文件夹。在电脑上打开该路径,可看到该编译器包含图 40_3 中
的各个编译工具,如 armar、armasm、armcc、armlink 及 fromelf,后面四个工具已在图 40_1
中已讲解,而 armar 是用于把.o 文件打包成 lib 文件的。

在这里插入图片描述
(2) 使用 armasm 编译汇编文件。图中列出了编译 startup 启动文件时的提示,编译后每个汇编
源文件都对应有一个独立的.o 文件。

(3) 使用 armcc 编译 c/c++ 文件。图中列出了工程中所有的 c/c++ 文件的提示,同样地,编译后
每个 c/c++ 源文件都对应有一个独立的.o 文件。

(4) 使用 armlink 链接对象文件,根据程序的调用把各个.o 文件的内容链接起来,最后生成程序
的 axf 映像文件,并附带程序各个域大小的说明,包括 Code、RO-data、RW-data 及 ZI-data
的大小。

(5) 使用 fromelf 生成下载格式文件,它根据 axf 映像文件转化成 hex 文件,并列出编译过程出
现的错误 (Error) 和警告 (Warning) 数量。
(6) 最后一段提示给出了整个构建过程消耗的时间。
构建完成后,可在工程的“Output”及“Listing”目录下找到由以上过程生成的各种文件,见图
40_4。

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

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

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);未初始化的全局变量,初始化为0的全局变量

ZI-data 的栈空间 (Stack) 及堆空间 (Heap):在 C 语言中,函数内部定义的局部变量属于栈
空间,进入函数的时候从向栈空间申请内存给局部变量,退出时释放局部变量,归还内存
空间。而使用 malloc 动态分配的变量属于堆空间。在程序中的栈空间和堆空间都是属于
ZI-data 区域的,这些空间都会被初始值化为 0 值。编译器给出的 ZI-data 占用的空间值中包
含了堆栈的大小 (经实际测试,若程序中完全没有使用 malloc 动态申请堆空间,编译器会
优化,不把堆空间计算在内)。临时变量(局部变量) malloc分布区

在这里插入图片描述

3、2程序的存储与运行

静止态的程序被存储在非易失存储器中,如 STM32 的内部 FLASH,因而系统掉电后也能正常保存。但是当程序在运行状态的时候,程序常常需要修改一些暂存数据,由于运行速度的要求,这些数据往往存放在内存中 (RAM),掉
电后这些数据会丢失。静止状态程序存在ROM中比如fllash 运行状态这些数据被放在RAM中

在这里插入图片描述
图中的左侧是应用程序的存储状态,右侧是运行状态,而上方是 RAM 存储器区域,下方是 ROM
存储器区域。

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

STM32 的 RO 区域不需要加载到 SRAM,内核直接从 FLASH 读取指令运行。计算机系统的应用
程序运行过程很类似,不过计算机系统的程序在存储状态时位于硬盘,执行的时候甚至会把上
述的 RO 区域 (代码、只读数据) 加载到内存,加快运行速度,还有虚拟内存管理单元 (MMU) 辅
助加载数据,使得可以运行比物理内存还大的应用程序。而 STM32 没有 MMU,所以无法支持
Linux 和 Windows 系统

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

在这里插入图片描述
静态code+ROdata+RWdata=flash占用控价大小
动态RWdata+ZIdata=SRAM(RAM)占用大小

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

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

相关文章

设计模式—创建型模式之工厂模式

设计模式—创建型模式之工厂模式 工厂模式(Factory Pattern)提供了一种创建对象的最佳方式。我们不必关心对象的创建细节,只需要根据不同情况获取不同产品即可。 简单工厂模式 比如我们有造车的工厂,来生产车,我们先…

b站so层sign算法

前言 大家好呀,欢迎来到我的博客!!! 本期我将带来b站so层sign算法实现 设备: pixel4 android10 下载地址: aHR0cHM6Ly93d3cud2FuZG91amlhLmNvbS9hcHBzLzI4MTI5MS9oaXN0b3J5X3Y2MTgwNTAw 版本: 6.18.0 工具: charles(抓包) socksdroid(流量转发) jadx(反编译dex) ida(反编…

中微CMS8S3680/69xx系列单片机

最近在使用中微CMS8S3680/69xx系列8位单片机来进行电源控制软件开发。 总体觉得这款单片机简单易用,特别是它的数字功能可以映射到任意脚,甚至包括程序的烧录脚,对于PCB布局特别灵活。另外它的存储器资源也是很丰富的,16K字节ROM…

实战 | SQL注入

一、资产搜集 我们都知道sql注入的传参有些是明文的,有些是经过编码或者加密的,所以我们搜索的时候不要仅限于inurl:.php?id1,可以额外的尝试搜搜1的base64编码值MQ,即可以搜索inurl:.php?idMQ,或者搜索1的md5加密值…

C代码的单元测试

C代码中集成gtest单元测试_gtest测试c语言_山河故人~的博客-CSDN博客 Linux安装gtest_gtest安装_山河故人~的博客-CSDN博客 一:安装gtest: 1. 安装gtest 采用源码安装的方式,需确保cmake已经安装。 git clone https://github.com/google/googletest …

网络安全(黑客)—小白自学路线

1.网络安全是什么 网络安全可以基于攻击和防御视角来分类,我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术,而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 2.网络安全市场 一、是市场需求量高; 二、则是发展相对成熟…

商业模式画布的9大模块全解读,产品经理不可不知!

“商场如战场”,在当今瞬息万变的商业环境中,创造出独特且创新的商业模式是每个企业家、策略家和决策者的首要任务。为了在激烈的市场竞争中取得优势,我们需要一个强大且直观的工具来帮助我们规划和塑造公司的商业模式,这个经常被…

从零开始实现神经网络(一)_NN神经网络

参考文章:神经网络介绍 一、神经元 这一神经网络的基本单元,神经元接受输入,对它们进行一些数学运算,并产生一个输出。 这里有三步。 首先,将每个输入(X1)乘以一个权重: 接下来&…

如何备份和恢复微信聊天记录?微信聊天记录1分钟轻松备份和恢复。

微信是一个非常流行的应用程序,不仅在中国,而且在全世界。这个应用程序允许来自其他国家的用户与他们的中国朋友进行群聊、语音消息、视频通话、发送贴纸或 GIF 以及照片。它可以为学生和商人/女性发送重要文件,以及位置共享以防游客在访问中…

内网穿透实现在外远程访问NAS威联通(QNAP)

文章目录 前言1. 威联通安装cpolar内网穿透2. 内网穿透2.1 创建隧道2.2 测试公网远程访问 3. 配置固定二级子域名3.1 保留二级子域名3.2 配置二级子域名 4. 使用固定二级子域名远程访问 前言 购入威联通NAS后,很多用户对于如何在外在公网环境下的远程访问威联通NAS…

系列四十、请谈一下Spring中事务的传播行为

一、概述 事务的传播行为指的是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。事务的传播行为至少发生在两个事务方法的嵌套调用中才会出现。 二、传播行为分类

专门解决数学问题的大模型

01 项目介绍 LLEMMA:一个专门解决数学问题的开源大语言模型,能力超过所有已知的开源模型 LLEMMA由多个大学和Eleuther AI公司共同研发,模型能够理解和生成数学表达式、解决数学问题,并与其他计算工具(如Python解释器…

Jenkins Gerrit Trigger插件配置

安装Jenkins 以Jenkins 2.361.1版本为例 docker pull jenkins/jenkins:2.361.1运行容器,将主机的8080端口映射到容器的8080端口,同时将主机的50000端口映射到容器的50000端口(用于构建代理) docker run -d -p 8080:8080 -p 500…

操作系统(Linux)外壳程序shell 、用户、权限

文章目录 操作系统和shell外壳Linux用户普通用户的创建和删除用户的切换 Linux 权限Linux 权限分类文件访问权限修改文件的权限权限掩码粘滞位 大家好,我是纪宁。 这篇文章将介绍 Linux的shell外壳程序,Linux用户切换机Linux权限的内容。 操作系统和shel…

基于SpringBoot的养老院信息管理系统

基于SpringBoot的养老院信息管理系统,java项目,springboot项目,idea都能打开运行。 推荐环境配置:idea jdk1.8 maven mysql5.5/mysql5.7 主要技术: SpringBoot,MySql,ajax,MyBatis 本系统的主要…

Vue 路由指南:畅游单页应用的地图(Vue Router 和 <router-view>)

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

STM32F407的系统定时器

文章目录 系统定时器SysTick滴答定时器寄存器STK_CTRL 控制寄存器STK_LOAD 重载寄存器STK_VAL 当前值寄存器STK_CALRB 校准值寄存器 初始化 Systick 定时器SysTick_InitSysTick_CLKSourceConfig delay_us寄存器delay_us库函数delay_xms短时delay_ms长时SysTick_Config 系统定时…

电阻距离------Resistance distance

原来的解释来自维基百科:https://en.wikipedia.org/wiki/Resistance_distance 在图论中,简单连通图G的两个顶点之间的电阻距离等于电网上两个等效点之间的电阻,电网被构造为与G相对应,每条边被一欧姆的电阻代替。它是图上的度量。…

Jenkins安装(Jenkins 2.429)及安装失败解决(Jenkins 2.222.4)

敏捷开发与持续集成 敏捷开发 敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发。在敏捷开发中,软件项目在构建初期被切分成多个子项目,各个子项目的成果都经过测试,具备可视、可集成和可运行使用的特征。…