stm32 堆和栈(stm32 Heap & Stack)

发布者:ByteWanderer最新更新时间:2017-09-12 来源: eefocus关键字:stm32 手机看文章 扫描二维码
随时随地手机看文章

原文地址:http://blog.csdn.net/slj_win/article/details/16906141

文章排版不是很好,但是写的还是很有道理的。


关于堆和栈已经是程序员的一个月经话题,大部分有是基于os层来聊的。


那么,在赤裸裸的单片机下的堆和栈是什么样的分布呢?以下是网摘:


  1. int main()  

  2. {  

  3.     while(1);  

  4. }  

BUILD://Program Size: Code=340 RO-data=252 RW-data=0 ZI-data=1632 


编译后,就会发现这么个程序已用了1600多的RAM,要是在51单片机上,会心疼死了,这1600多的RAM跑哪儿去了,


分析map,你会发现是堆和栈占用的,在startup_stm32f10x_md.s文件(这个是stm32的启动文件)中,它的前面几行就有以上定义,


这下该明白了吧。


Stack_Size   EQU   0x00000400


Heap_Size   EQU   0x00000200


以下引用网上资料 理解堆和栈的区别


(1)栈区(stack):由编译器自动分配和释放,存放函数的参数值、局部变量的值等,其操作方式类似于数据结构中的栈。


(2)堆区(heap):一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收。分配方式类似于数据结构中的链表。


(3)全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统自动释放。


(4)文字常量区:常量字符串就是存放在这里的。


(5)程序代码区:存放函数体的二进制代码。



例如:

  1. int a=0;   //全局初始化区  

  2.   

  3.   

  4. char *p1;   //全局未初始化区  

  5.   

  6.   

  7. main()  

  8.   

  9.   

  10. {  

  11.   

  12.   

  13. int b;   //栈  

  14.   

  15.   

  16. char s[]="abc";   //栈  

  17.   

  18.   

  19. char *p3= "1234567";   //在文字常量区Flash  

  20.   

  21.   

  22. static int c =0 ;   //静态初始化区  

  23.   

  24.   

  25. p1= (char *)malloc(10);   //堆区  

  26.   

  27.   

  28. strcpy(p1,"123456");   //"123456"放在常量区  

  29.   

  30.   

  31. }  


所以堆和栈的区别:


stack的空间由操作系统自动分配/释放,heap上的空间手动分配/释放。


stack的空间有限,heap是很大的自由存储区(heap虽然有很大的存储区,但是这个存储区并不是无限大的,在stm32中,heap区的最大值由SRAM区决定,而SRAM区的大小可以参考具体的数据手册)。


程序在编译期和函数分配内存都是在栈上进行,且程序运行中函数调用时参数的传递也是在栈上进行。


------------------------------------------------------------------------------------------------------


1.堆和栈大小


定义大小在startup_stm32f2xx.s (这个地方应该是有错,定义的大小是在startup_stm32f10x_hd.s,也就是启动文件中)


Stack_Size  EQU  0x00000400 


AREA  STACK, NOINIT, READWRITE, ALIGN=3 
Stack_Mem  SPACE  Stack_Size 
__initial_sp


; Heap Configuration 
;  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> 
;


Heap_Size  EQU  0x00000200  //这里就是分配的堆空间大小


AREA  HEAP, NOINIT, READWRITE, ALIGN=3 
__heap_base


2.堆和栈位置


通过MAP文件可知


HEAP  0x200106f8  Section  512  startup_stm32f2xx.o(HEAP) 
STACK  0x200108f8  Section  1024  startup_stm32f2xx.o(STACK)


__heap_base  0x200106f8  Data  0  startup_stm32f2xx.o(HEAP) 
__heap_limit  0x200108f8  Data  0  startup_stm32f2xx.o(HEAP) 
__initial_sp  0x20010cf8  Data  0  startup_stm32f2xx.o(STACK)


显然 Cortex-m3资料可知:__initial_sp是堆栈指针,它就是FLASH的0x8000000地址前面4个字节(它根据堆栈大小,由编译器自动生成)


显然堆和栈是相邻的。




3.堆和栈空间分配


栈:向低地址扩展


堆:向高地址扩展


显然如果依次定义变量,先定义的栈变量的内存地址比后定义的栈变量的内存地址要大先定义的堆变量的内存地址比后定义的堆变量的内存地址要小


4.堆和栈变量


栈:临时变量,退出该作用域就会自动释放


堆:malloc变量,通过free函数释放


另外:堆栈溢出,编译不会提示,需要注意


 


------------------------------------------------------------------------------------------------------


 


如果使用了HEAP,则必须设置HEAP大小。 
如果是STACK,可以设置为0,不影响程序运行。 
IAR STM8定义STACK,是预先在RAM尾端分配一个字节的区域作为堆栈预留区域。 
当程序静态变量,全局变量,或者堆与预留堆栈区域有冲突,编译器连接的时候就会报错。 
你可以吧STACK设置为0,并不影响运行。(会影响调试,调试会报堆栈溢出警告)。 
其实没必要这么做。 
一般程序,(在允许范围内)设置多少STACK,并不影响程序真实使用的RAM大小, 
(可以试验,把STACK设置多少,编译出来的HEX文件都是一样), 
程序还是按照它原本的状态使用RAM,把STACK设置为0,并不是真实地减少RAM使用。 
仅仅是欺骗一下编译器,让程序表面上看起来少用了RAM。 
而设置一定size的STACK,也并不是真的就多使用了RAM,只是让编译器帮你 
检查一下,是否能够保证有size大小的RAM没有被占用,可以用来作为堆栈。 
以上仅针对IAR STM8.


 


------------------------------------------------------------------------------------------------------


 


从以上网摘来看单片机的堆和栈是分配在RAM里的,有可能是内部也有可能是外部,可以读写;(堆在stm32是分配在SRAM中的)


 


栈:存函数的临时变量,即局部变量,函数返回时随时有可能被其他函数栈用。所以栈是一种分时轮流使用的存储区,


      编译器里定义的Stack_Size,是为了限定函数的局部数据活动的范围,操过这么范围有可以跑飞,也就是栈溢出;


     Stack_Size不影响Hex,更不影响Hex怎么运行的,只是在Debug调试时会提示错。栈溢出也有是超过了国界进行


     活动,只要老外没有意见,你可以接着玩,有老外不让你玩,你就的得死,或是大家都死(互相撕杀),有的人写


    单片机代码在函数里定义一个大数组 int buf[8192],栈要是小于8192是会死的很惨。


 


堆:存的是全局变量,这变量理论上是所有函数都可以访问的,全局变量有的有初始值,但这个值不是存在RAM里的,是


     存在Hex里,下载到Flash里,上电由代码(编译器生成的汇编代码)搬过去的。有的人很“霸道”,上电就霸占已一块很


    大的RAM(Heap_Size),作为己有(malloc_init),别人用只能通过他们管家借(malloc),用完还得换(free)。所以  


    一旦有“霸道”的人出现是编译器里必须定义Heap_Size,否则和他管家借也没有用。


 


总之:堆和栈有存在RAM里,他两各分多少看函数需求,但是他两的总值不能超过单片机硬件的实际RAM尺寸,否则只能


到海里玩(淹死了)或是自己打造船接着玩(外扩RAM)。


参考资料:

1 百度文库《stm32堆栈分析》

http://wenku.baidu.com/link?url=Fk8ht47IULQFtxV43tc36LMSqDaGihhImEiVWmch-3nqRwRv2Arg9HUxU-JtQy8E64Kfiuhn0QghFpFQBFV9jdTRqpmMoaowX2DiMTGHC7u


关键字:stm32 引用地址:stm32 堆和栈(stm32 Heap & Stack)

上一篇:STM32F407多通道ADC采样程序
下一篇:STM32F1的UART4串口配置

推荐阅读最新更新时间:2024-03-16 15:36

STM32学习二:理解位绑定
学习STM32首先要理解的就是对寄存器的操作了,因为在STM32中对各IO口的操作实际就是对寄存器中各个位的操作。 在看了一个关于寄存器位绑定操作的教学视频后仍然是一头雾水,只能去网上查询各种资料,如比较有用的有《STM32位绑定操作的理解》,加上其他文章,形成了自己对位绑定的理解。 STM32将寄存器映射到了位带区(bit_band region),这样就可以通过统一的线性寻址空间直接操作寄存器了,这个空间就是0x00000000~0xFFFF FFFF共4GB大小,寄存器只是其中一小部分,其他包括程序存储区、数据存储区、输入输出端口等。这样的映射有两段,分别是0x2000 0000~0x200F FFFF(SRAM)及
[单片机]
<font color='red'>STM32</font>学习二:理解位绑定
基于WiFi的网络授时时钟(带实时天气更新)STM32程序设计
本方案采用的是MCU+AT指令的形式开发,MCU是大家比较熟悉的意法半导体公司STM32F103C8T6,WiFi模块使用的是安信可ESP-12F,本方案是一个Demo设计,比较简单,仅实现了功能,算是一个抛砖引玉吧! 先上视频演示: https://v.youku.com/v_show/id_XN ... m=a2hzp.8244740.0.0 WiFi模块资料链接:wiki点ai-thinker点com/esp8266 STM32F103C8芯片资料链接: https://www.stmicroelectronics.c ... 103c8.html#overview 硬件部分,由时钟电路+WiFi模块+MCU最小系统+O
[单片机]
基于WiFi的网络授时时钟(带实时天气更新)<font color='red'>STM32</font>程序设计
详解STM32最小系统电路
STM32最小系统硬件组成 最小系统为单片机工作的最低要求,不含外设控制,原理简单,分析最小系统是STM32入门的基础。 组成: · 电源 · 复位 · 时钟 · 调试/下载接口 · 启动 电源 3.3V的电源从这里接入,其中电容起到滤波的作用。 复位电路 当RESET引脚被拉低产生外部复位时,产生复位脉冲,从而使系统复位。 有三种复位方式: · 上电复位 · 手动复位 · 程序自动复位 上电复位 ,在上电瞬间,电容充电,RESET出现短暂的低电平,该低电平持续时间由电阻和电容共同决定,需求的复位信号持续时间约在1ms左右,计算方式如下: t = 1.1RC(固定计算公式) 1.1*10K*0.1uF
[单片机]
Phantom AI与瑞萨电子合作 开发全L2 ADAS解决方案
据外媒报道,自动驾驶平台开发商Phantom AI宣布与半导体解决方案供应商瑞萨电子(Renesas Electronics)合作,共同开发全栈L2 ADAS解决方案。 (图片来源:Phantom AI) Phantom AI利用瑞萨的单个低功耗R-Car V3H系统芯片(SoC),打造灵活的、汽车级ADAS解决方案,从而提供足够的计算能力,以实现L2 ADAS功能集,并满足功能性安全需求。该全栈解决方案由三个核心产品组成: PhantomVisionTM :高度可扩展的基于深度学习的计算机视觉系统,支持车辆、行人、自行车、自由空间、交通标志和交通灯检测。 PhantomFusionTM :独立于平台的传感
[汽车电子]
Phantom AI与瑞萨电子合作 开发全<font color='red'>栈</font>L2 ADAS解决方案
STM32 在温度监控系统中的应用
引言 现代工业控制领域通常要测量很多信号,将其转化为计算机可以识别的二进制信号,并利用计算机监视和记录各种测量的信号。这个过程就要涉及到信号的采集和处理。CAN 总线是一种串行多主总线,它卓越的特性、极高的可靠性和独特的设计,特别适合工业过程监控设备的互连,因此,越来越受到工业界的重视,并已公认为最有前途的 现场总线 之一。本文介绍了基于 STM32 和 CAN 总线的温度监控系统的设计,通过上位机与下位机的通信,实现对温度数据的监控,并经初步实验达到了设计的要求。 1 系统总体方案概述 系统总体框图如图 1 所示,本系统采用主站+从站的结构,CAN 主站主要实现温度数据的存储以及 CAN 总线协议和串口协议之间的 桥接 ,CA
[单片机]
基于STM32单片机的DLP驱动电路研究
DLP投影技术是应用美国德州仪器公司开发的数字微镜元件--DMD(Digital Micromirror Device)作为主要关键处理元件以实现数字光学处理过程的技术。DLP显示的色彩清晰度高、艳丽、细腻、逼真,且为全数字显示即可靠性极高,能在各类产品(如大屏幕数字电视、公司/家庭/专业会议投影机和数码相机(DLP Cinema))中提供最佳图像效果。目前,大部分的家用或商用DLP投影机都采用了单片结构,使得其便于移动携带,因而得到越来越广泛的应用。在目前应用发展的基础上,又对其结构的精简性、携带的方便性提出了更高的要求。传统的DLP投影仪是通过DVI接口接收外部信号,并且经过信号转换传送给DLP控制器来控制DLP的显示,占用的
[单片机]
基于<font color='red'>STM32</font>单片机的DLP驱动电路研究
STM32——C语言数据类型
在编程过程中,不同的CPU,其数据类型的意义各不相同,所以一定要注意相应变量数据类型的定义和转换,否则在计算中可能会出现不确定的错误。 (一)C语言中的种类数据 整型:int short long 实型:float double STM32中的数据类型非常的多,常用的变量,文件中的定义如下: /* exact-width signed integer types */ typedef signed char int8_t; typedef signed short int int16_t; typedef signed int int32_t; typedef signed __int
[单片机]
基于STM32微控制器处理先进电机控制方法
    变频器的问世和先进的电机控制方法让三相无刷电机(交流感应电机或永磁同步电机)曾经在调速应用领域取得巨大成功。这些高性能的电机驱动器过去主要用于工厂自动化系统和机器人。十年来,电子元器件的大幅降价使得这些电机驱动器能够进入对成本敏感的市场,例如:家电、空调或个人医疗设备。本文将探讨基于ARM的标准微控制器如何在一个被DSP和FPGA长期垄断的市场上打破复杂的控制模式,我们将以意法半导体的基于Cortex-M3 内核的STM32系列微控制器为例论述这个过程。     首先,我们回顾一下电机控制的基本原理。在电机控制系统内,为什么处理器非常重要?我们为什么需要非常好的计算性能?毕竟,Nicolas Tesla在一个世纪前发明
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved