前言 
 
在这里会较为详细的阐述各种类型的存储器的特点及其之间的差别,以及我们会在STM32单片机上面使用一种超级便捷的方式来管理我们所使用到的内存。 
理清 xxRAM、xxROM、xxFlash 的核心作用 
 
三种不同存储器:RAM、ROM、Flash 
 
这三个总的概括,就使用一个表格来说明吧,表格如下: 
| 内存 存储类型 核心功能 数据保持 单片机对应硬件 典型存储内容 |  |  RAM | 易失性 | 存放动态数据、临时变量 | 掉电丢失 | DTCM/AXI SRAM / 普通 SRAM | 全局变量、局部变量、栈 / 堆 |  | ROM(概念) | 非易失性 | 只读存储(功能) | 掉电不丢 | 由 Flash 实现 | 无独立硬件,功能同 Flash |  | Flash | 非易失性 | 存放程序代码、常量 | 掉电不丢 | 片上 Flash(一般0x08000000 起) | 代码段、const 常量、复位向量表 |   四种 RAM:DRAM、SRAM、SDRAM、MRAM 
 
DRAM 
 
(Dynamic RAM,动态随机存取存储器) 
 
- 原理: 利用电容存储电荷来表示数据(0/1),但电容会漏电,需要定期 “刷新”(每隔几毫秒充电一次)才能保持数据。
 
 - 特点: 结构简单(一个晶体管 + 一个电容),密度高(相同体积下容量更大);速度中等(比 SRAM 慢),功耗较高(刷新需要耗电);价格便宜(单位容量成本低)。
 
 - 应用 : PC 的内存(DDR4/DDR5 都是 DRAM 的改进型)、智能手机的运行内存(RAM)等需要大容量临时存储的场景。
 
  SRAM 
 
(Static RAM,静态随机存取存储器) 
 
- 原理: 利用触发器(由多个晶体管组成)存储数据,无需刷新,只要供电就能保持数据。
 
 - 特点: 速度极快(访问时间纳秒级,比 DRAM 快 10~100 倍);结构复杂(一个 bit 需要 6~8 个晶体管),密度低(容量小);价格高(单位容量成本是 DRAM 的几倍),功耗中等(无需刷新但晶体管本身耗电)。
 
 - 应用 : CPU 内部的高速缓存(L1/L2/L3 Cache)、STM32 片上 RAM(如 DTCM、SRAM1~4 都是 SRAM)等需要高速访问的场景。
 
  SDRAM 
 
(Synchronous DRAM,同步动态随机存取存储器) 
 
- 原理: 属于 DRAM 的一种,工作时与 CPU 时钟同步(数据读写按时钟节拍进行),需要定期刷新。
 
 - 特点: 速度比传统异步 DRAM 快,容量大(常见 128MB~2GB);需外部控制器(如 STM32 的 FMC 接口),时序配置复杂。
 
 - 应用 : 嵌入式系统扩展大容量临时存储,如 STM32 H7 系列外接 SDRAM 用于存放视频帧、大型缓存数据等。
 
  MRAM 
 
(Magnetoresistive RAM,磁阻式随机存取存储器) 
 
- 原理: 利用磁阻效应存储数据(通过磁场变化改变电阻状态表示 0/1),非易失性,无需刷新。
 
 - 特点: 速度接近 SRAM,容量接近 DRAM,非易失性(掉电不丢数据);功耗低(无需刷新和电荷维持),寿命长(理论无限次擦写);成本高(目前还未大规模普及)。
 
 - 应用 : 高端嵌入式系统(如工业控制、汽车电子)需要 “高速 + 非易失” 的场景,替代部分 SRAM 和 Flash 的组合使用
 
  对比 
 
| 特性 DRAM SRAM SDRAM MRAM |  |  易失性 | 掉电丢失 | 掉电丢失 | 掉电丢失 | 掉电不丢失 |  | 速度 | 中等(几十纳秒) | 极快(几纳秒,接近 CPU 速度) | 比 DRAM 快(同步时钟优化) | 接近 SRAM(几纳秒) |  | 大小 | GB 级 | MB 级 | 数百 MB~ 数 GB | 目前可达 GB 级,逐步提升 |  | 功耗 | 较高 | 中等 | 略低于 DRAM | 低 |  | 成本 | 低 | 高 | 与 DRAM 接近 | 高(未大规模普及) |  | 应用 | 早期 PC 内存、低端嵌入式设备 | CPU 缓存、STM32 片内 RAM | 嵌入式扩展内存 | 工业控制、汽车电子 |   两种 Flash:NAND Flash、NOR Flash 
 
NOR Flash 
 
(或非闪存) 
原理: 同样基于浮栅晶体管,非易失性,但内部结构与 NAND 不同。 
 特点: 随机访问速度快(可直接 “按地址读取”,类似 RAM),支持 “代码在 Flash 中直接运行”(XIP,eXecute In Place);密度低(容量小),价格高(单位容量成本高),擦写速度慢(尤其大容量擦除)。 
 应用: 嵌入式系统的 “程序存储器”,如 STM32 片上 Flash 几乎都是 NOR Flash(用于存储程序代码、启动程序),路由器、交换机的固件存储等;STM32 中片内 Flash(如 0x08000000 起始地址的存储区域)均为 NOR Flash,支持程序直接在 Flash 中运行(无需加载到 RAM)。 
NAND Flash 
 
(与非闪存) 
原理: 基于浮栅晶体管存储电荷,通过电荷是否存在表示数据,属于非易失性存储(掉电不丢数据)。 
 特点: 结构简单,密度极高(相同体积下容量远大于 NOR Flash);读写速度 “页级快、随机慢”(适合连续读写,随机访问速度差);价格低(单位容量成本是 NOR Flash 的 1/5~1/10),但有 “坏块” 和 “擦写次数限制”(通常 10 万次以上)。 
 应用: 大容量存储场景,如 U 盘、SD 卡、固态硬盘(SSD)、嵌入式系统的 “硬盘”(如存储固件、日志、用户数据);STM32 中部分型号支持外接 NAND Flash(如 F4/F7/H7 系列),用于扩展大容量非易失性存储。 
对比 
 
| 特性 NOR Flash NAND Flash |  |  存储结构 | 并行结构,地址线可直接寻址单个字节 | 串行 / 页式结构,需按 “块 - 页” 层级寻址 |  | 速度 | 随机访问快(10~100ns),支持按地址读单个字节;连续读写速度慢 | 随机访问慢(需先找块、再找页);连续读写快(页级操作,几十 MB/s) |  | 执行能力 | 支持 XIP(就地执行):程序可直接在 Flash 中运行,无需加载到 RAM | 不支持 XIP:代码需先加载到 RAM 才能运行 |  | 擦写特性 | 支持小粒度擦除(扇区级,如 4KB/8KB),部分支持字节级修改 | 必须 “先擦除再写入”,擦除粒度大(块级,如 128KB/256KB),仅支持页级写入 |  | 容量与密度 | 密度低,单芯片容量小(通常 1MB~1GB) | 密度高,单芯片容量大(通常 8GB~1TB,甚至更高) |  | 成本 | 单位容量成本高(约为 NAND 的 5~10 倍) | 单位容量成本低,性价比高 |  | 引脚与接口 | 引脚多(需地址线、数据线分离),接口复杂 | 引脚少(地址 / 数据复用),接口简单(如 SPI/NAND、ONFI 接口) |  | 应用 | 小型嵌入式设备的程序存储、交换机 | 硬盘、手机、平板的内置存储 |   EEPROM 
 
原理: 通过电信号擦除和写入数据,非易失性,可字节级擦写(无需按块擦除)。 
 特点: 擦写方便(支持单个字节修改,无需整块擦除);容量小(通常 KB 级,最大几 MB),速度慢(擦写时间毫秒级),寿命有限(通常 10 万次擦写)。 
 应用: 存储少量需要频繁修改的非易失性数据,如设备参数(波特率、地址)、校准数据(传感器零点)、用户配置等;STM32 中部分型号内置 EEPROM(如 F1/F4 系列),或通过 “Flash 模拟 EEPROM” 功能实现类似效果(如 H7 系列无独立 EEPROM,需用 Flash 特定区域模拟)。 
H7 系列内存详解 
 
参考文章:[ST] STM32H7的TCM,SRAM等五块内存基础知识 
 H7的内部内存分为了ITCM,DTCM,AXI SRAM,SRAM1,SRAM2,SRAM3,SRAM4和备份SRAM。下图中分为了三个域:D1 Domain,D2 Domain和D3 Domain。 
 
TCM 区 
 
(Tightly-Coupled Memory 紧密耦合内存) 
 
- ITCM:用于运行指令,也就是程序代码。
 
 - DTCM:用于数据存取,特点是跟内核速度一样,而片上RAM的速度基本都达不到这个速度,所以有降频处理。
 
  AXI SRAM 区 
 
位于D1域,数据带宽是64bit,挂在A线上。除了D3域中的BDMB主控不能访问,其它都可以访问此RAM区。 
AXI SRAM  地址:0x2400 0000。  速度:200MHz。  大小:512KB。  用途:用途不限,可以用于用户应用数据存储或者LCD显存。 SRAM1,SRAM2和SRAM3 区 
 
位于D2域,数据带宽是32bit,挂在AHB总线上。除了D3域中的BDMB主控不能访问这三块SRAM,其它都可以访问这几个RAM区。 
SRAM1  地址:0x3000 0000。  速度:200MHz。  大小:128KB。  用途:用途不限,可用于D2域中的DMA缓冲,也可以当D1域断电后用于运行程序代码。 SRAM2  地址:0x3002 0000。  速度:200MHz。  大小:128KB。  用途:用途不限,可用于D2域中的DMA缓冲,也可以用于用户数据存取。 SRAM3  地址:0x3004 0000。  速度:200MHz。  大小:32KB。  用途:用途不限,主要用于以太网和USB的缓冲。 SRAM4 区 
 
位于D3域,数据带宽是32bit,挂在AHB总线上,大部分主控都能访这块SRAM区。 
地址:0x3800 0000。  速度:200MHz。  大小:64KB。  用途:用途不限,可以用于D3域中的DMA缓冲,也可以当D1和D2域进入DStandby待机方式后,继续保存用户数据。 Backup SRAM 区 
 
备份RAM区,位于D3域,数据带宽是32bit,挂在AHB总线上,大部分主控都能访问这块SRAM区。 
SRAM4  地址:0x3880 0000。  速度:200MHz。  大小:4KB。  用途:用途不限,主要用于系统进入低功耗模式后,继续保存数据(Vbat引脚外接电池)。 内存时钟问题 
 
AXI SRAM,SRAM4,ITCM和DTCM可以在上电后直接使用。而SRAM1,SRAM2,SRAM3是需要使能的,但是实际测试发现,不使能也可以正常使用。不过,建议用到时候开启下时钟,防止意想不到的问题发生。 
 
RAM 的 DMA 问题 
 
Bus Master总线主控端和Bus Slave设备端的控制互联: 
 
加粗字体是64位总线(ITCM,DTCM,Flash A,Flash,AXI SRAM,FMC等),普通字体是32位总线。  访问通路(每个小方块里面的字符)  任何有数字的表示有访问通路。  短横杠“-”表示不可访问。  有灰色阴影的表示有实用价值的访问通路。  表格中具体数值所代表的含义  D=direct,  1=via AXI bus matrix,  2=via AHB bus matrix in D2,  3=via AHB bus matrix in D3,  4=via AHB/APB bridge in D1,  5=via AHB/APB bridge in D2,  6=via AHB/APB bridge in D3,  7=via AHBS bus of Cortex-M7,  多个数值组合 = 互连路径以数字的顺序经过多个矩阵或/和桥。  总线访问类型  普通字体表示32位总线。  斜体表示32位总线主机端/ 64位总线从机端。  粗体表示64位总线。 超便捷的内存区域管理方法 
 
参考文章:【STM32H7教程】第26章 STM32H7的TCM,SRAM等五块内存的超方便使用方式 
一般的内存管理方式 
 
不太注意的话,一般都是在"target dialog"这里简单管理内存。这种情况下,所有管理工作都是编译来处理的。 
 
分散加载式管理内存区域 
 
使用分散加载的方式来管理内存,会超级灵活,想用哪一块就用哪一块。下面就是超级教程: 
在魔术棒的"OutPut"配置中,会生成一个相同名字的 .sct 文件,这个就是这个方法的关键,找到它。 
 
第一步 
 
 
- 取消勾选"Use Memiry Layout from Target Dialog"。
 
 - 点击"..."找到与输出文件同名的 .sct 文件(假如你这里没有显示的话)。
 
 - 点击"Edit"打开这个 .sct 文件。
 
 
  
第二步 
 
使用 STM32H7 系列的可以直接将以下程序复制进去。其他系列的单片机则需要稍加修改。 
假如不同,你需要修改的有: 点击查看代码- ; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* ; 定义加载区域LR_IROM1:起始地址0x08000000,大小0x00200000(2MB) ; 这是整个程序的加载区域,通常对应Flash存储器 LR_IROM1 0x08000000 0x00200000 { ; load region size_region ; 定义执行区域ER_IROM1:起始地址与加载地址相同(0x08000000),大小2MB ; 存放程序的只读代码和常量 ER_IROM1 0x08000000 0x00200000 { ; load address = execution address *.o (RESET, +First) ; 所有目标文件的RESET段,放在最前面(复位向量) *(InRoot$$Sections) ; 根区域必要的特殊段(如异常向量表) .ANY (+RO) ; 任何文件的只读代码和常量(RO段) .ANY (+XO) ; 任何文件的可执行代码(XO段) } ; 定义DTCM内存区域:起始地址0x20000000,大小0x00020000(128KB) ; DTCM是内核紧密耦合的数据存储器,访问速度快 RW_DTCM_IRAM 0x20000000 0x00020000 { ; RW data .ANY (+RW +ZI) ; 任何文件的读写数据(RW)和未初始化数据(ZI) ;*(.RAM_D0)        ;段选择器,若不手动选择,则完全不会被分配到此 } ; 定义AXI SRAM区域:起始地址0x24000000,大小0x00080000(512KB) ; AXI接口的SRAM,通常用于高性能数据访问 RW_AXI_SRAM_IRAM 0x24000000 0x00080000 { .ANY (+RW +ZI) ; 任何文件的读写数据和未初始化数据 ;*(.RAM_D1)        ;段选择器,若不手动选择,则完全不会被分配到此 } ; 定义SRAM1~SRAM3区域:起始地址0x30000000,大小0x00080000(512KB) ; 片上静态存储器区域1-3 RW_SRAM_1_3_IRAM 0x30000000 0x00080000 { .ANY (+RW +ZI) ; 任何文件的读写数据和未初始化数据 ;*(.RAM_D2)        ;段选择器,若不手动选择,则完全不会被分配到此 } ; 定义SRAM4区域:起始地址0x38000000,大小0x00010000(64KB) ; 片上静态存储器区域4 RW_SRAM_4_IRAM 0x38000000 0x00010000 { .ANY (+RW +ZI) ; 任何文件的读写数据和未初始化数据 ;*(.RAM_D3)        ;段选择器,若不手动选择,则完全不会被分配到此 } } ; 段选择器使用案例: ; __attribute__((section (".RAM_D1"))) uint32_t AXISRAMBuf[10]; ; __attribute__((section (".RAM_D2"))) uint16_t AXISRAMCount; ; ; 若没有使用段选择器,那么就会按照分散加载文件中内存区域的定义顺序依次分配, ; 直到前面的区域被占满后才会 “溢出” 到后面的区域。 
 
  复制代码 可以看出,RW区也是要存储到ROM/Flash里面的,在执行映像之前,必须将已初始化的 RW 数据从 ROM 中复制到 RAM 中的执行地址并创建ZI Section(初始化为0的变量区)。 
上面的程序注释中已经详细说明了这一段程序的作用,其中的加载区域就是程序在Flash中的实际存储,而运行区域是芯片上电后的运行状态,通过下面的框图可以有一个感性的认识: 
 
博客导航 
 
博客导航  
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除 
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |