在keil 编译后都会出现的术语

可以在编译后,或者 .map 文件最后处找到

| 工具链术语 | 标准术语 | 内容 | 位置 |

| rodata  | .rodata | 常量                | Flash                                    |

| rwdata | .data     | 初始化变量     | RAM(运行时) Flash(初始值) |

| zidata  | .bss       | 零初始化变量 | RAM                                     |

RO Data  (Read-Only Data)

  • 对应标准段.rodata

  • 内容:所有 只读的常量数据

    • 用 const 关键字声明的全局变量或静态变量(例如 const int version = 1;)。

    • 字符串字面量(例如 char *msg = "Hello"; 中的 "Hello" 字符串本身)。

    • 编译器生成的常量表(如跳转表、浮点常量等)。

  • 位置Flash (ROM) 中。因为它们是只读的,不需要在运行时修改。

  • 访问:CPU 可以直接从 Flash 中读取这些数据。不需要复制到 RAM。

  • 为什么叫 rodata:非常直观,就是 Read-Only Data

  • 举例 (STM32F103C8T6)

const uint32_t system_clock = 72000000; // 存储在 rodata (Flash @ 0x0800 XXXX)
void print_message() {
    const char *greeting = "Welcome!"; // 字符串 "Welcome!" 存储在 rodata (Flash @ 0x0800 YYYY)
    // ... 使用 greeting ...
}

RW Data (Read-Write Data)

  • 对应标准段.data

  • 内容:所有 已初始化且初始值不为零 的全局变量和静态变量。

  • 关键特性 - 双重存在

    • 初始值:存储在 Flash (ROM) 中(通常在 .rodata 段之后的一块区域)。链接器脚本里这个存储初始值的地方有时也被称为 rwdata 或者明确区分为 .data 的加载地址 (Load Address/LMA) 在 Flash。

    • 运行时变量本身:位于 SRAM (RAM) 中。链接器脚本里这个运行时位置称为 rwdata 或者 .data 的虚拟地址 (Virtual Address/VMA) 在 RAM。

  • 启动过程:芯片上电初始化时(在 main() 执行前),启动代码 必须 将 Flash 中存储的 rwdata 初始值 复制 到 SRAM 中对应的 rwdata 区域。

  • 为什么叫 rwdata:因为这些变量在程序运行时是 Read-Write(可读可写)的,它们位于 RAM 中。名字强调了其运行时特性。

  • 举例 (STM32F103C8T6)

int sensor_value;       // 未初始化 -> zidata (SRAM, e.g., 0x2000 00AA, 启动时清零为0)
static char buffer[128]; // 未初始化 -> zidata (SRAM, 启动时清零)
int error_count = 0;    // 显式初始化为0 -> zidata (SRAM, 启动时清零)
char *ptr = NULL;      // 显式初始化为NULL (0) -> zidata (SRAM, 启动时清零)

总结表格

段名 标准名 内容特性 位置 (编译/链接后) 位置 (运行时) 启动时操作 名称含义
rodata .rodata 只读常量 (const, 字符串字面量) Flash (0x0800 XXXX) Flash  (CPU 直接从 Flash 读) Read-Only Data
rwdata .data 已初始化且非零的全局/静态变量 Flash (存储初始值 LMA) SRAM (0x2000 0000起) 复制 Flash 初始值到 SRAM Read-Write Data (指运行时)
zidata .bss 未初始化或初始化为零的全局/静态变量  (不占 Flash 初始值空间) SRAM (紧随 .data) 清零 SRAM 中对应区域 Zero-Initialized Data

结论

  • rodatarwdatazidata 是嵌入式开发(特别是 ARM 生态)中广泛使用的术语,用于描述链接器如何处理不同类型的数据段。

  • 它们分别精确对应标准 C 概念中的 .rodata (只读常量), .data (初始化非零变量), .bss (未初始化/零初始化变量)。

  • 理解这些术语的关键在于:

    1. rodata:只读,永远在 Flash,CPU 直接访问。

    2. rwdata:有初始值(在 Flash),运行时在 RAM 可修改,启动时需要复制初始值。

    3. zidata:无初始值(或初始值就是0),运行时在 RAM,启动时需要清零

  • 链接器脚本和启动文件利用这些概念和生成的符号,在芯片启动时自动完成数据的正确初始化,为 C 程序的执行准备好正确的内存环境。

 

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐