以stm32H743为例介绍ROM、RAM、ZI
在嵌入式开发(尤其是 ARM 开发工具链,如 Keil MDK、ARMCC 或 GCC)中,ROM、RAM 和 ZI 是描述程序编译后内存分布的关键术语,直接关系到代码占用和运行时内存的分配。
- ROM(只读存储器)
· 物理介质:通常是芯片内部的 Flash 存储器。
· 存储内容:程序编译后的代码(RO - Read-Only)和常量数据(如 const 修饰的变量、字符串字面量)。这些内容在掉电后不会丢失。
· 特性:CPU 可以直接从 ROM 中执行代码(XIP,就地执行),但通常不能直接写入。
· 编译输出项:在 Keil 编译后通常显示为 Code + RO-data 的总和。
- RAM(随机存取存储器)
· 物理介质:芯片内部的 SRAM(如 STM32H743 的 DTCM、AXI SRAM 等)。
· 存储内容:程序运行时需要读写的数据段,包括:
· 已初始化的全局/静态变量(RW - Read-Write)
· 未初始化的全局/静态变量(ZI 的一部分)
· 堆(Heap) 和 栈(Stack) 空间
· 特性:掉电后数据丢失,读写速度快。
· 编译输出项:Keil 中通常显示为 RW-data(已初始化的变量占用的 RAM 空间,但初始值存储在 ROM 中,启动时由启动代码拷贝到 RAM)。
- ZI(零初始化数据,Zero Initialized)
· 归属:它是 RAM 的一部分,特指那些在程序启动时需要被清零的内存区域。
· 包含对象:
· 未初始化的全局/静态变量(例如 static int buffer[1024];)
· 初始化为 0 的全局/静态变量(例如 int flag = 0;)
· 运行时行为:在进入 main() 之前,C 运行时库(或启动文件中的代码)会将 ZI 段所占的 RAM 区域全部清零,确保这些变量初始值为 0。
· 编译输出项:Keil 中显示为 ZI-data。
典型编译输出示例(Keil MDK)
Program Size: Code=1234 RO-data=56 RW-data=100 ZI-data=2000
Total ROM Size (Flash) = Code + RO-data + RW-data = 1234 + 56 + 100 = 1390 bytes
Required RAM = RW-data + ZI-data = 100 + 2000 = 2100 bytes
· ROM 占用 = Code + RO-data + RW-data(因为 RW 变量的初始值需要存储在 Flash 中,启动时再拷贝到 RAM)
· RAM 运行时占用 = RW-data + ZI-data
在 STM32H743 中的实际意义
· ROM 对应 Flash 容量(STM32H743 通常为 2MB),代码和常量不能超过此容量。
· RAM 对应 SRAM 总容量(STM32H743 有多个 SRAM 区域,总大小约 1MB),需要确保 RW+ZI 不超过实际可用的 SRAM。
· ZI 过大可能意味着定义了巨大的全局数组(如 uint8_t buf[100000];),需要检查是否超出 RAM 空间。
补充:RO、RW、ZI 的完整对应关系(ARM 编译环境)
段名 存储介质 初始值来源 运行时位置 典型内容
RO ROM 固件烧录 通常在 Flash 中(XIP) 代码、常量
RW ROM(初始值) + RAM(运行副本) 初始值从 ROM 拷贝到 RAM RAM 已初始化的非零全局/静态变量
ZI 无(仅占 RAM 空间) 启动时由代码清零 RAM 未初始化或初始化为 0 的全局/静态变量
了解这些概念有助于优化程序内存布局,避免因 RAM 不足或 Flash 溢出导致的链接错误。在 STM32H743 的 BSP 开发中,链接脚本(.ld 或 .sct)正是通过这些段来分配内存地址的。
更多推荐

所有评论(0)