成就更好的自己

学习笔记篇

本文为转载,原文为CSDN博主dtj-ee
原文链接:https://blog.csdn.net/sinat_30146065/article/details/82221179

单片机内存的合理使用对于一名嵌入式软件工程师来说是至关重要的,这深深关系到项目代码的稳定性。对于c语言程序的bug,最为致命、最难发觉的也是内存的使用不当造成的,这种奇葩现象。之前对这一块有过了解,可惜没有真正的领会其中的要害和内涵。大抵是平时写写代码玩的时候单片机资源足够多,也从来不会去理会内存够不够的问题。

背景大概是这样的:某个项目写到一个数据处理函数,这里需要进行大量数据处理和拼接长字符串,需要大量的中间变量作为转存(超过1k长度的大数组),我左思右想到底是用全局变量?还是局部变量?抑或是利用malloc申请一段内存来使用,当时果断使用了定义在函数内的局部变量,理由是局部变量所占用的内存在该函数运行完之后即会自动释放,这样只会在短时间内占用cpu的ram,至于不使用malloc的理由是怕堆生长太大覆盖了栈区的内存。然而....,如果在函数内使用大数组的局部变量有可能会造成全局变量区的内存被覆盖,难不成使用全局?这样不会占用太多的RAM嘛?

--------宁可牺牲掉RAM的部分资源作为固定的内存,也不要这种随时可能爆炸的定时炸弹(大数组局部变量),因为它可能在某个时间节点内突然申请一块巨大的内存,到时候内存覆盖刷掉了全局变量的地址就真的GG了。仔细一想局部变量大数组还真的是一枚定时炸弹,开始重新去审视和理解关于单片机内存相关的知识。

说了一大段废话....

以下是我对该内容的一个整理:

单片机内存被分为flash和sram(ram),在查看任何一款单片机的时候都会有它们的介绍,可以看看最近使用的合泰单片机HT32F2253的介绍

我们看到它的flash是128KB、SRAM是16KB。(其实它的内存还算挺大的........)

以下是我按照自己的理解画的的一个内存结构图:

初始化前:

初始化后:

嗯...可以看到,初始化时RW-data从flash拷贝到RAM,所以在程序跑起来了Rw-data是在RAM里面的。

其中:Code为程序代码部分
RO-data 表示 程序定义的常量const temp;
RW-data 表示 已初始化的全局变量
ZI-data 表示 未初始化的全局变量

(以上这一段是copy的,原地址在:http://anlx27.iteye.com/blog/1575848)

而栈区(stack)、堆区(heap)、全局区(静态区)(static)、文字常量区和程序代码区和上面所介绍的code、RO-data等的关系。

1、栈区(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 这些值是可读写的,那么stack应该被包含在RW-data(读写数据存储区),也就是单片机的sram中。

2、堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。可以理解,这些也是被包含在单片机的sram中的。

3、全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,程序结束后由系统释放。这些数据也是可读可写的,和stack、heap一样,被包含在sram中。

4、文字常量区:常量字符串就是放在这里的。这些数据是只读的,分配在RO-data(只读数据存储区),则被包含在flash中。

5、程序代码区:存放函数体的二进制代码,可以想象也是被包含在flash,因为对于MCU来说,当其重新上电,代码还会继续运行,并不会消失,所以存储在flash中。

(然而上这一段还是copy的,原地址在:http://www.51hei.com/mcu/4293.html)

下面是网上找的例子:

int a = 0;          // RW-data 全局初始化区 
char *p1;           // ZI-data 全局未初始化区 
const int b = 0;    // RO-data 只读变量区
main(void)
{
  int b;            // RW-data 栈区 
  char s[] = "abc"; // RW-data 栈区
  char *p2;         // RW-data 栈区
  char *p3 = "123456";     // "123456/0" 在Ro-data 常量区,p3在RW-data 栈区
  static int c =0;         // 全局(静态)初始化区 rw-data -> static区
 
  p1 = (char *)malloc(10);
  p2 = (char *)malloc(20); // 分配得来的10和20字节的区域就在Rw-data 堆区
 
  strcpy(p1, "123456");    // "123456/0" 放在常量区,编译器可能会将它
                              // 与p3所指向的"123456"优化成一个地方
}
所以,重点来了,在实际编程中,应当实时关注.map的内容来判断单片机内存的使用情况。

在keil中,右击工程就会出现opne map flie的选项,打开它,浏览到最后一段

可以看到该工程占用单片机ram12.43kb,flash13.91kb。

关于单片机内存解释的整理(学习笔记篇)相关推荐

  1. 关于单片机内存解释的整理

    单片机内存的合理使用对于一名嵌入式软件工程师来说是至关重要的,这深深关系到项目代码的稳定性.对于c语言程序的bug,最为致命.最难发觉的也是内存的使用不当造成的,这种奇葩现象.之前对这一块有过了解,可 ...

  2. Java启动参数与内存调优一些学习笔记

    转载自  Java启动参数与内存调优一些学习笔记 .参数的含义 -Xms128m JVM初始分配的堆内存 -Xmx512m JVM最大允许分配的堆内存,按需分配 -XX:PermSize=64M JV ...

  3. 面向对象的编程思想写单片机程序——(3)学习笔记 之 程序分层、数据产生流程

    系列文章目录 面向对象的编程思想写单片机程序--(1)学习笔记 之 程序设计 面向对象的编程思想写单片机程序--(2)学习笔记 之 怎么抽象出结构体 面向对象的编程思想写单片机程序--(3)学习笔记 ...

  4. 树莓派可以移动linux,树莓派学习笔记 篇三:树莓派4B 与移动存储设备的那些事儿...

    树莓派学习笔记 篇三:树莓派4B 与移动存储设备的那些事儿 2019-11-24 23:03:55 39点赞 286收藏 14评论 本文是「树莓派学习笔记」系列的第三篇,将学习下 Linux 系统分区 ...

  5. homeassistant mysql_学习笔记 篇三:HomeAssistant学习笔记docker安装的ha更换数据库

    学习笔记 篇三:HomeAssistant学习笔记docker安装的ha更换数据库 2018-11-15 12:06:58 4点赞 18收藏 3评论 是返乡过年?还是就地过年?最新一届#双面过节指南# ...

  6. 【单片机】STM32 最小板 学习笔记

    目录&索引 前言 第一章 前期工作准备 软件获取 STM32 资料 相关下载 硬件准备 第二章 单片机系统介绍 第三章 库函数工程模板建立 第一步,下载固件库,文件分类 第二步,打开 mdk5 ...

  7. ipad分屏大小怎么调整_ipad软件应用推荐——学习笔记篇

    文末有 苹果ipad软件 应用APP  下载方式 前言 随着新型iPad Pro和妙控键盘的发布. iPad从原来的娱乐游戏机逐渐地变成了生产力工具. 搭配Apple pencil和蓝牙键盘,瞬间变成 ...

  8. 开始整理学习笔记啦~~~

    以前为了方便,把笔记随手写成了word文档,放在电脑上,但是换台设备查看的时候很不方便,加上项目也需要总结经验,所以从今天开始的近两个星期内要把之前的笔记整理好哦.有些杂乱,但是整理好以后再归类吧.

  9. B站【编程不良人】Redis教程整理学习笔记(超详细拓展)

    Redis 1. NoSQL的引言 NoSQL( Not Only SQL ),意即不仅仅是SQL, 泛指非关系型的数据库.Nosql这个技术门类,早期就有人提出,发展至2009年趋势越发高涨. 2. ...

最新文章

  1. Python分析101位《创造营2020》小姐姐,谁才是你心中的颜值担当?
  2. Cytoscape制作带bar图和pie图节点的网络图
  3. 转 Struct 和 Union区别 以及 对内存对齐方式的说明
  4. 转整型_156.Ruby烘焙大理石豆沙吐司解锁大理石花纹整型
  5. Jquery复习(七)之尺寸
  6. 深南和海能达那个好_打造特色定制茶谋划茶旅融合发展 “海垦”牌南海茶整装再出发...
  7. python闹钟_用python做了个高级闹钟 欢迎借鉴
  8. 智慧城市大数据运营中心及城市大脑综合运行管理平台建设方案WORD
  9. 易语言WebUI教程 —— 入门简介
  10. smobiler介绍(一)
  11. java getbytes 乱码_深入解析java String中getBytes()的编码问题
  12. android10.0连接wifi后提示“已连接,但无法访问互联网”
  13. SSRF深度解析Gopher协议
  14. matlab 彩色图片分解,MATLAB 彩色图像分割
  15. (Note)阿克西斯ACASIS DT-3608双盘位硬盘阵列盒RAID设置
  16. 企业咨询行业拓客的10个经典方法
  17. 迈卓诺(Metronor)光笔测量仪--大型模具的测量利器
  18. lighttpd隐藏index.php,lighttpd开启rewrite伪静态方法 - 老牛博客
  19. 《那些年我们追过的Wrox精品红皮计算机图书》有奖活动
  20. hjr-MUD游戏(五):字符串与二进制与protobuf通信

热门文章

  1. matlab落海搜救模型,面向海上应急搜救的无人船路径规划
  2. Unity 实现简单力场效果
  3. 计算机账务处理流程图,账务处理流程图
  4. node 爬虫处理cookie,代理
  5. 【IoT】产品设计之什么是覆膜与上光工艺
  6. DS哈希查找--Trie树
  7. footer.php置底,详解CSS五种方式实现Footer置底
  8. antd Pro 系列之初识antd Pro
  9. 盘点国内热门AI大模型
  10. 【C语言历程14.数组倒序输出】