首页 > 系统相关 >单片机 内存管理

单片机 内存管理

时间:2024-05-25 19:34:38浏览次数:28  
标签:存储 RW 管理 SRAM RAM 起始 单片机 内存 data

首先,我们用keil编译器将写完的单片机代码全部编译后,编译窗口会输出以下信息:
在这里插入图片描述

可以看到,编译之后的运行文件被分成Code, RO-data, RW-data, ZI-data四部分存放于单片机的SRAM和FLASH中。

Code:代码占用的flash大小。

RO-data[read-only data]:只读常量(包括const修饰变量和define定义的常量)

RW-data[read and write data]:初始化过的变量

ZI-data[zero initialized data]:没有初始化的变量,堆栈数据也属于它

在此之上,我们又可以将这四部分分为 Total RO Size(Code+RO-data), Total RW Size(RW-data+ZI-data), Total ROM Size(Code+RO-data+RW-data)。在keil生成的xxx.map文件的最后可以看到各部分具体的数据大小。
在这里插入图片描述
其中,RAM和FLASH组成如下:
在这里插入图片描述

注意,RW-data在FLASH和RAM中均会存在一份。

这里RW-data为什么既占用FLASH,又占用RAM呢?

这是因为RAM是随机存取存储器(random access memory),也就是手机上经常说的运行内存,RAM是易失性存储,断电会丢失数据。所以已初始化的数据会存储在Flash中,上电会从FLASH搬移至RAM中。

那为什么ROM Size不包括ZI Data?

这是因为已经初始化的数据,在掉电后需要保存初始值,以便上电运行后重载,因此存在rom中。而ZI Data数据都是0,上电运行后直接清零即可,包含进去反而浪费存储空间。

之后,在我们的keil编译器的设置选项卡中可以看到,在STM32F407VET中,FALSH(ROM)的存储起始地址是0x8000000,存储大小是512KB(0x80000)。同时SRAM(RAM)有两块,第一块(IRAM1)的存储起始地址是0x20000000,存储空间大小是112KB(0x1C000),第二块(IRAM2)的存储起始地址是0x2001C000,紧接着第一块,存储大小是16KB(0x4000),两块加起来一共有128KB。
block 1内有SARM1(112KB,0x2000 00000 ~ 0x2001 BFFF)和SRAM2(16KB, 0x2001 C000 ~ 0x2001 FFFF)两块连续的SRAM,可供所有的AHB 主控总线访问。
为什么是两块SRAM?这是因为主总线支持并发SRAM访问,提高执行效率。例如当 CPU 对 112 KB SRAM 进行读/写操作时,以太网MAC 可以同时对 16 KB SRAM 进行读/写操作;或者CPU和DMA可以同时访问不同的SRAM。

在这里插入图片描述
以上计算结果和芯片STM32F4芯片数据手册中的存储地址划分一致。
在这里插入图片描述

block 0共有512M,其中Reserved即为保留区,即可以使用外部flash扩展这个块的存储空间,只要地址在范围内就可以。
block 1名称就是SRAM,所以这个区域就是用来放置RAM。而图中的64KBSRAM就是stm32内置的RAM,MCU的基本配置就是得有CPU+RAM+外设。可以看到这个块也有512MB,所以这个RAM也可以通过外部扩展至512MB,当然外部扩展的肯定不如内置的好用了。
SRAM就是运行内存,就和电脑、手机上经常说的几G内存是同一个东西。它的作用就是把flash(这里只对于stm32来说)里正在运行的代码段(函数、变量等等)放进这个内存里,然后CPU对这里面的数据进行读写操作。
搞清楚RAM和FLASH的组成后,再把目光投向单片机的堆和栈。单片机产生的堆和栈数据属于ZI-data,所以这块数据也是存放在RAM中。其中堆是向上增长,栈是向下减少。如果堆空间使用过大(malloc开辟的空间过大),那会造成堆栈冲突,此时离程序崩溃已经不远了。左图是标准c程序内存组成,右图是stm32的程序内存组成。
在这里插入图片描述

MCU的堆、栈也是属于这片区域的,这里所说的堆栈和数据结构的堆栈概念不能混为一谈,当然也是类似的。堆空间存放上电后长久存在的值,即程序员malloc申请的存储空间,栈空间则是存放一些临时值,包括函数的参数值、局部变量值。而其他未初始化和初始化全局变量以及静态变量(属于已初始化全局变量)则是放在ZI-data,RW-data段(bss和data段)里。
在这里插入图片描述

通过keil编译器中ST官方编写的汇编启动文件,可以找到对应芯片的堆栈大小。下图可以看到,STM32F407的堆空间大小是1KB(0x400),栈空间大小是512B(0x200)。也就意味着,我们创建的局部变量和使用的函数临时参数不能超过栈内存空间大小1KB,malloc申请的内存空间大小不能超过512B。
在这里插入图片描述

在keil编译器生成的list文件(xxx.map)中同样可以看到代码段(Text)、数据段(data,包括所谓的静态存储区)、堆栈的具体存储起始地址。可以看到堆的起始位置是被分配在data段之后,如果我们申请的data段更大,那么堆的位置就会向后延伸,直至到达SRAM的理论上限(128KB)。下图看到堆的起始位置是0x20000588,存储大小是512B;栈的起始位置是0x20000788,存储大小是1KB。
在这里插入图片描述

注意,堆之前的bss段起始地址是0x20000588,占用存储空间是96B,所以下一个堆空间的起始位置应该是0x20000524+96D=0x20000584。但是从map文件中我们看到定义的堆空间起始是0x20000588,是因为0x20000588可以被8整除,即满足地址8字节对齐的需求。所以我们在之后使用RAM时也要遵循8字节对齐的原则分配存储空间。
现在,如果我们想要开辟一块存储空间上电后临时存储我们想要的数据,例如开辟一块数组,那么开辟的全局数组变量将会被存放在data段的起始位置,即0x20000000往后的128KB内存地址块内。如果我们要在不使用外部flash的情况下将数据永久保存,理论情况下可以将数据存放在0x80000000+Total ROM Size的后面,当然通常情况下代码段是不断扩张的,保险起见我们需要将断电保存的数据尽量保存在FLASH最后地址,即0x80080000附近。

参考多份博客整理,如有错误,请指正。
参考博客1 【STM32单片机入门-1】堆栈/全局变量,局部变量,静态全局变量,局部静态变量等
参考博客2 【单片机】MCU内存管理

标签:存储,RW,管理,SRAM,RAM,起始,单片机,内存,data
From: https://blog.csdn.net/caole0001/article/details/139201133

相关文章

  • C语言初阶 数据在内存中的存储
    数据在内存中的存储在编程的世界里,数据是如何存储和管理的,是每一位开发者都必须了解的基础知识。特别是对于C语言这样的底层语言,理解数据在内存中的存储方式,对于写出高效、安全的代码至关重要。本文将带您深入了解C语言中数据在内存中的存储方式。1.整数存储对于整型来说......
  • 芝奇发布全新旗舰皇家戟DDR5内存:首发频率高达8400MHz
    凭借华丽设计、超高规格、极致性能在圈内享誉已久的芝奇TridentZ5Royal皇家戟内存,终于进入了DDR5时代,首发频率就高达8400MHz。皇家戟DDR5内存延续了该系列超跑一般的独特流线造型,厚重精实的高质量铝合金散热马甲,经过精工细腻的电镀处理,呈现出水镜般清澈透亮的高质感光泽,经典金......
  • 基于JAVA GUI体育馆管理系统的会员功能
      JavaGUI即Java图形用户界面,是一种使用图形化元素(如窗口、按钮、文本框等)来构建用户界面的技术。它基于Java的Swing框架,可以用于创建各种复杂的用户界面,包括窗口、对话框、菜单、按钮、文本框、复选框、下拉列表等。  JavaGUI具有以下特点:跨平台性:Java是一种跨平台......
  • 基于Android Studio图书管理,图书借阅系统
    目录项目介绍图片展示运行环境获取方式项目介绍用户书架:搜索书籍,查看书籍,借阅书籍,收藏书籍,借阅书籍必须在一个月之内还书;我的:可以修改密码,退出登录,查看收藏,查看借书记录管理员书架:搜索书籍,查看书籍,借阅书籍,收藏书籍,借阅书籍必须在一个月之内还书;我的:可以修改密码......
  • 源代码管理工具——Github
    一.工具介绍1.我的理解GitHub他就是一个远程仓库,远程仓库通俗的理解就是一个可以保存自己代码的地方,在实际开发当中一个项目往往是有多个人来共同协作开发完成的,那么就需要一个统一代码保存的地方,而GitHub就是起到一个共享和汇总代码的作用。2.github登录与注册官方登录页:ht......
  • 在奖学金管理系统项目中使用 GitHub 管理源代码
    1.GitHub管理代码的基本步骤GitHub是一个基于Git的代码托管平台,提供了版本控制和协作开发的功能。以下是使用GitHub管理代码的基本步骤:注册和创建存储库:注册一个GitHub账号。创建一个新的存储库(Repository):登录GitHub,点击右上角的“+”号,选择“Newreposi......
  • 图书管理系统(二)--用户模块--Python版
    本课题要求编写Python程序实现对图书信息录入、图书信息查询、图书借阅等方面的管理。一个综合的图书借阅管理系统,要求能够管理图书的基本信息(包含新图书入库、读者图书查询借阅等),需要实现以下功能:读取以数据文件形式存储的图书信息;管理员可以增加、修改、删除图书的信息;读者可......
  • 嵌入式单片机寄存器操作与实现方法
       大家好,今天给大家分享一下,单片机中寄存器该如何操作与实现。“芯片里面的寄存器访问方式一般是: 1.可使用地址访问,2.可使用指令访问,3.不可访问”第一:挂载到内存地址总线上了的挂载到内存地址总线上了的,可以使用分配到的地址访问如下是STM32单片机存储器映像上挂载......
  • 【计算机毕业设计】基于SSM++jsp的实验室耗材管理系统【源码+lw+部署文档】
             目录第1章绪论1.1课题背景1.2课题意义1.3研究内容第2章开发环境与技术2.1MYSQL数据库2.2JSP技术 2.3SSM框架第3章系统分析3.1可行性分析3.1.1技术可行性3.1.2经济可行性3.1.3操作可行性3.2系统流程3.2.1操作流程3.2.2......
  • 基于arduino单片机汽车智能电子防碰撞装置设计
    **单片机设计介绍,基于arduino单片机汽车智能电子防碰撞装置设计文章目录一概要二、功能设计设计思路三、软件设计原理图五、程序六、文章目录一概要  基于Arduino单片机汽车智能电子防碰撞装置设计概要如下:一、引言随着汽车保有量的不断增加,道路安全成......