news 2026/9/25 11:52:27

简单理解:keil5终端显示这些内存是什么意思Program Size: Code=189906 RO-data=31078 RW-data=636 ZI-data=58604

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
简单理解:keil5终端显示这些内存是什么意思Program Size: Code=189906 RO-data=31078 RW-data=636 ZI-data=58604
Program Size: Code=189906 RO-data=31078 RW-data=636 ZI-data=58604

一、先明确核心规则

Keil 编译输出的Program Size中,每个字段的单位是字节(Byte),计算核心是区分「Flash 占用」和「RAM 占用」,这是嵌入式中最关键的两个维度:

字段含义存储介质计算公式(核心)
Code可执行代码段Flash独立计算(仅占 Flash)
RO-data只读数据段(常量)Flash独立计算(仅占 Flash)
RW-data初始化非 0 的全局变量Flash→RAM占 Flash(存储初始值)+ 占 RAM(运行时)
ZI-data未初始化 / 初始化为 0 的变量RAM仅占 RAM(运行时)

二、分步计算(以你的数据为例)

你的数据:Code=189906、RO-data=31078、RW-data=636、ZI-data=58604

1. 计算 Flash 总占用(程序烧录到 Flash 的大小)

Flash 需要存储「代码 + 只读常量 + RW-data 的初始值」,公式:

Flash占用 = Code + RO-data + RW-data

代入数值:

Flash占用 = 189906 + 31078 + 636 = 221620 字节

换算成更易读的单位(1KB=1024Byte):

221620 ÷ 1024 ≈ 216.43 KB

✅ 结论:程序烧录后占用 Flash 约 216.43KB,远小于 STM32F407VET6 的 512KB Flash,无溢出风险。

2. 计算 RAM 总占用(程序运行时占用的内存)

RAM 需要存储「RW-data 的运行时值 + ZI-data 的零初始化数据」,公式:

RAM占用 = RW-data + ZI-data

代入数值:

RAM占用 = 636 + 58604 = 59240 字节

换算单位:

59240 ÷ 1024 ≈ 57.85 KB

✅ 结论:程序运行时占用 RAM 约 57.85KB,远小于 STM32F407VET6 的 192KB RAM,剩余 RAM 可用于 LVGL 缓存、业务数据等。

3. 额外验证(可选)
  • RO-data 换算:31078 ÷ 1024 ≈ 30.35 KB(只读常量占用 Flash);
  • Code 换算:189906 ÷ 1024 ≈ 185.46 KB(纯代码占用 Flash);

三、关键补充(避免误解)

  1. 单位陷阱:Keil 输出的数值是「字节」,不是 KB!新手容易直接把 189906 当成 189KB,实际是 189906÷1024≈185.46KB;
  2. RW-data 的双重占用:RW-data 既占 Flash(存储初始值,比如int a=10;的 10 存在 Flash),又占 RAM(运行时 a 的数值存在 RAM),所以计算 Flash 时要加,计算 RAM 时也要加;
  3. ZI-data 不占 Flash:ZI-data 是 “零初始化数据”,程序启动时由系统自动清零,无需在 Flash 中存储初始值,仅占 RAM;
  4. 实际可用 RAM:计算出的 57.85KB 是「静态占用」,LVGL 的动态缓存(如显示缓冲区)、栈(Stack)、堆(Heap)会额外占用 RAM,需确保总和 < 192KB。

四、快速换算工具(懒人版)

可以用以下公式快速估算:

Flash(KB) = (Code + RO-data + RW-data) / 1024 RAM(KB) = (RW-data + ZI-data) / 1024

代入你的数据:

  • Flash = (189906+31078+636)/1024 = 221620/1024 ≈ 216.43 KB
  • RAM = (636+58604)/1024 = 59240/1024 ≈ 57.85 KB

总结:你的程序在 Flash 和 RAM 上的占用都远低于 STM32F407VET6 的硬件上限,资源充足,无需担心溢出问题。


结合你提供的Program Size: Code=189906 RO-data=31078 RW-data=636 ZI-data=58604,下面不仅给出精确计算过程,还会明确每个字段对应的存储区域(Flash/RAM)、数据类型和读写属性,彻底讲清 “每个数值存在哪里、为什么、怎么算”。

一、核心前提(先记牢)

字段单位核心存储区域(烧录 / 运行)数据类型读写属性
Code字节仅 Flash(烧录 + 永久存储)可执行指令(函数、逻辑)只读
RO-data字节仅 Flash(烧录 + 永久存储)只读常量(字符串、const 变量)只读
RW-data字节Flash(存初始值)+ RAM(运行时)初始化非 0 的全局 / 静态变量读写
ZI-data字节仅 RAM(仅运行时占用)未初始化 / 初始化为 0 的全局 / 静态变量读写

二、分步计算(含存储区域说明)

1. 第一步:计算「Flash 总占用」(程序烧录到芯片 Flash 的大小)

Flash 是 STM32 的 “只读存储区”,断电不丢失,用于存放烧录时需要固化的所有数据(代码、常量、RW-data 的初始值)。公式:Flash总占用 = Code + RO-data + RW-data代入你的数值:

Flash总占用 = 189906 + 31078 + 636 = 221620 字节 换算成KB(1KB=1024字节):221620 ÷ 1024 ≈ 216.43 KB
  • 各部分在 Flash 中的占比:
    • Code:189906 字节(≈185.46 KB)→ Flash 中存main()、lv_task_handler()等函数的机器指令;
    • RO-data:31078 字节(≈30.35 KB)→ Flash 中存const char str[] = "LVGL测试"、#define MAX_VAL 100等只读常量;
    • RW-data:636 字节(≈0.62 KB)→ Flash 中存int num = 10;(非 0 初始化)的初始值10(运行时会复制到 RAM)。
2. 第二步:计算「RAM 总占用」(程序运行时占用的内存大小)

RAM 是 STM32 的 “读写存储区”,断电丢失,用于存放运行时可修改的数据(RW-data 的实时值、ZI-data 的零初始化数据)。公式:RAM总占用 = RW-data + ZI-data代入你的数值:

RAM总占用 = 636 + 58604 = 59240 字节 换算成KB:59240 ÷ 1024 ≈ 57.85 KB
  • 各部分在 RAM 中的占比:
    • RW-data:636 字节 → RAM 中存int num = 10;运行时的实时值(比如程序中修改为 20,RAM 中就存 20);
    • ZI-data:58604 字节(≈57.23 KB)→ RAM 中存static uint32_t cnt;(未初始化)、int flag = 0;(初始化为 0),程序启动时系统会自动将这部分区域清零。
3. 第三步:验证资源是否充足(STM32F407VET6)
  • Flash 总容量:512 KB → 216.43 KB < 512 KB(剩余≈295.57 KB,可存更多代码 / 图片 / 字体);
  • RAM 总容量:192 KB → 57.85 KB < 192 KB(剩余≈134.15 KB,可用于 LVGL 显示缓存、栈 / 堆、业务数据)。

三、关键补充(避免误解)

  1. ZI-data 为什么不占 Flash?ZI-data 是 “零初始化数据”,程序启动时 STM32 的启动文件(startup_stm32f407xx.s)会自动把这部分 RAM 区域清零,无需在 Flash 中存储初始值(存 “0” 没有意义),所以仅占用 RAM、不占 Flash。

  2. RW-data 的 “双重占用” 怎么理解?比如定义int a = 10;:

    • 烧录时:10这个初始值存在 Flash(占 RW-data 的 1 份空间);
    • 运行时:CPU 把 Flash 中的10复制到 RAM,后续修改a=20只改 RAM 中的值,Flash 中的初始值不变。
  3. 栈(Stack)/ 堆(Heap)没算进去?你看到的ZI-data仅包含 “全局 / 静态变量”,程序运行时的栈(函数局部变量、函数调用)、堆(malloc动态分配)会额外占用 RAM,但 Keil 的Program Size不会统计这部分(属于运行时动态占用)。比如你给 LVGL 分配的显示缓存lv_color_t buf[480*10](约 9.6 KB),属于堆 / 全局变量,会算进 ZI-data/RW-data;而函数内的局部变量int tmp;属于栈,不会体现在当前数值中。

四、总结(一句话记全)

计算目标公式数值(字节)数值(KB)存储区域
Flash 总占用Code + RO-data + RW-data221620≈216.43仅 Flash
RAM 总占用RW-data + ZI-data59240≈57.85仅 RAM
纯代码占用Code189906≈185.46仅 Flash
只读常量占用RO-data31078≈30.35仅 Flash

你的程序资源占用非常健康,Flash 和 RAM 都有大量剩余,后续可以放心添加 LVGL 的复杂界面、更多字体 / 图片,或扩展业务逻辑。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 8:33:44

55、高级MS - DOS编程全解析

高级MS - DOS编程全解析 1. 段定义相关指令与操作 在汇编语言编程中,段定义是非常重要的概念,涉及到多个关键指令和操作。 - SEGMENT指令 :其目的是定义一个段,为程序中的代码、数据或堆栈等划分区域。 - SEG运算符 :返回段地址。 - ASSUME指令 :用于告诉汇编…

作者头像 李华
网站建设 2026/9/24 8:33:33

58、深入理解常见指令集

深入理解常见指令集 在计算机编程和系统操作中,指令集是非常重要的一部分,它决定了计算机能够执行的基本操作。下面将详细介绍一系列常见的指令及其功能、格式。 1. 数据转换与标志位操作指令 CDQ(Convert Doubleword to Quadword) :该指令用于将双字扩展为四字(IA -…

作者头像 李华
网站建设 2026/9/25 0:00:44

63、汇编编程中的操作符与指令详解

汇编编程中的操作符与指令详解 1. 运行时操作符 运行时操作符在汇编编程中有着重要的作用,它们主要在 .IF 、 .WHILE 或 .REPEAT 代码块中使用,并且在运行时进行计算,而非汇编时。以下是一些常见的运行时操作符及其功能: | 操作符 | 功能 | | — | — | | expr…

作者头像 李华
网站建设 2026/9/23 17:42:58

从告警风暴到智能运维:keep+Prometheus构建企业监控新范式

从告警风暴到智能运维&#xff1a;keepPrometheus构建企业监控新范式 【免费下载链接】keep The open-source alerts management and automation platform 项目地址: https://gitcode.com/GitHub_Trending/kee/keep 深夜两点&#xff0c;运维工程师小王再次被手机告警惊…

作者头像 李华
网站建设 2026/9/24 8:33:04

centos7 安装oracle11.2.0.4

一、安装oracle 1.软件安装需要的jdk1.8.0_241&#xff0c;下载并上传到服务器 cd /usr/local tar -zxvf jdk-8u241-linux-x64.tar.gz mv jdk_1.8.0_241 java vi /etc/profile #更改环境变量&#xff0c;在最后添加如下内容export JAVA_HOME/usr/local/java export CLASSPAT…

作者头像 李华
网站建设 2026/9/25 8:51:20

LobeChat限时折扣倒计时文案

LobeChat&#xff1a;让每个人都能轻松拥有自己的 AI 助手 在今天&#xff0c;构建一个像 ChatGPT 那样的智能对话系统&#xff0c;早已不再是科技巨头的专属能力。随着大语言模型&#xff08;LLM&#xff09;技术的普及&#xff0c;越来越多开发者和企业开始尝试打造属于自己的…

作者头像 李华