myMalloc.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #include "main.h"
  2. static void mymemcpy(void *des,void *src,uint32_t n);
  3. static void mymemset(void *s,uint8_t c,uint32_t count);
  4. static uint8_t mem_perused(void);
  5. #ifndef NULL
  6. #define NULL 0
  7. #endif
  8. #define MEM_BLOCK_SIZE 32 //内存块大小为32字节
  9. #define MEM_MAX_SIZE 2048 //最大管理内存 2K
  10. #define MEM_ALLOC_TABLE_SIZE MEM_MAX_SIZE/MEM_BLOCK_SIZE //内存表大小
  11. //内存池(4字节对齐)
  12. __align(4) uint8_t membase[MEM_MAX_SIZE]; //内部SRAM内存池
  13. //内存管理表
  14. uint16_t memmapbase[MEM_ALLOC_TABLE_SIZE]; //内部SRAM内存池MAP
  15. //内存管理参数
  16. const uint32_t memtblsize = MEM_ALLOC_TABLE_SIZE; //内存表大小
  17. const uint32_t memblksize = MEM_BLOCK_SIZE; //内存分块大小
  18. const uint32_t memsize = MEM_MAX_SIZE; //内存总大小
  19. //内存管理控制器
  20. struct _m_mallco_dev mallco_dev=
  21. {
  22. mem_init, //内存初始化
  23. mem_perused, //内存使用率
  24. membase, //内存池
  25. memmapbase, //内存管理状态表
  26. 0, //内存管理未就绪
  27. };
  28. //复制内存
  29. //*des:目的地址
  30. //*src:源地址
  31. //n:需要复制的内存长度(字节为单位)
  32. static void mymemcpy(void *des,void *src,uint32_t n)
  33. {
  34. uint8_t *xdes=des;
  35. uint8_t *xsrc=src;
  36. while(n--)*xdes++=*xsrc++;
  37. }
  38. //设置内存
  39. //*s:内存首地址
  40. //c :要设置的值
  41. //count:需要设置的内存大小(字节为单位)
  42. static void mymemset(void *s,uint8_t c,uint32_t count)
  43. {
  44. uint8_t *xs = s;
  45. while(count--)*xs++=c;
  46. }
  47. //获取内存使用率
  48. //memx:所属内存块
  49. //返回值:使用率(0~100)
  50. static uint8_t mem_perused(void)
  51. {
  52. uint32_t used=0;
  53. uint32_t i;
  54. for(i=0;i<memtblsize;i++)
  55. {
  56. if(mallco_dev.memmap[i])used++;
  57. }
  58. return (used*100)/(memtblsize);
  59. }
  60. //内存分配(内部调用)
  61. //memx:所属内存块
  62. //size:要分配的内存大小(字节)
  63. //返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
  64. static uint32_t mem_malloc(uint32_t size)
  65. {
  66. signed long offset=0;
  67. uint16_t nmemb; //需要的内存块数
  68. uint16_t cmemb=0;//连续空内存块数
  69. uint32_t i;
  70. if(!mallco_dev.memrdy)mallco_dev.init();//未初始化,先执行初始化
  71. if(size==0)return 0XFFFFFFFF;//不需要分配
  72. nmemb=size/memblksize; //获取需要分配的连续内存块数
  73. if(size%memblksize)nmemb++;
  74. for(offset=memtblsize-1;offset>=0;offset--)//搜索整个内存控制区
  75. {
  76. if(!mallco_dev.memmap[offset])cmemb++;//连续空内存块数增加
  77. else cmemb=0; //连续内存块清零
  78. if(cmemb==nmemb) //找到了连续nmemb个空内存块
  79. {
  80. for(i=0;i<nmemb;i++) //标注内存块非空
  81. {
  82. mallco_dev.memmap[offset+i]=nmemb;
  83. }
  84. return (offset*memblksize);//返回偏移地址
  85. }
  86. }
  87. return 0XFFFFFFFF;//未找到符合分配条件的内存块
  88. }
  89. //释放内存(内部调用)
  90. //memx:所属内存块
  91. //offset:内存地址偏移
  92. //返回值:0,释放成功;1,释放失败;
  93. static uint8_t mem_free(uint32_t offset)
  94. {
  95. int i;
  96. if(!mallco_dev.memrdy)//未初始化,先执行初始化
  97. {
  98. mallco_dev.init();
  99. return 1;//未初始化
  100. }
  101. if(offset<memsize)//偏移在内存池内.
  102. {
  103. int index=offset/memblksize; //偏移所在内存块号码
  104. int nmemb=mallco_dev.memmap[index]; //内存块数量
  105. for(i=0;i<nmemb;i++) //内存块清零
  106. {
  107. mallco_dev.memmap[index+i]=0;
  108. }
  109. return 0;
  110. }else return 2;//偏移超区了.
  111. }
  112. //内存管理初始化
  113. //memx:所属内存块
  114. void mem_init(void)
  115. {
  116. mymemset(mallco_dev.memmap, 0,memtblsize*2);//内存状态表数据清零
  117. mymemset(mallco_dev.membase, 0,memsize); //内存池所有数据清零
  118. mallco_dev.memrdy=1; //内存管理初始化OK
  119. }
  120. //释放内存(外部调用)
  121. //memx:所属内存块
  122. //ptr:内存首地址
  123. void myfree(void *ptr)
  124. {
  125. uint32_t offset;
  126. if(ptr==NULL)return;//地址为0.
  127. offset=(uint32_t)ptr-(uint32_t)mallco_dev.membase;
  128. mem_free(offset);//释放内存
  129. }
  130. //分配内存(外部调用)
  131. //memx:所属内存块
  132. //size:内存大小(字节)
  133. //返回值:分配到的内存首地址.
  134. void *mymalloc(uint32_t size)
  135. {
  136. uint32_t offset;
  137. offset=mem_malloc(size);
  138. if(offset==0XFFFFFFFF)return NULL;
  139. else return (void*)((uint32_t)mallco_dev.membase+offset);
  140. }
  141. //重新分配内存(外部调用)
  142. //memx:所属内存块
  143. //*ptr:旧内存首地址
  144. //size:要分配的内存大小(字节)
  145. //返回值:新分配到的内存首地址.
  146. void *myrealloc(void *ptr,uint32_t size)
  147. {
  148. uint32_t offset;
  149. offset=mem_malloc(size);
  150. if(offset==0XFFFFFFFF)return NULL;
  151. else
  152. {
  153. mymemcpy((void*)((uint32_t)mallco_dev.membase+offset),ptr,size); //拷贝旧内存内容到新内存
  154. myfree(ptr); //释放旧内存
  155. return (void*)((uint32_t)mallco_dev.membase+offset); //返回新内存首地址
  156. }
  157. }