STM32堆栈整理
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
STM32内存编程
在startup_stm32f10x_md.s文件中,它的前面几行就有以上定义,;
栈=1K
Stack_Size EQU 0x00000400
;堆=512B
Heap_Size EQU 0x00000200
Stack_Size不影响Hex,更不影响Hex怎么运行的,只是在Debug调试时会提示错。栈溢出也有是超过了国界进行活动,只要老外没有意见,你可以接着玩,有老外不让你玩,你就的得死,或是大家都死(互相撕杀),有的人写单片机代码在函数里定义一个大数组int buf[8192],栈要是小于8192是会死的很惨。
Heap_Size可为0,即不使用动态分配。Heap_Size的大小与malloc所分配的内存有关,当连续分配而又不释放,会导致满堆或内存泄露。
本文源起的诉求,即在object过多的情况下进行解析,程序需要N多次的动态内存分配,而Heap_Size太小,导致无法分配内存。通过修改Heap_Size的大小解决了诉求。
STM32的内存分配规律
从0X20000000开始依次为:静态存储区+堆区(可有可无)+栈区
所有的全局变量,包括静态变量之类的,全部存储在静态存储区。紧跟静态存储区之后的,是堆区(如没用到malloc,则没有该区),之后是栈区。
附录
STM32内存地址说明
在MDK编译过程中,内存的划分如下:
Code是存储程序代码的。
RO-data是存储const常量和指令。
RW-data是存储初始化值不为0的全局变量。
ZI-data是存储未初始化的全局变量或初始化值为0的全局变量。
Flash=Code + RO Data + RW Data;
RAM= RW-data+ZI-data;
此内存划分暂未包括堆栈,堆栈会在程序运行时,占用RAM。
堆栈的内存占用就是MDK里,RAM分配给RW-data+ZI-data之后的地址开始分配的。---------------------
STM32的堆栈大小在官方文件已经定义好了,分别是:
Heap_Size EQU 0x00000200 一共512字节
Stack_Size EQU 0x00000400 一共1K字节
/***********************************************************************************/
但是STM32在keil环境下每次编译后的堆栈起始地址并不是固定的(就算事先已经定义好了堆栈的大小),因为栈的起始地址是由用户程序中事先定义好的变量数目决定的(实测是如此)。但欣慰的是,一旦这次编译之后,堆栈的首地址就不会再发生改变了,换言之,就是在烧完程序之后,堆栈的地址就永远不变了。
/***********************************************************************************/
要关心STM32的堆栈关系,首先无法避免的就是下面这两幅图片了:
图一:MDK环境下,STM32 Bulid Output窗口部分截图
图二:MDK环境下,STM32的.map文件中关于堆栈地址的说明(绿色高亮部位)
/***********************************************************************************/
STM32的内部sram的首地址为0x20000000,图二中的__i nitial_sp既为栈的高地址(也就是栈的首地址)(STM32的堆栈地址在MDK下的配置默认是连续的,栈的地址高于堆的地址,栈的生长方向为从高地址向低地址生长,栈的地址为从低地址向高地址生长,最后两者生长到了一起,也就是“头碰头”)图二中的HEAP既为堆的低地址,STACK既为最后头碰头的地址(注意并不是栈的起始地址而是结束地址,因为栈相对于堆是逆向生长的)
/***********************************************************************************/
那么问题来了,__initial_sp的值是怎么来的呢?这就要看图一了。
首先抛出结论:__initial_sp = 0x20000000+RW+ZI
RW:Read/Write 可读可写的数据段。就是那些在任务初始化时就已经被赋值了的变量,MDK一般将这种类型的数据保存在STM32的SRAM中。(“全局变量”存在“普通意义上的”SRAM 中)(“局部变量”存储在“栈”中)(“局部的static变量”在存储上等价于全局变量)ZI:Zero Initial 初始化为0的变量,也就是直接初始化并没有赋值的变量
可以这么认为:在STM32的片内SRAM中,__initial_sp-0x20000000为用户已经使用了的SRAM空间,从高地址到低地址依次为“栈Stack”“堆Heap”“全局变量”
/***********************************************************************************/
至此,图二中绿色高亮部分的STACK和HEAP的数值也就不难理解了
STACK = __initial_sp - 0x400(栈的大小)
HEAP = STACK - 0x200(堆的大小)
---------------------