| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847 |
- /*
- * Copyright (c) 2013-2023 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
- #ifdef RTX_OBJ_MEM_USAGE
- osRtxObjectMemUsage_t osRtxMemoryPoolMemUsage \
- __attribute__((section(".data.os.mempool.obj"))) =
- { 0U, 0U, 0U };
- #endif
- // ==== Helper functions ====
- /// Verify that Memory Pool object pointer is valid.
- /// \param[in] mp memory pool object.
- /// \return true - valid, false - invalid.
- static bool_t IsMemoryPoolPtrValid (const os_memory_pool_t *mp) {
- #ifdef RTX_OBJ_PTR_CHECK
- //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
- uint32_t cb_start = (uint32_t)&__os_mempool_cb_start__;
- uint32_t cb_length = (uint32_t)&__os_mempool_cb_length__;
- // Check the section boundaries
- if (((uint32_t)mp - cb_start) >= cb_length) {
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return FALSE;
- }
- // Check the object alignment
- if ((((uint32_t)mp - cb_start) % sizeof(os_memory_pool_t)) != 0U) {
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return FALSE;
- }
- #else
- // Check NULL pointer
- if (mp == NULL) {
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return FALSE;
- }
- #endif
- return TRUE;
- }
- // ==== 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;
- }
- /// Destroy a Memory Pool object.
- /// \param[in] mp memory pool object.
- static void osRtxMemoryPoolDestroy (os_memory_pool_t *mp) {
- // 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) {
- #ifdef RTX_OBJ_PTR_CHECK
- (void)osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp);
- #else
- if (osRtxInfo.mpi.memory_pool != NULL) {
- (void)osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp);
- } else {
- (void)osRtxMemoryFree(osRtxInfo.mem.common, mp);
- }
- #endif
- #ifdef RTX_OBJ_MEM_USAGE
- osRtxMemoryPoolMemUsage.cnt_free++;
- #endif
- }
- EvrRtxMemoryPoolDestroyed(mp);
- }
- #ifdef RTX_SAFETY_CLASS
- /// Delete a Memory Pool safety class.
- /// \param[in] safety_class safety class.
- /// \param[in] mode safety mode.
- void osRtxMemoryPoolDeleteClass (uint32_t safety_class, uint32_t mode) {
- os_memory_pool_t *mp;
- os_thread_t *thread;
- uint32_t length;
- //lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
- mp = (os_memory_pool_t *)(uint32_t)&__os_mempool_cb_start__;
- length = (uint32_t)&__os_mempool_cb_length__;
- while (length >= sizeof(os_memory_pool_t)) {
- if ( (mp->id == osRtxIdMemoryPool) &&
- ((((mode & osSafetyWithSameClass) != 0U) &&
- ((mp->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
- (((mode & osSafetyWithLowerClass) != 0U) &&
- ((mp->attr >> osRtxAttrClass_Pos) < (uint8_t)safety_class)))) {
- while (mp->thread_list != NULL) {
- thread = osRtxThreadListGet(osRtxObject(mp));
- osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE);
- }
- osRtxMemoryPoolDestroy(mp);
- }
- length -= sizeof(os_memory_pool_t);
- mp++;
- }
- }
- #endif
- // ==== 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;
- #ifdef RTX_SAFETY_CLASS
- const os_thread_t *thread = osRtxThreadGetRunning();
- uint32_t attr_bits;
- #endif
- 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) ||
- ((__CLZ(block_count) + __CLZ(block_size)) < 32U)) {
- 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;
- size = b_count * b_size;
- // Process attributes
- if (attr != NULL) {
- name = attr->name;
- #ifdef RTX_SAFETY_CLASS
- attr_bits = attr->attr_bits;
- #endif
- //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;
- #ifdef RTX_SAFETY_CLASS
- if ((attr_bits & osSafetyClass_Valid) != 0U) {
- if ((thread != NULL) &&
- ((thread->attr >> osRtxAttrClass_Pos) <
- (uint8_t)((attr_bits & osSafetyClass_Msk) >> osSafetyClass_Pos))) {
- EvrRtxMemoryPoolError(NULL, (int32_t)osErrorSafetyClass);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return NULL;
- }
- }
- #endif
- if (mp != NULL) {
- if (!IsMemoryPoolPtrValid(mp) || (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} "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;
- #ifdef RTX_SAFETY_CLASS
- attr_bits = 0U;
- #endif
- 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);
- #ifndef RTX_OBJ_PTR_CHECK
- } 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);
- #endif
- }
- #ifdef RTX_OBJ_MEM_USAGE
- 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) {
- #ifdef RTX_OBJ_PTR_CHECK
- (void)osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp);
- #else
- if (osRtxInfo.mpi.memory_pool != NULL) {
- (void)osRtxMemoryPoolFree(osRtxInfo.mpi.memory_pool, mp);
- } else {
- (void)osRtxMemoryFree(osRtxInfo.mem.common, mp);
- }
- #endif
- #ifdef RTX_OBJ_MEM_USAGE
- osRtxMemoryPoolMemUsage.cnt_free++;
- #endif
- }
- mp = NULL;
- } else {
- (void)memset(mp_mem, 0, size);
- }
- flags |= osRtxFlagSystemMemory;
- }
- if (mp != NULL) {
- // Initialize control block
- mp->id = osRtxIdMemoryPool;
- mp->flags = flags;
- mp->attr = 0U;
- mp->name = name;
- mp->thread_list = NULL;
- #ifdef RTX_SAFETY_CLASS
- if ((attr_bits & osSafetyClass_Valid) != 0U) {
- mp->attr |= (uint8_t)((attr_bits & osSafetyClass_Msk) >>
- (osSafetyClass_Pos - osRtxAttrClass_Pos));
- } else {
- // Inherit safety class from the running thread
- if (thread != NULL) {
- mp->attr |= (uint8_t)(thread->attr & osRtxAttrClass_Msk);
- }
- }
- #endif
- (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 (!IsMemoryPoolPtrValid(mp) || (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);
- #ifdef RTX_SAFETY_CLASS
- const os_thread_t *thread;
- #endif
- void *block;
- // Check parameters
- if (!IsMemoryPoolPtrValid(mp) || (mp->id != osRtxIdMemoryPool)) {
- EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return NULL;
- }
- #ifdef RTX_SAFETY_CLASS
- // Check running thread safety class
- thread = osRtxThreadGetRunning();
- if ((thread != NULL) &&
- ((thread->attr >> osRtxAttrClass_Pos) < (mp->attr >> osRtxAttrClass_Pos))) {
- EvrRtxMemoryPoolError(mp, (int32_t)osErrorSafetyClass);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return NULL;
- }
- #endif
- // 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 (!IsMemoryPoolPtrValid(mp) || (mp->id != osRtxIdMemoryPool)) {
- EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorParameter;
- }
- #ifdef RTX_SAFETY_CLASS
- // Check running thread safety class
- thread = osRtxThreadGetRunning();
- if ((thread != NULL) &&
- ((thread->attr >> osRtxAttrClass_Pos) < (mp->attr >> osRtxAttrClass_Pos))) {
- EvrRtxMemoryPoolError(mp, (int32_t)osErrorSafetyClass);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorSafetyClass;
- }
- #endif
- // 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 (!IsMemoryPoolPtrValid(mp) || (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 (!IsMemoryPoolPtrValid(mp) || (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 (!IsMemoryPoolPtrValid(mp) || (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 (!IsMemoryPoolPtrValid(mp) || (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 (!IsMemoryPoolPtrValid(mp) || (mp->id != osRtxIdMemoryPool)) {
- EvrRtxMemoryPoolError(mp, (int32_t)osErrorParameter);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorParameter;
- }
- #ifdef RTX_SAFETY_CLASS
- // Check running thread safety class
- thread = osRtxThreadGetRunning();
- if ((thread != NULL) &&
- ((thread->attr >> osRtxAttrClass_Pos) < (mp->attr >> osRtxAttrClass_Pos))) {
- EvrRtxMemoryPoolError(mp, (int32_t)osErrorSafetyClass);
- //lint -e{904} "Return statement before end of function" [MISRA Note 1]
- return osErrorSafetyClass;
- }
- #endif
- // Unblock waiting threads
- if (mp->thread_list != NULL) {
- do {
- thread = osRtxThreadListGet(osRtxObject(mp));
- osRtxThreadWaitExit(thread, 0U, FALSE);
- } while (mp->thread_list != NULL);
- osRtxThreadDispatch(NULL);
- }
- osRtxMemoryPoolDestroy(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 (!IsMemoryPoolPtrValid(mp) || (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 (!IsMemoryPoolPtrValid(mp) || (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 (IsException() || 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 (IsException() || IsIrqMasked()) {
- name = svcRtxMemoryPoolGetName(mp_id);
- } 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 (IsException() || 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 (IsException() || 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 (IsException() || 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 (IsException() || 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 (IsException() || 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 (IsException() || 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 (IsException() || IsIrqMasked()) {
- EvrRtxMemoryPoolError(mp_id, (int32_t)osErrorISR);
- status = osErrorISR;
- } else {
- status = __svcMemoryPoolDelete(mp_id);
- }
- return status;
- }
|