适用范围:适用目前APTCHIP CK80x所有平台
一、概述
栈(STACK):由编译器自动分配和释放。
堆(HEAP):有的地方也叫堆栈,一般由用户自行分配和释放,因此在分配好使用完成后要及时释放内存,否则会导致系统可用的内存越来越少,我们管这种情况叫做内存泄漏。
二、如何实现堆空间分配
1、Linker链接如何定义堆区域,有两种实现方式:
方式一、堆放在bss段和data段之后,这种方式比较常用。
在Linker链接文件中,在data和bss段后,直接添加user_heap段,VMA和LMA均为ram
MEMORY
{
ROM(RX) : ORIGIN = 0x00000000, LENGTH = 64K
RAM(RWX) : ORIGIN = 0x20000000, LENGTH = 8K
}
.user_heap : /*user heap section */
{
. = ALIGN(0x4) ;
__heap_start = .;
. += __heap_size;
. = ALIGN(0x4) ;
__heap_end = .;
} > RAM /*> REGION_BSS AT > REGION_BSS */
方式二、堆放在固定的起始位置,假设要实现堆空间起始地址为0x0x20001C00,大小1KB
在Linker链接文件中,申请一段ram区(ram2)专门给heap用
MEMORY
{
ROM(RX) : ORIGIN = 0x00000000, LENGTH = 64K
RAM(RWX) : ORIGIN = 0x20000000, LENGTH = 8K
RAM2(RWX) : ORIGIN = 0x20001C00, LENGTH = 1K /*堆空间区域*/
}
然后在Linker链接文件中添加user_heap段,VMA和LMA都在ram2
.user_heap : /*user heap section */
{
. = ALIGN(0x4) ;
__heap_start = .;
. += __heap_size;
. = ALIGN(0x4) ;
__heap_end = .;
} > RAM2 /*> REGION_BSS AT > REGION_BSS */
二、在启动文件 startup.S中,申请堆大小名称,为全局可用
//heap size
.equ __heap_size, USER_HEAP_SIZE
.globl __heap_size
三、在board_config.h头文件中,根据需求,定义堆的大小
/* user heap size */
//定义用户堆的大小,用于动态分配内存,可根据具体需求调整大小
#define USER_HEAP_SIZE 0x100
三、如何实现栈区域分配
实现栈顶地址为0x20001ff8,需进行以下操作:
栈内存只在程序运行时出现,在函数内部使用的变量、函数的参数以及返回值将使用栈空间,栈空间由编译器自动分配和释放。
实现栈顶为0x20001ff8,只需在Linker链接文件中,定义栈顶即可
__kernel_stack = ORIGIN(RAM) + 0x2000 - 8 ; /* stack top ,ORIGIN(RAM)为0x20000000 */
四、注意事项
1、使用堆的时候,需要添加stdlib.h头文件,才可使用malloc、free等内存申请或释放函数,具体使用详见以下链接:动态内存使用;
2、不要在函数内部定义过大的局部变量,防止栈溢出,覆盖了堆等区域数据。如过大的结构体变量,联合变量,过大的字符串,数组等。