内存分布在单片机编程中至关重要,尤其是RTOS的多线程环境,堆栈溢出时则会出现程序出错、卡死、跑飞等现象。
堆栈的作用:
堆:动态内存管理所用的内存,都是属于"堆"
栈:用于局部变量,函数调用跳转时现场保护和返回地址,函数的形参等
堆栈的使用:
堆:对于一般小型应用的开发,程序没有动态内存管理,也就是不会在运行时动态申请内存空间,那么堆所占用的内存空间实在程序编译链接时就确定好了,设置多少占多少。
栈:一般来说栈空间会设置成一个固定大小的空间,比如在STM32汇编引导文件内有一项Stack_Size 后面的数值就是设置的栈空间的大小,栈空间在运行时存储局部变量、函数跳转时现场数据等,如果某一个函数内定义了一个很大的局部数组或者递归函数深度过深都会造成栈空间不足,因此可能会覆盖掉一部分“堆”中的数据,造成程序出错卡死等问题。
查看堆栈的占用空间:
堆栈在stm32内存中的分布(工程使用keil编译)
采用.s文件中的默认设置,栈0x400、堆0x200。
查看编译的map文件,ram占0x1a68byte,栈顶指针指向0x200000x1668
对应代码
tip:static修饰的局部变量数据会被放在静态区,不会随着函数的结束而释放,所以在第二次运行时能保持上一次的数据。
如图可看出
堆的空间在0x2000 1468到0x2000 1668。
栈的空间在0x2000 1668到0x2000 1a68。
经实验:
没有动态内存管理的单片机程序,定义堆空间大小为0x10程序也能正常运行。
包含stdlib.h文件后,使用malloc();函数动态申请内存所获取的就是这里分配的堆地址。所以如果不用动态内存管理,可将堆空间减小甚至改为0.
栈空间的使用情况
在线调试时,查看栈空间内存的使用情况,即可看出是否够用有无溢出,从栈顶0x2000 0838向地址值减小的方向可看出,栈空间的占用基本很少,
堆栈空间的修改
堆空间修改:基本用不到,可以设置小一点。
栈空间修改:IAR 和 Keil都在汇编引导文件内修改
//关联关键词:\程序跑飞程序卡死\单片机内存分布\ |