初始提交

This commit is contained in:
2025-06-27 00:32:57 +08:00
commit e40bb2ba8a
5134 changed files with 2158460 additions and 0 deletions

View File

@@ -0,0 +1,701 @@
#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<exmemtblsize;i++)
{
if(exmallco_dev.memmap[i])used++;
}
return (used*10000)/(exmemtblsize);
}
//内存分配(内部调用)
//memx:所属内存块
//size:要分配的内存大小(字节)
//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
static u32 exmem_malloc(u32 size)
{
signed long offset=0;
u32 nmemb; //需要的内存块数
u32 cmemb=0;//连续空内存块数
u32 i;
// if(!mallco_dev.memrdy)mallco_dev.init();//未初始化,先执行初始化
if(size==0)return 0XFFFFFFFF;//不需要分配
nmemb=size/exmemblksize; //获取需要分配的连续内存块数
if(size%exmemblksize)nmemb++;
for(offset=exmemtblsize-1;offset>=0;offset--)//搜索整个内存控制区
{
if(!exmallco_dev.memmap[offset])cmemb++;//连续空内存块数增加
else cmemb=0; //连续内存块清零
if(cmemb==nmemb) //找到了连续nmemb个空内存块
{
for(i=0;i<nmemb;i++) //标注内存块非空
{
exmallco_dev.memmap[offset+i]=nmemb;
}
return (offset*exmemblksize);//返回偏移地址
}
}
return 0XFFFFFFFF;//未找到符合分配条件的内存块
}
//释放内存(内部调用)
//memx:所属内存块
//offset:内存地址偏移
//返回值:0,释放成功;1,释放失败;
static u8 exmem_free(u32 offset)
{
u32 i;
if(!exmallco_dev.memrdy)//未初始化,先执行初始化
{
//mallco_dev.init();
return 1;//未初始化
}
if(offset<exmemsize)//偏移在内存池内.
{
u32 index=offset/exmemblksize; //偏移所在内存块号码
u32 nmemb=exmallco_dev.memmap[index]; //内存块数量
for(i=0;i<nmemb;i++) //内存块清零
{
exmallco_dev.memmap[index+i]=0;
}
return 0;
}else return 2;//偏移超区了.
}
//------------------------------------内部SRAM---------------------------------------
#define SRAM_USER_SIZE (120*1024)
u8 g_sram_mem[SRAM_USER_SIZE];
#define MEM_BLOCK_SIZE (32) //内存块大小为64字节
#define MEM_MAX_SIZE (((SRAM_USER_SIZE))*MEM_BLOCK_SIZE/(MEM_BLOCK_SIZE+2))
#define MEM_ALLOC_TABLE_SIZE ((MEM_MAX_SIZE/MEM_BLOCK_SIZE)&(~3)) //内存表大小,必须为偶数,双字对齐
#define SRAM_USER_ADDR ((u32)g_sram_mem)
//分配的内存都是双字对齐的
#define MEM_BASE ((u8 *)(SRAM_USER_ADDR+MEM_ALLOC_TABLE_SIZE*2))
#define MEMMAP_BASE ((u16 *)(SRAM_USER_ADDR))
//内存管理参数
u32 memtblsize ; //内存表大小
u32 memblksize; //内存分块大小
u32 memsize ; //内存总大小
//内存管理控制器
struct _m_mallco_dev mallco_dev;
//内存管理初始化
//memx:所属内存块
static void mem_init(void)
{
memtblsize = MEM_ALLOC_TABLE_SIZE; //内存表大小
memblksize = MEM_BLOCK_SIZE; //内存分块大小
memsize = MEM_MAX_SIZE; //内存总大小
// mallco_dev.init=mem_init; //内存初始化
// mallco_dev.perused=mem_perused; //内存使用率
mallco_dev.membase=MEM_BASE; //内存池
mallco_dev.memmap=MEMMAP_BASE; //内存管理状态表
mallco_dev.memrdy=0; //内存管理未就绪
mymemset(mallco_dev.memmap, 0,memtblsize*2);//内存状态表数据清零
mymemset(mallco_dev.membase, 0,memsize); //内存池所有数据清零
mallco_dev.memrdy=1; //内存管理初始化OK
}
//获取内存使用率
//memx:所属内存块
//返回值:使用率(0~100)
int mem_perused(void)
{
u32 used=0;
u32 i;
for(i=0;i<memtblsize;i++)
{
if(mallco_dev.memmap[i])used++;
}
return (used*10000)/(memtblsize);
}
//内存分配(内部调用)
//memx:所属内存块
//size:要分配的内存大小(字节)
//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
static u32 mem_malloc(u32 size)
{
signed long offset=0;
u16 nmemb; //需要的内存块数
u16 cmemb=0;//连续空内存块数
u32 i;
// if(!mallco_dev.memrdy)mallco_dev.init();//未初始化,先执行初始化
if(size==0)return 0XFFFFFFFF;//不需要分配
nmemb=size/memblksize; //获取需要分配的连续内存块数
if(size%memblksize)nmemb++;
for(offset=memtblsize-1;offset>=0;offset--)//搜索整个内存控制区
{
if(!mallco_dev.memmap[offset])cmemb++;//连续空内存块数增加
else cmemb=0; //连续内存块清零
if(cmemb==nmemb) //找到了连续nmemb个空内存块
{
for(i=0;i<nmemb;i++) //标注内存块非空
{
mallco_dev.memmap[offset+i]=nmemb;
}
return (offset*memblksize);//返回偏移地址
}
}
return 0XFFFFFFFF;//未找到符合分配条件的内存块
}
//释放内存(内部调用)
//memx:所属内存块
//offset:内存地址偏移
//返回值:0,释放成功;1,释放失败;
static u8 mem_free(u32 offset)
{
int i;
if(!mallco_dev.memrdy)//未初始化,先执行初始化
{
//mallco_dev.init();
return 1;//未初始化
}
if(offset<exmemsize)//偏移在内存池内.
{
int index=offset/memblksize; //偏移所在内存块号码
int nmemb=mallco_dev.memmap[index]; //内存块数量
for(i=0;i<nmemb;i++) //内存块清零
{
mallco_dev.memmap[index+i]=0;
}
return 0;
}else return 2;//偏移超区了.
}
//------------------------------------内部CCM---------------------------------------
#if USE_CCM==1
#define CCM_USER_SIZE 64*1024
u8 g_ccm_mem[CCM_USER_SIZE] __attribute__((at(0x10000000)));
#define CCM_BLOCK_SIZE (32) //内存块大小为64字节
#define CCM_MAX_SIZE (((CCM_USER_SIZE))*CCM_BLOCK_SIZE/(CCM_BLOCK_SIZE+2))
#define CCM_ALLOC_TABLE_SIZE ((CCM_MAX_SIZE/CCM_BLOCK_SIZE)&(~3)) //内存表大小,必须为偶数,双字对齐
#define CCM_USER_ADDR ((u32)g_ccm_mem)
//分配的内存都是双字对齐的
#define CCM_BASE ((u8 *)(CCM_USER_ADDR+CCM_ALLOC_TABLE_SIZE*2))
#define CCMMAP_BASE ((u16 *)(CCM_USER_ADDR))
//内存管理参数
u32 ccm_memtblsize ; //内存表大小
u32 ccm_memblksize; //内存分块大小
u32 ccm_memsize ; //内存总大小
//内存管理控制器
struct _m_mallco_dev ccm_mallco_dev;
//内存管理初始化
//memx:所属内存块
static void ccm_init(void)
{
ccm_memtblsize = CCM_ALLOC_TABLE_SIZE; //内存表大小
ccm_memblksize = CCM_BLOCK_SIZE; //内存分块大小
ccm_memsize = CCM_MAX_SIZE; //内存总大小
ccm_mallco_dev.membase=CCM_BASE; //内存池
ccm_mallco_dev.memmap=CCMMAP_BASE; //内存管理状态表
ccm_mallco_dev.memrdy=0; //内存管理未就绪
mymemset(ccm_mallco_dev.memmap, 0,ccm_memtblsize*2);//内存状态表数据清零
mymemset(ccm_mallco_dev.membase, 0,ccm_memsize); //内存池所有数据清零
ccm_mallco_dev.memrdy=1; //内存管理初始化OK
}
//获取内存使用率
//memx:所属内存块
//返回值:使用率(0~100)
int ccm_perused(void)
{
u32 used=0;
u32 i;
for(i=0;i<ccm_memtblsize;i++)
{
if(ccm_mallco_dev.memmap[i])used++;
}
return (used*10000)/(ccm_memtblsize);
}
//内存分配(内部调用)
//memx:所属内存块
//size:要分配的内存大小(字节)
//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
static u32 ccm_malloc(u32 size)
{
signed long offset=0;
u16 nmemb; //需要的内存块数
u16 cmemb=0;//连续空内存块数
u32 i;
// if(!mallco_dev.memrdy)mallco_dev.init();//未初始化,先执行初始化
if(size==0)return 0XFFFFFFFF;//不需要分配
nmemb=size/ccm_memblksize; //获取需要分配的连续内存块数
if(size%ccm_memblksize)nmemb++;
for(offset=ccm_memtblsize-1;offset>=0;offset--)//搜索整个内存控制区
{
if(!ccm_mallco_dev.memmap[offset])cmemb++;//连续空内存块数增加
else cmemb=0; //连续内存块清零
if(cmemb==nmemb) //找到了连续nmemb个空内存块
{
for(i=0;i<nmemb;i++) //标注内存块非空
{
ccm_mallco_dev.memmap[offset+i]=nmemb;
}
return (offset*ccm_memblksize);//返回偏移地址
}
}
return 0XFFFFFFFF;//未找到符合分配条件的内存块
}
//释放内存(内部调用)
//memx:所属内存块
//offset:内存地址偏移
//返回值:0,释放成功;1,释放失败;
static u8 ccm_free(u32 offset)
{
int i;
if(!ccm_mallco_dev.memrdy)//未初始化,先执行初始化
{
//mallco_dev.init();
return 1;//未初始化
}
if(offset<exmemsize)//偏移在内存池内.
{
int index=offset/ccm_memblksize; //偏移所在内存块号码
int nmemb=ccm_mallco_dev.memmap[index]; //内存块数量
for(i=0;i<nmemb;i++) //内存块清零
{
ccm_mallco_dev.memmap[index+i]=0;
}
return 0;
}else return 2;//偏移超区了.
}
#endif
//释放内存(外部调用)
//memx:所属内存块
//ptr:内存首地址
void myfree(void *ptr)
{
IRQ_DISABLE();
u32 free_addr=(u32)ptr;
u32 offset;
if(ptr==NULL)
{
IRQ_ENABLE();
return;//地址为0.
}
else if ((free_addr&0xf0000000)==0x20000000)//sram
{
offset=(u32)ptr-(u32)mallco_dev.membase;
mem_free(offset);//释放内存
}
else
{
offset=(u32)ptr-(u32)exmallco_dev.membase;
exmem_free(offset);//释放内存
}
//printf ("free:%#X\r\n",free_addr);
IRQ_ENABLE();
}
//分配内存(外部调用)
//首先尝试在内部分配,失败后再外部分配
//size:内存大小(字节)
//返回值:分配到的内存首地址.
void *mymalloc(u32 size)
{
IRQ_DISABLE();
u32 offset;
void *ret_addr=NULL;
if (size>5*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);
}