开发环境
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不够的问题,所以记录一下,如果有遇到同样类似的问题可参考。以上如有描述有误的也请指出。