1. 为什么要区分不同存储器
MCU 中的存储器在速度、容量、价格、掉电特性和擦写寿命方面各不相同。工程设计时不能把所有数据都放到同一种存储器中。
判断一份数据应该放在哪里,可以先问三个问题:
它是否需要执行? 程序代码必须放在可执行存储器中;
它运行时是否会改变? 会改变的数据必须放在可读写存储器中;
断电后是否还要保留? 需要保留的数据必须存入非易失性存储器。
最常见的结论是:
程序代码和固定常量 → Flash
运行时变量 → SRAM
任务栈和动态内存 → SRAM
掉电保持参数 → EEPROM、FRAM 或 Flash 分区
大量文件和日志 → 外部 Flash、SD 卡或 eMMC
2. MCU 的片内存储器
“片内”表示存储器直接集成在 MCU 芯片内部。它们访问速度快、硬件连接简单,是系统启动和实时控制的基础。
2.1 片内 Flash:保存程序和少量持久数据
Flash 是 Flash Memory 的缩写,中文为“闪存”。Flash 属于 NVM(Non-Volatile Memory,非易失性存储器),断电后数据不会消失。
片内 Flash 常用于保存:
-
Bootloader(引导程序);
-
中断向量表;
-
应用程序机器码;
-
字符串、查找表和 const 常量;
-
固件版本信息;
-
少量配置参数;
-
OTA 升级所需的镜像或备份。
Flash 的典型逻辑分区如下:
Flash 起始地址
┌────────────────────────┐
│ Bootloader │ 负责启动、升级和跳转
├────────────────────────┤
│ 配置参数区 │ 保存设备参数和校准数据
├────────────────────────┤
│ App 应用程序区 │ 保存当前运行固件
├────────────────────────┤
│ OTA 下载/备份区 │ 保存待升级固件
├────────────────────────┤
│ 日志/文件系统区 │ 保存历史数据和日志
└────────────────────────┘
具体地址和大小由芯片容量、Bootloader 方案和链接脚本决定。
Flash 的两个重要限制
Flash 不能像 SRAM 一样随意改写,通常具有以下特性:
-
写入前要先擦除;
-
擦除以页或扇区为单位;
-
写入以字、双字或页为单位;
-
不能直接把已经写入的 0 改回 1;
-
有擦写寿命,需要避免高频更新同一个扇区。
因此,保存配置时通常采用:
读取旧配置 → 在 SRAM 中修改 → 擦除 Flash 扇区 → 写
2.2 片内 ROM:固化的只读内容
ROM 是 Read-Only Memory 的缩写,中文为“只读存储器”。传统 ROM 出厂后不能修改;在现代 MCU 中,很多所谓的程序 ROM 实际上由 Flash 实现。
ROM 或 Flash 的只读区域适合放:
-
固化程序;
-
启动代码;
-
固定字库;
-
不变的校准表;
-
协议常量。
2.3 片内 SRAM:保存运行时数据
SRAM 是 Static Random-Access Memory 的缩写,中文为“静态随机存取存储器”。SRAM 读写速度快,但断电后数据丢失。
程序运行时,SRAM 通常划分为以下逻辑区域:
| 已初始化数据区 | .data、RW Data | 有初值且运行时可修改的全局/静态变量 |
| 未初始化数据区 | .bss、ZI Data | 无初值或初值为 0 的全局/静态变量 |
| 栈 | Stack | 局部变量、函数调用现场、中断现场 |
| 堆 | Heap | malloc 等动态申请的内存 |
| RTOS 堆 | FreeRTOS Heap | 任务、队列、信号量等动态对象 |
.data 区
uint32_t system_clock = 120000000;
static int retry_count = 3;
这些变量可在运行时修改,因此运行地址在 SRAM。但初始值需要随固件保存,所以镜像中还会在 Flash 保存一份初始值,启动时由 C 运行库复制到 SRAM。
Flash 中的初始值 → 启动时复制 → SRAM 中的运行
.bss/ZI 区
static uint8_t rx_buffer[256];
static device_state_t state;
这类变量没有显式初值,启动时由系统清零,放在 SRAM 的 .bss 或 ZI 区。
栈 Stack
函数中的局部变量通常使用栈:
void protocol_task(void *arg)
{
uint8_t frame[128];
uint32_t timeout;
}
栈还保存函数返回地址、寄存器现场和中断现场。Cortex-M 的主栈通常从高地址向低地址增长。
堆 Heap
堆用于运行时动态申请内存:
uint8_t *buffer = malloc
在 FreeRTOS 中,任务、队列和互斥锁也可能通过 RTOS 堆动态创建:
xTaskCreate(control_task, "control", 512, NULL, 3, NULL);
xQueueCreate(8, sizeof(message_t));
xSemaphoreCreateMutex();
如果采用 xTaskCreateStatic(),任务控制块和任务栈则由应用程序提供的静态数组占用 SRAM,而不使用动态堆。
2.4 片内 EEPROM:并非所有 MCU 都有
EEPROM 是 Electrically Erasable Programmable Read-Only Memory 的缩写,中文为“电可擦除可编程只读存储器”。部分 MCU 集成少量 EEPROM,适合保存:
-
用户配置;
-
校准系数;
-
设备编号;
-
少量掉电保持数据。
没有片内 EEPROM 时,常用 Flash 保留分区模拟 EEPROM。
3. MCU 的片外存储器
片外存储器通过 SPI、QSPI、I²C、SDIO、FMC/FSMC 等接口连接 MCU。它们主要用于扩展容量、保存大量数据或提高非易失数据的擦写能力。
3.1 外部 NOR Flash
NOR Flash 是 NOR 型闪存,随机读取速度较快,部分 MCU 支持通过 QSPI 映射后直接执行,即 XIP(Execute In Place,就地执行)。
适合存放:
-
OTA 下载固件;
-
图片、字库和语音资源;
-
中等容量日志;
-
文件系统;
-
不适合放入片内 Flash 的程序模块。
3.2 外部 NAND Flash
NAND Flash 是 NAND 型闪存,容量大、成本低,但通常需要:
-
ECC(Error Correcting Code,错误校正码);
-
坏块管理;
-
磨损均衡;
-
专用文件系统或 Flash 管理层。
适合保存大量历史记录、日志和文件。
3.3 外部 EEPROM
外部 EEPROM 常见两种接口:
-
I²C EEPROM:I²C 是 Inter-Integrated Circuit,中文为“内部集成电路总线”;
-
SPI EEPROM:SPI 是 Serial Peripheral Interface,中文为“串行外设接口”。
它们容量通常较小,但使用简单,适合保存少量参数和校准值。
3.4 FRAM
FRAM 是 Ferroelectric Random-Access Memory 的缩写,中文为“铁电随机存取存储器”。FRAM 具有非易失、读写快和耐写次数高等特点,通常不需要像 Flash 一样先擦除。
特别适合保存频繁变化的数据:
-
累计电量;
-
交易计数器;
-
故障次数;
-
需要频繁断电保存的状态。
3.5 外部 RAM
常见外部 RAM 包括:
-
SRAM:Static Random-Access Memory,静态随机存取存储器;
-
PSRAM:Pseudo Static RAM,伪静态随机存取存储器;
-
SDRAM:Synchronous Dynamic RAM,同步动态随机存取存储器;
-
DDR:Double Data Rate,双倍数据速率存储器。
这些存储器都是易失性的,适合保存:
-
大型通信缓冲区;
-
图像和音频缓存;
-
大型协议栈数据;
-
内部 SRAM 不足时的运行时数据。
3.6 SD 卡和 eMMC
-
SD:Secure Digital,安全数字存储卡;
-
eMMC:embedded MultiMediaCard,嵌入式多媒体卡。
它们容量大,通常通过文件系统访问,适合存放:
-
充电订单;
-
长期历史记录;
-
运行日志;
-
多个 OTA 升级包;
-
配置文件和报表。
使用时必须考虑断电保护、文件系统一致性、写放大和磨损问题。
4. C 代码对象与存储器的对应关系
| 函数 | 片内 Flash | 编译为机器码后执行 |
| 字符串常量 | Flash 只读区 | 例如 "OK" |
| const 全局数组 | Flash 只读区 | 运行时不修改 |
| 有初值的全局变量 | SRAM .data | 初始值镜像在 Flash |
| 无初值的全局变量 | SRAM .bss/ZI | 启动时清零 |
| 静态变量 | .data 或 .bss | 由是否有初值决定 |
| 自动局部变量 | 当前任务栈 | 进入函数时分配 |
| malloc() 内存 | SRAM 堆 | 运行时动态申请 |
| FreeRTOS 动态任务 | FreeRTOS 堆 | TCB 和任务栈都占 SRAM |
| 外设寄存器 | 外设地址空间 | 不是普通 SRAM 或 Flash |
| 掉电配置 | EEPROM、FRAM 或 Flash 分区 | 需要驱动读写 |
| 大容量日志 | 外部 NOR/NAND、SD、eMMC | 需要文件系统或存储管理 |
5. 常见英文缩写速查
| MCU | Microcontroller Unit | 微控制器 |
| ROM | Read-Only Memory | 只读存储器 |
| RAM | Random-Access Memory | 随机存取存储器 |
| SRAM | Static Random-Access Memory | 静态随机存取存储器 |
| DRAM | Dynamic Random-Access Memory | 动态随机存取存储器 |
| Flash | Flash Memory | 闪存 |
| EEPROM | Electrically Erasable Programmable ROM | 电可擦除可编程只读存储器 |
| FRAM | Ferroelectric RAM | 铁电随机存取存储器 |
| NOR | NOR Flash | NOR 型闪存 |
| NAND | NAND Flash | NAND 型闪存 |
| PSRAM | Pseudo Static RAM | 伪静态随机存取存储器 |
| SDRAM | Synchronous Dynamic RAM | 同步动态随机存取存储器 |
| DDR | Double Data Rate | 双倍数据速率存储器 |
| SD | Secure Digital | 安全数字存储卡 |
| eMMC | embedded MultiMediaCard | 嵌入式多媒体卡 |
| OTA | Over-The-Air | 空中升级 |
| XIP | Execute In Place | 就地执行 |
| NVM | Non-Volatile Memory | 非易失性存储器 |
| RTOS | Real-Time Operating System | 实时操作系统 |
| TCB | Task Control Block | 任务控制块 |
| DMA | Direct Memory Access | 直接存储器访问 |
| ECC | Error Correcting Code | 错误校正码 |
网硕互联帮助中心




评论前必须登录!
注册