| /* |
| * FreeRTOS Common V1.1.1 |
| * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a copy of |
| * this software and associated documentation files (the "Software"), to deal in |
| * the Software without restriction, including without limitation the rights to |
| * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
| * the Software, and to permit persons to whom the Software is furnished to do so, |
| * subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included in all |
| * copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
| * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
| * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
| * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| * |
| * http://aws.amazon.com/freertos |
| * http://www.FreeRTOS.org |
| */ |
| |
| /** |
| * @file iot_static_memory_common.c |
| * @brief Implementation of common static memory functions in iot_static_memory.h |
| */ |
| |
| /* The config header is always included first. */ |
| #include "iot_config.h" |
| |
| /* This file should only be compiled if dynamic memory allocation is forbidden. */ |
| #if IOT_STATIC_MEMORY_ONLY == 1 |
| |
| /* Standard includes. */ |
| #include <stdbool.h> |
| #include <stddef.h> |
| #include <stdint.h> |
| #include <string.h> |
| |
| /* Platform layer includes. */ |
| #include "platform/iot_threads.h" |
| |
| /* Static memory include. */ |
| #include "private/iot_static_memory.h" |
| |
| /*-----------------------------------------------------------*/ |
| |
| /** |
| * @cond DOXYGEN_IGNORE |
| * Doxygen should ignore this section. |
| * |
| * Provide default values for undefined configuration constants. |
| */ |
| #ifndef IOT_MESSAGE_BUFFERS |
| #define IOT_MESSAGE_BUFFERS ( 8 ) |
| #endif |
| #ifndef IOT_MESSAGE_BUFFER_SIZE |
| #define IOT_MESSAGE_BUFFER_SIZE ( 1024 ) |
| #endif |
| /** @endcond */ |
| |
| /* Validate static memory configuration settings. */ |
| #if IOT_MESSAGE_BUFFERS <= 0 |
| #error "IOT_MESSAGE_BUFFERS cannot be 0 or negative." |
| #endif |
| #if IOT_MESSAGE_BUFFER_SIZE <= 0 |
| #error "IOT_MESSAGE_BUFFER_SIZE cannot be 0 or negative." |
| #endif |
| |
| /*-----------------------------------------------------------*/ |
| |
| /** |
| * @brief Guards access to critical sections. |
| */ |
| static IotMutex_t _mutex; |
| |
| /* |
| * Static memory buffers and flags, allocated and zeroed at compile-time. |
| */ |
| static bool _pInUseMessageBuffers[ IOT_MESSAGE_BUFFERS ] = { 0 }; /**< @brief Message buffer in-use flags. */ |
| static char _pMessageBuffers[ IOT_MESSAGE_BUFFERS ][ IOT_MESSAGE_BUFFER_SIZE ] = { { 0 } }; /**< @brief Message buffers. */ |
| |
| /*-----------------------------------------------------------*/ |
| |
| int32_t IotStaticMemory_FindFree( bool * pInUse, |
| size_t limit ) |
| { |
| size_t i = 0; |
| int32_t freeIndex = -1; |
| |
| /* Perform the search for a free buffer in a critical section. */ |
| IotMutex_Lock( &( _mutex ) ); |
| |
| for( i = 0; i < limit; i++ ) |
| { |
| if( pInUse[ i ] == false ) |
| { |
| /* If a free buffer is found, mark it "in-use" and return its index. */ |
| pInUse[ i ] = true; |
| freeIndex = ( int32_t ) i; |
| break; |
| } |
| } |
| |
| /* Exit the critical section. */ |
| IotMutex_Unlock( &( _mutex ) ); |
| |
| return freeIndex; |
| } |
| |
| /*-----------------------------------------------------------*/ |
| |
| void IotStaticMemory_ReturnInUse( void * ptr, |
| void * pPool, |
| bool * pInUse, |
| size_t limit, |
| size_t elementSize ) |
| { |
| size_t i = 0; |
| uint8_t * element = NULL; |
| |
| /* Clear ptr. */ |
| ( void ) memset( ptr, 0x00, elementSize ); |
| |
| /* Perform a search for ptr to make sure it's part of pPool. This search |
| * is done in a critical section. */ |
| IotMutex_Lock( &( _mutex ) ); |
| |
| for( i = 0; i < limit; i++ ) |
| { |
| /* Calculate address of the i-th element in pPool. */ |
| element = ( ( uint8_t * ) pPool ) + elementSize * i; |
| |
| /* Check for a match. */ |
| if( ( ( void * ) element == ptr ) && |
| ( pInUse[ i ] == true ) ) |
| { |
| pInUse[ i ] = false; |
| break; |
| } |
| } |
| |
| /* Exit the critical section. */ |
| IotMutex_Unlock( &( _mutex ) ); |
| } |
| |
| /*-----------------------------------------------------------*/ |
| |
| bool IotStaticMemory_Init( void ) |
| { |
| return IotMutex_Create( &( _mutex ), false ); |
| } |
| |
| /*-----------------------------------------------------------*/ |
| |
| void IotStaticMemory_Cleanup( void ) |
| { |
| IotMutex_Destroy( &( _mutex ) ); |
| } |
| |
| /*-----------------------------------------------------------*/ |
| |
| size_t Iot_MessageBufferSize( void ) |
| { |
| return ( size_t ) IOT_MESSAGE_BUFFER_SIZE; |
| } |
| |
| /*-----------------------------------------------------------*/ |
| |
| void * Iot_MallocMessageBuffer( size_t size ) |
| { |
| int32_t freeIndex = -1; |
| void * pNewBuffer = NULL; |
| |
| /* Check that size is within the fixed message buffer size. */ |
| if( size <= IOT_MESSAGE_BUFFER_SIZE ) |
| { |
| /* Get the index of a free message buffer. */ |
| freeIndex = IotStaticMemory_FindFree( _pInUseMessageBuffers, |
| IOT_MESSAGE_BUFFERS ); |
| |
| if( freeIndex != -1 ) |
| { |
| pNewBuffer = &( _pMessageBuffers[ freeIndex ][ 0 ] ); |
| } |
| } |
| |
| return pNewBuffer; |
| } |
| |
| /*-----------------------------------------------------------*/ |
| |
| void Iot_FreeMessageBuffer( void * ptr ) |
| { |
| /* Return the in-use message buffer. */ |
| IotStaticMemory_ReturnInUse( ptr, |
| _pMessageBuffers, |
| _pInUseMessageBuffers, |
| IOT_MESSAGE_BUFFERS, |
| IOT_MESSAGE_BUFFER_SIZE ); |
| } |
| |
| /*-----------------------------------------------------------*/ |
| |
| #endif /* if IOT_STATIC_MEMORY_ONLY == 1 */ |