569 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			569 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #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 (110 * 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(size_t 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); }
 | 
