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

Keil中内存概念:Flash、SRAM、RO、RW、ZI、.data、.bss、heap、stack、MAP文件

此文章转载于微信公众号嵌入式电子学习只作为笔记备忘录使用内存属性理解Keil MDK或ARM编译器中关于程序内存布局的一些基本概念RO、RW、ZI和.data、.bss、heap、stack、Flash、SRAM。这些概念对于理解程序如何被加载和运行以及如何优化内存使用至关重要。1. 基础概念详解1.1 存储介质分类Flash非易失性存储• 特点掉电数据不丢失读取速度快写入速度慢• 存储内容程序代码、常量数据、初始化数据• 访问方式直接读取需要通过特定接口编程RAM易失性存储• 特点掉电数据丢失读写速度快• 存储内容变量、堆栈、运行时数据• 访问方式直接读写1.2 程序段分类RORead Only段•存储位置Flash•包含内容• 程序代码.text段• 只读数据.rodata段• 常量字符串、const变量•特点运行时不可修改RWRead Write段•存储位置Flash中存初始值RAM中存运行时值•包含内容已初始化且非零的全局/静态变量•特点启动时需要从Flash复制到RAMZIZero Initialized段•存储位置RAM•包含内容未初始化或显式初始化为0的全局/静态变量•特点启动时清零初始化1.3 常见段名与内存区域•.text表示代码段Code存放在Flash中。•.constdata 或 .rodata只读数据段RO存放在Flash中。•.data已初始化的全局变量和静态变量RW数据在Flash中保存初始值在RAM中存放运行时值。•.bss未初始化的全局变量和静态变量ZI数据在RAM中程序启动时初始化为0堆和栈属于.bss。• 栈stack用于局部变量、函数调用等由编译器自动管理通常从RAM的高地址向低地址增长。• 堆heap用于动态内存分配由程序员管理malloc/free通常从RAM的低地址向高地址增长。1.4 加载域和执行域1、加载区域表示代码和数据下载到芯片时存储到哪段地址可以存储到片上Flash也可以存储到片外Flash也可以存储到RAM。• 对于代码为只读类型运行时无法更改因此存储在Flash中即加载区域是Flash地址段。• 对于数据其分成几类:• 对于RO只读数据比如const类型、字符串等等其存储在Flash因此加载区域也是Flash地址段• 对于RW读写数据比如.data如果其有初值那么初值要存放在Flash中运行时先从Flash中取出初值对RW数据进行赋值然后运行时RW数据的访问地址是在RAM里也就是RW数据的加载区域是Flash地址段执行区域是RAM地址段• 对于ZI数据比如.bss和stack、heap表示初始化为零的全局变量因此无需在Flash中存放初值也就无所谓加载区域只有执行区域执行区域也就是程序运行时如果要访问这个变量要去哪个地址段寻找。2、执行区域表示上电运行后程序和数据从哪个地址开始执行或访问。• 对于代码也就是从哪个地址开始读取代码语句并执行一般是程序存储在哪里就从哪里执行代码的执行区域和加载区域保持一致。• 对于数据表示程序运行起来后去哪个地址可以访问数据。• 对于RO数据例如const需要存储在Flash中因此其加载区域地址就处在Flash中程序运行起来后也是去Flash地址段访问const变量因此其执行区域也是Flash地址段两个区域保持一致• 对于RW数据如果初值不为零那么初值需要存储到Flash中即使初值为零加载区域似乎也是Flash段则其加载区域是Flash地址段运行时访问RW数据则要去RAM里因此执行区域是RAM地址段。参考文章内存分配基础2简单例子2. 内存区域详细对应关系2.1 编译时段的映射2.2 详细对应表内存区域对应段存储介质初始化方式内容示例.textROFlash编译时确定函数代码、中断向量表.rodataROFlash编译时确定const常量、字符串常量.dataRWFlashRAM启动时从Flash复制int a 100;.bssZIRAM启动时清零int b; 或 int c 0;heapZI(动态)RAM运行时分配malloc()分配的内存stackZI(动态)RAM运行时压栈局部变量、函数参数3. 启动过程分析系统上电后首先从Flash中读取代码和数据进行初始化。具体步骤1. 初始化栈指针SP和程序计数器PC。2. 将RW数据从Flash中复制到RAM中这部分数据在Flash中紧跟在RO数据之后。3. 将ZI数据所在的RAM区域全部清零。4. 跳转到main函数执行。参考文章上电启动3从复位到main()的启动文件详解万字长文整理4. Map文件解析Map文件展示了程序的内存布局包括各个段的大小、地址分配等。通过Map文件我们可以查看• 代码段、RO数据段、RW数据段、ZI数据段的大小和位置。• 各个模块源文件占用的代码和数据空间。4.1 Map文件分析1. 模块摘要 Module Summary: Code (inc. data) RO Data RW Data ZI Data Debug Object Name 1200 200 400 100 500 8000 main.o 800 150 200 50 300 6000 library.o可以看到用户每个源文件所占据内存大小inc表示内联函数和数据。2. 总内存占用 Total RO Size (Code RO Data) 1600 ( 1.56kB) Total RW Size (RW Data ZI Data) 900 ( 0.88kB) Total ROM Size (Code RO Data RW Data) 1700 ( 1.66kB)汇总看到整个工程所占据的Flash和SRAM空间。3. 内存区域分布 Memory Map of the image: Flash区域 Load Region LR_FLASH (Base: 0x08000000, Size: 0x00000800, Max: 0x00080000) Execution Region ER_FLASH (Base: 0x08000000, Size: 0x00000650) Base Addr Size Type Attr Idx E Section Name Object 0x08000000 0x00000200 Code RO 1 .text startup_stm32f10x.o 0x08000200 0x00000400 Data RO 2 .constdata main.o RAM区域 Execution Region RW_IRAM1 (Base: 0x20000000, Size: 0x00000400) Base Addr Size Type Attr Idx E Section Name Object 0x20000000 0x00000100 Data RW 10 .data main.o 0x20000100 0x00000200 Zero RW 11 .bss main.o 0x20000300 0x00000100 Zero RW 12 heap .o可以看到Flash和SRAM中具体的每一段地址存放了哪些数据和代码。4.2 关键指标解读编译信息解读Program Size: Codexxxx RO-dataxxxx RW-dataxxxx ZI-dataxxxx•Code: 实际代码大小存储在Flash中•RO-data: 只读数据大小存储在Flash中•RW-data: 已初始化的读写数据大小在Flash中存储初始值在RAM中占用相同大小的空间•ZI-data: 零初始化数据大小在RAM中占用空间但不在Flash中占用空间除了初始化为0的说明信息但不占用实际数据空间重要计算公式Flash占用 Code RO Data RW Data的初始值 RAM占用 RW Data ZI Data Stack Heap注意RW数据在Flash和RAM中各有一份Flash中存储的是初始值RAM中是运行时的值。5. 内存优化5.1 常见优化方法通过理解这些概念我们可以有针对性地优化程序• 减少全局变量的使用特别是已初始化的全局变量RW数据和未初始化的全局变量ZI数据可以节省RAM空间。• 将常量数据尽量使用const关键字定义为只读数据使其存储在Flash中而不是RAM中。• 优化代码大小减少Flash占用。• 合理设置堆栈大小避免溢出。5.2 优化建议说明int global_var 100;• 定义一个全局变量带有非零初始值属于RW数据在Flash中存储初始值100在RAM中有一个变量占4字节。int global_var2;• 定义一个全局变量零初始值属于ZI数据在RAM中占4字节启动时被初始化为0。const int global_const 200;• 定义一个const数据属于RO数据存储在Flash中不占用RAM。• 堆和栈的大小通常由启动文件startup.s中的设置决定在Map文件中可以查看它们的地址范围。查看MAP文件• 查看各个模块的代码和数据占用找出占用较大的模块进行优化。• 检查RW和ZI数据的大小优化全局变量和静态变量的使用。• 确认堆栈大小是否足够避免堆栈溢出。优化方向• 如果Flash紧张可以优化代码和常量数据例如使用更高效的算法减少常量数据如字符串、数组等。• 如果RAM紧张可以减少全局变量和静态变量使用局部变量栈上分配减少动态内存分配堆等。• 注意栈和堆的增长方向以及边界检查很重要如果堆和栈发生重叠会导致程序崩溃。因此需要合理设置堆栈大小并可能使用内存保护功能。在代码中监控堆栈使用。/*********************************************************************************************************************** * Function Name: StackFillMagic * Description : 初始化阶段调用一次将栈区全部填充幻数 * Arguments : None * Return Value : None ***********************************************************************************************************************/ void StackFillMagic(void) { uint32_t* base __base_sp; //栈顶边界 uint32_t* top (uint32_t*)__get_MSP(); //这里要使用当前栈指针 while(base top) { * base 0xDEADBEEF; //填充幻数 } }/*********************************************************************************************************************** * Function Name: CheckStackOverflow * Description : 程序运行过程中一直调用此函数检测栈空间使用是否溢出 * Arguments : None * Return Value : None ***********************************************************************************************************************/ uint16_t CheckStackOverflow(void) { uint16_t use_size 0; uint32_t* base __base_sp; //栈顶边界 while(*base 0xDEADBEEF base (__initial_sp)) { base; //检查哪些地方的数据不是幻数表示此区域已经使用了 } use_size (base - (__base_sp))*sizeof(uint32_t); //字节个数 return (use_size); }5.3 优化检查项• 检查全局变量是否必要能否改为局部变量• 常量数据使用const修饰确保存储在Flash• 大数组考虑使用动态分配或放在特定内存区域• 定期检查堆栈使用情况避免溢出• 使用合适的编译优化选项-Os, -O2等• 分析Map文件找出内存占用大的模块

相关文章:

Keil中内存概念:Flash、SRAM、RO、RW、ZI、.data、.bss、heap、stack、MAP文件

此文章转载于微信公众号:嵌入式电子学习,只作为笔记备忘录使用 内存属性 理解Keil MDK(或ARM编译器)中关于程序内存布局的一些基本概念(RO、RW、ZI和.data、.bss、heap、stack、Flash、SRAM)。这些概念对…...

免费音频转换器fre:ac终极指南:从零开始掌握跨平台音频处理

免费音频转换器fre:ac终极指南:从零开始掌握跨平台音频处理 【免费下载链接】freac The fre:ac audio converter project 项目地址: https://gitcode.com/gh_mirrors/fr/freac fre:ac是一款功能强大的免费音频转换器,支持MP3、AAC、FLAC、Opus等多…...

OmenSuperHub:硬件控制与性能优化的开源工具解决方案

OmenSuperHub:硬件控制与性能优化的开源工具解决方案 【免费下载链接】OmenSuperHub 使用 WMI BIOS控制性能和风扇速度,自动解除DB功耗限制。 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub OmenSuperHub是一款专为惠普暗影精灵系列…...

Visual C++ Redistributable AIO架构师指南:从问题诊断到系统优化

Visual C Redistributable AIO架构师指南:从问题诊断到系统优化 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 一、问题溯源:运行库故障…...

WarcraftHelper:让经典《魔兽争霸III》适配现代设备的开源解决方案

WarcraftHelper:让经典《魔兽争霸III》适配现代设备的开源解决方案 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 当你在高清显示器上启动…...

深度解析:数据挖掘核心任务与实战应用场景

深度解析:数据挖掘核心任务与实战应用场景前言一、数据挖掘核心定义二、数据挖掘标准执行流程(CRISP-DM 流程图)流程节点说明:三、数据挖掘的主要任务(6大核心分类)1. 分类分析:预测已知类别2. …...

DeepSeek kubernetes-1.35.3/api/api-rules/sample_apiserver_violation_exceptions.list 源码分析

我来分析 Kubernetes API 规则文件 sample_apiserver_violation_exceptions.list。这个文件是 Kubernetes API 合规性检查的一部分,用于管理 API 规则违规的例外情况。 文件概述 该文件位于 Kubernetes 源码的 api/api-rules/ 目录下,用于记录 API 规则检…...

OmenSuperHub:暗影精灵游戏本硬件控制的开源革新方案

OmenSuperHub:暗影精灵游戏本硬件控制的开源革新方案 【免费下载链接】OmenSuperHub 使用 WMI BIOS控制性能和风扇速度,自动解除DB功耗限制。 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 一、问题引入:原厂硬件控制软…...

OpenClaw多模态实践:Qwen3-14B分析截图生成操作指南

OpenClaw多模态实践:Qwen3-14B分析截图生成操作指南 1. 为什么需要截图分析自动化 上周团队来了三位新同事,我需要反复演示软件操作流程。每次截屏标注步骤后,还要手动整理成PDF发送。这种重复劳动让我开始思考:能否让AI自动识别…...

实战指南:基于快马ai与ubuntu24.04从零部署高可用个人博客系统

今天想和大家分享一个实战项目:在Ubuntu 24.04上从零部署一个高可用的个人博客系统。这个系统不仅前后端分离,还用到了Nginx反向代理和Gunicorn应用服务器,非常适合想学习全栈开发的朋友练手。 系统架构设计 整个博客系统采用经典的前后端分离…...

Python-100-Days:从算法优化到架构设计的深度技术演进

Python-100-Days:从算法优化到架构设计的深度技术演进 【免费下载链接】Python-100-Days Python - 100天从新手到大师 项目地址: https://gitcode.com/GitHub_Trending/py/Python-100-Days 在当今快速迭代的技术生态中,Python开发者的核心挑战已从…...

豆包导出的Excel公式失效

豆包导出的Excel公式为何失效?结构化分析与实用解决方案 在AI辅助办公场景中,豆包(Doubao)凭借数据分析模块成为不少职场用户的选择。用户通过自然语言指令生成销售报表、预算模板或统计表格后,期待直接导出可用的.xls…...

4大维度精通RPG Maker Decrypter:从解密原理到场景落地的全攻略

4大维度精通RPG Maker Decrypter:从解密原理到场景落地的全攻略 【免费下载链接】RPGMakerDecrypter Tool for decrypting and extracting RPG Maker XP, VX and VX Ace encrypted archives and MV and MZ encrypted files. 项目地址: https://gitcode.com/gh_mir…...

OpenClaw人人养虾:桥接协议

桥接协议(Bridge Protocol)允许多个 Gateway 实例之间建立通信通道,实现跨网关的模型共享、会话转移和负载分担。概述┌──────────────┐ Bridge Protocol ┌──────────────┐ │ Gateway A │ ◀───…...

Go 网关模式:让业务逻辑和外部服务“保持距离“的艺术

🎬 场景小剧场 想象一下:你的电商系统要接支付功能。如果直接在 order 包里写 stripe.Charge(),明天老板说"换支付宝",你就要满世界改代码 😫 网关模式就是给业务逻辑装个"万能插座":不…...

SO(3) (本质理解)

一、SO(3) 是什么 SO(3)(Special Orthogonal Group): 几何理解(非常重要) SO(3) 表示: “刚体绕某个轴旋转一个角度” 任何旋转都可以表示为: 一个单位轴 一个角度 这就是: 轴…...

WarcraftHelper:魔兽争霸3终极兼容性工具,轻松实现5大版本完美适配

WarcraftHelper:魔兽争霸3终极兼容性工具,轻松实现5大版本完美适配 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 你是否想让…...

11. 免费GPU资源汇总(三):腾讯云、百度智能云免费算力实操

调试卡在CUDA out of memory?聊聊免费GPU算力的门道 昨天帮同事调试一个目标检测模型,明明batch_size已经调到4了,还是爆显存。实验室的2080Ti卡被其他项目占着,自己笔记本的3060跑不动。这种时候才真切感受到——独立GPU资源对开发者来说,有时候比代码能力还关键。 免费…...

10. 免费GPU资源汇总(二):AutoDL、阿里云免费算力申请与使用

001、系列引言:为什么你需要关注AutoDL与阿里云免费算力? 深夜两点,示波器的波形还在跳,我盯着屏幕里那个诡异的时序毛刺,突然意识到一件事——手头这块老旧的开发板已经跑不动更复杂的模型验证了。同事上周训练一个轻量级YOLO,在自己的笔记本上跑了整整两天,结果因为散…...

Delphi经典8大天坑|第六篇:方法参数缺省值写在实现区,导致缺省值不生效

一、现象描述给方法(过程/函数)定义参数缺省值(默认值)后,调用方法时不传递该参数,期望使用缺省值,但实际运行时,缺省值不生效,参数呈现随机值或错误值,排查时…...

每日一道面试题 08:SpringBoot 自动配置原理

一、核心前提SpringBoot 核心优势:自动配置,无需手动编写大量 XML 配置,简化开发(本质是 “约定优于配置”)自动配置底层依赖:EnableAutoConfiguration 注解 Spring 工厂加载机制 条件注解核心目标&#…...

实战构建多房间直播平台:基于快马AI生成核心业务代码框架

今天想和大家分享一个实战项目的搭建过程——多房间直播平台。这个项目涉及高并发、实时交互等典型直播场景需求,正好用InsCode(快马)平台来快速验证核心功能。以下是具体实现思路和关键设计: 整体架构设计 直播平台的核心在于实时性和扩展性。采用前后端…...

abaqus constraint 中,tie和coupling的区别

通过AI整理相关问题回答 tie和coupling的区别 在 Abaqus 中,Tie (绑定) 和 Coupling (耦合) 是最常用的两种连接约束,但它们在力学逻辑、自由度限制和应用场景上有着本质的区别。1. Tie Constraint (绑定约束) Tie 的核心逻辑是“胶合”。它将两个表面&a…...

从安装到实战:基于快马AI生成openclaw的网站内容监控应用项目

最近在做一个网站内容监控的小工具,尝试用openclaw框架来实现自动化采集和变更检测。这个项目从环境搭建到功能实现踩了不少坑,记录下完整过程给有类似需求的同学参考。 环境准备与openclaw安装 openclaw的安装其实挺简单,直接用pip就能搞定…...

Qwen3-VL-2B低成本方案:边缘设备部署实战案例分享

Qwen3-VL-2B低成本方案:边缘设备部署实战案例分享 边缘设备也能跑多模态大模型?Qwen3-VL-2B给你答案 1. 项目背景与价值 如果你正在寻找一个既强大又轻量的多模态模型,Qwen3-VL-2B-Instruct绝对值得关注。这是阿里最新开源的视觉-语言模型&a…...

小白友好:bge-large-zh-v1.5中文向量模型部署完整流程

小白友好:bge-large-zh-v1.5中文向量模型部署完整流程 1. bge-large-zh-v1.5模型简介 bge-large-zh-v1.5是一款专为中文优化的文本嵌入模型,能够将文本转换为高维向量表示。简单来说,它可以把任何中文句子变成一串数字(向量&…...

不同海外市场,跨境电商AI搜索优化有何差异?

跨境电商的核心特点是“面向全球市场”,而不同海外市场的语言习惯、搜索逻辑、消费场景、采购需求差异巨大,这就决定了AI搜索优化不能“一刀切”,需要结合不同市场的特性,制定差异化的优化策略。很多企业之所以优化效果不佳&#…...

从 OData 元数据到强类型前端:SAP UI5 与 TypeScript 生成服务类型定义的完整实践

在 UI5 项目里引入 TypeScript,很多团队已经能享受到编辑器补全、静态检查、重构安全这些直接收益。可一旦应用开始真正处理业务数据,一个很现实的问题就会出现:UI5 的官方类型定义覆盖了控件、模型、事件、基类 API,但你自己服务里的实体结构,像 Person、SalesOrder、Bus…...

终极GTA5菜单指南:如何用YimMenu彻底改变你的游戏体验

终极GTA5菜单指南:如何用YimMenu彻底改变你的游戏体验 【免费下载链接】YimMenu YimMenu, a GTA V menu protecting against a wide ranges of the public crashes and improving the overall experience. 项目地址: https://gitcode.com/GitHub_Trending/yi/YimM…...

界面重构神器:让Windows 11回归高效操作的ExplorerPatcher深度指南

界面重构神器:让Windows 11回归高效操作的ExplorerPatcher深度指南 【免费下载链接】ExplorerPatcher This project aims to enhance the working environment on Windows 项目地址: https://gitcode.com/GitHub_Trending/ex/ExplorerPatcher 你是否经历过这…...