单片机堆栈知识汇总,持续更新中
单片机常用的堆栈知识汇总
先来聊聊为什么要说这个吧,因为今天代码首先遇到在运行Freertos代码,只能运行一个task,另一个task无法运行,debug后,报hardfault错误,查询后,可能是堆栈分配异常。查阅资料后,修改代码,又遇到了代码No space in execution regions with .问题,单片机资源有限,报这个错误,是我之前并没有考虑过的,因此做出这个汇总,以便阅者和作者自查。
首先关于堆栈空间分配问题
这里0x400,默认是1024(1K)字节(Byte)大小。
讲到字节,我们就来聊聊一点基础知识:
1字节=8位(1 byte = 8bit)
1字=2字节(1 word = 2 byte)
char = uint_8 = 1字节
uint_16 = u16 = 2字节
int_32 = int = 4字节
来举个例子 char a[1024],也就是1024字节空间
接下来继续:
栈(stack)空间,用于局部变量,函数调时现场保护和返回地址,函数的形参等。
堆(heap)空间,主要用于动态内存分配,也就是说用 malloc,calloc, realloc 等函数分配的变量空间是在堆上。
全局区(static)
文字常亮区程序代码区
我们再来聊聊一点基础知识:
使用CubeMX对该芯片创建一个工程,然后点击魔术棒可以看到:
它的内置ROM起始地址为0X0800 0000,大小为0X10000,也就是FLASH的大小为:0X10000个字节 = 65536个字节 = 64k个字节 = 64kBytes。
它的内置RAM起始地址为0X2000 0000,大小为0X5000,也就是RAM的大小为:0X5000个字节 = 20480个字节 = 20k个字节 = 20kBytes
接下来继续:
我们如何知道程序占用内存大小:
Program Size: Code=23472 RO-data=852 RW-data=3252 ZI-data=16700
可以在MDK-ARM\XXX(你的项目名)找到.map文件<前提是你在魔术棒的Listing,勾选了.map文件生成>,具体如下:
==============================================================================
Total RO Size (Code + RO Data) 24324 ( 23.75kB)
Total RW Size (RW Data + ZI Data) 19952 ( 19.48kB)
Total ROM Size (Code + RO Data + RW Data) 24596 ( 24.02kB)
==============================================================================
以上名词我只捡我关注的简单解释下,详细解释看参考1。
RO_data:Read Only data,包括const关键字定义的变量,在flash区
RW_data:Read Write data,包括C语言中定义的全局变量中未初始化为0的数据,运行时在RAM区,不运行时在flash区
ZI_data:Zero Initialie data,即0初始化数据,即RW_data的0初始化变量,在RAM区
总结:Code + RO_data + RW_data(RO + RW)三种类型需要占用 Flash 空间(未运行时)。RAM不需要用到。
接下来是我们的堆和栈:
总结想要让一个程序正常运行。
且视他人之疑目如盏盏鬼火,大胆去走你的夜路。 ——By史铁生
参考1 :STM32深入系列01——内存简述(Flash和SRAM)https://blog.csdn.net/weixin_46253745/article/details/130032941
参考2: STM32 堆栈大小的设置及分析 https://blog.csdn.net/qq_27747359/article/details/109106895
作者:我真不想CV