RT-Thread动态内存扩展,使用多块不连续的RAM作为动态内存

开发环境

MCU:STM32F429VET6(1M Flash,192K+64K共256K SRAM)
编译环境:MDK5.38
实时系统:RT-Thread标准版

目的

这颗MCU的SRAM默认是使用192K,即从地址0x20000000开始,最大0x30000(192KB)大小,另外64K的RAM是从地址0x10000000开始,最大0x10000(64KB)大小。
在这里插入图片描述

最近项目开发过程中,发现SRAM空间不足了,使用想着怎么把剩余的64KB给用起来,把系统的运行内存从192K提升到256K。

实现过程

1.原理

由于RT-Thread自带内存管理,其中针对多内存堆的管理,即memheap管理算法, 支持多块内存(物理地址不连续)拼接使用。当系统中存在多个内存堆的时候,用户只需要在系统初始化时将多个所需的 memheap 初始化,并开启 memheap 功能就可以很方便地把多个 memheap(地址可不连续)粘合起来用于系统的 heap 分配。
注意:在开启 memheap 之后原来的 heap 功能将被关闭,两者只可以通过打开或关闭 RT_USING_MEMHEAP_AS_HEAP 来选择其一。
memheap 工作机制如下图所示,首先将多块内存加入 memheap_item 链表进行粘合。当分配内存块时,会先从默认内存堆去分配内存,当分配不到时会查找 memheap_item 链表,尝试从其他的内存堆上分配内存块。应用程序不用关心当前分配的内存块位于哪个内存堆上,就像是在操作一个内存堆。
在这里插入图片描述

2.实现步骤

2.1 开启memheap

在这里插入图片描述
选择使用memheap as heap。

2.2 使能RT_USING_MEMHEAP_AUTO_BINDING

查看rt_malloc代码发现,默认heap申请不到则去其他heap申请内存,如下图:
在这里插入图片描述

2.3 将64K的SRAM加入 memheap_item 链表

我们把64K的SRAM定义为SRAM2,起始地址和大小都定义好,如下:

#define STM32_SRAM2_SIZE          (64)
#define STM32_SRAM2_BEGIN         (0x10000000)
#define STM32_SRAM2_END           (STM32_SRAM2_BEGIN + STM32_SRAM2_SIZE * 1024)

在heap初始化的时候,同时初始化64K的SRAM:

    /* Heap initialization */
#if defined(RT_USING_HEAP)
    static struct rt_memheap tcmsram_heap;
    rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
    rt_memheap_init(&tcmsram_heap, "sram2", (void *)STM32_SRAM2_BEGIN, (rt_size_t)(STM32_SRAM2_END - STM32_SRAM2_BEGIN));
#endif
2.4 查看内存池大小

在这里插入图片描述
从上图中看出,heap共有57536Byte,sram2有65536Byte大小,即我们前面新增的64KB SRAM。
同时也能看到heap的可用大小只有2716Byte了,本次新增sram2也就是因为这个可用空间不够。

3.延展

HEAP的起始地址定义如下:

#if defined(__CC_ARM) || defined(__CLANG_ARM)
extern int Image$$RW_IRAM1$$ZI$$Limit;
#define HEAP_BEGIN      (&Image$$RW_IRAM1$$ZI$$Limit)
#elif __ICCARM__
#pragma section="CSTACK"
#define HEAP_BEGIN      (__segment_end("CSTACK"))
#else
extern int __bss_end;
#define HEAP_BEGIN      (&__bss_end)
#endif

目前用的MDK编译环境, Image$$RW_IRAM1$$ZI$$Limit是ARM链接器符号,指执行区中ZI输出节末尾后面的字节的地址。

映像结构如下图:
在这里插入图片描述
从分散加载文件得知,RW_IRAM1 为程序 RW 和 ZI 区加载地址,如下图:
在这里插入图片描述
所以,HEAP_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit)就是RW和ZI所需加载空间剩余的起始地址。举个例子:假如MCU的RAM为256K,RW+ZI共占用了180K,则heap内存池可用空间为256-180=76K字节大小。

4.结尾

最近用RT-Thread调试项目,遇到RAM不够的情况,按照上面的方法解决了RAM不够的问题,所以记录一下,如果有遇到同样类似的问题可参考。以上如有描述有误的也请指出。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值