结合STM32的开发讲述堆栈从上面的描述可以看得出来,在代码中是如何占用堆和栈的。可能很多人还是无法理解,这里再结合 STM32 的开发过程中与堆栈相关的内容来进行讲述。如何设置STM32的堆栈大小?在基于MDK的启动文件开始,有一段汇编代码是分配堆栈大小的。
这里重点知道堆栈数值大小就行。还有一段 AREA(区域),表示分配一段堆栈数据段。数值大小可以自己修改,也可以使用 STM32CubeMX 数值大小配置,如下图所示。
STM32F1 默认设置值 0x400,也就是 1K 大小。 view plaincopy to clipboardprint?
函数体内局部变量: view plaincopy to clipboardprint?
- void Fun(void)
- {
- char i;
- int Tmp[256]; //...
- }
局部变量总共占用了 256*4 + 1 字节的栈空间。所以,在函数内有较多局部变量时,就需要注意是否超过我们配置的堆栈大小。函数参数: view plaincopy to clipboardprint?
- void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
这里要强调一点:传递指针只占 4 字节,如果传递的是结构体,就会占用结构大小空间。提示:在函数嵌套,递归时,系统仍会占用栈空间。堆(Heap)的默认设置 0x200(512)字节。 view plaincopy to clipboardprint?
大部分人应该很少使用 malloc 来分配堆空间。虽然堆上的数据只要程序员不释放空间就可以一直访问,但是,如果忘记了释放堆内存,那么将会造成内存泄漏,甚至致命的潜在错误。MDK中RAM占用大小分析经常在线调试的人,可能会分析一些底层的内容。这里结合 MDK-ARM 来分析一下RAM 占用大小的问题。在 MDK 编译之后,会有一段 RAM 大小信息:
这里 4+1636=1640,转换成16进制就是 0x668,在线进行调试时,会出现:
这个 MSP 就是主堆栈指针,一般我们复位之后指向的位置,复位指向的其实是栈顶:
而MSP指向地址 0x20000668 是 0x20000000 偏移 0x668 而得来。具体哪些地方占用了 RAM,可以参看 map 文件中【Image Symbol Table】处的内容:
转载自网络,如有侵权,联系删除。
|