Skip to content

Commit

Permalink
freertos: Add wrapper functions to create objects with capabilities
Browse files Browse the repository at this point in the history
This commit adds various ...WithCaps() functions to create FreeRTOS objects
with specific memory capabilities.
  • Loading branch information
Dazza0 committed Apr 12, 2023
1 parent 478e041 commit 4e7cd2e
Show file tree
Hide file tree
Showing 6 changed files with 545 additions and 4 deletions.
1 change: 1 addition & 0 deletions components/freertos/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ endif()

set(srcs
"heap_idf.c"
"esp_additions/idf_additions.c"
"${kernel_dir}/list.c"
"${kernel_dir}/queue.c"
"${kernel_dir}/tasks.c"
Expand Down
275 changes: 275 additions & 0 deletions components/freertos/esp_additions/idf_additions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "sdkconfig.h"
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "freertos/stream_buffer.h"
#include "freertos/message_buffer.h"
#include "freertos/event_groups.h"
#include "freertos/timers.h"
#include "freertos/idf_additions.h"
#include "esp_heap_caps.h"

/*
* This file contains the implementation for some the functions in
* idf_additions.h
*/

/* -----------------------------------------------------------------------------
* Creation With Memory Caps
* -------------------------------------------------------------------------- */

#if ( configSUPPORT_STATIC_ALLOCATION == 1 )

/* ---------------------------------- Queue --------------------------------- */

QueueHandle_t xQueueCreateWithCaps( UBaseType_t uxQueueLength,
UBaseType_t uxItemSize,
UBaseType_t uxMemoryCaps )
{
QueueHandle_t xQueue;
StaticQueue_t * pxQueueBuffer;
uint8_t * pucQueueStorageBuffer;

/* Allocate memory for the queue using the provided memory caps */
pxQueueBuffer = heap_caps_malloc( sizeof( StaticQueue_t ), ( uint32_t ) uxMemoryCaps );

if( uxItemSize == 0 )
{
pucQueueStorageBuffer = NULL;
}
else
{
pucQueueStorageBuffer = heap_caps_malloc( uxQueueLength * uxItemSize, ( uint32_t ) uxMemoryCaps );
}

if( ( pxQueueBuffer == NULL ) || ( ( uxItemSize > 0 ) && ( pucQueueStorageBuffer == NULL ) ) )
{
goto err;
}

/* Create the queue using static creation API */
xQueue = xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorageBuffer, pxQueueBuffer );

if( xQueue == NULL )
{
goto err;
}

return xQueue;

err:
heap_caps_free( pucQueueStorageBuffer );
heap_caps_free( pxQueueBuffer );
return NULL;
}

void vQueueDeleteWithCaps( QueueHandle_t xQueue )
{
BaseType_t xResult;
StaticQueue_t * pxQueueBuffer;
uint8_t * pucQueueStorageBuffer;

/* Retrieve the buffers used to create the queue before deleting it */
xResult = xQueueGetStaticBuffers( xQueue, &pucQueueStorageBuffer, &pxQueueBuffer );
configASSERT( xResult == pdTRUE );

/* Delete the queue */
vQueueDelete( xQueue );

/* Free the memory buffers */
heap_caps_free( pxQueueBuffer );
heap_caps_free( pucQueueStorageBuffer );
}

/* -------------------------------- Semaphore ------------------------------- */

SemaphoreHandle_t xSemaphoreCreateGenericWithCaps( UBaseType_t uxMaxCount,
UBaseType_t uxInitialCount,
const uint8_t ucQueueType,
UBaseType_t uxMemoryCaps )
{
SemaphoreHandle_t xSemaphore;
StaticSemaphore_t * pxSemaphoreBuffer;

/* Allocate memory for the semaphore using the provided memory caps */
pxSemaphoreBuffer = heap_caps_malloc( sizeof( StaticSemaphore_t ), ( uint32_t ) uxMemoryCaps );

if( pxSemaphoreBuffer == NULL )
{
return NULL;
}

/* Create the semaphore using static creation API */
if( ucQueueType == queueQUEUE_TYPE_MUTEX )
{
xSemaphore = xSemaphoreCreateMutexStatic( pxSemaphoreBuffer );
}
else if( ucQueueType == queueQUEUE_TYPE_COUNTING_SEMAPHORE )
{
xSemaphore = xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer );
}
else if( ucQueueType == queueQUEUE_TYPE_BINARY_SEMAPHORE )
{
xSemaphore = xSemaphoreCreateBinaryStatic( pxSemaphoreBuffer );
}
else /* ucQueueType == queueQUEUE_TYPE_RECURSIVE_MUTEX */
{
xSemaphore = xSemaphoreCreateRecursiveMutexStatic( pxSemaphoreBuffer );
}

if( xSemaphore == NULL )
{
heap_caps_free( pxSemaphoreBuffer );
}

return xSemaphore;
}

void vSemaphoreDeleteWithCaps( SemaphoreHandle_t xSemaphore )
{
BaseType_t xResult;
StaticSemaphore_t * pxSemaphoreBuffer;

/* Retrieve the buffer used to create the semaphore before deleting it
* */
xResult = xSemaphoreGetStaticBuffer( xSemaphore, &pxSemaphoreBuffer );
configASSERT( xResult == pdTRUE );

/* Delete the semaphore */
vSemaphoreDelete( xSemaphore );

/* Free the memory buffer */
heap_caps_free( pxSemaphoreBuffer );
}

/* ------------------------- Stream & Message Buffers ----------------------- */

StreamBufferHandle_t xStreamBufferGenericCreateWithCaps( size_t xBufferSizeBytes,
size_t xTriggerLevelBytes,
BaseType_t xIsMessageBuffer,
UBaseType_t uxMemoryCaps )
{
StreamBufferHandle_t xStreamBuffer;
StaticStreamBuffer_t * pxStaticStreamBuffer;
uint8_t * pucStreamBufferStorageArea;

/* Allocate memory for the stream or message buffer using the provided
* memory caps */
pxStaticStreamBuffer = heap_caps_malloc( sizeof( StaticStreamBuffer_t ), ( uint32_t ) uxMemoryCaps );
pucStreamBufferStorageArea = heap_caps_malloc( xBufferSizeBytes, ( uint32_t ) uxMemoryCaps );

if( ( pxStaticStreamBuffer == NULL ) || ( pucStreamBufferStorageArea == NULL ) )
{
goto err;
}

/* Create the stream or message buffer using static creation API */
if( xIsMessageBuffer == pdTRUE )
{
xStreamBuffer = ( StreamBufferHandle_t ) xMessageBufferCreateStatic( xBufferSizeBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer );
}
else
{
xStreamBuffer = xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer );
}

if( xStreamBuffer == NULL )
{
goto err;
}

return xStreamBuffer;

err:
heap_caps_free( pucStreamBufferStorageArea );
heap_caps_free( pxStaticStreamBuffer );
return NULL;
}

void vStreamBufferGenericDeleteWithCaps( StreamBufferHandle_t xStreamBuffer,
BaseType_t xIsMessageBuffer )
{
BaseType_t xResult;
StaticStreamBuffer_t * pxStaticStreamBuffer;
uint8_t * pucStreamBufferStorageArea;

/* Retrieve the buffers used to create the stream or message buffer
* before deleting it */
if( xIsMessageBuffer == pdTRUE )
{
xResult = xMessageBufferGetStaticBuffers( xStreamBuffer, &pucStreamBufferStorageArea, &pxStaticStreamBuffer );
}
else
{
xResult = xStreamBufferGetStaticBuffers( xStreamBuffer, &pucStreamBufferStorageArea, &pxStaticStreamBuffer );
}

configASSERT( xResult == pdTRUE );

/* Delete the stream or message buffer */
if( xIsMessageBuffer == pdTRUE )
{
vMessageBufferDelete( xStreamBuffer );
}
else
{
vSemaphoreDelete( xStreamBuffer );
}

/* Free the memory buffers */
heap_caps_free( pxStaticStreamBuffer );
heap_caps_free( pucStreamBufferStorageArea );
}

/* ------------------------------ Event Groups ------------------------------ */

EventGroupHandle_t xEventGroupCreateWithCaps( UBaseType_t uxMemoryCaps )
{
EventGroupHandle_t xEventGroup;
StaticEventGroup_t * pxEventGroupBuffer;

/* Allocate memory for the event group using the provided memory caps */
pxEventGroupBuffer = heap_caps_malloc( sizeof( StaticEventGroup_t ), uxMemoryCaps );

if( pxEventGroupBuffer == NULL )
{
return NULL;
}

/* Create the event group using static creation API */
xEventGroup = xEventGroupCreateStatic( pxEventGroupBuffer );

if( xEventGroup == NULL )
{
heap_caps_free( pxEventGroupBuffer );
}

return xEventGroup;
}

void vEventGroupDeleteWithCaps( EventGroupHandle_t xEventGroup )
{
BaseType_t xResult;
StaticEventGroup_t * pxEventGroupBuffer;

/* Retrieve the buffer used to create the event group before deleting it
* */
xResult = xEventGroupGetStaticBuffer( xEventGroup, &pxEventGroupBuffer );
configASSERT( xResult == pdTRUE );

/* Delete the event group */
vEventGroupDelete( xEventGroup );

/* Free the memory buffer */
heap_caps_free( pxEventGroupBuffer );
}

#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
Loading

0 comments on commit 4e7cd2e

Please sign in to comment.