1. 存储体系总体架构

MCU 的存储系统采用分层设计,以 CPU 核心为中心向外辐射,形成速度递减、容量递增、掉电保持特性各异的多级结构。该设计的核心目标是在访问速度、存储容量、成本与功耗之间取得平衡。

层级存储器类型典型容量访问速度掉电保持主要用途
L0寄存器数十~数百字节1 周期运算操作数、地址指针
L1Cache数 KB ~ 数百 KB1~3 周期指令与数据加速缓冲
L1.5TCM / ILM / DLM数十~数百 KB零等待实时性关键代码与数据
L2SRAM数十 KB ~ 数 MB1~2 等待周期运行时变量、栈、堆
L3Flash (NOR)数十 KB ~ 数 MB多等待周期程序指令、只读常量
L3.5ROM数 KB ~ 数十 KB较快Bootloader、出厂参数
L4EEPROM数百字节 ~ 数 KB较慢频繁修改的配置数据

2. 核心内存储器

2.1 寄存器

寄存器位于 CPU 核心内部或外设模块内部,是 MCU 中访问速度最快的存储单元。

CPU 通用寄存器

  • 用于暂存当前运算的操作数、地址指针与中间结果。任何算术逻辑运算均需先将数据载入寄存器方可执行。
  • 以 RISC-V 架构为例,包含 x0 ~ x31 共 32 个通用寄存器;ARM Cortex-M 系列则包含 R0 ~ R15 等寄存器组。

外设寄存器

  • 通过**内存映射(Memory-Mapped)**机制挂载在系统总线上,CPU 通过 Load/Store 指令对其进行读写。
  • 例如 UART->THR(发送保持寄存器)控制数据发送,GPIO->DO(数据输出寄存器)控制引脚电平。
  • 外设寄存器的位定义通常包含功能位、状态位与中断标志位,直接决定硬件行为。

2.2 缓存(Cache)

缓存位于 CPU 核心与总线矩阵之间,用于缓解 CPU 与慢速存储器之间的速度差异。

  • 指令缓存(I-Cache):加速程序取指过程。
  • 数据缓存(D-Cache):加速数据读写过程。
  • 缓存对软件透明,由硬件自动管理命中、缺失与替换策略。

嵌入式场景中的关键问题:DMA 与 Cache 一致性

DMA 控制器直接访问 SRAM,不经过 Cache。若 CPU 此前读取过某块内存,Cache 中可能保留旧值;DMA 修改该内存后,CPU 再次读取时仍从 Cache 获取,导致得到脏数据。解决方式是在 DMA 传输前后手动执行 Cache 的 Clean(写回)与 Invalidate(失效)操作。

2.3 紧耦合内存(TCM / ILM / DLM)

紧耦合内存直接连接在 CPU 核心上,绕过总线矩阵,提供零等待周期的确定性访问。

  • ILM(Instruction Local Memory):存放对时序极度敏感的代码,如电机控制中断服务函数。
  • DLM(Data Local Memory):存放实时采样数据缓冲、控制参数等关键数据。
  • 由于不受总线竞争影响,其访问延迟固定,适用于硬实时场景。
  • 以 HPM6E00 为例,ILM/DLM 通过专用接口与 CPU 核心直连,AXI 总线上的其他主设备无法直接访问。

3. 易失性工作存储器

3.1 SRAM

SRAM 通过内部总线(AHB/AXI)与 CPU 连接,是程序运行时的主要工作区。固件启动后,链接器脚本按以下规则分配 SRAM 空间:

内存段来源说明
.dataFlash 复制已初始化的全局变量与静态变量
.bss运行时清零未初始化的全局变量与静态变量
heap运行时划分动态内存分配区(malloc/free
stack运行时划分函数调用现场、局部变量、返回地址

SRAM 支持字节、半字、字等多种访问宽度,速度较快(通常 1~2 个等待周期),但掉电后数据全部丢失

3.2 栈(Stack)与堆(Heap)

  • :从高地址向低地址生长,用于保存函数调用的返回地址、局部变量与寄存器现场。中断发生时,当前执行上下文自动压栈。
  • :从低地址向高地址生长,由程序通过动态分配函数管理。嵌入式系统中通常限制堆的使用,以避免内存碎片与泄漏。

4. 非易失性程序存储器

4.1 Flash(NOR Flash)

Flash 是 MCU 中最主要的非易失性存储器,掉电后程序与常量数据仍然保持。

存储内容

  • .text 段:程序指令代码。
  • .rodata 段:只读常量,如字符串字面量、查找表、校准参数。
  • 用户配置:部分应用将设备参数存储于 Flash 的独立扇区。

读写特性

  • 读取:支持随机寻址,但访问速度慢于 SRAM。现代 MCU 通常配备 Flash 预取缓冲器(Prefetch Buffer),在连续取指时可将有效吞吐率提升至接近 SRAM 水平。
  • 写入/擦除:Flash 不能按字节直接覆盖写入,必须遵循"先擦除后写入"原则,且擦除操作以 Page(页)Sector(扇区) 为单位进行。擦写寿命有限,典型值为 10 万次左右。
  • 部分高性能 MCU(如 HPM6E00)支持 XPI 接口连接外部 SPI Flash,扩展存储容量。

4.2 ROM(Boot ROM / Mask ROM)

ROM 在芯片制造阶段固化,用户无法修改。

典型内容

  • Bootloader:芯片厂商预置的启动加载程序,支持 UART、USB 等接口的 ISP(在系统编程)或 DFU(设备固件升级)功能。例如 STM32 的 System Memory 区域、N32G457 的出厂 Bootloader。
  • 出厂参数:芯片唯一标识符(UID)、ADC 校准系数、温度传感器校准值等。

CPU 上电复位后,PC 指针首先指向 ROM 中的启动代码,由 Bootloader 检测启动模式引脚(如 BOOT0),决定进入 ISP 模式还是跳转至用户 Flash 执行。

4.3 EEPROM

EEPROM 支持按字节擦写,寿命较长(通常 100 万次以上),容量较小(数百字节至数 KB),适合存放需频繁修改且掉电保持的配置数据。

现代 MCU 出于成本与工艺考虑,较少集成独立 EEPROM 阵列,转而采用 Flash 模拟 EEPROM 方案(如 STM32 的 EEPROM Emulation 库),通过磨损均衡算法延长有效寿命。

5. 启动过程与数据流向

5.1 典型上电启动流程

以 ARM Cortex-M 系列 MCU 为例,上电后的存储器交互流程如下:

  1. 复位向量取值:CPU 从地址 0x0000_0000(或 0x0800_0000 经重映射)读取初始栈指针(MSP),从 0x0000_0004 读取复位处理函数地址。
  2. 启动代码执行:复位处理函数(通常位于 Flash 的 .text 段)开始运行,完成系统时钟初始化、中断向量表重定位等操作。
  3. 数据段搬运:将 .data 段从 Flash 复制到 SRAM 的指定地址;将 .bss 段在 SRAM 中清零。
  4. 运行时环境建立:初始化 heapstack 边界,调用 main() 函数。
  5. 正常运行期:CPU 从 Flash 取指令,在 SRAM 中读写变量。DMA 在 SRAM 与外设寄存器之间直接搬运数据。中断发生时,上下文保存至 SRAM 的栈空间。
  6. 掉电:SRAM、寄存器、Cache 内容全部丢失;Flash、ROM 数据保持不变。

5.2 DMA 数据流

DMA 控制器作为独立总线主设备,可直接在以下路径传输数据,无需 CPU 介入:

  • 外设 → SRAM:如 ADC 采样结果直接写入内存缓冲。
  • SRAM → 外设:如 SPI 发送数据从内存缓冲直接加载。
  • SRAM → SRAM:内存块拷贝。

若系统启用了 D-Cache,DMA 访问 SRAM 前必须执行 SCB_CleanDCache() 确保数据写回主存,DMA 完成后执行 SCB_InvalidateDCache() 使 Cache 行失效,以保证 CPU 后续读取到最新数据。

6. 概念辨析

对比项本质差异
Flash vs ROMFlash 属于可擦写可编程 ROM 范畴,但在 MCU 语境中,ROM 特指出厂固化的 Boot ROM,Flash 是用户可反复烧写的程序存储区。
寄存器 vs RAM寄存器集成于 CPU/外设内部,无独立存储阵列;RAM 是独立的存储器,拥有连续的地址空间。
Cache vs RAMCache 是 RAM 的透明加速层,由硬件自动管理;RAM 是显式存储,程序员直接通过变量地址访问。
Flash vs EEPROMFlash 按扇区擦除、寿命较短(约 10 万次),适合存储程序;EEPROM 按字节擦除、寿命较长(约 100 万次),适合存储配置参数。
ILM/DLM vs SRAMILM/DLM 绕过总线矩阵直连 CPU,零等待、确定性高;SRAM 通过总线访问,可能受总线仲裁影响产生延迟。