单片机堆栈知识汇总,持续更新中

单片机常用的堆栈知识汇总

先来聊聊为什么要说这个吧,因为今天代码首先遇到在运行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)

文字常亮区程序代码区

我们再来聊聊一点基础知识:
  • stm32f103c8t6 小容量芯片 RAM容量为20KB,FLASH容量为64KB
  • ​ 使用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不需要用到。

  • 接下来是我们的堆和栈:

  • ZI-data 的栈空间(Stack)及堆空间(Heap):在C语言中,函数内部定义的局部变量属于栈空间,进入函数的时候会向栈空间申请内存给局部变量,退出时释放局部变量,归还内存空间。而使用malloc动态分配的变量属于堆空间。在程序中的栈空间和堆空间都是属于ZI-data区域的,这些空间都会被初始值化为0值。编译器给出的ZI-data占用的空间值中包含了堆栈的大小(经实际测试,若程序中完全没有使用malloc动态申请堆空间,编译器会优化,不把堆空间计算在内)。
  • 总结想要让一个程序正常运行。
  • 芯片的 Flash 大小 要大于 Code + RO-data + RW-data 的大小;
  • 芯片的 RAM 大小 要大于 RW-data + ZI_data 的大小。
  • 且视他人之疑目如盏盏鬼火,大胆去走你的夜路。 ——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

    物联沃分享整理
    物联沃-IOTWORD物联网 » 单片机堆栈知识汇总,持续更新中

    发表回复