根据Cortex-M3(包括STM32F1)权威指南讲解MCU内存架构与如何查看编译器生成的地址具体位置

首先我们先查看官方对于Cortex-M3预定义的存储器映射

1.存储器映射

1.1 Cortex-M3架构的存储器结构

内部私有外设总线:即AHB总线,包括NVIC中断,ITM硬件调试,FPB, DWT。

外部私有外设总线:即APB总线,用于内部“外设”的操作(SPI,IIC,USART)等,也用于些片上APB外设到APB私有总线上(SD卡,LCD显示屏)的访问。

他们的物理地址关系如下图所示:

2.RAM和FLASH的基本概念与作用

从上面的描述可以知道,其实Cortex-M3分配的地址很多都是不允许修改的,能修改的只有代码区的FLASH和上电后代码运行的片上SRAM区的RAM,我们这章就着重讲一下这两个地方。

1.2.1RAM的基本概念与作用

RAM(随机存取存储器)在STM32中主要用于存储运行时的数据和变量。它是易失性存储器,断电后数据会丢失。RAM的作用包括:

  • 存储程序运行时的临时数据,如局部变量、堆栈和动态分配的内存。
  • 提供快速的数据访问,支持CPU的高效运行。
  • 用于存储中断向量表、全局变量和静态变量。

1.2.2 FLASH的基本概念与作用

FLASH存储器在STM32中用于存储程序代码和常量数据。它是非易失性存储器,断电后数据不会丢失。FLASH的作用包括:

  • 存储固件程序代码,包括主程序、中断服务程序和库函数。
  • 存储常量数据,如查找表、配置参数和字符串。
  • 支持程序更新和固件升级,通过编程接口可以擦除和写入数据。

1.2.3 程序的典型内存分布和用途

内存分布:


+------------------+ 0x20005000 (RAM 结束)
|       Heap      |  动态分配(malloc)
+------------------+
|       Stack     |  栈(局部变量、返回地址)
+------------------+
|      .bss       |  未初始化数据(RAM)
+------------------+
|      .data      |  已初始化全局变量(RAM)
+------------------+ 0x20000000 (RAM 起始)+------------------+ 0x08010000 (Flash 结束)
|      .rodata    |  只读数据(Flash)
+------------------+
|      .text      |  代码段(Flash)
+------------------+ 0x08000000 (Flash 起始)

各个区域用途:

存储区域用途存储位置
.text(Code)存放编译后的程序指令(代码)Flash(只读)
.rodata(RO-data)存放只读常量const 变量等)Flash(只读)
.data(RW-data)已初始化的全局/静态变量Flash + RAM
.bss(ZI-data)未初始化的全局/静态变量,启动时清零RAM(自动清零)
Heap(堆)malloc() 动态分配的内存RAM(向上增长)
Stack(栈)局部变量、函数调用返回地址RAM(向下增长)

注意

  1. .data 段在 Flash 里存有初值,但运行时会被复制到 RAM
  2. .bss 段不会占用 Flash,但会在 RAM 里初始化为 0
  3. 栈和堆共享 RAM,栈 Stack 从 高地址→ 低地址方向增长。
  4. 堆 Heap 从 低地址→ 高地址 方向增长。
  5. 当 Stack 和 Heap 彼此增长到一个临界点(即二者相遇),就会导致 Stack Overflow(栈溢出)。

下面举一个例子供大家更深入了解代码变量的存储方式:


int a = 0;    //全局初始化区 
char *p1;    //全局未初始化区 
main() 
{ int b;//栈 char s[] = "abc";//栈 char * p2;//栈 char * p3 = "123456";//123456\0在常量区,p3在栈上。 static int c =0;//全局(静态)初始化区 p1 = (char *)malloc(10);//堆 p2 = (char *)malloc(20);//堆 
}

3.如何查看自己代码的各个区的地址位置

3.1 为什么要查看各个区的地址

虽然我们在官方文档中知道了Cortex-M3的各个部分的大概范围,但我们使用CUBEMX或者操作系统生成的项目肯定不会规规矩矩的完全按照官方文档的推荐来配置各个区。有时候推荐的去大小没占完,你不知道结束地址。比如RT-Thread的内存管理将.data段和.bss段也一起管理起来了,创建各种任务所使用的内存都由RT-Thread统一分配。或者在CUBEMX中你可以自行设计堆区和栈区的大小等等。

而我们在使用内存管理的时候开辟一个专门存放变量的空间,我们需要的不只是简单的知道这个变量的大小,我们还需要知道它的地址要不然你使用这个变量,还要编译器找这个地址在哪里,这样才能提升项目的管理分配和运行效率,那根我直接开辟一个变量有什么区别?)而我开辟的地方也有讲究,因为只有Heap(堆区)才能给与我们自由分配空间并进行读写的权利。因此找到各个区的地址我认为是有必要的。

那我们应该怎么找到各个区的地址呢?

那就是查看代码编译后生成的.map文件

3.2 解析查找地址的.map文件的代码含义

代码来源:https://www.waveshare.net/w/upload/3/39/E-Paper_code.7z

注意:你要使用了malloc等函数才会存在heap区的开辟,要不然你在.map文件中是找不到heap的创建地址的。

我们得到了下面的关于堆的说明

 HEAP                     0x200002e0   Section    49152  startup_stm32f103xe.o(HEAP) 
   

STACK                    0x2000c2e0   Section     4096  startup_stm32f103xe.o(STACK)

__heap_base         0x200002e0   Data           0       startup_stm32f103xe.o(HEAP)
__heap_limit          0x2000c2e0   Data           0       startup_stm32f103xe.o(HEAP)
__initial_sp            0x2000d2e0   Data           0       startup_stm32f103xe.o(STACK)

HEAP:是堆的基地址

__initial_sp:是栈的起始地址(栈顶)

__heap_base:堆的​​起始地址​​。

__heap_limit:堆的​​结束地址​​。

示意图如下

4. 总结

如果我们设置了堆的空间大小,但是我们程序中没有进行malloc申请,那么在程序事假运行的时候,我们栈的空间超过本身设置的空间,进入到堆里面,那么程序是不会出错的,但是超过了堆的空间了,进入到全局变量区域,就会出现莫名其妙的错误。

不使用malloc,我们可以将堆设置成0,这是没有问题的,但是栈的空间大小要设置成合适的,不然就会因为栈溢出,进入harderror,程序奔溃。

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

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

相关文章

Linux中硬件信息查询利器——lshw命令详解!

lshw(List Hardware)是 Linux 系统下的一款命令行工具,用于全面检测并显示详细的硬件信息。它能够报告 CPU、内存、主板、存储设备、显卡、网络设备等几乎所有硬件组件的详细信息,适用于系统管理、故障排查和硬件兼容性检查等场景…

用llama3微调了一个WiFiGPT 用于室内定位

一段话总结 本文提出WiFiGPT,一种基于Decoder-Only Transformer(如LLaMA 3)的室内定位系统,通过将WiFi遥测数据(如CSI、FTM、RSSI)转换为文本序列进行端到端训练,无需手工特征工程即可实现高精度定位。实验表明,WiFiGPT在LOS环境中实现亚米级精度(MAE低至0.90米),在…

大模型系列22-MCP

大模型系列22-MCP 玩转 MCP 协议:用 Cline DeepSeek 接入天气服务什么是 MCP?环境准备:VScode Cline DeepSeek**配置 DeepSeek 模型:****配置 MCP 工具****uvx是什么?****安装 uv(会自动有 uvx 命令&…

Go语言Map的底层原理

概念 map 又称字典,是一种常用的数据结构,核心特征包含下述三点: (1)存储基于 key-value 对映射的模式; (2)基于 key 维度实现存储数据的去重; (3&#x…

循环神经网络(RNN):原理、架构与实战

循环神经网络(Recurrent Neural Network, RNN)是一类专门处理序列数据的神经网络,如时间序列、自然语言、音频等。与前馈神经网络不同,RNN 引入了循环结构,能够捕捉序列中的时序信息,使模型在不同时间步之间…

java 项目登录请求业务解耦模块全面

登录是统一的闸机; 密码存在数据库中,用的是密文,后端加密,和数据库中做对比 1、UserController public class UserController{Autowiredprivate IuserService userservicepublic JsonResult login(Validated RequestBody UserLo…

【手写数据库核心揭秘系列】第9节 可重入的SQL解析器,不断解析Structure Query Language,语言翻译好帮手

可重入的SQL解析器 文章目录 可重入的SQL解析器一、概述 二、可重入解析器 2.1 可重入设置 2.2 记录状态的数据结构 2.3 节点数据类型定义 2.4 头文件引用 三、调整后的程序结构 四、总结 一、概述 现在就来修改之前sqlscanner.l和sqlgram.y程序,可以不断输入SQL语句,循环执…

微软开源bitnet b1.58大模型,应用效果测评(问答、知识、数学、逻辑、分析)

微软开源bitnet b1.58大模型,应用效果测评(问答、知识、数学、逻辑、分析) 目 录 1. 前言... 2 2. 应用部署... 2 3. 应用效果... 3 1.1 问答方面... 3 1.2 知识方面... 4 1.3 数字运算... 6 1.4 逻辑方面... …

用HTML5+JavaScript实现汉字转拼音工具

用HTML5JavaScript实现汉字转拼音工具 前一篇博文(https://blog.csdn.net/cnds123/article/details/148067680)提到,当需要将拼音添加到汉字上面时,用python实现比HTML5JavaScript实现繁琐。在这篇博文中用HTML5JavaScript实现汉…

鸿蒙OSUniApp 开发的动态背景动画组件#三方框架 #Uniapp

使用 UniApp 开发的动态背景动画组件 前言 在移动应用开发中,动态背景动画不仅能提升界面美感,还能增强用户的沉浸感和品牌辨识度。无论是登录页、首页还是活动页,恰到好处的动态背景都能让产品脱颖而出。随着鸿蒙(HarmonyOS&am…

云原生技术架构技术探索

文章目录 前言一、什么是云原生技术架构二、云原生技术架构的优势三、云原生技术架构的应用场景结语 前言 在当今的技术领域,云原生技术架构正以一种势不可挡的姿态席卷而来,成为了众多开发者、企业和技术爱好者关注的焦点。那么,究竟什么是…

AWS之AI服务

目录 一、AWS AI布局 ​​1. 底层基础设施与芯片​​ ​​2. AI训练框架与平台​​ ​​3. 大模型与应用层​​ ​​4. 超级计算与网络​​ ​​与竞品对比​​ AI服务 ​​1. 机器学习平台​​ ​​2. 预训练AI服务​​ ​​3. 边缘与物联网AI​​ ​​4. 数据与AI…

lwip_bind、lwip_listen 是阻塞函数吗

在 lwIP 协议栈中,lwip_bind 和 lwip_listen 函数本质上是非阻塞的。 通常,bind和listen在大多数实现中都是非阻塞的,因为它们只是设置套接字的属性,不需要等待外部事件。阻塞通常发生在接受连接(accept)、…

【后端高阶面经:消息队列篇】28、从零设计高可用消息队列

一、消息队列架构设计的核心目标与挑战 设计高性能、高可靠的消息队列需平衡功能性与非功能性需求,解决分布式系统中的典型问题。 1.1 核心设计目标 吞吐量:支持百万级消息/秒处理,通过分区并行化实现横向扩展。延迟:端到端延迟控制在毫秒级,适用于实时业务场景。可靠性…

【运维实战】Linux 内存调优之进程内存深度监控

写在前面 内容涉及 Linux 进程内存监控 监控方式包括传统工具 ps/top/pmap ,以及 cgroup 内存子系统,proc 内存伪文件系统 监控内容包括进程内存使用情况, 内存全局数据统计,内存事件指标,以及进程内存段数据监控 监控进程的内…

决策树 GBDT XGBoost LightGBM

一、决策树 1. 决策树有一个很强的假设: 信息是可分的,否则无法进行特征分支 2. 决策树的种类: 2. ID3决策树: ID3决策树的数划分标准是信息增益: 信息增益衡量的是通过某个特征进行数据划分前后熵的变化量。但是&…

java基础学习(十四)

文章目录 4-1 面向过程与面向对象4-2 Java语言的基本元素:类和对象面向对象的思想概述 4-3 对象的创建和使用内存解析匿名对象 4-1 面向过程与面向对象 面向过程(POP) 与 面向对象(OOP) 二者都是一种思想,面向对象是相对于面向过程而言的。面向过程&…

TCP 三次握手,第三次握手报文丢失会发生什么?

文章目录 RTO(Retransmission Timeout)注意 客户端收到服务端的 SYNACK 报文后,会回给服务端一个 ACK 报文,之后处于 ESTABLISHED 状态 因为第三次握手的 ACK 是对第二次握手中 SYN 的确认报文,如果第三次握手报文丢失了,服务端就…

deepseek告诉您http与https有何区别?

有用户经常问什么是Http , 什么是Https ? 两者有什么区别,下面为大家介绍一下两者的区别 一、什么是HTTP HTTP是一种无状态的应用层协议,用于在客户端浏览器和服务器之间传输网页信息,默认使用80端口 二、HTTP协议的特点 HTTP协议…

openresty如何禁止海外ip访问

前几天,我有一个徒弟问我,如何禁止海外ip访问他的网站系统?操作系统采用的是centos7.9,发布服务采用的是openresty。通过日志他发现,有很多类似以下数据 {"host":"172.30.7.95","clientip&q…