FreeRTOS学习记录--内存管理

学习FreeRTOS的内存管理首先要知道C语言的内存管理,对于C语言来说,它的库函数有malloc和free,但是这两个并不适用于FreeRTOS,原因如下:

1、malloc和free函数的实现较为复杂,其代码占用的空间量较大,对于嵌入式系统来说并不友好

2、不是线程安全的(什么是线程安全)

3、经常使用malloc和free会导致内存碎片化

4、malloc和free的运行时间不确定

5、有时候难以调试

堆和栈

堆:一块空闲内存,需要有管理函数

栈:从堆中分配一部分内存用于保存局部变量和现场环境

 FreeRTOS的五种内存管理方式

heap_1:只分配不回收(简单、时间确定)

heap_2:分配+回收但是不合并会造成内存碎片(动态分配、最佳匹配)

heap_3:速度慢时间不定(使用标准库函数)

heap_4:分配+回收并且合并相邻的内存空间(解决碎片问题但是时间不定)

heap_5:在4的基础上还能合并不相邻的内存空间

heap_1

一些不允许使用动态内存的系统使用该方式,不会产生内存碎片

原理:首先定义一个堆的指定大小的数组,每次调用pvPortMalloc()函数都从数组中划分一部分空间,创建任务时要使用TCB和Stack这两个内核对象,就在这个大数组中分配

heap_2 

现在已经不推荐使用heap_2了,能使用heap_4就使用heap_4,但是heap_2虽然也是在一个大数组中分配内存,但是它采取了最佳匹配算法,但是最佳匹配算法也会带来大量的内存碎片(除非每次最佳匹配都匹配到正好大小的内存空间),所以能用heap_4还是不要用这个了,因为heap_4能够合并相邻的内存碎片呀

 

heap_3 

使用标准库函数malloc和free,所以自定义的堆的大小(configTOTAL_HEAP_SIZE)也不再起作用,而是由链接器决定

保证线程安全:在调用标准库函数时先暂停FreeRTOS的调度器

heap_4

和方式1和2相同也是使用大数组来分配内存,使用的是首次适应算法,同时会合并相邻空间的内存碎片。

首次适应算法:找到第一个足够大小的内存空间就直接分配(找到的第一个)

执行时间不确定,但是效率高于标准库函数

heap_5

算法和heap_4相同,但是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 );

把制定多块内存的结构体传入这个初始化函数即可

附录-内存分配的相关函数

分配释放内存:

void * pvPortMalloc( size_t xWantedSize );
void vPortFree( void * pv );

获取当前还有多大的空闲内存:(heap_3无法使用)

size_t xPortGetFreeHeapSize( void );

程序运行过程中空闲内存的最小值:(heap_4、5专用)

size_t xPortGetMinimumEverFreeHeapSize( void );

malloc失败的钩子函数:

void * pvPortMalloc( size_t xWantedSize )vPortDefineHeapRegions
{
    ......
    #if ( configUSE_MALLOC_FAILED_HOOK == 1 )
    {
        if( pvReturn == NULL )
        {
            extern void vApplicationMallocFailedHook( void );
            vApplicationMallocFailedHook();
        }
    }
    #endif
    return pvReturn;
}

注意使用前提:

configUSE_MALLOC_FAILED_HOOK == 1

还要存在钩子函数

vApplicationMallocFailedHook();

  • 22
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

傲娇书生打嗝

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值