深入理解STM32堆栈设置的笔记
内存堆栈Stack_Size、Heap_Size
如果程序在keil中编译时,函数当中定义的的局部变量超过栈空间大小编译时不会报错,但运行时会有可能出现错误,甚至会导致程序卡死
常见的情况就是定义的字符数组过度或过大 编译时不会报错 但是烧录进入板子时就会卡死
以下是一个简单的C语言示例,
标注说明了堆栈溢出、栈和堆的使用情况以及堆、栈的释放的时机和方式:
在这个例子中,我们可以看到以下情况:
1.栈的使用:栈被用来存放函数的局部变量、函数调用的参数以及函数调用时保存的返回地址。在main()函数中,localVariable是一个存放在栈上的局部变量
2.堆的使用:堆被用来存放动态分配的内存,例如通过malloc()函数分配的内存。在main()函数中,heapVariable是一个指向堆上分配内存的指针
3.堆栈溢出:functionWithStackOverflow()函数中递归调用自身,导致栈空间不断增长,最终导致栈溢出。这是因为每次函数调用都会在栈上分配一定的空间,如果递归调用次数过多,栈空间会被耗尽
4.堆栈的释放时机:当函数执行结束时,其在栈上分配的局部变量会被自动释放,而在堆上动态分配的内存需要手动调用free()函数来释放。在main()函数中,当程序执行结束时,所有的堆栈空间都会被系统自动释放
在STM32(以及大多数现代微控制器)中,通常
栈(Stack)向下生长(从高地址向低地址)
而堆(Heap)向上生长(从低地址向高地址)
这两个区域在内存中的位置是相邻的,确实是朝相反方向扩展的
如果栈和堆的使用不当确实有可能会相互“撞上”,这种情况通常被称为“堆栈溢出”
堆栈溢出
如果堆和栈的使用空间超过了它们之间的空间,就会发生堆栈溢出。这意味着堆上的数据可能会覆盖栈上的数据,或者栈上的数据覆盖堆上的数据,这通常会导致程序崩溃或者不可预测的行为
地址和大小设置
堆和栈的起始地址通常可以在手册中查找。栈的最大大小可能在启动代码(startup code)中设置,而堆的大小则由剩余的可用内存决定
栈的大小:通常在系统初始化时确定,可以根据应用需求调整。栈太小可能会导致栈溢出,太大则可能浪费内存
堆的大小:堆的大小通常是动态的,由剩余的可用内存决定。如果堆空间不足以满足动态内存分配的需求,会导致内存分配失败
空间利用
未使用的空间:对于栈而言,未使用的空间基本上不会占用实际资源,因为栈的使用是动态的,只有在调用函数时才会占用空间。对于堆,未分配的空间同样处于未使用状态,等待未来的分配
设置过大的问题:如果栈或堆设置得过大,可能会导致它们之间的空间不足,增加相撞的风险。即使没有发生堆栈溢出,过大的设置也可能导致内存资源的浪费,特别是在资源有限的嵌入式系统中
参考文章:
STM32的堆和栈-CSDN博客
STM32堆栈方面知识点-CSDN博客
单片机数据结构 堆栈-CSDN博客
stm32 heap stack-CSDN博客
SRAM空间用来存放了什么东西了:
1、各个文件中声明和定义的全局变量、静态数据和常量;
2、HEAP区;
3、STACK区;
参考学习,望有助
作者:f14ts同学