首页 > 系统相关 >单片机的内存分配你了解多少呢?

单片机的内存分配你了解多少呢?

时间:2023-04-01 23:32:04浏览次数:33  
标签:RAM ROM Flash 单片机 内存 分配

单片机的内存分配你了解多少呢?_单片机

单片机开发也是嵌入式开发中的一个大群体,有许多的的人是进行单片机逻辑开发的,也有些人是单片机+嵌入式实时操作系统,当然也有单片机+linux+人工智能技术的。

当然,不管你是什么样的组合方式,只要你最终开发的产品中有使用到MCU,进行程序开发时,都应该会涉及到内存的分配问题。只要是开发程序过程中有过动态申请内存的朋友,对malloc、free估计是不会陌生的。

很多时候单片机的内存分配是会让人感觉到头疼的,有些单片机的内存很大,可以肆无忌惮的申请,有些内存空间又很有限,捉襟见肘,既要完美的实现产品功能,又要考虑内存的问题,不断的各种优化进行适配。而且可能很多人玩了几年的单片机可能都不清楚单片机内部的内存是如何分配的。

想要清楚单片机内部的内存是怎么分配的,我觉得首先应该要知道单片机内部都有哪些可供使用的存储空间。

常见的单片机它的内存一般有两部分:ROM + RAM。这两个到底有什么不同呢?

1、ROM & RAM

RAM+ROM 的组合方式就像电脑里面的运行内存(ram)+硬盘(rom)的组合方式。

(1)ROM

ROM:我们常说的存储数据的部分,它的一般的特点是只读(only read)。ROM在单片机中常用于BootLoader、应用程序App、OTA升级包存放、某些掉电以后希望被保存的数据等等的。

最早的出现的ROM是PROM,它只能编程一次,无法重复写入,当时基本用于固化程序或者保存一些重要数据。但是也有弊端,就是一旦出现写入错误,因为不能重复写入的缘故,就只能废弃。

后面随着相关技术的进步和发展,发展出紫外线照射下可写可擦的EPROM,但是那个时候的EPROM的擦写是很麻烦的,需要专门的仪器。

鉴于EPROM的擦写麻烦,又发展出了EEPROM,它可以通过电可擦的的方式进行擦写,使用的门槛降低了,成本可以大幅减低,应用场景是很大的。

还有到今天为止常见的Flash,这也是属于ROM类的存储方式。很多的单片机都有自带的Flash,而且现在的单片机Flash容量也是越做越大。还有我们常说的 Nor Flash、NAND Flash等等的。

这几类ROM的特点如下:

单片机的内存分配你了解多少呢?_单片机_02

(2)RAM

RAM:随机存储器,可按字节读写,读写速度快,但它也有缺点,就是掉电以后会丢失数据。所以,RAM一般用作运行时的内存空间分配。这就跟我们的手机的运行内存是一个道理的,运行内存的空间小了手机还会卡。

RAM 的特点和作用如下:

单片机的内存分配你了解多少呢?_单片机_03

在单片机中,RAM一般都被分配为堆、栈、变量等的空间,还有某些编译时放在ROM的变量也会在上电过程中拷贝到RAM中。

而且,我们常说的内存泄漏和内存溢出,它其实也都是发生在RAM中的。


2、内存模型 & 空间分配

在很多的单片机中,它的内存分配的一般模型如下图:

单片机的内存分配你了解多少呢?_单片机_04

在内存中的分配模型中,包含了五个部分:


1、栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量的值等。


2、堆区(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS释放。内存碎片化也是出现在这个部分。


3、数据区(.bss、.data):初始化的全局变量和静态变量放在一块区域,未初始化的全局变量和和未初始化的静态变量在相邻的的另一块区域。程序结束后由系统自动释放。 


4、文字常量:常量字符串就是放在这里的。这些数据是只读的,分配在RO-data(只读数据存储区),则被包含在flash中,程序结束后由系统自动释放。


5、程序代码(code):存放程序代码的,一般是函数体的二进制代码。



单片机程序中的定义变量的所在空间说明如下:

单片机的内存分配你了解多少呢?_单片机_05



3、STM单片机的内存分配的分析

使用过STM32的朋友应该知道map文件是可以提供程序的内存和链接的相关信息的,下面就用STM32的map文件说明一下它的内存分配方式。

在map文件的最后,都会有这样的汇总信息,如下图:

单片机的内存分配你了解多少呢?_单片机_06

上图中:

Code:代码存储区。这部分是存放代码的。

RO-Data:只读数据区。这部分保存程序中用 const 定义的全局常量数据和字符串。

RW-Data:已初始化的读写数据。程序中定义的已经初始化的全局变量和静态变量。

ZI-Data:未初始化的读写数据。程序中定义的未初始化的全局变量和静态变量。这部分内容是在程序运行的时候保存在RAM中的。

map文件中还做了统计:

单片机的内存分配你了解多少呢?_单片机_07

从上图可以看出:

RO:只读数据。这部分包含 Code 和 RO-Data 这部分是存放在Flash中的。

RW:可读写数据。这部分包含 RW-Data 和 ZI-Data,这部分是存放在RAM中的,就是占据运行内存的。

ROM Size:总的ROM的大小。这部分包含Code、RO-data、RW-Data,是程序中占Flash的实际大小。

    为了方便理解,可以参考下图:

单片机的内存分配你了解多少呢?_单片机_08



标签:RAM,ROM,Flash,单片机,内存,分配
From: https://blog.51cto.com/wangjunlv/6164086

相关文章

  • Python内存管理
    Python内存管理的三个阶段:1.引用计数引用计数是Python内存管理的第一道防线。当一个对象被引用时,Python会为其分配一段内存,并将其引用计数设置为1。当对象被多次引用时,其引用计数会逐渐增加。当一个对象不再被引用时,Python将其引用计数减少1。当一个对象的引用计数变为......
  • Redis——内存淘汰策略
    一、缓存耗尽的原因1、每台机器的内存是一定的2、key未设置过期时间key不设置过期时间则在内存中一直存在,直到我们明确删除它。3、过度或不合理的持久化无论RDB快照或者AOF日志,都会在内存和磁盘中反复操作,需要一定的内存空间。4、不及时清理过期缓存有时过期缓存依旧存在,主......
  • 一维数组内存分析
    Java虚拟机的内存划分为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。区域名称作用虚拟机栈用于存储正在执行的每个Java方法的局部变量表等。局部变量表存放了编译期可知长度<br/>的各种基本数据类型、对......
  • 项目一众筹网06_01_【权限控制】角色和权限分配、Admin分配Role、Role分配Auth、前端j
    系列文章目录众筹网文章目录系列文章目录01-角色和权限分配-引入02-Admin分配Role-目标和思路03Admin分配Role创建中间表有些表是不需要实体类的自然也就不需要做逆向工程04-Admin分配Role-前往分配页面-handler方法05-Admin分配Role-前往分配页面-Service方法和SQL06-Admin分......
  • 项目一众筹网06_02给用户分配角色、执行用户角色的分配、提交的 只是我们选中的解决、
    项目一众筹网06_02项目一众筹网06_02文章目录项目一众筹网06_0209-Admin分配Role-执行分配-handler方法(执行角色分配的后端代码开始)隐藏域的东西,不用传,点击submit(提交)的时候就会传过去,如下图允许参数是空值10-Admin分配Role-执行分配-Service方法==重复问题==11-Admin分配Role-执行......
  • 成都控制板开发:STC单片机IO引脚驱动不了光耦PC817的原因及解决(带PC817参数及驱动电路
    这是一个单片机通过光耦来信号隔离,驱动外部负载的电路。单片机为STC15系列,光耦为PC817,如图1,光耦的阳极输入端接到单片机的P20-P23引脚,光耦的输出DJ1-DJ4接到外部电路。但是在改变P20的电平时却出现了问题,并不能改变DJ1的电平,怎么回事呢?1、是限流电阻的问题吗?先看看光耦的参数......
  • 51单片机软件keil+stc-isp+驱动安装
    参考教程[1-2]开发工具介绍及软件安装_哔哩哔哩_bilibili驱动安装完成之后在设备管理器中可以看到,你插不同的usb口,com号应该不一样 ......
  • 什么是内存泄漏?哪些情况造成内存泄露?
    内存泄漏是指:一块被分配的内存既不能使用又不能回收,直到浏览器进程结束;以下列举内存泄漏的情况: <body>  <divclass="main">   <divclass="test">天</div>   <divclass="item">天</div>   <divclass="item">向<......
  • 一个对象的内存布局是怎么样的?
      「1.对象头」:对象头又分为 「MarkWord」 和 「ClassPointer」 两部分。「MarkWord」:包含一系列的标记位,比如轻量级锁的标记位,偏向锁标记位,gc记录信息等等。「ClassPointer」:用来指向对象对应的Class对象(其对应的元数据对象)的内存地址。在32位系统占......
  • 一个对象的内存布局是怎么样的?
      「1.对象头」:对象头又分为 「MarkWord」 和 「ClassPointer」 两部分。「MarkWord」:包含一系列的标记位,比如轻量级锁的标记位,偏向锁标记位,gc记录信息等等。「ClassPointer」:用来指向对象对应的Class对象(其对应的元数据对象)的内存地址。在32位系统占......