FreeRTOS的堆管理

FreeRTOS的堆是什么

FreeRTOS的堆实际上就是一个静态数组,大小由FreeRTOSConfig.h中的configTOTAL_HEAP_SIZE宏决定。如果定义的值超出芯片可用RAM,编译时会报错。

5种Heap方案对比

方案特点适用场景使用频率
heap_1只分配,不回收所有任务永久运行,从不删除很少
heap_2可分配可释放,但不合并相邻空闲块固定大小分配很少
heap_3封装标准库malloc/free基本不用(嵌入式一般不依赖标准库)
heap_4可分配可释放,自动合并相邻空闲块最常用推荐
heap_5支持多段不连续内存有外部RAM等多块内存的硬件特殊场景

heap_2释放内存后不会合并相邻的空闲块,长期运行会导致严重的内存碎片。heap_4改进了这一点,释放时会自动合并相邻空闲块,因此是最常用的方案。

如果硬件上有多块不连续内存(如片内RAM + 外扩RAM),就需要使用heap_5。

内存管理辅助函数

  • xPortGetFreeHeapSize():获取当前剩余空闲堆大小(所有未分配字节的总和)
  • xPortGetMinimumEverFreeHeapSize():获取运行以来空闲堆的历史最小值,用来判断堆大小是否够用

让程序跑一段时间后调用xPortGetMinimumEverFreeHeapSize(),如果返回值只剩个位数或十位数字节,说明堆空间很紧张,需要调大configTOTAL_HEAP_SIZE

pvPortMalloc分配失败时,会触发钩子函数vApplicationMallocFailedHook(),可以在其中输出调试信息,方便定位问题。