mempool.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /*
  2. * Copyright (c) 2018 Intel Corporation
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <kernel.h>
  7. #include <string.h>
  8. #include "wrapper.h"
  9. #define TIME_OUT_TICKS 10
  10. K_MEM_SLAB_DEFINE(cv2_mem_slab, sizeof(struct cv2_mslab),
  11. CONFIG_CMSIS_V2_MEM_SLAB_MAX_COUNT, 4);
  12. static const osMemoryPoolAttr_t init_mslab_attrs = {
  13. .name = "ZephyrMemPool",
  14. .attr_bits = 0,
  15. .cb_mem = NULL,
  16. .cb_size = 0,
  17. .mp_mem = NULL,
  18. .mp_size = 0,
  19. };
  20. /**
  21. * @brief Create and Initialize a memory pool.
  22. */
  23. osMemoryPoolId_t osMemoryPoolNew(uint32_t block_count, uint32_t block_size,
  24. const osMemoryPoolAttr_t *attr)
  25. {
  26. struct cv2_mslab *mslab;
  27. BUILD_ASSERT(CONFIG_HEAP_MEM_POOL_SIZE >=
  28. CONFIG_CMSIS_V2_MEM_SLAB_MAX_DYNAMIC_SIZE,
  29. "heap must be configured to be at least the max dynamic size");
  30. if (k_is_in_isr()) {
  31. return NULL;
  32. }
  33. if ((attr != NULL) && (attr->mp_size < block_count * block_size)) {
  34. return NULL;
  35. }
  36. if (attr == NULL) {
  37. attr = &init_mslab_attrs;
  38. }
  39. if (k_mem_slab_alloc(&cv2_mem_slab, (void **)&mslab, K_MSEC(100)) == 0) {
  40. (void)memset(mslab, 0, sizeof(struct cv2_mslab));
  41. } else {
  42. return NULL;
  43. }
  44. if (attr->mp_mem == NULL) {
  45. __ASSERT((block_count * block_size) <=
  46. CONFIG_CMSIS_V2_MEM_SLAB_MAX_DYNAMIC_SIZE,
  47. "memory slab/pool size exceeds dynamic maximum");
  48. mslab->pool = k_calloc(block_count, block_size);
  49. if (mslab->pool == NULL) {
  50. k_mem_slab_free(&cv2_mem_slab, (void *) &mslab);
  51. return NULL;
  52. }
  53. mslab->is_dynamic_allocation = TRUE;
  54. } else {
  55. mslab->pool = attr->mp_mem;
  56. mslab->is_dynamic_allocation = FALSE;
  57. }
  58. k_mem_slab_init(&mslab->z_mslab, mslab->pool, block_size, block_count);
  59. if (attr->name == NULL) {
  60. strncpy(mslab->name, init_mslab_attrs.name,
  61. sizeof(mslab->name) - 1);
  62. } else {
  63. strncpy(mslab->name, attr->name, sizeof(mslab->name) - 1);
  64. }
  65. return (osMemoryPoolId_t)mslab;
  66. }
  67. /**
  68. * @brief Allocate a memory block from a memory pool.
  69. */
  70. void *osMemoryPoolAlloc(osMemoryPoolId_t mp_id, uint32_t timeout)
  71. {
  72. struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;
  73. int retval;
  74. void *ptr;
  75. if (mslab == NULL) {
  76. return NULL;
  77. }
  78. /* Can be called from ISRs only if timeout is set to 0 */
  79. if (timeout > 0 && k_is_in_isr()) {
  80. return NULL;
  81. }
  82. if (timeout == 0U) {
  83. retval = k_mem_slab_alloc(
  84. (struct k_mem_slab *)(&mslab->z_mslab),
  85. (void **)&ptr, K_NO_WAIT);
  86. } else if (timeout == osWaitForever) {
  87. retval = k_mem_slab_alloc(
  88. (struct k_mem_slab *)(&mslab->z_mslab),
  89. (void **)&ptr, K_FOREVER);
  90. } else {
  91. retval = k_mem_slab_alloc(
  92. (struct k_mem_slab *)(&mslab->z_mslab),
  93. (void **)&ptr, K_TICKS(timeout));
  94. }
  95. if (retval == 0) {
  96. return ptr;
  97. } else {
  98. return NULL;
  99. }
  100. }
  101. /**
  102. * @brief Return an allocated memory block back to a specific memory pool.
  103. */
  104. osStatus_t osMemoryPoolFree(osMemoryPoolId_t mp_id, void *block)
  105. {
  106. struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;
  107. if (mslab == NULL) {
  108. return osErrorParameter;
  109. }
  110. /* Note: Below error code is not supported.
  111. * osErrorResource: the memory pool specified by parameter mp_id
  112. * is in an invalid memory pool state.
  113. */
  114. k_mem_slab_free((struct k_mem_slab *)(&mslab->z_mslab), (void *)&block);
  115. return osOK;
  116. }
  117. /**
  118. * @brief Get name of a Memory Pool object.
  119. */
  120. const char *osMemoryPoolGetName(osMemoryPoolId_t mp_id)
  121. {
  122. struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;
  123. if (!k_is_in_isr() && (mslab != NULL)) {
  124. return mslab->name;
  125. } else {
  126. return NULL;
  127. }
  128. }
  129. /**
  130. * @brief Get maximum number of memory blocks in a Memory Pool.
  131. */
  132. uint32_t osMemoryPoolGetCapacity(osMemoryPoolId_t mp_id)
  133. {
  134. struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;
  135. if (mslab == NULL) {
  136. return 0;
  137. } else {
  138. return mslab->z_mslab.num_blocks;
  139. }
  140. }
  141. /**
  142. * @brief Get memory block size in a Memory Pool.
  143. */
  144. uint32_t osMemoryPoolGetBlockSize(osMemoryPoolId_t mp_id)
  145. {
  146. struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;
  147. if (mslab == NULL) {
  148. return 0;
  149. } else {
  150. return mslab->z_mslab.block_size;
  151. }
  152. }
  153. /**
  154. * @brief Get number of memory blocks used in a Memory Pool.
  155. */
  156. uint32_t osMemoryPoolGetCount(osMemoryPoolId_t mp_id)
  157. {
  158. struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;
  159. if (mslab == NULL) {
  160. return 0;
  161. } else {
  162. return k_mem_slab_num_used_get(&mslab->z_mslab);
  163. }
  164. }
  165. /**
  166. * @brief Get number of memory blocks available in a Memory Pool.
  167. */
  168. uint32_t osMemoryPoolGetSpace(osMemoryPoolId_t mp_id)
  169. {
  170. struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;
  171. if (mslab == NULL) {
  172. return 0;
  173. } else {
  174. return k_mem_slab_num_free_get(&mslab->z_mslab);
  175. }
  176. }
  177. /**
  178. * @brief Delete a Memory Pool object.
  179. */
  180. osStatus_t osMemoryPoolDelete(osMemoryPoolId_t mp_id)
  181. {
  182. struct cv2_mslab *mslab = (struct cv2_mslab *)mp_id;
  183. if (mslab == NULL) {
  184. return osErrorParameter;
  185. }
  186. if (k_is_in_isr()) {
  187. return osErrorISR;
  188. }
  189. /* The status code "osErrorResource" (the memory pool specified by
  190. * parameter mp_id is in an invalid memory pool state) is not
  191. * supported in Zephyr.
  192. */
  193. if (mslab->is_dynamic_allocation) {
  194. k_free(mslab->pool);
  195. }
  196. k_mem_slab_free(&cv2_mem_slab, (void *)&mslab);
  197. return osOK;
  198. }