2.1 为什么要自己实现内存管理
为了让FreeRTOS更容易使用,内核对象一般都是动态分配:用到时分配,不使用时释放。使用内存的动态管理功能,简化了程序设计,不再需要小心翼翼地提前规划各类对象,简化API函数的涉及,甚至可以减少内存的使用。
在C语言的库函数中,有mallc、free等函数,但是在FreeRTOS中,它们不适用:
2.2 什么堆栈
????????其实栈是栈,堆是堆,没有堆栈之说,堆栈通常是指栈。
2.3 FreeRTOS的5种内存管理方法
FreeRTOS中内存管理的接口函数为:pvPortMalloc 、vPortFree,对应于C库的malloc、free。
文件在FreeRTOS/Source/portable/MemMang 下,它也是放在portable 目录下,表示你可以提供自己的函数。
参考文章:FreeRTOS说明书吐血整理【适合新手+入门】
文件 | 优点 | 缺点 | 应用场合 |
---|
heap_1.c | 分配简单,没有碎片,时间确定 | 只分配、不回收 | 适用要求非常严格的系统里,不允许使用动态内存的场景 | heap_2.c | 动态分配、最佳匹配算法 | 碎片、时间不定 | 过时了,不推荐Heap_2。用Heap_4替代Heap_2,更高效。 | heap_3.c | 调用标准库函数 | 速度慢、时间不定 | 适用使用标准C库中的malloc、free函数的场景 | heap_4.c | 动态分配、相邻空闲内存可合并 | 较少碎片问题、时间不定 | 适用频繁分配、释放不同大小内存的场景 | heap_5.c | 在heap_4基础上支持分隔的内存块 | 较少碎片问题、时间不定 | 适用内存块地址不连续的场景 |
注:通过对比可以看出一般最常用的是heap_4.c内存管理方式。
2.4 Heap相关的函数
2.4.1 pvPortMalloc 和 vPortFree
函数原型:
void * pvPortMalloc( size_t xWantedSize ); // 分配内存,如果分配内存不成功,则返回值为NULL。
void vPortFree( void * pv ); // 释放内存
作用:分配内存、释放内存。如果分配内存不成功,则返回值为NULL。
2.4.2 xPortGetFreeHeapSize
函数原型:
size_t xPortGetFreeHeapSize( void );
当前还有多少空闲内存,这函数可以用来优化内存的使用情况。比如当所有内核对象都分配好后,执行此函数返回2000,那么configTOTAL_HEAP_SIZE就可减小2000。
注意:在heap_3中无法使用。
2.4.3 xPortGetMinimumEverFreeHeapSize
函数原型:
size_t xPortGetMinimumEverFreeHeapSize( void );
返回:程序运行过程中,空闲内存容量的最小值。 注意:只有heap_4、heap_5支持此函数。
2.4.4 malloc失败的钩子函数
在pvPortMalloc函数内部:
void * pvPortMalloc( size_t xWantedSize )
{
......
#if ( configUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook(); //钩子函数
}
}
#endif
return pvReturn;
}
所以,如果想使用这个钩子函数:
什么是回调函数、钩子函数
|