stm32内存分配

https://www.cnblogs.com/yanghong-hnu/p/4705755.html

http://blog.csdn.net/c12345423/article/details/53004747

http://blog.csdn.net/spdian/article/details/52963829


bss段:

  bss段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。

  bss是英文Block Started by Symbol的简称。

  bss段属于静态内存分配。 

  

data段:

  数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。

  数据段属于静态内存分配。 

  

text段:

  代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。

  这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读(某些架构也允许代码段为可写,即允许修改程序)。

  在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。 

  

堆(heap):

  堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。

  当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);

  当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)。

  

栈(stack)

   栈又称堆栈,是用户存放程序临时创建的局部变量,

  也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。

  除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。

  由于栈的先进先出(FIFO)特点,所以栈特别方便用来保存/恢复调用现场。

  从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。 


一个程序本质上都是由 bss段、data段、text段三个组成的。

  这样的概念,不知道最初来源于哪里的规定,但在当前的计算机程序设计中是很重要的一个基本概念。

  而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统运行时的内存大小分配,存储单元占用空间大小的问题。

    在采用段式内存管理的架构中(比如intel的80x86系统),bss段通常是指用来存放程序中未初始化的全局变量的一块内存区域,

  一般在初始化时bss 段部分将会清零。bss段属于静态内存分配,即程序一开始就将其清零了。

    比如,在C语言之类的程序编译完成之后,已初始化的全局变量保存在.data 段中,未初始化的全局变量保存在.bss 段中。

  text和data段都在可执行文件中(在嵌入式系统里一般是固化在镜像文件中),由系统从可执行文件中加载;

  而bss段不在可执行文件中,由系统初始化



今天仔细读了一下内存管理的代码,然后还有看了堆栈的相关知识,把以前不太明白的一些东西想通了,写下来,方便以后查看,也想大家看了能指出哪里不对,然后修改。    

[转载]STM32的内存管理和堆栈相关的认知




首先,先看一下stm32的存储器结构。

FlashSRAM寄存器和输入输出端口被组织在同一个4GB的线性地址空间内。可访问的存储器空间被分成8个主要块,每个块为512MB

FLASH存储下载的程序。

SRAM是存储运行程序中的数据。

所以,只要你不外扩存储器,写完的程序中的所有东西也就会出现在这两个存储器中。

这是一个前提!

 

 







堆栈的认知

1.     STM32中的堆栈

这个我产生过混淆,导致了很多逻辑上的混乱。首先要说明的是单片机是一种集成电路芯片,集成CPURAMROM、多种I/O口和中断系统、定时器/计数器等功能。CPU中包括了各种总线电路,计算电路,逻辑电路,还有各种寄存器。Stm32有通用寄存器R0R15 以及一些特殊功能寄存器,其中包括了堆栈指针寄存器。当stm32正常运行程序的时候,来了一个中断,CPU就需要将寄存器中的值压栈到RAM里,然后将数据所在的地址存放在堆栈寄存器中。等中断处理完成退出时,再将数据出栈到之前的寄存器中,这个在C语言里是自动完成的。

2.     编程中的堆栈。

在编程中很多时候会提到堆栈这个东西,准确的说这个就是RAM中的一个区域。我们先来了解几个说明:

(1) 程序中的所有内容最终只会出现在flashram里(不外扩)。

(2) 段的划分,是将类似数据种类存储在一个区域里,方便管理,但正如上面所说,不管什么段的数据,都是最终在flashram里面。

C语言上分为栈、堆、bssdatacode段。具体每个段具体是存储什么数据的,直接百度吧。重点分析一下STM32以及在MDK里面段的划分。

MDKCode,RO-data,RW-data,ZI-data这几个段:

Code是存储程序代码的。

RO-data是存储const常量和指令。

RW-data是存储初始化值不为0的全局变量。

ZI-data是存储未初始化的全局变量或初始化值为0的全局变量。

Flash=Code + RO-Data + RW-Data;

RAM= RW-data+ZI-data;

这个是MDK编译之后能够得到的每个段的大小,也就能得到占用相应的FLASHRAM的大小,但是还有两个数据段也会占用RAM,但是是在程序运行的时候,才会占用,那就是堆和栈。在stm32的启动文件.s文件里面,就有堆栈的设置,其实这个堆栈的内存占用就是在上面RAM分配给RW-data+ZI-data之后的地址开始分配的。

:是编译器调用动态内存分配的内存区域。

:是程序运行的时候局部变量的地方,所以局部变量用数组太大了都有可能造成栈溢出。

堆栈的大小在编译器编译之后是不知道的,只有运行的时候才知道,所以需要注意一点,就是别造成堆栈溢出了。。。不然就等着hardfault找你吧。

3.     OS中的堆栈及其内存管理。

嵌入式系统的堆栈,不管是用什么方法来得到内存,感觉他的方式都和编程中的堆差不多。目前我知道两种获得内存情况:

(1)用庞大的全局变量数组来圈住一块内存,然后将这个内存拿来进行内存管理和分配。这种情况下,堆栈占用的内存就是上面说的:如果没有初始化数组,或者数组的初始化值为0,堆栈就是占用的RAM的ZI-data部分;如果数组初始化值不为0,堆栈就占用的RAM的RW-data部分。这种方式的好处是容易从逻辑上知道数据的来由和去向。

(2)​就是把编译器没有用掉的RAM部分拿来做内存分配,也就是除掉RW-data+ZI-data+编译器堆+编译器栈后剩下的RAM内存中的一部分或者全部进行内存管理和分配。这样的情况下就只需要知道内存剩下部分的首地址和内存的尾地址,然后要用多少内存,就用首地址开始挖,做一个链表,把内存获取和释放相关信息链接起来,就能及时的对内存进行管理了。内存管理的算法多种多样,不详说,这样的情况下:OS的内存分配和自身局部变量或者全局变量不冲突,之前我就在这上面纠结了很久,以为函数里面的变量也是从系统的动态内存中得来的。这种方式感觉更加能够明白自己地址的开始和结束。

这两种方法我感觉没有谁更高明,因为只是一个内存的获取方式,高明的在于内存的管理和分配。


keil编译后会有一行:Program Size:Code=xxxRO-data=xxxRW-data=xxxZI-data=xxx

Code 代表执行的代码,程序中所有的函数都位于此处。

RO-data 代表只读数据,程序中所定义的全局常量数据和字符串都位于此处。

RW-data 代表已初始化的读写数据,程序中定义并且初始化的全局变量和静态变量位于此处。

ZI-data 代表未初始化的读写数据,程序中定义了但没有初始化的全局变量和静态变量位于此处。ZI英语是zero initial,就是程序中用到的变量并且被系统初始化为0的变量的字节数,keil编译器默认是把你没有初始化的变量都赋值一个0,这些变量在程序运行时是保存在RAM中的。

Code: 程序所占用的FLASH大小,存储在FLASH.

RO-data: Read-only-data,程序定义的常量,存储在FLASH中。

RW-data:Read-write-data,已经被初始化的变量,存储在SRAM中。

ZI-data:Zero-Init-data,未被初始化的变量,存储在SRAM中。


2.如果你查看.map文件,如下例子:

==============================================================================

    Total RO  Size (Code + RO Data)                 2980 (   2.91kB)
    Total RW  Size (RW Data + ZI Data)               104 (   0.10kB)
    Total ROM Size (Code + RO Data + RW Data)       2988 (   2.92kB)

==============================================================================

Total ROM Size (Code + RO Data + RW Data)这样所写的程序占用的ROM的字节总数,也就是说程序所下载到ROM flash 中的大小。为什么Rom中还要存RW,因为掉电后RAM中所有数据都丢失了,每次上电RAM中的数据是被重新赋值的,每次这些固定的值就是存储在Rom中的,为什么不包含ZI段呢,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可,包含进去反而浪费存储空间。

实际上,ROM中的指令至少应该有这样的功能:
       1. 将RW从ROM中搬到RAM中,因为RW是变量,变量不能存在ROM中。
       2. 将ZI所在的RAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中。
       在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含变量的代码。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/243573.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

同步/异步移动文件列表框选中的文件

//PlayBackDlg.hCStringArray m_ArrayFiles;HANDLEm_hThreadMoveFiles;//异步移动文件句柄unsigned int ThreadID;void OnRefresh();void OnMoveTo(); //这个同步移动文件void OnMoveToAsync(); //使用线程, 异步//PlayBackDlg.cpp//m_listVideo…

小女人的建筑大梦

去年在台北,好友台湾恒兆出版公司的总编辑郑花束女士以及一家旅游杂志的女主编请我与深圳作家千夫长一起吃饭。两个台湾女人领着两个蒙古男人来到了一家奇特的餐厅——“伍角船板”。黄昏里,餐厅怪异夸张的外形让我惊奇。餐厅主体结构是两个狂舞的女孩的…

VHDL程序基本构建

VHDL程序基本构建 实体和端口模式 VHDL实体是整个设计实体(即独立的电路功能结构)的重要组成部分,其功能是对这个设计实体与外部电路进行接口描述。 实体说明单元的一般语句结构如下:ENTITY 实体名 IS[GENERIC (参数名 : 数据类型);][PORT(端口表 : 数据类型);]END ENTI…

“像你一样”与海容天天:OPEN国际行为艺术展十周年

8月5日。OPEN国际行为艺术展十周年在北京798艺术区开幕。来自欧美、日本、中国的艺术家参展。其中有费尔南多雷耶斯马塔、詹克诺尔、中岛美、田中洋平、吴方洲、杨青等,将近一百人。这个题为“像你一样”的行为艺术是美国艺术家托马斯史蒂文森的作品。内容是他给一个…

父进程和子进程之间

fork后父子进程共享资源 Unix环境高级编程中8.3节中说,“子进程是父进程的副本。例如,子进程获得父进程数据空间、堆和栈的副本。注意,这是子进程所拥有的副本。父进程和子进程并不共享这些存储空间部分。父进程和子进程共享正文段。” 书中还…

VHDL文字规则

VHDL文字规则 数字 "=>" 有“于是,then” 的意思 d1 <= 10#170#; --向d1赋值10#170#(十进制表示,等于170) d2 <= 16#FE#; --(十六进制表示,等于254) d1 <= 2#1111_1110#; --(二进制表示,等于254) d1 <= 8#376#; --(八进制表示,等于254) d1 &…

微软:PHP在IIS 7上雄起

WordCamp是WordPress爱好者及开发人员的大会&#xff0c;在上周末的WordCamp China 2009大会上&#xff0c;来自微软的王超群发表了题为“熟悉的陌生人 - 微软对PHP的新支持使WordPress在IIS 7上雄起”的主题演讲&#xff0c;展示了PHP在IIS 7上运行的现状及微软在这方面做出的…

798·锣鼓巷·牛街

798艺术区。一个外国女人和一个中国女孩。涂鸦。 锣鼓巷。两个小伙子以独特的方式在交谈。 牛街。清晨。街头花园。小孩与小狗。 牛街。清晨。街头花园。一个晨睡的男人。 798艺术区的后街。一个外国女孩。 798后街。一个骑自行车的小男孩。

SQL多字段模糊查询

http://user.qzone.qq.com/382164370#!app2&viaQZ.HashRefresh&pos1346996967 代码是在VC里面: CString sql, str;sql.Format(_T("SELECT * FROM tbPatient WHERE admitDate BETWEEN CDate(%s %s) AND CDate(%s %s)"),dtStartDate.Format(_T("%x"…

数据类型与顺序语句

数据类型与顺序语句 数据类型 VHDL要求设计实体中的每一个常数、信号、变量、函数以及设定的各种参量都必须具有确定的数据类型, 只要相同的数据类型的量才能互相传递和作用。VHDL作为一种强类型语言主要表现在以下两方面 (1)VHDL程序中的任何数据对象都必须定义一个确定的…

就是想让你无法无动于衷:观瑞士的“行为艺术”

798艺术区国际行为艺术节。瑞士女艺术家吉色拉•侯楚力&#xff08;Gisela Hochuli &#xff09;表演的作品&#xff1a;3倍长度的蜡烛。 时间&#xff1a;20-30分钟。场地&#xff1a;室内。过程&#xff1a;点燃一根长棉线&#xff0c;从线的一头烧到另头——棉线燃尽后再点燃…

Linux 内核源代码的目录结构

Linux 内核源代码的目录结构Linux 内核源代码包含如下目录。● arch &#xff1a;包含和硬件体系结构相关的代码&#xff0c;每种平台占一个相应的目录&#xff0c;如i386、arm、arm64、powerpc、mips 等。Linux 内核目前已经支持30 种左右的体系结构。在arch目录下&#xff0c…

北京曲剧《烟壶》也好看

几乎是第一次看地方戏。应朋友之邀前两天看了北京曲剧《烟壶》。导演是人艺老导演顾威先生。内容是根据当代作家邓友梅先生的同名小说改编。 曲剧属于北京的地方戏种&#xff0c;唱腔来源于单弦曲牌&#xff0c;是上世纪50年代兴起的剧种&#xff0c;创始人为奉调大鼓演员魏喜奎…

常用顺序语句

常用顺序语句 VHDL有6类基本顺序语句:赋值语句、流程控制语句、等待语句、子程序调用语句、返回语句和空操作语句。 赋值语句 赋值语句有两种,即信号赋值语句和变量赋值语句。 VHDL规定,赋值目标与赋值源的数据类型必须严格一致。CASE语句 CASE语句属于顺序语句,因此必…

“城迷”:黑白梦与精神逃离

杨羽的城市是虚拟的&#xff0c;所以看她的《城迷》系列&#xff0c;你不必感到意外或者试图通过她的图片去对应现实中的城市。因为它是不存在的&#xff0c;或者说&#xff0c;它只是存在于杨羽内心的一个幻象。 用摄影记录一个城市的大师很多&#xff0c;他们通过游走或者驻足…

什么是SoC?什么是IP核?它们有什么关系?

1. 什么是SoC​ SoC&#xff08;System on a Chip &#xff09;中文名是系统级芯片。20世纪90年代中期&#xff0c;因使用ASIC实现芯片组受到启发&#xff0c;萌生应该将完整计算机所有不同的功能块一次直接集成于一颗硅片上的想法。SoC应由可设计重用的IP核组成&#xff0c;IP…

历史是“混合体”,也是“内幕”:说说《三国大传》

“三国”时代是中国历史最上短命的一个时期之一&#xff0c;历史学家认为只有四十五年&#xff0c;最多不过百年。但是关于这个时代的文字记载和民间传说却可谓汗牛充栋&#xff0c;人们对它的关注不亚于盛唐和明清。上有《后汉书》、《三国志》&#xff0c;后有《资治通鉴》和…

一个C++加密工具EncryptDecrypt.dll

EncryptDecrypt.dll文件封装了Rijndael加密算法, 结合SHA-256与 CNewRandom( http://www.codeproject.com/Articles/5489/KeePass-Password-Safe这个里面用到的基于SHA-256伪随机数)加密与解密字符串.......这个加密工具有个重要的特性就是, 就算是用同样的密钥加密同一个字符…

实用的计数器

实用的计数器 library IEEE; use IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL;entity CNT10 is -- Port ( );PORT(CLK,RST,EN,LOAD : IN STD_LOGIC;DATA : IN STD_LOGIC_VECTOR(3 DOWNTO 0); --4位预置数 DOUT : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --计数值输…

香港版的芭蕾舞剧《吉赛尔》

保利剧院。由香港芭蕾舞团演出的二幕舞剧《吉赛尔》&#xff08;Giselle&#xff09;。《吉赛尔》与《天鹅湖》《睡美人》被称为世界三大芭蕾舞剧。作曲是法国作曲家亚杜夫亚当(Adolphe Adam 1803-1856)。伴奏是中央芭蕾舞团交响乐团&#xff0c;指挥张艺。舞蹈演员大多来自内地…