内存管理(RTOS)

     

目录

#RTOS内存管理介绍

#堆定义

#栈定义

#RTOS四种堆分配方案

#Heap_1.c

#Heap_2.c

#Heap_3.c

#Heap_4.c

#Heap_5.c

#stm32cublemx对堆的配置

#配置堆相关函数

#申请内存函数

#钩子函数


          前言:本课程参考韦东山老师视频,连接放在最后。

#RTOS内存管理介绍

        后续的RTOS学习中,通常会使用这些对象   任务(task)    队列(queue)  多线程(semaphores)   事件( event group),这些对象定义地时候在内存中通常是,动态分配内存(使用分配,不用释放),也就是通过堆,来申请内存或者释放内存,这样做有一个好处,简化了程序设计。

        动态分配内存是C语言中的知识,但是与RTOS联系紧密,相关函数有 mallc(申请内存) free(释放内存),但是这些函数在RTOS系统里面并不适用,原因是,嵌入式系统资源紧缺,函数定义实现过于复杂,代码占用空间太大。

        因为上述的缺点,在RTOS中并不使用mallc free对堆进行分配和释放,而是通过 pvPortMalloc vPortFree 这两个函数进行内存的分配与释放,pvPortMalloc对堆的内存进行分配 vPortFree 进行释放堆的内存。

        pvPortMalloc对应着C语言中的mallc vPortFree对应着C语言中的free函数,也就是平替。

                 

#堆定义

        heap    堆   

         解释:空闲的内存,通过函数占用或者释放

        mallc :从堆里面申请一个内存给程序进行使用

        free :将已经分配给程序的堆,进行释放,释放过后的堆可用于在此使用。

#栈定义

        stack

        解释:调用函数的局部变量LR寄存器,还有切换函数保存的环境也是在栈中

        关联:从堆里面分配一块内存空间可以当做栈使用

                

#RTOS四种堆分配方案

        RTOS里面对应堆的管理有5种文件,每种文件分别对应着不同的内存管理方法,有着不同的效果。

#Heap_1.c

        相关介绍:heap_1.c 这个文件只实现了,pvPortMalloc 没有实现 vPortFree 也就是只实现了分配堆内存,没有实现释放堆内存

         如果程序不需要删除,堆内存对象可以使用这个文件,对堆内存进行管理,如果在一些严格的系统里面,如果不允许使用动态内存(就是不允许分配内存,使用过后回收内存),就可以使用这个函数,进行分配内存,因为这个文件不回收内存。

                    

        A在创建任务之前整个Heap都是空着的,B是分配一个任务之后heap的使用情况,C是3个任务之后heap的使用情况,这个时候如果有任务结束,这些空间是不会被收回的。

#Heap_2.c

        相关介绍:heap_2.c使用最佳匹配算法(best fit)进行分配内存空间,支持释放内存空间也就是vPortFree  heap_2.c被保留是为了兼容以前的代码,新设计中建议使用heap_4来代替heap_2来使用。

        最佳匹配算法:当任务需要30个字节的heap,算法会寻找,容量相同的内存空间如果没有,找到差值最小的内存空间进行分配,而二者的差值,会被重新使用分配。

        heap_2.c:释放内存空间:在任务结束之后,所占用的内存空间会被释放,因为heap_2.c支持

vPortFree  也就能释放内存空间。

           

        A阶段创建了3个任务,B阶段释放了一个任务的内存空间,C阶段将释放掉的内存空间重新进行分配,但是空闲空间大小不会被合并。也有事当堆释放时,会有严重的碎片问题。
 

#Heap_3.c

        相关介绍:heap_3.c使用标准库里面的  mallc free 函数 这里堆的大小由连接器配置,配置选项 configTOTAL_HEAP_SIZE(stm32cubleMX选项) 不在起到作用,heap_3.c 支持 释放 分配堆内存。

        C库里面的 malloc free 函数并非线程安全的,heap_3中首先暂停RTOS的任务调度器,再去调用这些函数,使用这些方法实现了线程安全。

#Heap_4.c

        相关介绍:heap_4.c 和heap_1.c   heap_2.c 堆管理文件一样,都是靠着大数组来分配内存,heap_4.c使用首次适应算法(first fit)来分配内存,同时会把相邻空间分配为更大的空间,有效减少内存碎片的问题。

        首次适应算法:如果pvPortMalloc需要申请A大小的内存空间,算法会寻找现有内存空间,从中划分出A大小的空间进行分配,剩下的仍然给 pvPortMalloc 进行分配。

        heap_4.c想对于heap_2.c,当对于堆释放内存的时候,前者可以合并已经释放的内存空间,合并为更大的内存空间

#Heap_5.c

        相关介绍:支持  pvPortMalloc  vPortFree 分配内存释放内存,可以管理多块分隔开的内存,如果内存的地址不连续,可以使用 heap_5.c 如果内存是分开的不连续的,在使用 pvPortMalloc 进行分配之前就需要初始化,确定内存块在哪里,多大。

        内存初始化函数:vPortfineHeapRegions 来指定信息

typedef struct HeapRegion
{
 uint8_t * pucStartAddress; // 起始地址
 size_t xSizeInBytes; // 大小
} HeapRegion_t;

                结构体类型定义:这个结构体,有两个成员变量,分别是起始地址,还有地址大小,如果要定义多块内存,就需要使用 HeapRegion_t 去声明一个数组进行使用

HeapRegion_t xHeapRegions[] =
{
 { ( uint8_t * ) 0x80000000UL, 0x10000 }, // 起始地址0x80000000,大小0x10000
 { ( uint8_t * ) 0x90000000UL, 0xa0000 }, // 起始地址0x90000000,大小0xa0000
 { NULL, 0 } // 表示数组结束

        这里定义数组,表示多块内存,定义格式需要注意。

#stm32cublemx对堆的配置

        这里下图是堆的配置,heap的大小在3072个字节,使用heap_4进行分配。

#配置堆相关函数
#申请内存函数
size_t xPortGetMinimumEvenFreeHeapSize(void);

        这个函数返回值,是运行程序所剩内存空间的最小值,只有heap_4.c   heap_4.c支持这个函数。如果调用函数返回值很小,也就是堆内存分配出去很多,可以适当的将,内存空间调大。

#钩子函数
void *pvPortMalloc(size_t xWantedSize)vPortDefineHeapRegions
{
    #if(configUSE_MALLOC_FAILED_HOOK == 1)
    {
        if(pvReturn == NULL)
        {
        extern void vAPPlicationMallocFailedHook(void);
        vAPPlicationMallocFailedHook();
        }
    }
}

       pvPortMalloc这个函数如果申请内存失败,在内部可以定义申请一个钩子函数,返回一些信息,这个失败调用的函数可以自己定义使用。

                                欢迎指正,希望对你有所帮助!!!

[4-1]_FreeRTOS源码概述_哔哩哔哩

  • 43
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值