单片机常用的堆栈知识汇总(后续不断更新)

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

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

  • 28
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值