赞
踩
本博客讨论的堆栈是内存分配的堆和栈,并不是数据结构中的堆栈。
C语言内存分配可以看下这篇文章
栈
(stack)作用是用于局部变量、函数形参、函数调用时的现场保护和返回地址,以及进入中断函数前和中断嵌套等的开销。这部分内存是由编译器自动申请和释放的。
特点:先入后出
根据最后指针指向内存是否有数据可以分为
空栈
:SP指针指向最后压入数据的后一个地址。新数据压栈时,先写入地址,指针+1(-1)PS:指针是+1还是-1需要看栈的生长方向。
满栈
:SP指针指向最后压入的数据。先指针+1或-1,再写入数据。
根据栈的生长方向可以分:
递增式
:栈地址由低地址向高地址生长
递减式
:栈地址由高地址向低地址生长
对于STM32F1而言是递减式满栈。
我们可以看下栈定义:
Stack_Size EQU 0x400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
栈的大小是0x800也就是2kB。如果定义一个1024字节的局部变量数据,就占了1/2个栈空间了,再进进中断实现嵌套很容易出现栈溢出的hardfaul。所以大数组不适合定义成局部变量放在函数中。
堆
(Heap)主要用来动态分配内存
Heap_Size EQU 0x200
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
堆的大小:0x200,这部分是程序员可以自己动态申请和释放的。在裸机中可以调用malloc()
和free()
来申请和释放。有RTOS操作系统的一般会提供动态内存分配的方案。
堆栈在内存中分配如下图所示:
由于STM32中Stack空间是向下生长的,HEAP空间是向上生长的。如果malloc过多内存,会出现内存申请失败。或者子函数中有大数组,经过几次嵌套会出现栈空间向下溢出,导致程序崩溃。
解决方法:
方案一:在stm32f103ex.s文件定义增加栈空间的大小。
方案二:定义成全局变量
方案三:使用动态内存的方法放在堆空间中,这样至少在嵌套的时候不断被编译器的被压入栈空间。
https://blog.csdn.net/qlexcel/article/details/78916934
https://www.cnblogs.com/yangrourou/p/15883009.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。