当前位置: 首页 > news >正文

简单理解: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=189906RO-data=31078RW-data=636ZI-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 的复杂界面、更多字体 / 图片,或扩展业务逻辑。

http://www.cnnetsun.cn/news/98237.html

相关文章:

  • 44、MS-DOS INT 21h 功能调用详解
  • 61、MASM 参考指南
  • 如何调优EmotiVoice的情感强度参数以获得最佳听感?
  • 2025终极指南:5分钟掌握GitHub风格CSS样式库
  • Koodo Reader封面管理系统:打造个性化数字图书馆的艺术
  • 3、Qt 界面开发:小部件与布局全解析
  • 6、Qt 自定义小部件开发全解析
  • Spring AI 最新实战系列(一)完成一个简单的AI项目
  • LobeChat智谱ChatGLM接入全流程:Zhipu AI API对接
  • EmotiVoice能否实现语音情感渐变过渡?动态控制探索
  • 终极微博备份指南:Speechless免费工具完整使用教程
  • 暗黑破坏神2存档编辑器终极指南:从零基础到精通进阶
  • LobeChat Google Gemini Pro接入方法:多模态能力整合
  • LobeChat用量统计面板:跟踪Token消耗与GPU使用率
  • 基于VUE的企业咨询管理系统 [VUE]-计算机毕业设计源码+LW文档
  • 具身智能:零基础入门睿尔曼机械臂(五)—— 手眼标定核心原理与数学求解
  • C++元编程完全指南
  • 3分钟搞定Windows Syslog服务器:从零搭建日志监控系统
  • autofit.js 大屏自适应终极方案:简单配置实现完美布局
  • 【Java抽象类和接口】
  • 全新一代H5免签封装神器:一键生成苹果绿标/安卓双端APP,可在线热更新,彻底隐藏顶部地址栏!
  • 绝区零辅助工具终极指南:10分钟快速上手完整教程
  • JavaScript解密神器:JStillery让你的代码分析变得如此简单
  • Mem Reduct终极指南:简单三步解决电脑内存不足问题
  • 【单片机毕业设计】【mcugc-mcu922】基于单片机的智能窗帘控制系统
  • 开发过程中动态 SQL 中where 1=1的作用是什么
  • 洛谷 P1551 亲戚
  • d2s-editor终极指南:暗黑破坏神2存档修改完全教程
  • UniExtract2深度评测:万能文件提取工具的技术解析与实战应用
  • MySQL主从数据同步实战