rtx_mempool.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. /*
  2. * Copyright (c) 2013-2016 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. * http://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 os_MemoryPoolInit (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) ||
  37. (block_count == 0U) ||
  38. (block_size == 0U) ||
  39. (block_mem == NULL)) {
  40. return 0U;
  41. }
  42. // Initialize information structure
  43. mp_info->max_blocks = block_count;
  44. mp_info->used_blocks = 0U;
  45. mp_info->block_size = block_size;
  46. mp_info->block_base = block_mem;
  47. mp_info->block_free = block_mem;
  48. mp_info->block_lim = (uint8_t *)block_mem + (block_count * block_size);
  49. // Link all free blocks
  50. while (--block_count) {
  51. block = (uint8_t *)block_mem + block_size;
  52. *((void **)block_mem) = block;
  53. block_mem = block;
  54. }
  55. *((void **)block_mem) = NULL;
  56. return 1U;
  57. }
  58. /// Allocate a memory block from a Memory Pool.
  59. /// \param[in] mp_info memory pool info.
  60. /// \return address of the allocated memory block or NULL in case of no memory is available.
  61. void *os_MemoryPoolAlloc (os_mp_info_t *mp_info) {
  62. #ifdef __NO_EXCLUSIVE_ACCESS
  63. uint32_t primask = __get_PRIMASK();
  64. #endif
  65. void *block;
  66. if (mp_info == NULL) {
  67. return NULL;
  68. }
  69. #ifdef __NO_EXCLUSIVE_ACCESS
  70. __disable_irq();
  71. block = mp_info->block_free;
  72. if (block != NULL) {
  73. mp_info->block_free = *((void **)block);
  74. mp_info->used_blocks++;
  75. }
  76. if (primask == 0U) {
  77. __enable_irq();
  78. }
  79. #else
  80. {
  81. register uint32_t val, res;
  82. __ASM volatile (
  83. "loop1%=:\n\t"
  84. "ldrex %[block],[%[mp_info],%[_block_free]]\n\t"
  85. "cbnz %[block],update%=\n\t"
  86. "clrex\n\t"
  87. "b exit%=\n\t"
  88. "update%=:\n\t"
  89. "ldr %[val],[%[block]]\n\t"
  90. "strex %[res],%[val],[%[mp_info],%[_block_free]]\n\t"
  91. "cbz %[res],loop2%=\n\t"
  92. "b loop1%=\n\t"
  93. "loop2%=:\n\t"
  94. "ldrex %[val],[%[mp_info],%[_used_blocks]]\n\t"
  95. "adds %[val],#1\n\t"
  96. "strex %[res],%[val],[%[mp_info],%[_used_blocks]]\n\t"
  97. "cbz %[res],exit%=\n\t"
  98. "b loop2%=\n\t"
  99. "exit%=:"
  100. : [block] "=&l" (block),
  101. [val] "=&l" (val),
  102. [res] "=&l" (res)
  103. : [mp_info] "l" (mp_info),
  104. [_block_free] "I" (offsetof(os_mp_info_t, block_free)),
  105. [_used_blocks] "I" (offsetof(os_mp_info_t, used_blocks))
  106. : "cc", "memory"
  107. );
  108. }
  109. #endif
  110. return block;
  111. }
  112. /// Return an allocated memory block back to a Memory Pool.
  113. /// \param[in] mp_info memory pool info.
  114. /// \param[in] block address of the allocated memory block to be returned to the memory pool.
  115. /// \return status code that indicates the execution status of the function.
  116. osStatus_t os_MemoryPoolFree (os_mp_info_t *mp_info, void *block) {
  117. #ifdef __NO_EXCLUSIVE_ACCESS
  118. uint32_t primask = __get_PRIMASK();
  119. #endif
  120. if (mp_info == NULL) {
  121. return osErrorParameter;
  122. }
  123. if ((block < mp_info->block_base) || (block >= mp_info->block_lim)) {
  124. return osErrorParameter;
  125. }
  126. #ifdef __NO_EXCLUSIVE_ACCESS
  127. __disable_irq();
  128. *((void **)block) = mp_info->block_free;
  129. mp_info->block_free = block;
  130. mp_info->used_blocks--;
  131. if (primask == 0U) {
  132. __enable_irq();
  133. }
  134. #else
  135. {
  136. register uint32_t val1, val2, res;
  137. __ASM volatile (
  138. "loop1%=:\n\t"
  139. "ldr %[val1],[%[mp_info],%[_block_free]]\n\t"
  140. "str %[val1],[%[block]]\n\t"
  141. "dmb\n\t"
  142. "ldrex %[val1],[%[mp_info],%[_block_free]]\n\t"
  143. "ldr %[val2],[%[block]]\n\t"
  144. "cmp %[val2],%[val1]\n\t"
  145. "bne loop1%=\n\t"
  146. "strex %[res],%[block],[%[mp_info],%[_block_free]]\n\t"
  147. "cbz %[res],loop2%=\n\t"
  148. "b loop1%=\n\t"
  149. "loop2%=:\n\t"
  150. "ldrex %[val1],[%[mp_info],%[_used_blocks]]\n\t"
  151. "subs %[val1],#1\n\t"
  152. "strex %[res],%[val1],[%[mp_info],%[_used_blocks]]\n\t"
  153. "cbz %[res],exit%=\n\t"
  154. "b loop2%=\n\t"
  155. "exit%=:"
  156. : [val1] "=&l" (val1),
  157. [val2] "=&l" (val2),
  158. [res] "=&l" (res)
  159. : [block] "l" (block),
  160. [mp_info] "l" (mp_info),
  161. [_block_free] "I" (offsetof(os_mp_info_t, block_free)),
  162. [_used_blocks] "I" (offsetof(os_mp_info_t, used_blocks))
  163. : "cc", "memory"
  164. );
  165. }
  166. #endif
  167. return osOK;
  168. }
  169. /// Memory Pool post ISR processing.
  170. /// \param[in] mp memory pool object.
  171. void os_MemoryPoolPostProcess (os_memory_pool_t *mp) {
  172. void *block;
  173. os_thread_t *thread;
  174. if (mp->state == os_ObjectInactive) {
  175. return;
  176. }
  177. // Check if Thread is waiting to allocate memory
  178. if (mp->thread_list != NULL) {
  179. // Allocate memory
  180. block = os_MemoryPoolAlloc(&mp->mp_info);
  181. if (block != NULL) {
  182. // Wakeup waiting Thread with highest Priority
  183. thread = os_ThreadListGet((os_object_t*)mp);
  184. os_ThreadWaitExit(thread, (uint32_t)block, false);
  185. }
  186. }
  187. }
  188. // ==== Service Calls ====
  189. // Service Calls definitions
  190. SVC0_3(MemoryPoolNew, osMemoryPoolId_t, uint32_t, uint32_t, const osMemoryPoolAttr_t *)
  191. SVC0_2(MemoryPoolAlloc, void *, osMemoryPoolId_t, uint32_t)
  192. SVC0_2(MemoryPoolFree, osStatus_t, osMemoryPoolId_t, void *)
  193. SVC0_1(MemoryPoolGetCapacity, uint32_t, osMemoryPoolId_t)
  194. SVC0_1(MemoryPoolGetBlockSize, uint32_t, osMemoryPoolId_t)
  195. SVC0_1(MemoryPoolGetCount, uint32_t, osMemoryPoolId_t)
  196. SVC0_1(MemoryPoolGetSpace, uint32_t, osMemoryPoolId_t)
  197. SVC0_1(MemoryPoolDelete, osStatus_t, osMemoryPoolId_t)
  198. /// Create and Initialize a Memory Pool object.
  199. /// \note API identical to osMemoryPoolNew
  200. osMemoryPoolId_t os_svcMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) {
  201. os_memory_pool_t *mp;
  202. void *mp_mem;
  203. uint32_t mp_size;
  204. uint32_t size;
  205. uint8_t flags;
  206. const char *name;
  207. // Check parameters
  208. if ((block_count == 0U) ||
  209. (block_size == 0U)) {
  210. return (osMemoryPoolId_t)NULL;
  211. }
  212. block_size = (block_size + 3U) & ~3UL;
  213. if ((__CLZ(block_count) + __CLZ(block_size)) < 32) {
  214. return (osMemoryPoolId_t)NULL;
  215. }
  216. size = block_count * block_size;
  217. // Process attributes
  218. if (attr != NULL) {
  219. name = attr->name;
  220. mp = attr->cb_mem;
  221. mp_mem = attr->mp_mem;
  222. mp_size = attr->mp_size;
  223. if (mp != NULL) {
  224. if (((uint32_t)mp & 3U) || (attr->cb_size < sizeof(os_memory_pool_t))) {
  225. return (osMemoryPoolId_t)NULL;
  226. }
  227. } else {
  228. if (attr->cb_size != 0U) {
  229. return (osMemoryPoolId_t)NULL;
  230. }
  231. }
  232. if (mp_mem != NULL) {
  233. if (((uint32_t)mp_mem & 3U) || (mp_size < size)) {
  234. return (osMemoryPoolId_t)NULL;
  235. }
  236. } else {
  237. if (mp_size != 0U) {
  238. return (osMemoryPoolId_t)NULL;
  239. }
  240. }
  241. } else {
  242. name = NULL;
  243. mp = NULL;
  244. mp_mem = NULL;
  245. }
  246. // Allocate object memory if not provided
  247. if (mp == NULL) {
  248. if (os_Info.mpi.memory_pool != NULL) {
  249. mp = os_MemoryPoolAlloc(os_Info.mpi.memory_pool);
  250. } else {
  251. mp = os_MemoryAlloc(os_Info.mem.cb, sizeof(os_memory_pool_t));
  252. }
  253. if (mp == NULL) {
  254. return (osMemoryPoolId_t)NULL;
  255. }
  256. flags = os_FlagSystemObject;
  257. } else {
  258. flags = 0U;
  259. }
  260. // Allocate data memory if not provided
  261. if (mp_mem == NULL) {
  262. mp_mem = os_MemoryAlloc(os_Info.mem.data, size);
  263. if (mp_mem == NULL) {
  264. if (flags & os_FlagSystemObject) {
  265. if (os_Info.mpi.memory_pool != NULL) {
  266. os_MemoryPoolFree(os_Info.mpi.memory_pool, mp);
  267. } else {
  268. os_MemoryFree(os_Info.mem.cb, mp);
  269. }
  270. }
  271. return (osMemoryPoolId_t)NULL;
  272. }
  273. memset(mp_mem, 0, size);
  274. flags |= os_FlagSystemMemory;
  275. }
  276. // Initialize control block
  277. mp->id = os_IdMemoryPool;
  278. mp->state = os_ObjectActive;
  279. mp->flags = flags;
  280. mp->name = name;
  281. mp->thread_list = NULL;
  282. os_MemoryPoolInit(&mp->mp_info, block_count, block_size, mp_mem);
  283. // Register post ISR processing function
  284. os_Info.post_process.memory_pool = os_MemoryPoolPostProcess;
  285. return (osMemoryPoolId_t)mp;
  286. }
  287. /// Allocate a memory block from a Memory Pool.
  288. /// \note API identical to osMemoryPoolAlloc
  289. void *os_svcMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t millisec) {
  290. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  291. void *block;
  292. // Check parameters
  293. if ((mp == NULL) ||
  294. (mp->id != os_IdMemoryPool)) {
  295. return NULL;
  296. }
  297. // Check object state
  298. if (mp->state == os_ObjectInactive) {
  299. return NULL;
  300. }
  301. // Allocate memory
  302. block = os_MemoryPoolAlloc(&mp->mp_info);
  303. if (block == NULL) {
  304. // No memory available
  305. if (millisec != 0U) {
  306. // Suspend current Thread
  307. os_ThreadListPut((os_object_t*)mp, os_ThreadGetRunning());
  308. os_ThreadWaitEnter(os_ThreadWaitingMemoryPool, millisec);
  309. }
  310. }
  311. return block;
  312. }
  313. /// Return an allocated memory block back to a Memory Pool.
  314. /// \note API identical to osMemoryPoolFree
  315. osStatus_t os_svcMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) {
  316. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  317. os_thread_t *thread;
  318. osStatus_t status;
  319. // Check parameters
  320. if ((mp == NULL) ||
  321. (mp->id != os_IdMemoryPool)) {
  322. return osErrorParameter;
  323. }
  324. // Check object state
  325. if (mp->state == os_ObjectInactive) {
  326. return osErrorResource;
  327. }
  328. // Free memory
  329. status = os_MemoryPoolFree(&mp->mp_info, block);
  330. if (status == osOK) {
  331. // Check if Thread is waiting to allocate memory
  332. if (mp->thread_list != NULL) {
  333. // Allocate memory
  334. block = os_MemoryPoolAlloc(&mp->mp_info);
  335. if (block != NULL) {
  336. // Wakeup waiting Thread with highest Priority
  337. thread = os_ThreadListGet((os_object_t*)mp);
  338. os_ThreadWaitExit(thread, (uint32_t)block, true);
  339. }
  340. }
  341. }
  342. return status;
  343. }
  344. /// Get maximum number of memory blocks in a Memory Pool.
  345. /// \note API identical to osMemoryPoolGetCapacity
  346. uint32_t os_svcMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) {
  347. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  348. // Check parameters
  349. if ((mp == NULL) ||
  350. (mp->id != os_IdMemoryPool)) {
  351. return 0U;
  352. }
  353. // Check object state
  354. if (mp->state == os_ObjectInactive) {
  355. return 0U;
  356. }
  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 os_svcMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) {
  362. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  363. // Check parameters
  364. if ((mp == NULL) ||
  365. (mp->id != os_IdMemoryPool)) {
  366. return 0U;
  367. }
  368. // Check object state
  369. if (mp->state == os_ObjectInactive) {
  370. return 0U;
  371. }
  372. return mp->mp_info.block_size;
  373. }
  374. /// Get number of memory blocks used in a Memory Pool.
  375. /// \note API identical to osMemoryPoolGetCount
  376. uint32_t os_svcMemoryPoolGetCount (osMemoryPoolId_t mp_id) {
  377. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  378. // Check parameters
  379. if ((mp == NULL) ||
  380. (mp->id != os_IdMemoryPool)) {
  381. return 0U;
  382. }
  383. // Check object state
  384. if (mp->state == os_ObjectInactive) {
  385. return 0U;
  386. }
  387. return mp->mp_info.used_blocks;
  388. }
  389. /// Get number of memory blocks available in a Memory Pool.
  390. /// \note API identical to osMemoryPoolGetSpace
  391. uint32_t os_svcMemoryPoolGetSpace (osMemoryPoolId_t mp_id) {
  392. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  393. // Check parameters
  394. if ((mp == NULL) ||
  395. (mp->id != os_IdMemoryPool)) {
  396. return 0U;
  397. }
  398. // Check object state
  399. if (mp->state == os_ObjectInactive) {
  400. return 0U;
  401. }
  402. return (mp->mp_info.max_blocks - mp->mp_info.used_blocks);
  403. }
  404. /// Delete a Memory Pool object.
  405. /// \note API identical to osMemoryPoolDelete
  406. osStatus_t os_svcMemoryPoolDelete (osMemoryPoolId_t mp_id) {
  407. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  408. os_thread_t *thread;
  409. // Check parameters
  410. if ((mp == NULL) ||
  411. (mp->id != os_IdMemoryPool)) {
  412. return osErrorParameter;
  413. }
  414. // Check object state
  415. if (mp->state == os_ObjectInactive) {
  416. return osErrorResource;
  417. }
  418. // Mark object as inactive
  419. mp->state = os_ObjectInactive;
  420. // Unblock waiting threads
  421. if (mp->thread_list != NULL) {
  422. do {
  423. thread = os_ThreadListGet((os_object_t*)mp);
  424. os_ThreadWaitExit(thread, 0U, false);
  425. } while (mp->thread_list != NULL);
  426. os_ThreadDispatch(NULL);
  427. }
  428. // Free data memory
  429. if (mp->flags & os_FlagSystemMemory) {
  430. os_MemoryFree(os_Info.mem.data, mp->mp_info.block_base);
  431. }
  432. // Free object memory
  433. if (mp->flags & os_FlagSystemObject) {
  434. if (os_Info.mpi.memory_pool != NULL) {
  435. os_MemoryPoolFree(os_Info.mpi.memory_pool, mp);
  436. } else {
  437. os_MemoryFree(os_Info.mem.cb, mp);
  438. }
  439. }
  440. return osOK;
  441. }
  442. // ==== ISR Calls ====
  443. /// Allocate a memory block from a Memory Pool.
  444. /// \note API identical to osMemoryPoolAlloc
  445. __STATIC_INLINE
  446. void *os_isrMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t millisec) {
  447. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  448. void *block;
  449. // Check parameters
  450. if ((mp == NULL) ||
  451. (mp->id != os_IdMemoryPool)) {
  452. return NULL;
  453. }
  454. if (millisec != 0U) {
  455. return NULL;
  456. }
  457. // Check object state
  458. if (mp->state == os_ObjectInactive) {
  459. return NULL;
  460. }
  461. // Allocate memory
  462. block = os_MemoryPoolAlloc(&mp->mp_info);
  463. return block;
  464. }
  465. /// Return an allocated memory block back to a Memory Pool.
  466. /// \note API identical to osMemoryPoolFree
  467. __STATIC_INLINE
  468. osStatus_t os_isrMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) {
  469. os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
  470. osStatus_t status;
  471. // Check parameters
  472. if ((mp == NULL) ||
  473. (mp->id != os_IdMemoryPool)) {
  474. return osErrorParameter;
  475. }
  476. // Check object state
  477. if (mp->state == os_ObjectInactive) {
  478. return osErrorResource;
  479. }
  480. // Free memory
  481. status = os_MemoryPoolFree(&mp->mp_info, block);
  482. if (status == osOK) {
  483. // Register post ISR processing
  484. os_PostProcess((os_object_t *)mp);
  485. }
  486. return status;
  487. }
  488. // ==== Public API ====
  489. /// Create and Initialize a Memory Pool object.
  490. osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr) {
  491. if (__get_IPSR() != 0U) {
  492. return (osMemoryPoolId_t)NULL; // Not allowed in ISR
  493. }
  494. if ((os_KernelGetState() == os_KernelReady) && ((__get_CONTROL() & 1U) == 0U)) {
  495. // Kernel Ready (not running) and in Privileged mode
  496. return os_svcMemoryPoolNew(block_count, block_size, attr);
  497. } else {
  498. return __svcMemoryPoolNew(block_count, block_size, attr);
  499. }
  500. }
  501. /// Allocate a memory block from a Memory Pool.
  502. void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t millisec) {
  503. if (__get_IPSR() != 0U) { // in ISR
  504. return os_isrMemoryPoolAlloc(mp_id, millisec);
  505. } else { // in Thread
  506. return __svcMemoryPoolAlloc(mp_id, millisec);
  507. }
  508. }
  509. /// Return an allocated memory block back to a Memory Pool.
  510. osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) {
  511. if (__get_IPSR() != 0U) { // in ISR
  512. return os_isrMemoryPoolFree(mp_id, block);
  513. } else { // in Thread
  514. return __svcMemoryPoolFree(mp_id, block);
  515. }
  516. }
  517. /// Get maximum number of memory blocks in a Memory Pool.
  518. uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) {
  519. if (__get_IPSR() != 0U) { // in ISR
  520. return os_svcMemoryPoolGetCapacity(mp_id);
  521. } else { // in Thread
  522. return __svcMemoryPoolGetCapacity(mp_id);
  523. }
  524. }
  525. /// Get memory block size in a Memory Pool.
  526. uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) {
  527. if (__get_IPSR() != 0U) { // in ISR
  528. return os_svcMemoryPoolGetBlockSize(mp_id);
  529. } else { // in Thread
  530. return __svcMemoryPoolGetBlockSize(mp_id);
  531. }
  532. }
  533. /// Get number of memory blocks used in a Memory Pool.
  534. uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id) {
  535. if (__get_IPSR() != 0U) { // in ISR
  536. return os_svcMemoryPoolGetCount(mp_id);
  537. } else { // in Thread
  538. return __svcMemoryPoolGetCount(mp_id);
  539. }
  540. }
  541. /// Get number of memory blocks available in a Memory Pool.
  542. uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id) {
  543. if (__get_IPSR() != 0U) { // in ISR
  544. return os_svcMemoryPoolGetSpace(mp_id);
  545. } else { // in Thread
  546. return __svcMemoryPoolGetSpace(mp_id);
  547. }
  548. }
  549. /// Delete a Memory Pool object.
  550. osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id) {
  551. if (__get_IPSR() != 0U) {
  552. return osErrorISR; // Not allowed in ISR
  553. }
  554. return __svcMemoryPoolDelete(mp_id);
  555. }