【FreeRTOS】关于FreeRTOS中堆栈的一些思考

裸机时的堆栈问题

内存被分为许多区域,其中包含堆和栈,当然还有其他一些区域,见内存各区域区别

  • 内存栈中存储的是函数调用的形参、非静态局部变量以及函数调用信息。栈由编译器自动进行管理,无需人为干预。如果函数的局部变量定义大小过大(比如定义在函数内部定义超大型数组等),超过了链接脚本定义的栈区大小将会发生溢出,程序将会崩溃!

  • 内存堆是用于动态内存分配的,由编程人员手动进行管理。

    使用malloc函数手动申请内存和使用free手动释放,申请的内存在使用结束之后没有得到释放将会产生内存泄漏,导致程序崩溃!
    当使用malloc申请的内存大于堆剩余的容量时,将会导致申请失败!

以stm32为例,在在启动文件中可以定义栈和堆空间的大小,一般堆和栈默认都为0x200,如下所示。
启动文件
为了满足项目需求,可以按需对堆和栈空间进行调整。当然,调整的大小不能超过内存总容量(😄)!

运行FreeRTOS时的堆栈问题

FreeRTOS每个任务在创建时都会分配一个任务栈,任务的非静态局部变量等都会存储在任务创建分配时的任务栈中,而非系统栈(也就是前面裸机中提到的栈区)中,而只有中断函数和中断嵌套使用系统栈。1

任务栈的总容量是在FreeRTOSConfig.h文件中定义的,或者说任务栈是从这个HEAP中分配的。我们使用pvPortMalloc函数申请内存时,也是从这个HEAP中申请的。

#define configTOTAL_HEAP_SIZE                    ((size_t)8192)

那这个HEAP的来源呢?FreeRTOS使用一个静态数组作为HEAP,以我使用的heap_4.c内存管理策略来说,它定义在heap_4.c这个文件里面。因为这个HEAP来自于静态数组,所以它存在于数据段(具体为.bss段),并不是我一开始认为的FreeRTOS所使用的HEAP来自于系统的堆。

	static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];

在启动文件配置的Heap_Size EQU 0x200和FreeRTOS中的HEAP并无关系,启动文件中配置的Heap_size必须比configTOTAL_HEAP_SIZE大是没有依据的。

C库的malloc函数在微控制器并不是线程安全的。所以,为了线程安全,在使用FreeRTOS时进行动态内存申请时,请使用FreeRTOS提供的pvPortMallocvPortFree函数。

这里仅为自己的一些思考,如有错误,请大家指正!


参考文献


  1. FreeRTOS 任务栈大小确定及其溢出检测 ↩︎

  • 12
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Liangtao`

请作者喝杯咖啡吧~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值