#include "mymem.h" #include "sdram.h" // 定义是否使用ccm内存,1,使用,0,不使用 #define USE_CCM 0 #ifndef BOOTLOADER #define OS_RTT #ifdef OS_RTT #include "rthw.h" #define IRQ_DISABLE() rt_enter_critical() #define IRQ_ENABLE() rt_exit_critical() #else #include "os.h" #define IRQ_DISABLE() {CPU_SR_ALLOC(); CPU_CRITICAL_ENTER();} #define IRQ_ENABLE() CPU_CRITICAL_EXIT() #endif #else #define IRQ_DISABLE() { } #define IRQ_ENABLE() { } #endif static void exmem_init(void); //内存管理初始化函数 static u32 exmem_malloc(u32 size); //内存分配 static u8 exmem_free(u32 offset); //内存释放 static void mem_init(void); //内存管理初始化函数 static u32 mem_malloc(u32 size); //内存分配 static u8 mem_free(u32 offset); //内存释放 static void ccm_init(void) ; void mymem_init (void) { mem_init (); exmem_init( ); // ccm_init(); } #define EXMEM_BLOCK_SIZE (256) //内存块大小为64字节 #define EXMEM_MAX_SIZE ((uint64_t)((SDRAM_USER_SIZE))*EXMEM_BLOCK_SIZE/(EXMEM_BLOCK_SIZE+2)) #define EXMEM_ALLOC_TABLE_SIZE ((u32)(EXMEM_MAX_SIZE/EXMEM_BLOCK_SIZE)&(~3)) //内存表大小,必须为偶数,双字对齐 //分配的内存都是双字对齐的 #define EXMEM_BASE ((u8 *)(SDRAM_USER_ADDR+EXMEM_ALLOC_TABLE_SIZE*2)) #define EXMEMMAP_BASE ((u16 *)(SDRAM_USER_ADDR)) //内存管理参数 u32 exmemtblsize ; //内存表大小 u32 exmemblksize; //内存分块大小 uint64_t exmemsize ; //内存总大小 //内存管理控制器 struct _m_mallco_dev exmallco_dev; //复制内存 //*des:目的地址 //*src:源地址 //n:需要复制的内存长度(字节为单位) void mymemcpy(void *des,void *src,u32 n) { u8 *xdes=des; u8 *xsrc=src; while(n--)*xdes++=*xsrc++; } //设置内存 //*s:内存首地址 //c :要设置的值 //count:需要设置的内存大小(字节为单位) void mymemset(void *s,u8 c,u32 count) { u8 *xs = s; while(count--)*xs++=c; } //内存管理初始化 //memx:所属内存块 static void exmem_init(void) { exmemtblsize = EXMEM_ALLOC_TABLE_SIZE; //内存表大小 exmemblksize = EXMEM_BLOCK_SIZE; //内存分块大小 exmemsize = EXMEM_MAX_SIZE; //内存总大小 exmallco_dev.membase=EXMEM_BASE; //内存池 exmallco_dev.memmap=EXMEMMAP_BASE; //内存管理状态表 exmallco_dev.memrdy=0; //内存管理未就绪 mymemset(exmallco_dev.memmap, 0,exmemtblsize*2);//内存状态表数据清零 mymemset(exmallco_dev.membase, 0,exmemsize); //内存池所有数据清零 exmallco_dev.memrdy=1; //内存管理初始化OK } //获取内存使用率 //memx:所属内存块 //返回值:使用率(0~100) int exmem_perused(void) { u32 used=0; u32 i; for(i=0;i=0;offset--)//搜索整个内存控制区 { if(!exmallco_dev.memmap[offset])cmemb++;//连续空内存块数增加 else cmemb=0; //连续内存块清零 if(cmemb==nmemb) //找到了连续nmemb个空内存块 { for(i=0;i=0;offset--)//搜索整个内存控制区 { if(!mallco_dev.memmap[offset])cmemb++;//连续空内存块数增加 else cmemb=0; //连续内存块清零 if(cmemb==nmemb) //找到了连续nmemb个空内存块 { for(i=0;i=0;offset--)//搜索整个内存控制区 { if(!ccm_mallco_dev.memmap[offset])cmemb++;//连续空内存块数增加 else cmemb=0; //连续内存块清零 if(cmemb==nmemb) //找到了连续nmemb个空内存块 { for(i=0;i5*1024) offset=0XFFFFFFFF; else offset=mem_malloc(size); if(offset!=0XFFFFFFFF) { ret_addr=(void*)((u32)mallco_dev.membase+offset); } else { offset=exmem_malloc(size); if (offset!=0XFFFFFFFF) { ret_addr=(void*)((u32)exmallco_dev.membase+offset); } } //printf ("malloc:%#X,%d\r\n",(u32)ret_addr,size); IRQ_ENABLE(); return ret_addr; } //分配内存(外部调用) //首先尝试在内部分配,失败后再外部分配 //size:内存大小(字节) //返回值:分配到的内存首地址. void *mymalloc_fast(u32 size) { IRQ_DISABLE(); u32 offset; void *ret_addr=NULL; offset=mem_malloc(size); if(offset!=0XFFFFFFFF) { ret_addr=(void*)((u32)mallco_dev.membase+offset); } else { offset=exmem_malloc(size); if (offset!=0XFFFFFFFF) { ret_addr=(void*)((u32)exmallco_dev.membase+offset); } } //printf ("malloc:%#X,%d\r\n",(u32)ret_addr,size); IRQ_ENABLE(); return ret_addr; } //分配外部内存(外部调用) //首先尝试在内部分配,失败后再外部分配 //size:内存大小(字节) //返回值:分配到的内存首地址. void *mymalloc_exm(u32 size) { IRQ_DISABLE(); u32 offset; void *ret_addr=NULL; offset=exmem_malloc(size); if (offset!=0XFFFFFFFF) { ret_addr=(void*)((u32)exmallco_dev.membase+offset); } IRQ_ENABLE(); return ret_addr; } #if USE_CCM==1 //释放CCM内存 void myfree_ccm(void *ptr) { IRQ_DISABLE(); u32 free_addr=(u32)ptr; u32 offset; if(ptr==NULL) { IRQ_ENABLE(); return;//地址为0. } else if ((free_addr&0xf0000000)==0x10000000)//sram { offset=(u32)ptr-(u32)ccm_mallco_dev.membase; ccm_free(offset);//释放内存 } else { offset=(u32)ptr-(u32)exmallco_dev.membase; exmem_free(offset);//释放内存 } //printf ("free:%#X\r\n",free_addr); IRQ_ENABLE(); } //分配CCM内存 void *mymalloc_ccm(u32 size) { IRQ_DISABLE(); u32 offset; void *ret_addr=NULL; offset=ccm_malloc(size); if(offset!=0XFFFFFFFF) { ret_addr=(void*)((u32)ccm_mallco_dev.membase+offset); } else { offset=exmem_malloc(size); if (offset!=0XFFFFFFFF) { ret_addr=(void*)((u32)exmallco_dev.membase+offset); } } IRQ_ENABLE(); return ret_addr; } #endif //重新分配内存(外部调用) //memx:所属内存块 //*ptr:旧内存首地址 //size:要分配的内存大小(字节) //返回值:新分配到的内存首地址. void *myrealloc(void *ptr,u32 size) { IRQ_DISABLE(); void *ret_addr; ret_addr=mymalloc_exm(size); if(ret_addr!=NULL) { if(ptr!=NULL) { mymemcpy (ret_addr,ptr,size); myfree(ptr); } } IRQ_ENABLE(); return ret_addr; } //分配内存并清零 void *mycalloc (u32 size) { void *ptr=mymalloc(size); if (ptr) mymemset(ptr,0,size); return ptr; } //////////////////////////////////////////////////////////////////////////////// //基本调用接口 void *malloc(size_t size) { return mymalloc(size); } void free (void *ptr) { myfree(ptr); } void *realloc(void *ptr,size_t size) { return myrealloc(ptr,size); } void *calloc(size_t nmemb, size_t size) { return mycalloc(nmemb*size); }