pinebuds/rtos/rtx5/rtx_mempool.c

721 lines
21 KiB
C

/*
* Copyright (c) 2013-2018 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* -----------------------------------------------------------------------------
*
* Project: CMSIS-RTOS RTX
* Title: Memory Pool functions
*
* -----------------------------------------------------------------------------
*/
#include "rtx_lib.h"
// OS Runtime Object Memory Usage
#if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)))
osRtxObjectMemUsage_t osRtxMemoryPoolMemUsage
__attribute__((section(".data.os.mempool.obj"))) = {0U, 0U, 0U};
#endif
// ==== Library functions ====
/// Initialize Memory Pool.
/// \param[in] mp_info memory pool info.
/// \param[in] block_count maximum number of memory blocks in memory pool.
/// \param[in] block_size size of a memory block in bytes.
/// \param[in] block_mem pointer to memory for block storage.
/// \return 1 - success, 0 - failure.
uint32_t osRtxMemoryPoolInit(os_mp_info_t *mp_info, uint32_t block_count,
uint32_t block_size, void *block_mem) {
// lint --e{9079} --e{9087} "conversion from pointer to void to pointer to
// other type" [MISRA Note 6]
void *mem;
void *block;
// Check parameters
if ((mp_info == NULL) || (block_count == 0U) || (block_size == 0U) ||
(block_mem == NULL)) {
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return 0U;
}
// Initialize information structure
mp_info->max_blocks = block_count;
mp_info->used_blocks = 0U;
mp_info->block_size = block_size;
mp_info->block_base = block_mem;
mp_info->block_free = block_mem;
mp_info->block_lim = &(((uint8_t *)block_mem)[block_count * block_size]);
EvrRtxMemoryBlockInit(mp_info, block_count, block_size, block_mem);
// Link all free blocks
mem = block_mem;
while (--block_count != 0U) {
block = &((uint8_t *)mem)[block_size];
*((void **)mem) = block;
mem = block;
}
*((void **)mem) = NULL;
return 1U;
}
/// Allocate a memory block from a Memory Pool.
/// \param[in] mp_info memory pool info.
/// \return address of the allocated memory block or NULL in case of no memory
/// is available.
void *osRtxMemoryPoolAlloc(os_mp_info_t *mp_info) {
#if (EXCLUSIVE_ACCESS == 0)
uint32_t primask = __get_PRIMASK();
#endif
void *block;
if (mp_info == NULL) {
EvrRtxMemoryBlockAlloc(NULL, NULL);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return NULL;
}
#if (EXCLUSIVE_ACCESS == 0)
__disable_irq();
block = mp_info->block_free;
if (block != NULL) {
// lint --e{9079} --e{9087} "conversion from pointer to void to pointer to
// other type"
mp_info->block_free = *((void **)block);
mp_info->used_blocks++;
}
if (primask == 0U) {
__enable_irq();
}
#else
block = atomic_link_get(&mp_info->block_free);
if (block != NULL) {
(void)atomic_inc32(&mp_info->used_blocks);
}
#endif
EvrRtxMemoryBlockAlloc(mp_info, block);
return block;
}
/// Return an allocated memory block back to a Memory Pool.
/// \param[in] mp_info memory pool info.
/// \param[in] block address of the allocated memory block to be
/// returned to the memory pool. \return status code that indicates the
/// execution status of the function.
osStatus_t osRtxMemoryPoolFree(os_mp_info_t *mp_info, void *block) {
#if (EXCLUSIVE_ACCESS == 0)
uint32_t primask = __get_PRIMASK();
#endif
// lint -e{946} "Relational operator applied to pointers"
if ((mp_info == NULL) || (block < mp_info->block_base) ||
(block >= mp_info->block_lim)) {
EvrRtxMemoryBlockFree(mp_info, block, (int32_t)osErrorParameter);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return osErrorParameter;
}
#if (EXCLUSIVE_ACCESS == 0)
__disable_irq();
// lint --e{9079} --e{9087} "conversion from pointer to void to pointer to
// other type"
*((void **)block) = mp_info->block_free;
mp_info->block_free = block;
mp_info->used_blocks--;
if (primask == 0U) {
__enable_irq();
}
#else
atomic_link_put(&mp_info->block_free, block);
(void)atomic_dec32(&mp_info->used_blocks);
#endif
EvrRtxMemoryBlockFree(mp_info, block, (int32_t)osOK);
return osOK;
}
// ==== Post ISR processing ====
/// Memory Pool post ISR processing.
/// \param[in] mp memory pool object.
static void osRtxMemoryPoolPostProcess(os_memory_pool_t *mp) {
void *block;
os_thread_t *thread;
// Check if Thread is waiting to allocate memory
if (mp->thread_list != NULL) {
// Allocate memory
block = osRtxMemoryPoolAlloc(&mp->mp_info);
if (block != NULL) {
// Wakeup waiting Thread with highest Priority
thread = osRtxThreadListGet(osRtxObject(mp));
// lint -e{923} "cast from pointer to unsigned int"
osRtxThreadWaitExit(thread, (uint32_t)block, FALSE);
EvrRtxMemoryPoolAllocated(mp, block);
}
}
}
// ==== Service Calls ====
/// Create and Initialize a Memory Pool object.
/// \note API identical to osMemoryPoolNew
static osMemoryPoolId_t svcRtxMemoryPoolNew(uint32_t block_count,
uint32_t block_size,
const osMemoryPoolAttr_t *attr) {
os_memory_pool_t *mp;
void *mp_mem;
uint32_t mp_size;
uint32_t b_count;
uint32_t b_size;
uint32_t size;
uint8_t flags;
const char *name;
// Check parameters
if ((block_count == 0U) || (block_size == 0U)) {
EvrRtxMemoryPoolError(NULL, (int32_t)osErrorParameter);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return NULL;
}
b_count = block_count;
b_size = (block_size + 3U) & ~3UL;
if ((__CLZ(b_count) + __CLZ(b_size)) < 32U) {
EvrRtxMemoryPoolError(NULL, (int32_t)osErrorParameter);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return NULL;
}
size = b_count * b_size;
// Process attributes
if (attr != NULL) {
name = attr->name;
// lint -e{9079} "conversion from pointer to void to pointer to other type"
// [MISRA Note 6]
mp = attr->cb_mem;
// lint -e{9079} "conversion from pointer to void to pointer to other type"
// [MISRA Note 6]
mp_mem = attr->mp_mem;
mp_size = attr->mp_size;
if (mp != NULL) {
// lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note
// 7]
if ((((uint32_t)mp & 3U) != 0U) ||
(attr->cb_size < sizeof(os_memory_pool_t))) {
EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidControlBlock);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return NULL;
}
} else {
if (attr->cb_size != 0U) {
EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidControlBlock);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return NULL;
}
}
if (mp_mem != NULL) {
// lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note
// 7]
if ((((uint32_t)mp_mem & 3U) != 0U) || (mp_size < size)) {
EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidDataMemory);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return NULL;
}
} else {
if (mp_size != 0U) {
EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidDataMemory);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return NULL;
}
}
} else {
name = NULL;
mp = NULL;
mp_mem = NULL;
}
// Allocate object memory if not provided
if (mp == NULL) {
if (osRtxInfo.mpi.memory_pool != NULL) {
// lint -e{9079} "conversion from pointer to void to pointer to other
// type" [MISRA Note 5]
mp = osRtxMemoryPoolAlloc(osRtxInfo.mpi.memory_pool);
} else {
// lint -e{9079} "conversion from pointer to void to pointer to other
// type" [MISRA Note 5]
mp = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_memory_pool_t), 1U);
}
#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
if (mp != NULL) {
uint32_t used;
osRtxMemoryPoolMemUsage.cnt_alloc++;
used =
osRtxMemoryPoolMemUsage.cnt_alloc - osRtxMemoryPoolMemUsage.cnt_free;
if (osRtxMemoryPoolMemUsage.max_used < used) {
osRtxMemoryPoolMemUsage.max_used = used;
}
}
#endif
flags = osRtxFlagSystemObject;
} else {
flags = 0U;
}
// Allocate data memory if not provided
if ((mp != NULL) && (mp_mem == NULL)) {
// lint -e{9079} "conversion from pointer to void to pointer to other type"
// [MISRA Note 5]
mp_mem = osRtxMemoryAlloc(osRtxInfo.mem.mp_data, size, 0U);
if (mp_mem == NULL) {
if ((flags & osRtxFlagSystemObject) != 0U) {
if (osRtxInfo.mpi.memory_pool != NULL) {
(void)osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp);
} else {
(void)osRtxMemoryFree(osRtxInfo.mem.common, mp);
}
#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
osRtxMemoryPoolMemUsage.cnt_free++;
#endif
}
mp = NULL;
} else {
memset(mp_mem, 0, size);
}
flags |= osRtxFlagSystemMemory;
}
if (mp != NULL) {
// Initialize control block
mp->id = osRtxIdMemoryPool;
mp->flags = flags;
mp->name = name;
mp->thread_list = NULL;
(void)osRtxMemoryPoolInit(&mp->mp_info, b_count, b_size, mp_mem);
// Register post ISR processing function
osRtxInfo.post_process.memory_pool = osRtxMemoryPoolPostProcess;
EvrRtxMemoryPoolCreated(mp, mp->name);
} else {
EvrRtxMemoryPoolError(NULL, (int32_t)osErrorNoMemory);
}
return mp;
}
/// Get name of a Memory Pool object.
/// \note API identical to osMemoryPoolGetName
static const char *svcRtxMemoryPoolGetName(osMemoryPoolId_t mp_id) {
os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
// Check parameters
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
EvrRtxMemoryPoolGetName(mp, NULL);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return NULL;
}
EvrRtxMemoryPoolGetName(mp, mp->name);
return mp->name;
}
/// Allocate a memory block from a Memory Pool.
/// \note API identical to osMemoryPoolAlloc
static void *svcRtxMemoryPoolAlloc(osMemoryPoolId_t mp_id, uint32_t timeout) {
os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
void *block;
// Check parameters
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return NULL;
}
// Allocate memory
block = osRtxMemoryPoolAlloc(&mp->mp_info);
if (block != NULL) {
EvrRtxMemoryPoolAllocated(mp, block);
} else {
// No memory available
if (timeout != 0U) {
EvrRtxMemoryPoolAllocPending(mp, timeout);
// Suspend current Thread
if (osRtxThreadWaitEnter(osRtxThreadWaitingMemoryPool, timeout)) {
osRtxThreadListPut(osRtxObject(mp), osRtxThreadGetRunning());
} else {
EvrRtxMemoryPoolAllocTimeout(mp);
}
} else {
EvrRtxMemoryPoolAllocFailed(mp);
}
}
return block;
}
/// Return an allocated memory block back to a Memory Pool.
/// \note API identical to osMemoryPoolFree
static osStatus_t svcRtxMemoryPoolFree(osMemoryPoolId_t mp_id, void *block) {
os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
void *block0;
os_thread_t *thread;
osStatus_t status;
// Check parameters
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return osErrorParameter;
}
// Free memory
status = osRtxMemoryPoolFree(&mp->mp_info, block);
if (status == osOK) {
EvrRtxMemoryPoolDeallocated(mp, block);
// Check if Thread is waiting to allocate memory
if (mp->thread_list != NULL) {
// Allocate memory
block0 = osRtxMemoryPoolAlloc(&mp->mp_info);
if (block0 != NULL) {
// Wakeup waiting Thread with highest Priority
thread = osRtxThreadListGet(osRtxObject(mp));
// lint -e{923} "cast from pointer to unsigned int"
osRtxThreadWaitExit(thread, (uint32_t)block0, TRUE);
EvrRtxMemoryPoolAllocated(mp, block0);
}
}
} else {
EvrRtxMemoryPoolFreeFailed(mp, block);
}
return status;
}
/// Get maximum number of memory blocks in a Memory Pool.
/// \note API identical to osMemoryPoolGetCapacity
static uint32_t svcRtxMemoryPoolGetCapacity(osMemoryPoolId_t mp_id) {
os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
// Check parameters
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
EvrRtxMemoryPoolGetCapacity(mp, 0U);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return 0U;
}
EvrRtxMemoryPoolGetCapacity(mp, mp->mp_info.max_blocks);
return mp->mp_info.max_blocks;
}
/// Get memory block size in a Memory Pool.
/// \note API identical to osMemoryPoolGetBlockSize
static uint32_t svcRtxMemoryPoolGetBlockSize(osMemoryPoolId_t mp_id) {
os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
// Check parameters
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
EvrRtxMemoryPoolGetBlockSize(mp, 0U);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return 0U;
}
EvrRtxMemoryPoolGetBlockSize(mp, mp->mp_info.block_size);
return mp->mp_info.block_size;
}
/// Get number of memory blocks used in a Memory Pool.
/// \note API identical to osMemoryPoolGetCount
static uint32_t svcRtxMemoryPoolGetCount(osMemoryPoolId_t mp_id) {
os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
// Check parameters
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
EvrRtxMemoryPoolGetCount(mp, 0U);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return 0U;
}
EvrRtxMemoryPoolGetCount(mp, mp->mp_info.used_blocks);
return mp->mp_info.used_blocks;
}
/// Get number of memory blocks available in a Memory Pool.
/// \note API identical to osMemoryPoolGetSpace
static uint32_t svcRtxMemoryPoolGetSpace(osMemoryPoolId_t mp_id) {
os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
// Check parameters
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
EvrRtxMemoryPoolGetSpace(mp, 0U);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return 0U;
}
EvrRtxMemoryPoolGetSpace(mp,
mp->mp_info.max_blocks - mp->mp_info.used_blocks);
return (mp->mp_info.max_blocks - mp->mp_info.used_blocks);
}
/// Delete a Memory Pool object.
/// \note API identical to osMemoryPoolDelete
static osStatus_t svcRtxMemoryPoolDelete(osMemoryPoolId_t mp_id) {
os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
os_thread_t *thread;
// Check parameters
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return osErrorParameter;
}
// Unblock waiting threads
if (mp->thread_list != NULL) {
do {
thread = osRtxThreadListGet(osRtxObject(mp));
osRtxThreadWaitExit(thread, 0U, FALSE);
} while (mp->thread_list != NULL);
osRtxThreadDispatch(NULL);
}
// Mark object as invalid
mp->id = osRtxIdInvalid;
// Free data memory
if ((mp->flags & osRtxFlagSystemMemory) != 0U) {
(void)osRtxMemoryFree(osRtxInfo.mem.mp_data, mp->mp_info.block_base);
}
// Free object memory
if ((mp->flags & osRtxFlagSystemObject) != 0U) {
if (osRtxInfo.mpi.memory_pool != NULL) {
(void)osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp);
} else {
(void)osRtxMemoryFree(osRtxInfo.mem.common, mp);
}
#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
osRtxMemoryPoolMemUsage.cnt_free++;
#endif
}
EvrRtxMemoryPoolDestroyed(mp);
return osOK;
}
// Service Calls definitions
// lint ++flb "Library Begin" [MISRA Note 11]
SVC0_3(MemoryPoolNew, osMemoryPoolId_t, uint32_t, uint32_t,
const osMemoryPoolAttr_t *)
SVC0_1(MemoryPoolGetName, const char *, osMemoryPoolId_t)
SVC0_2(MemoryPoolAlloc, void *, osMemoryPoolId_t, uint32_t)
SVC0_2(MemoryPoolFree, osStatus_t, osMemoryPoolId_t, void *)
SVC0_1(MemoryPoolGetCapacity, uint32_t, osMemoryPoolId_t)
SVC0_1(MemoryPoolGetBlockSize, uint32_t, osMemoryPoolId_t)
SVC0_1(MemoryPoolGetCount, uint32_t, osMemoryPoolId_t)
SVC0_1(MemoryPoolGetSpace, uint32_t, osMemoryPoolId_t)
SVC0_1(MemoryPoolDelete, osStatus_t, osMemoryPoolId_t)
// lint --flb "Library End"
// ==== ISR Calls ====
/// Allocate a memory block from a Memory Pool.
/// \note API identical to osMemoryPoolAlloc
__STATIC_INLINE
void *isrRtxMemoryPoolAlloc(osMemoryPoolId_t mp_id, uint32_t timeout) {
os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
void *block;
// Check parameters
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool) || (timeout != 0U)) {
EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return NULL;
}
// Allocate memory
block = osRtxMemoryPoolAlloc(&mp->mp_info);
if (block == NULL) {
EvrRtxMemoryPoolAllocFailed(mp);
} else {
EvrRtxMemoryPoolAllocated(mp, block);
}
return block;
}
/// Return an allocated memory block back to a Memory Pool.
/// \note API identical to osMemoryPoolFree
__STATIC_INLINE
osStatus_t isrRtxMemoryPoolFree(osMemoryPoolId_t mp_id, void *block) {
os_memory_pool_t *mp = osRtxMemoryPoolId(mp_id);
osStatus_t status;
// Check parameters
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter);
// lint -e{904} "Return statement before end of function" [MISRA Note 1]
return osErrorParameter;
}
// Free memory
status = osRtxMemoryPoolFree(&mp->mp_info, block);
if (status == osOK) {
// Register post ISR processing
osRtxPostProcess(osRtxObject(mp));
EvrRtxMemoryPoolDeallocated(mp, block);
} else {
EvrRtxMemoryPoolFreeFailed(mp, block);
}
return status;
}
// ==== Public API ====
/// Create and Initialize a Memory Pool object.
osMemoryPoolId_t osMemoryPoolNew(uint32_t block_count, uint32_t block_size,
const osMemoryPoolAttr_t *attr) {
osMemoryPoolId_t mp_id;
EvrRtxMemoryPoolNew(block_count, block_size, attr);
if (IsIrqMode() || IsIrqMasked()) {
EvrRtxMemoryPoolError(NULL, (int32_t)osErrorISR);
mp_id = NULL;
} else {
mp_id = __svcMemoryPoolNew(block_count, block_size, attr);
}
return mp_id;
}
/// Get name of a Memory Pool object.
const char *osMemoryPoolGetName(osMemoryPoolId_t mp_id) {
const char *name;
if (IsIrqMode() || IsIrqMasked()) {
EvrRtxMemoryPoolGetName(mp_id, NULL);
name = NULL;
} else {
name = __svcMemoryPoolGetName(mp_id);
}
return name;
}
/// Allocate a memory block from a Memory Pool.
void *osMemoryPoolAlloc(osMemoryPoolId_t mp_id, uint32_t timeout) {
void *memory;
EvrRtxMemoryPoolAlloc(mp_id, timeout);
if (IsIrqMode() || IsIrqMasked()) {
memory = isrRtxMemoryPoolAlloc(mp_id, timeout);
} else {
memory = __svcMemoryPoolAlloc(mp_id, timeout);
}
return memory;
}
/// Return an allocated memory block back to a Memory Pool.
osStatus_t osMemoryPoolFree(osMemoryPoolId_t mp_id, void *block) {
osStatus_t status;
EvrRtxMemoryPoolFree(mp_id, block);
if (IsIrqMode() || IsIrqMasked()) {
status = isrRtxMemoryPoolFree(mp_id, block);
} else {
status = __svcMemoryPoolFree(mp_id, block);
}
return status;
}
/// Get maximum number of memory blocks in a Memory Pool.
uint32_t osMemoryPoolGetCapacity(osMemoryPoolId_t mp_id) {
uint32_t capacity;
if (IsIrqMode() || IsIrqMasked()) {
capacity = svcRtxMemoryPoolGetCapacity(mp_id);
} else {
capacity = __svcMemoryPoolGetCapacity(mp_id);
}
return capacity;
}
/// Get memory block size in a Memory Pool.
uint32_t osMemoryPoolGetBlockSize(osMemoryPoolId_t mp_id) {
uint32_t block_size;
if (IsIrqMode() || IsIrqMasked()) {
block_size = svcRtxMemoryPoolGetBlockSize(mp_id);
} else {
block_size = __svcMemoryPoolGetBlockSize(mp_id);
}
return block_size;
}
/// Get number of memory blocks used in a Memory Pool.
uint32_t osMemoryPoolGetCount(osMemoryPoolId_t mp_id) {
uint32_t count;
if (IsIrqMode() || IsIrqMasked()) {
count = svcRtxMemoryPoolGetCount(mp_id);
} else {
count = __svcMemoryPoolGetCount(mp_id);
}
return count;
}
/// Get number of memory blocks available in a Memory Pool.
uint32_t osMemoryPoolGetSpace(osMemoryPoolId_t mp_id) {
uint32_t space;
if (IsIrqMode() || IsIrqMasked()) {
space = svcRtxMemoryPoolGetSpace(mp_id);
} else {
space = __svcMemoryPoolGetSpace(mp_id);
}
return space;
}
/// Delete a Memory Pool object.
osStatus_t osMemoryPoolDelete(osMemoryPoolId_t mp_id) {
osStatus_t status;
EvrRtxMemoryPoolDelete(mp_id);
if (IsIrqMode() || IsIrqMasked()) {
EvrRtxMemoryPoolError(mp_id, (int32_t)osErrorISR);
status = osErrorISR;
} else {
status = __svcMemoryPoolDelete(mp_id);
}
return status;
}