rtx_mempool.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. /*
  2. * Copyright (c) 2013-2017 ARM Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * -----------------------------------------------------------------------------
  19. *
  20. * Project: CMSIS-RTOS RTX
  21. * Title: Memory Pool functions
  22. *
  23. * -----------------------------------------------------------------------------
  24. */
  25. #include "rtx_lib.h"
  26. // ==== Library functions ====
  27. /// Initialize Memory Pool.
  28. /// \param[in] mp_info memory pool info.
  29. /// \param[in] block_count maximum number of memory blocks in memory pool.
  30. /// \param[in] block_size size of a memory block in bytes.
  31. /// \param[in] block_mem pointer to memory for block storage.
  32. /// \return 1 - success, 0 - failure.
  33. uint32_t osRtxMemoryPoolInit (os_mp_info_t *mp_info, uint32_t block_count, uint32_t block_size, void *block_mem) {
  34. void *block;
  35. // Check parameters
  36. if ((mp_info == NULL) || (block_count == 0U) || (block_size == 0U) || (block_mem == NULL)) {
  37. return 0U;
  38. }
  39. // Initialize information structure
  40. mp_info->max_blocks = block_count;
  41. mp_info->used_blocks = 0U;
  42. mp_info->block_size = block_size;
  43. mp_info->block_base = block_mem;
  44. mp_info->block_free = block_mem;
  45. mp_info->block_lim = (uint8_t *)block_mem + (block_count * block_size);
  46. EvrRtxMemoryBlockInit(mp_info, block_count, block_size, block_mem);
  47. // Link all free blocks
  48. while (--block_count) {
  49. block = (uint8_t *)block_mem + block_size;
  50. *((void **)block_mem) = block;
  51. block_mem = block;
  52. }
  53. *((void **)block_mem) = NULL;
  54. return 1U;
  55. }
  56. /// Allocate a memory block from a Memory Pool.
  57. /// \param[in] mp_info memory pool info.
  58. /// \return address of the allocated memory block or NULL in case of no memory is available.
  59. void *osRtxMemoryPoolAlloc (os_mp_info_t *mp_info) {
  60. #if (__EXCLUSIVE_ACCESS == 0U)
  61. uint32_t primask = __get_PRIMASK();
  62. #endif
  63. void *block;
  64. if (mp_info == NULL) {
  65. EvrRtxMemoryBlockAlloc(NULL, NULL);
  66. return NULL;
  67. }
  68. #if (__EXCLUSIVE_ACCESS == 0U)
  69. __disable_irq();
  70. if (mp_info->used_blocks < mp_info->max_blocks) {
  71. mp_info->used_blocks++;
  72. block = mp_info->block_free;
  73. if (block != NULL) {
  74. mp_info->block_free = *((void **)block);
  75. }
  76. } else {
  77. block = NULL;
  78. }
  79. if (primask == 0U) {
  80. __enable_irq();
  81. }
  82. #else
  83. if (atomic_inc32_lt(&mp_info->used_blocks, mp_info->max_blocks) < mp_info->max_blocks) {
  84. block = atomic_link_get(&mp_info->block_free);
  85. } else {
  86. block = NULL;
  87. }
  88. #endif
  89. EvrRtxMemoryBlockAlloc(mp_info, block);
  90. return block;
  91. }
  92. /// Return an allocated memory block back to a Memory Pool.
  93. /// \param[in] mp_info memory pool info.
  94. /// \param[in] block address of the allocated memory block to be returned to the memory pool.
  95. /// \return status code that indicates the execution status of the function.
  96. osStatus_t osRtxMemoryPoolFree (os_mp_info_t *mp_info, void *block) {
  97. #if (__EXCLUSIVE_ACCESS == 0U)
  98. uint32_t primask = __get_PRIMASK();
  99. #endif
  100. osStatus_t status;
  101. if ((mp_info == NULL) || (block < mp_info->block_base) || (block >= mp_info->block_lim)) {
  102. EvrRtxMemoryBlockFree(mp_info, block, osErrorParameter);
  103. return osErrorParameter;
  104. }
  105. #if (__EXCLUSIVE_ACCESS == 0U)
  106. __disable_irq();
  107. if (mp_info->used_blocks != 0U) {
  108. mp_info->used_blocks--;
  109. *((void **)block) = mp_info->block_free;
  110. mp_info->block_free = block;
  111. status = osOK;
  112. } else {
  113. status = osErrorResource;
  114. }
  115. if (primask == 0U) {
  116. __enable_irq();
  117. }
  118. #else
  119. if (atomic_dec32_nz(&mp_info->used_blocks) != 0U) {
  120. atomic_link_put(&mp_info->block_free, block);
  121. status = osOK;
  122. } else {
  123. status = osErrorResource;
  124. }
  125. #endif
  126. EvrRtxMemoryBlockFree(mp_info, block, status);
  127. return status;
  128. }
  129. /// Memory Pool post ISR processing.
  130. /// \param[in] mp memory pool object.
  131. void osRtxMemoryPoolPostProcess (os_memory_pool_t *mp) {
  132. void *block;
  133. os_thread_t *thread;
  134. if (mp->state == osRtxObjectInactive) {
  135. return;
  136. }
  137. // Check if Thread is waiting to allocate memory
  138. if (mp->thread_list != NULL) {
  139. // Allocate memory
  140. block = osRtxMemoryPoolAlloc(&mp->mp_info);
  141. if (block != NULL) {
  142. // Wakeup waiting Thread with highest Priority
  143. thread = osRtxThreadListGet((os_object_t*)mp);
  144. osRtxThreadWaitExit(thread, (uint32_t)block, false);
  145. EvrRtxMemoryPoolAllocated(mp, block);
  146. }
  147. }
  148. }
  149. // ==== Service Calls ====
  150. // Service Calls definitions
  151. SVC0_3M(MemoryPoolNew, osMemoryPoolId_t, uint32_t, uint32_t, const osMemoryPoolAttr_t *)
  152. SVC0_1 (MemoryPoolGetName, const char *, osMemoryPoolId_t)
  153. SVC0_2 (MemoryPoolAlloc, void *, osMemoryPoolId_t, uint32_t)
  154. SVC0_2 (MemoryPoolFree, osStatus_t, osMemoryPoolId_t, void *)
  155. SVC0_1 (MemoryPoolGetCapacity, uint32_t, osMemoryPoolId_t)
  156. SVC0_1 (MemoryPoolGetBlockSize, uint32_t, osMemoryPoolId_t)
  157. SVC0_1 (MemoryPoolGetCount, uint32_t, osMemoryPoolId_t)
  158. SVC0_1 (MemoryPoolGetSpace, uint32_t, osMemoryPoolId_t)
  159. SVC0_1 (MemoryPoolDelete, osStatus_t, osMemoryPoolId_t)
  160. /// Create and Initialize a Memory Pool object.
  161. /// \note API identical to osMemoryPoolNew
  162. osMemoryPoolId_t svcRtxMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) {
  163. os_memory_pool_t *mp;
  164. void *mp_mem;
  165. uint32_t mp_size;
  166. uint32_t size;
  167. uint8_t flags;
  168. const char *name;
  169. // Check parameters
  170. if ((block_count == 0U) || (block_size == 0U)) {
  171. EvrRtxMemoryPoolError(NULL, osErrorParameter);
  172. return NULL;
  173. }
  174. block_size = (block_size + 3U) & ~3UL;
  175. if ((__CLZ(block_count) + __CLZ(block_size)) < 32) {
  176. EvrRtxMemoryPoolError(NULL, osErrorParameter);
  177. return NULL;
  178. }
  179. size = block_count * block_size;
  180. // Process attributes
  181. if (attr != NULL) {
  182. name = attr->name;
  183. mp = attr->cb_mem;
  184. mp_mem = attr->mp_mem;
  185. mp_size = attr->mp_size;
  186. if (mp != NULL) {
  187. if (((uint32_t)mp & 3U) || (attr->cb_size < sizeof(os_memory_pool_t))) {
  188. EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidControlBlock);
  189. return NULL;
  190. }
  191. } else {
  192. if (attr->cb_size != 0U) {
  193. EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidControlBlock);
  194. return NULL;
  195. }
  196. }
  197. if (mp_mem != NULL) {
  198. if (((uint32_t)mp_mem & 3U) || (mp_size < size)) {
  199. EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidDataMemory);
  200. return NULL;
  201. }
  202. } else {
  203. if (mp_size != 0U) {
  204. EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidDataMemory);
  205. return NULL;
  206. }
  207. }
  208. } else {
  209. name = NULL;
  210. mp = NULL;
  211. mp_mem = NULL;
  212. }
  213. // Allocate object memory if not provided
  214. if (mp == NULL) {
  215. if (osRtxInfo.mpi.memory_pool != NULL) {
  216. mp = osRtxMemoryPoolAlloc(osRtxInfo.mpi.memory_pool);
  217. } else {
  218. mp = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_memory_pool_t), 1U);
  219. }
  220. if (mp == NULL) {
  221. EvrRtxMemoryPoolError(NULL, osErrorNoMemory);
  222. return NULL;
  223. }
  224. flags = osRtxFlagSystemObject;
  225. } else {
  226. flags = 0U;
  227. }
  228. // Allocate data memory if not provided
  229. if (mp_mem == NULL) {
  230. mp_mem = osRtxMemoryAlloc(osRtxInfo.mem.mp_data, size, 0U);
  231. if (mp_mem == NULL) {
  232. EvrRtxMemoryPoolError(NULL, osErrorNoMemory);
  233. if (flags & osRtxFlagSystemObject) {
  234. if (osRtxInfo.mpi.memory_pool != NULL) {
  235. osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp);
  236. } else {
  237. osRtxMemoryFree(osRtxInfo.mem.common, mp);
  238. }
  239. }
  240. return NULL;
  241. }
  242. memset(mp_mem, 0, size);
  243. flags |= osRtxFlagSystemMemory;
  244. }
  245. // Initialize control block
  246. mp->id = osRtxIdMemoryPool;
  247. mp->state = osRtxObjectActive;
  248. mp->flags = flags;
  249. mp->name = name;
  250. mp->thread_list = NULL;
  251. osRtxMemoryPoolInit(&mp->mp_info, block_count, block_size, mp_mem);
  252. // Register post ISR processing function
  253. osRtxInfo.post_process.memory_pool = osRtxMemoryPoolPostProcess;
  254. EvrRtxMemoryPoolCreated(mp);
  255. return mp;
  256. }
  257. /// Get name of a Memory Pool object.
  258. /// \note API identical to osMemoryPoolGetName
  259. const char *svcRtxMemoryPoolGetName (osMemoryPoolId_t mp_id) {
  260. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  261. // Check parameters
  262. if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
  263. EvrRtxMemoryPoolGetName(mp, NULL);
  264. return NULL;
  265. }
  266. // Check object state
  267. if (mp->state == osRtxObjectInactive) {
  268. EvrRtxMemoryPoolGetName(mp, NULL);
  269. return NULL;
  270. }
  271. EvrRtxMemoryPoolGetName(mp, mp->name);
  272. return mp->name;
  273. }
  274. /// Allocate a memory block from a Memory Pool.
  275. /// \note API identical to osMemoryPoolAlloc
  276. void *svcRtxMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) {
  277. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  278. void *block;
  279. // Check parameters
  280. if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
  281. EvrRtxMemoryPoolError(mp, osErrorParameter);
  282. return NULL;
  283. }
  284. // Check object state
  285. if (mp->state == osRtxObjectInactive) {
  286. EvrRtxMemoryPoolError(mp, osErrorResource);
  287. return NULL;
  288. }
  289. // Allocate memory
  290. block = osRtxMemoryPoolAlloc(&mp->mp_info);
  291. if (block == NULL) {
  292. // No memory available
  293. if (timeout != 0U) {
  294. EvrRtxMemoryPoolAllocPending(mp, timeout);
  295. // Suspend current Thread
  296. osRtxThreadListPut((os_object_t*)mp, osRtxThreadGetRunning());
  297. osRtxThreadWaitEnter(osRtxThreadWaitingMemoryPool, timeout);
  298. } else {
  299. EvrRtxMemoryPoolAllocFailed(mp);
  300. }
  301. } else {
  302. EvrRtxMemoryPoolAllocated(mp, block);
  303. }
  304. return block;
  305. }
  306. /// Return an allocated memory block back to a Memory Pool.
  307. /// \note API identical to osMemoryPoolFree
  308. osStatus_t svcRtxMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) {
  309. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  310. os_thread_t *thread;
  311. osStatus_t status;
  312. // Check parameters
  313. if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
  314. EvrRtxMemoryPoolError(mp, osErrorParameter);
  315. return osErrorParameter;
  316. }
  317. // Check object state
  318. if (mp->state == osRtxObjectInactive) {
  319. EvrRtxMemoryPoolError(mp, osErrorResource);
  320. return osErrorResource;
  321. }
  322. // Free memory
  323. status = osRtxMemoryPoolFree(&mp->mp_info, block);
  324. if (status == osOK) {
  325. EvrRtxMemoryPoolDeallocated(mp, block);
  326. // Check if Thread is waiting to allocate memory
  327. if (mp->thread_list != NULL) {
  328. // Allocate memory
  329. block = osRtxMemoryPoolAlloc(&mp->mp_info);
  330. if (block != NULL) {
  331. // Wakeup waiting Thread with highest Priority
  332. thread = osRtxThreadListGet((os_object_t*)mp);
  333. osRtxThreadWaitExit(thread, (uint32_t)block, true);
  334. EvrRtxMemoryPoolAllocated(mp, block);
  335. }
  336. }
  337. } else {
  338. EvrRtxMemoryPoolFreeFailed(mp, block);
  339. }
  340. return status;
  341. }
  342. /// Get maximum number of memory blocks in a Memory Pool.
  343. /// \note API identical to osMemoryPoolGetCapacity
  344. uint32_t svcRtxMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) {
  345. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  346. // Check parameters
  347. if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
  348. EvrRtxMemoryPoolGetCapacity(mp, 0U);
  349. return 0U;
  350. }
  351. // Check object state
  352. if (mp->state == osRtxObjectInactive) {
  353. EvrRtxMemoryPoolGetCapacity(mp, 0U);
  354. return 0U;
  355. }
  356. EvrRtxMemoryPoolGetCapacity(mp, mp->mp_info.max_blocks);
  357. return mp->mp_info.max_blocks;
  358. }
  359. /// Get memory block size in a Memory Pool.
  360. /// \note API identical to osMemoryPoolGetBlockSize
  361. uint32_t svcRtxMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) {
  362. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  363. // Check parameters
  364. if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
  365. EvrRtxMemoryPoolGetBlockSize(mp, 0U);
  366. return 0U;
  367. }
  368. // Check object state
  369. if (mp->state == osRtxObjectInactive) {
  370. EvrRtxMemoryPoolGetBlockSize(mp, 0U);
  371. return 0U;
  372. }
  373. EvrRtxMemoryPoolGetBlockSize(mp, mp->mp_info.block_size);
  374. return mp->mp_info.block_size;
  375. }
  376. /// Get number of memory blocks used in a Memory Pool.
  377. /// \note API identical to osMemoryPoolGetCount
  378. uint32_t svcRtxMemoryPoolGetCount (osMemoryPoolId_t mp_id) {
  379. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  380. // Check parameters
  381. if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
  382. EvrRtxMemoryPoolGetCount(mp, 0U);
  383. return 0U;
  384. }
  385. // Check object state
  386. if (mp->state == osRtxObjectInactive) {
  387. EvrRtxMemoryPoolGetCount(mp, 0U);
  388. return 0U;
  389. }
  390. EvrRtxMemoryPoolGetCount(mp, mp->mp_info.used_blocks);
  391. return mp->mp_info.used_blocks;
  392. }
  393. /// Get number of memory blocks available in a Memory Pool.
  394. /// \note API identical to osMemoryPoolGetSpace
  395. uint32_t svcRtxMemoryPoolGetSpace (osMemoryPoolId_t mp_id) {
  396. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  397. // Check parameters
  398. if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
  399. EvrRtxMemoryPoolGetSpace(mp, 0U);
  400. return 0U;
  401. }
  402. // Check object state
  403. if (mp->state == osRtxObjectInactive) {
  404. EvrRtxMemoryPoolGetSpace(mp, 0U);
  405. return 0U;
  406. }
  407. EvrRtxMemoryPoolGetSpace(mp, mp->mp_info.max_blocks - mp->mp_info.used_blocks);
  408. return (mp->mp_info.max_blocks - mp->mp_info.used_blocks);
  409. }
  410. /// Delete a Memory Pool object.
  411. /// \note API identical to osMemoryPoolDelete
  412. osStatus_t svcRtxMemoryPoolDelete (osMemoryPoolId_t mp_id) {
  413. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  414. os_thread_t *thread;
  415. // Check parameters
  416. if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
  417. EvrRtxMemoryPoolError(mp, osErrorParameter);
  418. return osErrorParameter;
  419. }
  420. // Check object state
  421. if (mp->state == osRtxObjectInactive) {
  422. EvrRtxMemoryPoolError(mp, osErrorResource);
  423. return osErrorResource;
  424. }
  425. // Mark object as inactive
  426. mp->state = osRtxObjectInactive;
  427. // Unblock waiting threads
  428. if (mp->thread_list != NULL) {
  429. do {
  430. thread = osRtxThreadListGet((os_object_t*)mp);
  431. osRtxThreadWaitExit(thread, 0U, false);
  432. } while (mp->thread_list != NULL);
  433. osRtxThreadDispatch(NULL);
  434. }
  435. // Free data memory
  436. if (mp->flags & osRtxFlagSystemMemory) {
  437. osRtxMemoryFree(osRtxInfo.mem.mp_data, mp->mp_info.block_base);
  438. }
  439. // Free object memory
  440. if (mp->flags & osRtxFlagSystemObject) {
  441. if (osRtxInfo.mpi.memory_pool != NULL) {
  442. osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp);
  443. } else {
  444. osRtxMemoryFree(osRtxInfo.mem.common, mp);
  445. }
  446. }
  447. EvrRtxMemoryPoolDestroyed(mp);
  448. return osOK;
  449. }
  450. // ==== ISR Calls ====
  451. /// Allocate a memory block from a Memory Pool.
  452. /// \note API identical to osMemoryPoolAlloc
  453. __STATIC_INLINE
  454. void *isrRtxMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) {
  455. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  456. void *block;
  457. // Check parameters
  458. if ((mp == NULL) || (mp->id != osRtxIdMemoryPool) || (timeout != 0U)) {
  459. EvrRtxMemoryPoolError(mp, osErrorParameter);
  460. return NULL;
  461. }
  462. // Check object state
  463. if (mp->state == osRtxObjectInactive) {
  464. EvrRtxMemoryPoolError(mp, osErrorResource);
  465. return NULL;
  466. }
  467. // Allocate memory
  468. block = osRtxMemoryPoolAlloc(&mp->mp_info);
  469. if (block == NULL) {
  470. EvrRtxMemoryPoolAllocFailed(mp);
  471. } else {
  472. EvrRtxMemoryPoolAllocated(mp, block);
  473. }
  474. return block;
  475. }
  476. /// Return an allocated memory block back to a Memory Pool.
  477. /// \note API identical to osMemoryPoolFree
  478. __STATIC_INLINE
  479. osStatus_t isrRtxMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) {
  480. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  481. osStatus_t status;
  482. // Check parameters
  483. if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
  484. EvrRtxMemoryPoolError(mp, osErrorParameter);
  485. return osErrorParameter;
  486. }
  487. // Check object state
  488. if (mp->state == osRtxObjectInactive) {
  489. EvrRtxMemoryPoolError(mp, osErrorResource);
  490. return osErrorResource;
  491. }
  492. // Free memory
  493. status = osRtxMemoryPoolFree(&mp->mp_info, block);
  494. if (status == osOK) {
  495. // Register post ISR processing
  496. osRtxPostProcess((os_object_t *)mp);
  497. EvrRtxMemoryPoolDeallocated(mp, block);
  498. } else {
  499. EvrRtxMemoryPoolFreeFailed(mp, block);
  500. }
  501. return status;
  502. }
  503. // ==== Public API ====
  504. /// Create and Initialize a Memory Pool object.
  505. osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) {
  506. EvrRtxMemoryPoolNew(block_count, block_size, attr);
  507. if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
  508. EvrRtxMemoryPoolError(NULL, osErrorISR);
  509. return NULL;
  510. }
  511. return __svcMemoryPoolNew(block_count, block_size, attr);
  512. }
  513. /// Get name of a Memory Pool object.
  514. const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id) {
  515. if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
  516. EvrRtxMemoryPoolGetName(mp_id, NULL);
  517. return NULL;
  518. }
  519. return __svcMemoryPoolGetName(mp_id);
  520. }
  521. /// Allocate a memory block from a Memory Pool.
  522. void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) {
  523. EvrRtxMemoryPoolAlloc(mp_id, timeout);
  524. if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
  525. return isrRtxMemoryPoolAlloc(mp_id, timeout);
  526. } else {
  527. return __svcMemoryPoolAlloc(mp_id, timeout);
  528. }
  529. }
  530. /// Return an allocated memory block back to a Memory Pool.
  531. osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) {
  532. EvrRtxMemoryPoolFree(mp_id, block);
  533. if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
  534. return isrRtxMemoryPoolFree(mp_id, block);
  535. } else {
  536. return __svcMemoryPoolFree(mp_id, block);
  537. }
  538. }
  539. /// Get maximum number of memory blocks in a Memory Pool.
  540. uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) {
  541. if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
  542. return svcRtxMemoryPoolGetCapacity(mp_id);
  543. } else {
  544. return __svcMemoryPoolGetCapacity(mp_id);
  545. }
  546. }
  547. /// Get memory block size in a Memory Pool.
  548. uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) {
  549. if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
  550. return svcRtxMemoryPoolGetBlockSize(mp_id);
  551. } else {
  552. return __svcMemoryPoolGetBlockSize(mp_id);
  553. }
  554. }
  555. /// Get number of memory blocks used in a Memory Pool.
  556. uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id) {
  557. if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
  558. return svcRtxMemoryPoolGetCount(mp_id);
  559. } else {
  560. return __svcMemoryPoolGetCount(mp_id);
  561. }
  562. }
  563. /// Get number of memory blocks available in a Memory Pool.
  564. uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id) {
  565. if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
  566. return svcRtxMemoryPoolGetSpace(mp_id);
  567. } else {
  568. return __svcMemoryPoolGetSpace(mp_id);
  569. }
  570. }
  571. /// Delete a Memory Pool object.
  572. osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id) {
  573. EvrRtxMemoryPoolDelete(mp_id);
  574. if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
  575. EvrRtxMemoryPoolError(mp_id, osErrorISR);
  576. return osErrorISR;
  577. }
  578. return __svcMemoryPoolDelete(mp_id);
  579. }