685 lines
20 KiB
C
685 lines
20 KiB
C
/*
|
|
* Copyright (c) 2013-2017 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"
|
|
|
|
|
|
// ==== 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) {
|
|
void *block;
|
|
|
|
// Check parameters
|
|
if ((mp_info == NULL) || (block_count == 0U) || (block_size == 0U) || (block_mem == NULL)) {
|
|
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
|
|
while (--block_count) {
|
|
block = (uint8_t *)block_mem + block_size;
|
|
*((void **)block_mem) = block;
|
|
block_mem = block;
|
|
}
|
|
*((void **)block_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 == 0U)
|
|
uint32_t primask = __get_PRIMASK();
|
|
#endif
|
|
void *block;
|
|
|
|
if (mp_info == NULL) {
|
|
EvrRtxMemoryBlockAlloc(NULL, NULL);
|
|
return NULL;
|
|
}
|
|
|
|
#if (__EXCLUSIVE_ACCESS == 0U)
|
|
__disable_irq();
|
|
|
|
if (mp_info->used_blocks < mp_info->max_blocks) {
|
|
mp_info->used_blocks++;
|
|
block = mp_info->block_free;
|
|
if (block != NULL) {
|
|
mp_info->block_free = *((void **)block);
|
|
}
|
|
} else {
|
|
block = NULL;
|
|
}
|
|
|
|
if (primask == 0U) {
|
|
__enable_irq();
|
|
}
|
|
#else
|
|
if (atomic_inc32_lt(&mp_info->used_blocks, mp_info->max_blocks) < mp_info->max_blocks) {
|
|
block = atomic_link_get(&mp_info->block_free);
|
|
} else {
|
|
block = NULL;
|
|
}
|
|
#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 == 0U)
|
|
uint32_t primask = __get_PRIMASK();
|
|
#endif
|
|
osStatus_t status;
|
|
|
|
if ((mp_info == NULL) || (block < mp_info->block_base) || (block >= mp_info->block_lim)) {
|
|
EvrRtxMemoryBlockFree(mp_info, block, osErrorParameter);
|
|
return osErrorParameter;
|
|
}
|
|
|
|
#if (__EXCLUSIVE_ACCESS == 0U)
|
|
__disable_irq();
|
|
|
|
if (mp_info->used_blocks != 0U) {
|
|
mp_info->used_blocks--;
|
|
*((void **)block) = mp_info->block_free;
|
|
mp_info->block_free = block;
|
|
status = osOK;
|
|
} else {
|
|
status = osErrorResource;
|
|
}
|
|
|
|
if (primask == 0U) {
|
|
__enable_irq();
|
|
}
|
|
#else
|
|
if (atomic_dec32_nz(&mp_info->used_blocks) != 0U) {
|
|
atomic_link_put(&mp_info->block_free, block);
|
|
status = osOK;
|
|
} else {
|
|
status = osErrorResource;
|
|
}
|
|
#endif
|
|
|
|
EvrRtxMemoryBlockFree(mp_info, block, status);
|
|
|
|
return status;
|
|
}
|
|
|
|
/// Memory Pool post ISR processing.
|
|
/// \param[in] mp memory pool object.
|
|
void osRtxMemoryPoolPostProcess (os_memory_pool_t *mp) {
|
|
void *block;
|
|
os_thread_t *thread;
|
|
|
|
if (mp->state == osRtxObjectInactive) {
|
|
return;
|
|
}
|
|
|
|
// 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((os_object_t*)mp);
|
|
osRtxThreadWaitExit(thread, (uint32_t)block, false);
|
|
EvrRtxMemoryPoolAllocated(mp, block);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// ==== Service Calls ====
|
|
|
|
// Service Calls definitions
|
|
SVC0_3M(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)
|
|
|
|
/// Create and Initialize a Memory Pool object.
|
|
/// \note API identical to osMemoryPoolNew
|
|
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 size;
|
|
uint8_t flags;
|
|
const char *name;
|
|
|
|
// Check parameters
|
|
if ((block_count == 0U) || (block_size == 0U)) {
|
|
EvrRtxMemoryPoolError(NULL, osErrorParameter);
|
|
return NULL;
|
|
}
|
|
block_size = (block_size + 3U) & ~3UL;
|
|
if ((__CLZ(block_count) + __CLZ(block_size)) < 32) {
|
|
EvrRtxMemoryPoolError(NULL, osErrorParameter);
|
|
return NULL;
|
|
}
|
|
|
|
size = block_count * block_size;
|
|
|
|
// Process attributes
|
|
if (attr != NULL) {
|
|
name = attr->name;
|
|
mp = attr->cb_mem;
|
|
mp_mem = attr->mp_mem;
|
|
mp_size = attr->mp_size;
|
|
if (mp != NULL) {
|
|
if (((uint32_t)mp & 3U) || (attr->cb_size < sizeof(os_memory_pool_t))) {
|
|
EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidControlBlock);
|
|
return NULL;
|
|
}
|
|
} else {
|
|
if (attr->cb_size != 0U) {
|
|
EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidControlBlock);
|
|
return NULL;
|
|
}
|
|
}
|
|
if (mp_mem != NULL) {
|
|
if (((uint32_t)mp_mem & 3U) || (mp_size < size)) {
|
|
EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidDataMemory);
|
|
return NULL;
|
|
}
|
|
} else {
|
|
if (mp_size != 0U) {
|
|
EvrRtxMemoryPoolError(NULL, osRtxErrorInvalidDataMemory);
|
|
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) {
|
|
mp = osRtxMemoryPoolAlloc(osRtxInfo.mpi.memory_pool);
|
|
} else {
|
|
mp = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_memory_pool_t), 1U);
|
|
}
|
|
if (mp == NULL) {
|
|
EvrRtxMemoryPoolError(NULL, osErrorNoMemory);
|
|
return NULL;
|
|
}
|
|
flags = osRtxFlagSystemObject;
|
|
} else {
|
|
flags = 0U;
|
|
}
|
|
|
|
// Allocate data memory if not provided
|
|
if (mp_mem == NULL) {
|
|
mp_mem = osRtxMemoryAlloc(osRtxInfo.mem.mp_data, size, 0U);
|
|
if (mp_mem == NULL) {
|
|
EvrRtxMemoryPoolError(NULL, osErrorNoMemory);
|
|
if (flags & osRtxFlagSystemObject) {
|
|
if (osRtxInfo.mpi.memory_pool != NULL) {
|
|
osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp);
|
|
} else {
|
|
osRtxMemoryFree(osRtxInfo.mem.common, mp);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
memset(mp_mem, 0, size);
|
|
flags |= osRtxFlagSystemMemory;
|
|
}
|
|
|
|
// Initialize control block
|
|
mp->id = osRtxIdMemoryPool;
|
|
mp->state = osRtxObjectActive;
|
|
mp->flags = flags;
|
|
mp->name = name;
|
|
mp->thread_list = NULL;
|
|
osRtxMemoryPoolInit(&mp->mp_info, block_count, block_size, mp_mem);
|
|
|
|
// Register post ISR processing function
|
|
osRtxInfo.post_process.memory_pool = osRtxMemoryPoolPostProcess;
|
|
|
|
EvrRtxMemoryPoolCreated(mp);
|
|
|
|
return mp;
|
|
}
|
|
|
|
/// Get name of a Memory Pool object.
|
|
/// \note API identical to osMemoryPoolGetName
|
|
const char *svcRtxMemoryPoolGetName (osMemoryPoolId_t mp_id) {
|
|
os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
|
|
|
|
// Check parameters
|
|
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
|
|
EvrRtxMemoryPoolGetName(mp, NULL);
|
|
return NULL;
|
|
}
|
|
|
|
// Check object state
|
|
if (mp->state == osRtxObjectInactive) {
|
|
EvrRtxMemoryPoolGetName(mp, NULL);
|
|
return NULL;
|
|
}
|
|
|
|
EvrRtxMemoryPoolGetName(mp, mp->name);
|
|
|
|
return mp->name;
|
|
}
|
|
|
|
/// Allocate a memory block from a Memory Pool.
|
|
/// \note API identical to osMemoryPoolAlloc
|
|
void *svcRtxMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) {
|
|
os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
|
|
void *block;
|
|
|
|
// Check parameters
|
|
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
|
|
EvrRtxMemoryPoolError(mp, osErrorParameter);
|
|
return NULL;
|
|
}
|
|
|
|
// Check object state
|
|
if (mp->state == osRtxObjectInactive) {
|
|
EvrRtxMemoryPoolError(mp, osErrorResource);
|
|
return NULL;
|
|
}
|
|
|
|
// Allocate memory
|
|
block = osRtxMemoryPoolAlloc(&mp->mp_info);
|
|
if (block == NULL) {
|
|
// No memory available
|
|
if (timeout != 0U) {
|
|
EvrRtxMemoryPoolAllocPending(mp, timeout);
|
|
// Suspend current Thread
|
|
osRtxThreadListPut((os_object_t*)mp, osRtxThreadGetRunning());
|
|
osRtxThreadWaitEnter(osRtxThreadWaitingMemoryPool, timeout);
|
|
} else {
|
|
EvrRtxMemoryPoolAllocFailed(mp);
|
|
}
|
|
} else {
|
|
EvrRtxMemoryPoolAllocated(mp, block);
|
|
}
|
|
|
|
return block;
|
|
}
|
|
|
|
/// Return an allocated memory block back to a Memory Pool.
|
|
/// \note API identical to osMemoryPoolFree
|
|
osStatus_t svcRtxMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) {
|
|
os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
|
|
os_thread_t *thread;
|
|
osStatus_t status;
|
|
|
|
// Check parameters
|
|
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
|
|
EvrRtxMemoryPoolError(mp, osErrorParameter);
|
|
return osErrorParameter;
|
|
}
|
|
|
|
// Check object state
|
|
if (mp->state == osRtxObjectInactive) {
|
|
EvrRtxMemoryPoolError(mp, osErrorResource);
|
|
return osErrorResource;
|
|
}
|
|
|
|
// 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
|
|
block = osRtxMemoryPoolAlloc(&mp->mp_info);
|
|
if (block != NULL) {
|
|
// Wakeup waiting Thread with highest Priority
|
|
thread = osRtxThreadListGet((os_object_t*)mp);
|
|
osRtxThreadWaitExit(thread, (uint32_t)block, true);
|
|
EvrRtxMemoryPoolAllocated(mp, block);
|
|
}
|
|
}
|
|
} else {
|
|
EvrRtxMemoryPoolFreeFailed(mp, block);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/// Get maximum number of memory blocks in a Memory Pool.
|
|
/// \note API identical to osMemoryPoolGetCapacity
|
|
uint32_t svcRtxMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) {
|
|
os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
|
|
|
|
// Check parameters
|
|
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
|
|
EvrRtxMemoryPoolGetCapacity(mp, 0U);
|
|
return 0U;
|
|
}
|
|
|
|
// Check object state
|
|
if (mp->state == osRtxObjectInactive) {
|
|
EvrRtxMemoryPoolGetCapacity(mp, 0U);
|
|
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
|
|
uint32_t svcRtxMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) {
|
|
os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
|
|
|
|
// Check parameters
|
|
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
|
|
EvrRtxMemoryPoolGetBlockSize(mp, 0U);
|
|
return 0U;
|
|
}
|
|
|
|
// Check object state
|
|
if (mp->state == osRtxObjectInactive) {
|
|
EvrRtxMemoryPoolGetBlockSize(mp, 0U);
|
|
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
|
|
uint32_t svcRtxMemoryPoolGetCount (osMemoryPoolId_t mp_id) {
|
|
os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
|
|
|
|
// Check parameters
|
|
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
|
|
EvrRtxMemoryPoolGetCount(mp, 0U);
|
|
return 0U;
|
|
}
|
|
|
|
// Check object state
|
|
if (mp->state == osRtxObjectInactive) {
|
|
EvrRtxMemoryPoolGetCount(mp, 0U);
|
|
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
|
|
uint32_t svcRtxMemoryPoolGetSpace (osMemoryPoolId_t mp_id) {
|
|
os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
|
|
|
|
// Check parameters
|
|
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
|
|
EvrRtxMemoryPoolGetSpace(mp, 0U);
|
|
return 0U;
|
|
}
|
|
|
|
// Check object state
|
|
if (mp->state == osRtxObjectInactive) {
|
|
EvrRtxMemoryPoolGetSpace(mp, 0U);
|
|
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
|
|
osStatus_t svcRtxMemoryPoolDelete (osMemoryPoolId_t mp_id) {
|
|
os_memory_pool_t *mp = (os_memory_pool_t *)mp_id;
|
|
os_thread_t *thread;
|
|
|
|
// Check parameters
|
|
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
|
|
EvrRtxMemoryPoolError(mp, osErrorParameter);
|
|
return osErrorParameter;
|
|
}
|
|
|
|
// Check object state
|
|
if (mp->state == osRtxObjectInactive) {
|
|
EvrRtxMemoryPoolError(mp, osErrorResource);
|
|
return osErrorResource;
|
|
}
|
|
|
|
// Mark object as inactive
|
|
mp->state = osRtxObjectInactive;
|
|
|
|
// Unblock waiting threads
|
|
if (mp->thread_list != NULL) {
|
|
do {
|
|
thread = osRtxThreadListGet((os_object_t*)mp);
|
|
osRtxThreadWaitExit(thread, 0U, false);
|
|
} while (mp->thread_list != NULL);
|
|
osRtxThreadDispatch(NULL);
|
|
}
|
|
|
|
// Free data memory
|
|
if (mp->flags & osRtxFlagSystemMemory) {
|
|
osRtxMemoryFree(osRtxInfo.mem.mp_data, mp->mp_info.block_base);
|
|
}
|
|
|
|
// Free object memory
|
|
if (mp->flags & osRtxFlagSystemObject) {
|
|
if (osRtxInfo.mpi.memory_pool != NULL) {
|
|
osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp);
|
|
} else {
|
|
osRtxMemoryFree(osRtxInfo.mem.common, mp);
|
|
}
|
|
}
|
|
|
|
EvrRtxMemoryPoolDestroyed(mp);
|
|
|
|
return osOK;
|
|
}
|
|
|
|
|
|
// ==== 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 = (os_memory_pool_t *)mp_id;
|
|
void *block;
|
|
|
|
// Check parameters
|
|
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool) || (timeout != 0U)) {
|
|
EvrRtxMemoryPoolError(mp, osErrorParameter);
|
|
return NULL;
|
|
}
|
|
|
|
// Check object state
|
|
if (mp->state == osRtxObjectInactive) {
|
|
EvrRtxMemoryPoolError(mp, osErrorResource);
|
|
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 = (os_memory_pool_t *)mp_id;
|
|
osStatus_t status;
|
|
|
|
// Check parameters
|
|
if ((mp == NULL) || (mp->id != osRtxIdMemoryPool)) {
|
|
EvrRtxMemoryPoolError(mp, osErrorParameter);
|
|
return osErrorParameter;
|
|
}
|
|
|
|
// Check object state
|
|
if (mp->state == osRtxObjectInactive) {
|
|
EvrRtxMemoryPoolError(mp, osErrorResource);
|
|
return osErrorResource;
|
|
}
|
|
|
|
// Free memory
|
|
status = osRtxMemoryPoolFree(&mp->mp_info, block);
|
|
if (status == osOK) {
|
|
// Register post ISR processing
|
|
osRtxPostProcess((os_object_t *)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) {
|
|
EvrRtxMemoryPoolNew(block_count, block_size, attr);
|
|
if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
|
|
EvrRtxMemoryPoolError(NULL, osErrorISR);
|
|
return NULL;
|
|
}
|
|
return __svcMemoryPoolNew(block_count, block_size, attr);
|
|
}
|
|
|
|
/// Get name of a Memory Pool object.
|
|
const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id) {
|
|
if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
|
|
EvrRtxMemoryPoolGetName(mp_id, NULL);
|
|
return NULL;
|
|
}
|
|
return __svcMemoryPoolGetName(mp_id);
|
|
}
|
|
|
|
/// Allocate a memory block from a Memory Pool.
|
|
void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout) {
|
|
EvrRtxMemoryPoolAlloc(mp_id, timeout);
|
|
if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
|
|
return isrRtxMemoryPoolAlloc(mp_id, timeout);
|
|
} else {
|
|
return __svcMemoryPoolAlloc(mp_id, timeout);
|
|
}
|
|
}
|
|
|
|
/// Return an allocated memory block back to a Memory Pool.
|
|
osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block) {
|
|
EvrRtxMemoryPoolFree(mp_id, block);
|
|
if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
|
|
return isrRtxMemoryPoolFree(mp_id, block);
|
|
} else {
|
|
return __svcMemoryPoolFree(mp_id, block);
|
|
}
|
|
}
|
|
|
|
/// Get maximum number of memory blocks in a Memory Pool.
|
|
uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id) {
|
|
if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
|
|
return svcRtxMemoryPoolGetCapacity(mp_id);
|
|
} else {
|
|
return __svcMemoryPoolGetCapacity(mp_id);
|
|
}
|
|
}
|
|
|
|
/// Get memory block size in a Memory Pool.
|
|
uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id) {
|
|
if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
|
|
return svcRtxMemoryPoolGetBlockSize(mp_id);
|
|
} else {
|
|
return __svcMemoryPoolGetBlockSize(mp_id);
|
|
}
|
|
}
|
|
|
|
/// Get number of memory blocks used in a Memory Pool.
|
|
uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id) {
|
|
if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
|
|
return svcRtxMemoryPoolGetCount(mp_id);
|
|
} else {
|
|
return __svcMemoryPoolGetCount(mp_id);
|
|
}
|
|
}
|
|
|
|
/// Get number of memory blocks available in a Memory Pool.
|
|
uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id) {
|
|
if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
|
|
return svcRtxMemoryPoolGetSpace(mp_id);
|
|
} else {
|
|
return __svcMemoryPoolGetSpace(mp_id);
|
|
}
|
|
}
|
|
|
|
/// Delete a Memory Pool object.
|
|
osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id) {
|
|
EvrRtxMemoryPoolDelete(mp_id);
|
|
if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
|
|
EvrRtxMemoryPoolError(mp_id, osErrorISR);
|
|
return osErrorISR;
|
|
}
|
|
return __svcMemoryPoolDelete(mp_id);
|
|
}
|