-
Notifications
You must be signed in to change notification settings - Fork 7.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
freertos: Add wrapper functions to create objects with capabilities
This commit adds various ...WithCaps() functions to create FreeRTOS objects with specific memory capabilities.
- Loading branch information
Showing
6 changed files
with
545 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 ) */ |
Oops, something went wrong.