You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

274 lines
9.0 KiB

3 years ago
  1. /**
  2. ****************************************************************************************************
  3. * @file malloc.c
  4. * @author (ALIENTEK)
  5. * @version V1.0
  6. * @date 2021-11-04
  7. * @brief
  8. * @license Copyright (c) 2020-2032, 广
  9. ****************************************************************************************************
  10. * @attention
  11. *
  12. * : STM32开发板
  13. * 线:www.yuanzige.com
  14. * :www.openedv.com
  15. * :www.alientek.com
  16. * :openedv.taobao.com
  17. *
  18. *
  19. * V1.0 20211104
  20. *
  21. *
  22. ****************************************************************************************************
  23. */
  24. #include "./MALLOC/malloc.h"
  25. #if !(__ARMCC_VERSION >= 6010050) /* 不是AC6编译器,即使用AC5编译器时 */
  26. /* 内存池(64字节对齐) */
  27. static __align(64) uint8_t mem1base[MEM1_MAX_SIZE]; /* 内部SRAM内存池 */
  28. static __align(64) uint8_t mem2base[MEM2_MAX_SIZE] __attribute__((at(0x10000000))); /* 内部CCM内存池 */
  29. static __align(64) uint8_t mem3base[MEM3_MAX_SIZE] __attribute__((at(0x68000000))); /* 外部SRAM内存池 */
  30. /* 内存管理表 */
  31. static MT_TYPE mem1mapbase[MEM1_ALLOC_TABLE_SIZE]; /* 内部SRAM内存池MAP */
  32. static MT_TYPE mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((at(0x10000000 + MEM2_MAX_SIZE))); /* 内部CCM内存池MAP */
  33. static MT_TYPE mem3mapbase[MEM3_ALLOC_TABLE_SIZE] __attribute__((at(0x68000000 + MEM3_MAX_SIZE))); /* 外部SRAM内存池MAP */
  34. #else /* 使用AC6编译器时 */
  35. /* 内存池(64字节对齐) */
  36. static __ALIGNED(64) uint8_t mem1base[MEM1_MAX_SIZE]; /* 内部SRAM内存池 */
  37. static __ALIGNED(64) uint8_t mem2base[MEM2_MAX_SIZE] __attribute__((section(".bss.ARM.__at_0x10000000"))); /* 内部CCM内存池 */
  38. static __ALIGNED(64) uint8_t mem3base[MEM3_MAX_SIZE] __attribute__((section(".bss.ARM.__at_0x68000000"))); /* 外部SRAM内存池 */
  39. /* 内存管理表 */
  40. static MT_TYPE mem1mapbase[MEM1_ALLOC_TABLE_SIZE]; /* 内部SRAM内存池MAP */
  41. static MT_TYPE mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((section(".bss.ARM.__at_0x1000F000"))); /* 内部CCM内存池MAP */
  42. static MT_TYPE mem3mapbase[MEM3_ALLOC_TABLE_SIZE] __attribute__((section(".bss.ARM.__at_0x680F0C00"))); /* 外部SRAM内存池MAP */
  43. #endif
  44. /* 内存管理参数 */
  45. const uint32_t memtblsize[SRAMBANK] = {MEM1_ALLOC_TABLE_SIZE, MEM2_ALLOC_TABLE_SIZE, MEM3_ALLOC_TABLE_SIZE}; /* 内存表大小 */
  46. const uint32_t memblksize[SRAMBANK] = {MEM1_BLOCK_SIZE, MEM2_BLOCK_SIZE, MEM3_BLOCK_SIZE}; /* 内存分块大小 */
  47. const uint32_t memsize[SRAMBANK] = {MEM1_MAX_SIZE, MEM2_MAX_SIZE, MEM3_MAX_SIZE}; /* 内存总大小 */
  48. /* 内存管理控制器 */
  49. struct _m_mallco_dev mallco_dev =
  50. {
  51. my_mem_init, /* 内存初始化 */
  52. my_mem_perused, /* 内存使用率 */
  53. mem1base, mem2base, mem3base, /* 内存池 */
  54. mem1mapbase, mem2mapbase, mem3mapbase, /* 内存管理状态表 */
  55. 0, 0, 0, /* 内存管理未就绪 */
  56. };
  57. /**
  58. * @brief
  59. * @param *des :
  60. * @param *src :
  61. * @param n : ()
  62. * @retval
  63. */
  64. void my_mem_copy(void *des, void *src, uint32_t n)
  65. {
  66. uint8_t *xdes = des;
  67. uint8_t *xsrc = src;
  68. while (n--)*xdes++ = *xsrc++;
  69. }
  70. /**
  71. * @brief
  72. * @param *s :
  73. * @param c :
  74. * @param count : ()
  75. * @retval
  76. */
  77. void my_mem_set(void *s, uint8_t c, uint32_t count)
  78. {
  79. uint8_t *xs = s;
  80. while (count--)*xs++ = c;
  81. }
  82. /**
  83. * @brief
  84. * @param memx :
  85. * @retval
  86. */
  87. void my_mem_init(uint8_t memx)
  88. {
  89. uint8_t mttsize = sizeof(MT_TYPE); /* 获取memmap数组的类型长度(uint16_t /uint32_t)*/
  90. my_mem_set(mallco_dev.memmap[memx], 0, memtblsize[memx]*mttsize); /* 内存状态表数据清零 */
  91. mallco_dev.memrdy[memx] = 1; /* 内存管理初始化OK */
  92. }
  93. /**
  94. * @brief 使
  95. * @param memx :
  96. * @retval 使(10,0~1000,0.0%~100.0%)
  97. */
  98. uint16_t my_mem_perused(uint8_t memx)
  99. {
  100. uint32_t used = 0;
  101. uint32_t i;
  102. for (i = 0; i < memtblsize[memx]; i++)
  103. {
  104. if (mallco_dev.memmap[memx][i])used++;
  105. }
  106. return (used * 1000) / (memtblsize[memx]);
  107. }
  108. /**
  109. * @brief ()
  110. * @param memx :
  111. * @param size : ()
  112. * @retval
  113. * @arg 0 ~ 0xFFFFFFFE :
  114. * @arg 0xFFFFFFFF :
  115. */
  116. static uint32_t my_mem_malloc(uint8_t memx, uint32_t size)
  117. {
  118. signed long offset = 0;
  119. uint32_t nmemb; /* 需要的内存块数 */
  120. uint32_t cmemb = 0; /* 连续空内存块数 */
  121. uint32_t i;
  122. if (!mallco_dev.memrdy[memx])
  123. {
  124. mallco_dev.init(memx); /* 未初始化,先执行初始化 */
  125. }
  126. if (size == 0) return 0xFFFFFFFF; /* 不需要分配 */
  127. nmemb = size / memblksize[memx]; /* 获取需要分配的连续内存块数 */
  128. if (size % memblksize[memx]) nmemb++;
  129. for (offset = memtblsize[memx] - 1; offset >= 0; offset--) /* 搜索整个内存控制区 */
  130. {
  131. if (!mallco_dev.memmap[memx][offset])
  132. {
  133. cmemb++; /* 连续空内存块数增加 */
  134. }
  135. else
  136. {
  137. cmemb = 0; /* 连续内存块清零 */
  138. }
  139. if (cmemb == nmemb) /* 找到了连续nmemb个空内存块 */
  140. {
  141. for (i = 0; i < nmemb; i++) /* 标注内存块非空 */
  142. {
  143. mallco_dev.memmap[memx][offset + i] = nmemb;
  144. }
  145. return (offset * memblksize[memx]); /* 返回偏移地址 */
  146. }
  147. }
  148. return 0xFFFFFFFF; /* 未找到符合分配条件的内存块 */
  149. }
  150. /**
  151. * @brief ()
  152. * @param memx :
  153. * @param offset :
  154. * @retval
  155. * @arg 0, ;
  156. * @arg 1, ;
  157. * @arg 2, ();
  158. */
  159. static uint8_t my_mem_free(uint8_t memx, uint32_t offset)
  160. {
  161. int i;
  162. if (!mallco_dev.memrdy[memx]) /* 未初始化,先执行初始化 */
  163. {
  164. mallco_dev.init(memx);
  165. return 1; /* 未初始化 */
  166. }
  167. if (offset < memsize[memx]) /* 偏移在内存池内. */
  168. {
  169. int index = offset / memblksize[memx]; /* 偏移所在内存块号码 */
  170. int nmemb = mallco_dev.memmap[memx][index]; /* 内存块数量 */
  171. for (i = 0; i < nmemb; i++) /* 内存块清零 */
  172. {
  173. mallco_dev.memmap[memx][index + i] = 0;
  174. }
  175. return 0;
  176. }
  177. else
  178. {
  179. return 2; /* 偏移超区了. */
  180. }
  181. }
  182. /**
  183. * @brief ()
  184. * @param memx :
  185. * @param ptr :
  186. * @retval
  187. */
  188. void myfree(uint8_t memx, void *ptr)
  189. {
  190. uint32_t offset;
  191. if (ptr == NULL)return; /* 地址为0. */
  192. offset = (uint32_t)ptr - (uint32_t)mallco_dev.membase[memx];
  193. my_mem_free(memx, offset); /* 释放内存 */
  194. }
  195. /**
  196. * @brief ()
  197. * @param memx :
  198. * @param size : ()
  199. * @retval .
  200. */
  201. void *mymalloc(uint8_t memx, uint32_t size)
  202. {
  203. uint32_t offset;
  204. offset = my_mem_malloc(memx, size);
  205. if (offset == 0xFFFFFFFF) /* 申请出错 */
  206. {
  207. return NULL; /* 返回空(0) */
  208. }
  209. else /* 申请没问题, 返回首地址 */
  210. {
  211. return (void *)((uint32_t)mallco_dev.membase[memx] + offset);
  212. }
  213. }
  214. /**
  215. * @brief ()
  216. * @param memx :
  217. * @param *ptr :
  218. * @param size : ()
  219. * @retval .
  220. */
  221. void *myrealloc(uint8_t memx, void *ptr, uint32_t size)
  222. {
  223. uint32_t offset;
  224. offset = my_mem_malloc(memx, size);
  225. if (offset == 0xFFFFFFFF) /* 申请出错 */
  226. {
  227. return NULL; /* 返回空(0) */
  228. }
  229. else /* 申请没问题, 返回首地址 */
  230. {
  231. my_mem_copy((void *)((uint32_t)mallco_dev.membase[memx] + offset), ptr, size); /* 拷贝旧内存内容到新内存 */
  232. myfree(memx, ptr); /* 释放旧内存 */
  233. return (void *)((uint32_t)mallco_dev.membase[memx] + offset); /* 返回新内存首地址 */
  234. }
  235. }