C库函数与FreeRTOS内存管理区别
在C语言的库函数中,有mallc、free等函数可以申请以及释放内存空间,那么这为什么不适用于FreeRTOS的内存管理呢?
- 不适合用在资源紧缺的嵌入式系统中
 - 这些函数的实现过于复杂、占据的代码空间太大
 - 并非线程安全的(thread-safe)
 - 运行有不确定性:每次调用这些函数时花费的时间可能都不相同
 - 内存碎片化
 - 使用不同的编译器时,需要进行复杂的配置
 - 有时候难以调试
 
FreeRTOS内存管理
FreeRTOS内存管理方式主要依靠堆和栈来实现
- 堆,heap,就是一块空闲的内存,需要提供管理函数 
  
- malloc:从堆里划出一块空间给程序使用
 - free:用完后,再把它标记为"空闲"的,可以再次使用
 
 - 栈,stack,函数调用时局部变量保存在栈中,当前程序的环境也是保存在栈中 
  
- 可以从堆中分配一块空间用作栈

 
 - 可以从堆中分配一块空间用作栈
 
FreeRTOS内存管理方法比较
Heap_1
它只实现了pvPortMalloc,没有实现vPortFree。
 如果你的程序不需要删除内核对象,那么可以使用heap_1
 ⚫ 实现最简单,在定义好的一个大数组中分配内存
 ⚫ 没有碎片问题
 ⚫ 一些要求非常严格的系统里,不允许使用动态内存,就可以使用heap_1
 
Heap_2
Heap_2之所以还保留,只是为了兼容以前的代码。新设计中不再推荐使用Heap_2。建议使用Heap_4来替代Heap_2,更加高效。 Heap_2也是在数组上分配内存,跟Heap_1不一样的地方在于:
 ⚫ Heap_2使用最佳匹配算法(best fit)来分配内存
 ⚫ 它支持vPortFree
 ⚫最佳匹配算法: 假设heap有3块空闲内存:5字节、25字节、100字节。pvPortMalloc 想申请20字节,找出最小的、能满足pvPortMalloc的内存:25字节 把它划分为20字节、5字节。返回这20字节的地址,剩下的5字节仍然是空闲状态,留给后续的pvPortMalloc使用 。
 
 缺点:
 
Heap_3

Heap_4
跟Heap_1、Heap_2一样,Heap_4也是使用大数组来分配内存。 Heap_4使用首次适应算法(first
fit)来分配内存。它还会把相邻的空闲内存合并为一个更大的空闲内存,这有助于较少内存的碎片问题。
首次适应算法:
 ⚫ 假设堆中有3块空闲内存:5字节、200字节、100字节
 ⚫ pvPortMalloc 想申请20字节
 ⚫ 找出第1个能满足pvPortMalloc的内存:200字节
 ⚫ 把它划分为20字节、180字节
 ⚫ 返回这20字节的地址
 ⚫ 剩下的180字节仍然是空闲状态,留给后续的pvPortMalloc使用
 
 
Heap_5
Heap_5 分配内存、释放内存的算法跟Heap_4是一样的。 相比于Heap_4,Heap_5并不局限于管理一个大数组:它可以管理多块、分隔开的内存。 在嵌入式系统中,内存的地址可能并不连续,这种场景下可以使用Heap_5。既然内存时分隔开的,那么就需要进行初始化:确定这些内存块在哪、多大。
指定内存方法,使用结构体。
typedef struct HeapRegion 
{ 
uint8_t * pucStartAddress; // 起始地址 
size_t xSizeInBytes;       // 大小 
} HeapRegion_t; 
 
指定多块内存方法
 HeapRegion_t xHeapRegions[] = 
{ 
{ ( uint8_t * ) 0x80000000UL, 0x10000 }, // 起始地址0x80000000,大小0x10000 
{ ( uint8_t * ) 0x90000000UL, 0xa0000 }, // 起始地址0x90000000,大小0xa0000 
{ NULL, 0 } // 表示数组结束 
};
 
初始化内存
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ); 
                


















