diff --git a/components/freertos/CMakeLists.txt b/components/freertos/CMakeLists.txt index 903c69f851..aea0dfbcca 100644 --- a/components/freertos/CMakeLists.txt +++ b/components/freertos/CMakeLists.txt @@ -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" diff --git a/components/freertos/FreeRTOS-Kernel-SMP/event_groups.c b/components/freertos/FreeRTOS-Kernel-SMP/event_groups.c index ae8e20be7d..3e72547c49 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/event_groups.c +++ b/components/freertos/FreeRTOS-Kernel-SMP/event_groups.c @@ -665,6 +665,42 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup ) } /*-----------------------------------------------------------*/ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, + StaticEventGroup_t ** ppxEventGroupBuffer ) + { + BaseType_t xReturn; + EventGroup_t * pxEventBits = xEventGroup; + + configASSERT( pxEventBits ); + configASSERT( ppxEventGroupBuffer ); + + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Check if the event group was statically allocated. */ + if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdTRUE ) + { + *ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + #else /* configSUPPORT_DYNAMIC_ALLOCATION */ + { + /* Event group must have been statically allocated. */ + *ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits; + xReturn = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + return xReturn; + } +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + /* For internal use only - execute a 'set bits' command that was pended from * an interrupt. */ portTIMER_CALLBACK_ATTRIBUTE diff --git a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/FreeRTOS.h b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/FreeRTOS.h index 60abd75b6c..b25b7bd330 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/FreeRTOS.h +++ b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/FreeRTOS.h @@ -1391,4 +1391,11 @@ typedef StaticStreamBuffer_t StaticMessageBuffer_t; #endif /* *INDENT-ON* */ +/* IDF API additions have been moved to idf_additions.h when building for + * Amazon SMP FreeRTOS. However, the rest of ESP-IDF has not been updated to + * include this header explicitly when calling this additional API. Thus, we + * include this here as a workaround until the rest of ESP-IDF can be updated + * to include idf_additions.h explicitly. */ +#include "freertos/idf_additions.h" + #endif /* INC_FREERTOS_H */ diff --git a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/event_groups.h b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/event_groups.h index 3a80d78564..48108a3da3 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/event_groups.h +++ b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/event_groups.h @@ -753,6 +753,28 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEG */ void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; +/** + * event_groups.h + * @code{c} + * BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, + * StaticEventGroup_t ** ppxEventGroupBuffer ); + * @endcode + * + * Retrieve a pointer to a statically created event groups's data structure + * buffer. It is the same buffer that is supplied at the time of creation. + * + * @param xEventGroup The event group for which to retrieve the buffer. + * + * @param ppxEventGroupBuffer Used to return a pointer to the event groups's + * data structure buffer. + * + * @return pdTRUE if the buffer was retrieved, pdFALSE otherwise. + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, + StaticEventGroup_t ** ppxEventGroupBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + /* For internal use only. */ void vEventGroupSetBitsCallback( void * pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION; diff --git a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/message_buffer.h b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/message_buffer.h index be16eb1f30..aa05f233cb 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/message_buffer.h +++ b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/message_buffer.h @@ -210,6 +210,37 @@ typedef void * MessageBufferHandle_t; #define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) \ ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer ) +/** + * message_buffer.h + * + * @code{c} + * BaseType_t xMessageBufferGetStaticBuffers( MessageBufferHandle_t xMessageBuffer, + * uint8_t ** ppucMessageBufferStorageArea, + * StaticMessageBuffer_t ** ppxStaticMessageBuffer ); + * @endcode + * + * Retrieve pointers to a statically created message buffer's data structure + * buffer and storage area buffer. These are the same buffers that are supplied + * at the time of creation. + * + * @param xMessageBuffer The message buffer for which to retrieve the buffers. + * + * @param ppucMessageBufferStorageArea Used to return a pointer to the + * message buffer's storage area buffer. + * + * @param ppxStaticMessageBuffer Used to return a pointer to the message + * buffer's data structure buffer. + * + * @return pdTRUE if buffers were retrieved, pdFALSE otherwise.. + * + * \defgroup xMessageBufferGetStaticBuffers xMessageBufferGetStaticBuffers + * \ingroup MessageBufferManagement + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xMessageBufferGetStaticBuffers( xMessageBuffer, ppucMessageBufferStorageArea, ppxStaticMessageBuffer ) \ + xStreamBufferGetStaticBuffers( ( xMessageBuffer ), ( ppucMessageBufferStorageArea ), ( ppxStaticMessageBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + /** * message_buffer.h * diff --git a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/queue.h b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/queue.h index 1f8b3a75e8..446f73493f 100644 --- a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/queue.h +++ b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/queue.h @@ -233,6 +233,35 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t; #define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer ) xQueueGenericCreateStatic( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) ) #endif /* configSUPPORT_STATIC_ALLOCATION */ +/** + * queue. h + * @code{c} + * BaseType_t xQueueGetStaticBuffers( QueueHandle_t xQueue, + * uint8_t ** ppucQueueStorage, + * StaticQueue_t ** ppxStaticQueue ); + * @endcode + * + * Retrieve pointers to a statically created queue's data structure buffer + * and storage area buffer. These are the same buffers that are supplied + * at the time of creation. + * + * @param xQueue The queue for which to retrieve the buffers. + * + * @param ppucQueueStorage Used to return a pointer to the queue's storage + * area buffer. + * + * @param ppxStaticQueue Used to return a pointer to the queue's data + * structure buffer. + * + * @return pdTRUE if buffers were retrieved, pdFALSE otherwise. + * + * \defgroup xQueueGetStaticBuffers xQueueGetStaticBuffers + * \ingroup QueueManagement + */ +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xQueueGetStaticBuffers( xQueue, ppucQueueStorage, ppxStaticQueue ) xQueueGenericGetStaticBuffers( ( xQueue ), ( ppucQueueStorage ), ( ppxStaticQueue ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + /** * queue. h *
@@ -1558,6 +1587,18 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION;
const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
#endif
+/*
+ * Generic version of the function used to retrieve the buffers of statically
+ * created queues. This is called by other functions and macros that retrieve
+ * the buffers of other statically created RTOS objects that use the queue
+ * structure as their base.
+ */
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ BaseType_t xQueueGenericGetStaticBuffers( QueueHandle_t xQueue,
+ uint8_t ** ppucQueueStorage,
+ StaticQueue_t ** ppxStaticQueue ) PRIVILEGED_FUNCTION;
+#endif
+
/*
* Queue sets provide a mechanism to allow a task to block (pend) on a read
* operation from multiple queues or semaphores simultaneously.
diff --git a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/semphr.h b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/semphr.h
index fd9469d9c9..d72bf45b1b 100644
--- a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/semphr.h
+++ b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/semphr.h
@@ -1170,4 +1170,25 @@ typedef QueueHandle_t SemaphoreHandle_t;
*/
#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
+/**
+ * semphr.h
+ * @code{c}
+ * BaseType_t xSemaphoreGetStaticBuffer( SemaphoreHandle_t xSemaphore );
+ * @endcode
+ *
+ * Retrieve pointer to a statically created binary semaphore, counting semaphore,
+ * or mutex semaphore's data structure buffer. This is the same buffer that is
+ * supplied at the time of creation.
+ *
+ * @param xSemaphore The semaphore for which to retrieve the buffer.
+ *
+ * @param ppxSemaphoreBuffer Used to return a pointer to the semaphore's
+ * data structure buffer.
+ *
+ * @return pdTRUE if buffer was retrieved, pdFALSE otherwise.
+ */
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ #define xSemaphoreGetStaticBuffer( xSemaphore, ppxSemaphoreBuffer ) xQueueGenericGetStaticBuffers( ( QueueHandle_t ) ( xSemaphore ), NULL, ( ppxSemaphoreBuffer ) )
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
#endif /* SEMAPHORE_H */
diff --git a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/stream_buffer.h b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/stream_buffer.h
index c5eac02b02..00f9d0585e 100644
--- a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/stream_buffer.h
+++ b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/stream_buffer.h
@@ -219,6 +219,38 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t;
#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) \
xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer )
+/**
+ * stream_buffer.h
+ *
+ * @code{c}
+ * BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer,
+ * uint8_t ** ppucStreamBufferStorageArea,
+ * StaticStreamBuffer_t ** ppxStaticStreamBuffer );
+ * @endcode
+ *
+ * Retrieve pointers to a statically created stream buffer's data structure
+ * buffer and storage area buffer. These are the same buffers that are supplied
+ * at the time of creation.
+ *
+ * @param xStreamBuffer The stream buffer for which to retrieve the buffers.
+ *
+ * @param ppucStreamBufferStorageArea Used to return a pointer to the stream
+ * buffer's storage area buffer.
+ *
+ * @param ppxStaticStreamBuffer Used to return a pointer to the stream
+ * buffer's data structure buffer.
+ *
+ * @return pdTRUE if buffers were retrieved, pdFALSE otherwise.
+ *
+ * \defgroup xStreamBufferGetStaticBuffers xStreamBufferGetStaticBuffers
+ * \ingroup StreamBufferManagement
+ */
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer,
+ uint8_t ** ppucStreamBufferStorageArea,
+ StaticStreamBuffer_t ** ppxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
/**
* stream_buffer.h
*
diff --git a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/task.h b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/task.h
index 0a91ae8b98..93f6079d08 100644
--- a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/task.h
+++ b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/task.h
@@ -1704,6 +1704,36 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lin
*/
TaskHandle_t xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+/**
+ * task. h
+ * @code{c}
+ * BaseType_t xTaskGetStaticBuffers( TaskHandle_t xTask,
+ * StackType_t ** ppuxStackBuffer,
+ * StaticTask_t ** ppxTaskBuffer );
+ * @endcode
+ *
+ * Retrieve pointers to a statically created task's data structure
+ * buffer and stack buffer. These are the same buffers that are supplied
+ * at the time of creation.
+ *
+ * @param xTask The task for which to retrieve the buffers.
+ *
+ * @param ppuxStackBuffer Used to return a pointer to the task's stack buffer.
+ *
+ * @param ppxTaskBuffer Used to return a pointer to the task's data structure
+ * buffer.
+ *
+ * @return pdTRUE if buffers were retrieved, pdFALSE otherwise.
+ *
+ * \defgroup xTaskGetStaticBuffers xTaskGetStaticBuffers
+ * \ingroup TaskUtils
+ */
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ BaseType_t xTaskGetStaticBuffers( TaskHandle_t xTask,
+ StackType_t ** ppuxStackBuffer,
+ StaticTask_t ** ppxTaskBuffer ) PRIVILEGED_FUNCTION;
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
/**
* task.h
* UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
diff --git a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/timers.h b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/timers.h
index 13492897af..5604cdd91e 100644
--- a/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/timers.h
+++ b/components/freertos/FreeRTOS-Kernel-SMP/include/freertos/timers.h
@@ -1307,6 +1307,25 @@ TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
*/
TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
+/**
+ * BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer,
+ * StaticTimer_t ** ppxTimerBuffer );
+ *
+ * Retrieve pointer to a statically created timer's data structure
+ * buffer. This is the same buffer that is supplied at the time of
+ * creation.
+ *
+ * @param xTimer The timer for which to retrieve the buffer.
+ *
+ * @param ppxTimerBuffer Used to return a pointer to the timers's data
+ * structure buffer.
+ *
+ * @return pdTRUE if the buffer was retrieved, pdFALSE otherwise.
+ */
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer,
+ StaticTimer_t ** ppxTimerBuffer ) PRIVILEGED_FUNCTION;
+#endif /* configSUPPORT_STATIC_ALLOCATION */
/*
* Functions beyond this part are not part of the public API and are intended
* for use by the kernel only.
diff --git a/components/freertos/FreeRTOS-Kernel-SMP/queue.c b/components/freertos/FreeRTOS-Kernel-SMP/queue.c
index 56869290b8..51895e5a23 100644
--- a/components/freertos/FreeRTOS-Kernel-SMP/queue.c
+++ b/components/freertos/FreeRTOS-Kernel-SMP/queue.c
@@ -379,6 +379,55 @@ BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
#endif /* configSUPPORT_STATIC_ALLOCATION */
/*-----------------------------------------------------------*/
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+
+ BaseType_t xQueueGenericGetStaticBuffers( QueueHandle_t xQueue,
+ uint8_t ** ppucQueueStorage,
+ StaticQueue_t ** ppxStaticQueue )
+ {
+ BaseType_t xReturn;
+ Queue_t * const pxQueue = xQueue;
+
+ configASSERT( pxQueue );
+ configASSERT( ppxStaticQueue );
+
+ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+ {
+ /* Check if the queue was statically allocated. */
+ if( pxQueue->ucStaticallyAllocated == ( uint8_t ) pdTRUE )
+ {
+ if( ppucQueueStorage != NULL )
+ {
+ *ppucQueueStorage = ( uint8_t * ) pxQueue->pcHead;
+ }
+
+ *ppxStaticQueue = ( StaticQueue_t * ) pxQueue;
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+ }
+ #else /* configSUPPORT_DYNAMIC_ALLOCATION */
+ {
+ /* Queue must have been statically allocated. */
+ if( ppucQueueStorage != NULL )
+ {
+ *ppucQueueStorage = ( uint8_t * ) pxQueue->pcHead;
+ }
+
+ *ppxStaticQueue = ( StaticQueue_t * ) pxQueue;
+ xReturn = pdTRUE;
+ }
+ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
+
+ return xReturn;
+ }
+
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+/*-----------------------------------------------------------*/
+
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength,
diff --git a/components/freertos/FreeRTOS-Kernel-SMP/stream_buffer.c b/components/freertos/FreeRTOS-Kernel-SMP/stream_buffer.c
index 47c8a9a652..0208032186 100644
--- a/components/freertos/FreeRTOS-Kernel-SMP/stream_buffer.c
+++ b/components/freertos/FreeRTOS-Kernel-SMP/stream_buffer.c
@@ -367,6 +367,34 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
#endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
/*-----------------------------------------------------------*/
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer,
+ uint8_t ** ppucStreamBufferStorageArea,
+ StaticStreamBuffer_t ** ppxStaticStreamBuffer )
+ {
+ BaseType_t xReturn;
+ const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+
+ configASSERT( pxStreamBuffer );
+ configASSERT( ppucStreamBufferStorageArea );
+ configASSERT( ppxStaticStreamBuffer );
+
+ if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) != ( uint8_t ) 0 )
+ {
+ *ppucStreamBufferStorageArea = pxStreamBuffer->pucBuffer;
+ *ppxStaticStreamBuffer = ( StaticStreamBuffer_t * ) pxStreamBuffer;
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+
+ return xReturn;
+ }
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+/*-----------------------------------------------------------*/
+
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer )
{
StreamBuffer_t * pxStreamBuffer = xStreamBuffer;
diff --git a/components/freertos/FreeRTOS-Kernel-SMP/tasks.c b/components/freertos/FreeRTOS-Kernel-SMP/tasks.c
index ff3d3d9030..8ebecd7102 100644
--- a/components/freertos/FreeRTOS-Kernel-SMP/tasks.c
+++ b/components/freertos/FreeRTOS-Kernel-SMP/tasks.c
@@ -3359,6 +3359,53 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char
#endif /* INCLUDE_xTaskGetHandle */
/*-----------------------------------------------------------*/
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+
+ BaseType_t xTaskGetStaticBuffers( TaskHandle_t xTask,
+ StackType_t ** ppuxStackBuffer,
+ StaticTask_t ** ppxTaskBuffer )
+ {
+ BaseType_t xReturn;
+ TCB_t * pxTCB;
+
+ configASSERT( ppuxStackBuffer != NULL );
+ configASSERT( ppxTaskBuffer != NULL );
+
+ pxTCB = prvGetTCBFromHandle( xTask );
+
+ #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 )
+ {
+ if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB )
+ {
+ *ppuxStackBuffer = pxTCB->pxStack;
+ *ppxTaskBuffer = ( StaticTask_t * ) pxTCB;
+ xReturn = pdTRUE;
+ }
+ else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY )
+ {
+ *ppuxStackBuffer = pxTCB->pxStack;
+ *ppxTaskBuffer = NULL;
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+ }
+ #else /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 */
+ {
+ *ppuxStackBuffer = pxTCB->pxStack;
+ *ppxTaskBuffer = ( StaticTask_t * ) pxTCB;
+ xReturn = pdTRUE;
+ }
+ #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 */
+
+ return xReturn;
+ }
+
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+/*-----------------------------------------------------------*/
+
#if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
diff --git a/components/freertos/FreeRTOS-Kernel-SMP/timers.c b/components/freertos/FreeRTOS-Kernel-SMP/timers.c
index 65455cc8da..b98e9b9ec9 100644
--- a/components/freertos/FreeRTOS-Kernel-SMP/timers.c
+++ b/components/freertos/FreeRTOS-Kernel-SMP/timers.c
@@ -534,6 +534,30 @@
}
/*-----------------------------------------------------------*/
+ #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer,
+ StaticTimer_t ** ppxTimerBuffer )
+ {
+ BaseType_t xReturn;
+ Timer_t * pxTimer = xTimer;
+
+ configASSERT( ppxTimerBuffer != NULL );
+
+ if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) != 0 )
+ {
+ *ppxTimerBuffer = ( StaticTimer_t * ) pxTimer;
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+
+ return xReturn;
+ }
+ #endif /* configSUPPORT_STATIC_ALLOCATION */
+/*-----------------------------------------------------------*/
+
const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
{
Timer_t * pxTimer = xTimer;
diff --git a/components/freertos/FreeRTOS-Kernel/event_groups.c b/components/freertos/FreeRTOS-Kernel/event_groups.c
index ffdf23db5c..8b1b184b17 100644
--- a/components/freertos/FreeRTOS-Kernel/event_groups.c
+++ b/components/freertos/FreeRTOS-Kernel/event_groups.c
@@ -702,6 +702,42 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup )
}
/*-----------------------------------------------------------*/
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup,
+ StaticEventGroup_t ** ppxEventGroupBuffer )
+ {
+ BaseType_t xReturn;
+ EventGroup_t * pxEventBits = xEventGroup;
+
+ configASSERT( pxEventBits );
+ configASSERT( ppxEventGroupBuffer );
+
+ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+ {
+ /* Check if the event group was statically allocated. */
+ if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdTRUE )
+ {
+ *ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits;
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+ }
+ #else /* configSUPPORT_DYNAMIC_ALLOCATION */
+ {
+ /* Event group must have been statically allocated. */
+ *ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits;
+ xReturn = pdTRUE;
+ }
+ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
+
+ return xReturn;
+ }
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+/*-----------------------------------------------------------*/
+
/* For internal use only - execute a 'set bits' command that was pended from
* an interrupt. */
void vEventGroupSetBitsCallback( void * pvEventGroup,
diff --git a/components/freertos/FreeRTOS-Kernel/include/freertos/event_groups.h b/components/freertos/FreeRTOS-Kernel/include/freertos/event_groups.h
index d84dcaf92b..8a26ccf9fe 100644
--- a/components/freertos/FreeRTOS-Kernel/include/freertos/event_groups.h
+++ b/components/freertos/FreeRTOS-Kernel/include/freertos/event_groups.h
@@ -807,6 +807,30 @@ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEG
*/
void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
+/**
+ * @cond !DOC_EXCLUDE_HEADER_SECTION
+ * event_groups.h
+ * @code{c}
+ * BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup,
+ * StaticEventGroup_t ** ppxEventGroupBuffer );
+ * @endcode
+ * @endcond
+ *
+ * Retrieve a pointer to a statically created event groups's data structure
+ * buffer. It is the same buffer that is supplied at the time of creation.
+ *
+ * @param xEventGroup The event group for which to retrieve the buffer.
+ *
+ * @param ppxEventGroupBuffer Used to return a pointer to the event groups's
+ * data structure buffer.
+ *
+ * @return pdTRUE if the buffer was retrieved, pdFALSE otherwise.
+ */
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup,
+ StaticEventGroup_t ** ppxEventGroupBuffer ) PRIVILEGED_FUNCTION;
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
/** @cond !DOC_EXCLUDE_HEADER_SECTION */
/* For internal use only. */
diff --git a/components/freertos/FreeRTOS-Kernel/include/freertos/message_buffer.h b/components/freertos/FreeRTOS-Kernel/include/freertos/message_buffer.h
index 36efe9dc37..701a5d4ae9 100644
--- a/components/freertos/FreeRTOS-Kernel/include/freertos/message_buffer.h
+++ b/components/freertos/FreeRTOS-Kernel/include/freertos/message_buffer.h
@@ -226,6 +226,39 @@ typedef void * MessageBufferHandle_t;
#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) \
( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer )
+/**
+ * @cond !DOC_EXCLUDE_HEADER_SECTION
+ * message_buffer.h
+ *
+ * @code{c}
+ * BaseType_t xMessageBufferGetStaticBuffers( MessageBufferHandle_t xMessageBuffer,
+ * uint8_t ** ppucMessageBufferStorageArea,
+ * StaticMessageBuffer_t ** ppxStaticMessageBuffer );
+ * @endcode
+ * @endcond
+ *
+ * Retrieve pointers to a statically created message buffer's data structure
+ * buffer and storage area buffer. These are the same buffers that are supplied
+ * at the time of creation.
+ *
+ * @param xMessageBuffer The message buffer for which to retrieve the buffers.
+ *
+ * @param ppucMessageBufferStorageArea Used to return a pointer to the
+ * message buffer's storage area buffer.
+ *
+ * @param ppxStaticMessageBuffer Used to return a pointer to the message
+ * buffer's data structure buffer.
+ *
+ * @return pdTRUE if buffers were retrieved, pdFALSE otherwise..
+ *
+ * \defgroup xMessageBufferGetStaticBuffers xMessageBufferGetStaticBuffers
+ * \ingroup MessageBufferManagement
+ */
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ #define xMessageBufferGetStaticBuffers( xMessageBuffer, ppucMessageBufferStorageArea, ppxStaticMessageBuffer ) \
+ xStreamBufferGetStaticBuffers( ( xMessageBuffer ), ( ppucMessageBufferStorageArea ), ( ppxStaticMessageBuffer ) )
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
/**
* @cond !DOC_EXCLUDE_HEADER_SECTION
* message_buffer.h
diff --git a/components/freertos/FreeRTOS-Kernel/include/freertos/queue.h b/components/freertos/FreeRTOS-Kernel/include/freertos/queue.h
index a5200d7312..c16faf1046 100644
--- a/components/freertos/FreeRTOS-Kernel/include/freertos/queue.h
+++ b/components/freertos/FreeRTOS-Kernel/include/freertos/queue.h
@@ -252,6 +252,37 @@ typedef struct QueueDefinition * QueueSetMemberHandle_t;
#define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer ) xQueueGenericCreateStatic( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) )
#endif /* configSUPPORT_STATIC_ALLOCATION */
+/**
+ * @cond !DOC_EXCLUDE_HEADER_SECTION
+ * queue. h
+ * @code{c}
+ * BaseType_t xQueueGetStaticBuffers( QueueHandle_t xQueue,
+ * uint8_t ** ppucQueueStorage,
+ * StaticQueue_t ** ppxStaticQueue );
+ * @endcode
+ * @endcond
+ *
+ * Retrieve pointers to a statically created queue's data structure buffer
+ * and storage area buffer. These are the same buffers that are supplied
+ * at the time of creation.
+ *
+ * @param xQueue The queue for which to retrieve the buffers.
+ *
+ * @param ppucQueueStorage Used to return a pointer to the queue's storage
+ * area buffer.
+ *
+ * @param ppxStaticQueue Used to return a pointer to the queue's data
+ * structure buffer.
+ *
+ * @return pdTRUE if buffers were retrieved, pdFALSE otherwise.
+ *
+ * \defgroup xQueueGetStaticBuffers xQueueGetStaticBuffers
+ * \ingroup QueueManagement
+ */
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ #define xQueueGetStaticBuffers( xQueue, ppucQueueStorage, ppxStaticQueue ) xQueueGenericGetStaticBuffers( ( xQueue ), ( ppucQueueStorage ), ( ppxStaticQueue ) )
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
/**
* @cond !DOC_EXCLUDE_HEADER_SECTION
* queue. h
@@ -1649,6 +1680,18 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION;
const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
#endif
+/*
+ * Generic version of the function used to retrieve the buffers of statically
+ * created queues. This is called by other functions and macros that retrieve
+ * the buffers of other statically created RTOS objects that use the queue
+ * structure as their base.
+ */
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ BaseType_t xQueueGenericGetStaticBuffers( QueueHandle_t xQueue,
+ uint8_t ** ppucQueueStorage,
+ StaticQueue_t ** ppxStaticQueue ) PRIVILEGED_FUNCTION;
+#endif
+
/**
* Queue sets provide a mechanism to allow a task to block (pend) on a read
* operation from multiple queues or semaphores simultaneously.
diff --git a/components/freertos/FreeRTOS-Kernel/include/freertos/semphr.h b/components/freertos/FreeRTOS-Kernel/include/freertos/semphr.h
index 41d724a12c..47d8ae13c5 100644
--- a/components/freertos/FreeRTOS-Kernel/include/freertos/semphr.h
+++ b/components/freertos/FreeRTOS-Kernel/include/freertos/semphr.h
@@ -1244,4 +1244,27 @@ typedef QueueHandle_t SemaphoreHandle_t;
*/
#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) )
+/**
+ * @cond !DOC_EXCLUDE_HEADER_SECTION
+ * semphr.h
+ * @code{c}
+ * BaseType_t xSemaphoreGetStaticBuffer( SemaphoreHandle_t xSemaphore );
+ * @endcode
+ * @endcond
+ *
+ * Retrieve pointer to a statically created binary semaphore, counting semaphore,
+ * or mutex semaphore's data structure buffer. This is the same buffer that is
+ * supplied at the time of creation.
+ *
+ * @param xSemaphore The semaphore for which to retrieve the buffer.
+ *
+ * @param ppxSemaphoreBuffer Used to return a pointer to the semaphore's
+ * data structure buffer.
+ *
+ * @return pdTRUE if buffer was retrieved, pdFALSE otherwise.
+ */
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ #define xSemaphoreGetStaticBuffer( xSemaphore, ppxSemaphoreBuffer ) xQueueGenericGetStaticBuffers( ( QueueHandle_t ) ( xSemaphore ), NULL, ( ppxSemaphoreBuffer ) )
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
#endif /* SEMAPHORE_H */
diff --git a/components/freertos/FreeRTOS-Kernel/include/freertos/stream_buffer.h b/components/freertos/FreeRTOS-Kernel/include/freertos/stream_buffer.h
index 3bbecb223c..6a11fbfe79 100644
--- a/components/freertos/FreeRTOS-Kernel/include/freertos/stream_buffer.h
+++ b/components/freertos/FreeRTOS-Kernel/include/freertos/stream_buffer.h
@@ -236,6 +236,40 @@ typedef struct StreamBufferDef_t * StreamBufferHandle_t;
#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) \
xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer )
+/**
+ * @cond !DOC_EXCLUDE_HEADER_SECTION
+ * stream_buffer.h
+ *
+ * @code{c}
+ * BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer,
+ * uint8_t ** ppucStreamBufferStorageArea,
+ * StaticStreamBuffer_t ** ppxStaticStreamBuffer );
+ * @endcode
+ * @endcond
+ *
+ * Retrieve pointers to a statically created stream buffer's data structure
+ * buffer and storage area buffer. These are the same buffers that are supplied
+ * at the time of creation.
+ *
+ * @param xStreamBuffer The stream buffer for which to retrieve the buffers.
+ *
+ * @param ppucStreamBufferStorageArea Used to return a pointer to the stream
+ * buffer's storage area buffer.
+ *
+ * @param ppxStaticStreamBuffer Used to return a pointer to the stream
+ * buffer's data structure buffer.
+ *
+ * @return pdTRUE if buffers were retrieved, pdFALSE otherwise.
+ *
+ * \defgroup xStreamBufferGetStaticBuffers xStreamBufferGetStaticBuffers
+ * \ingroup StreamBufferManagement
+ */
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer,
+ uint8_t ** ppucStreamBufferStorageArea,
+ StaticStreamBuffer_t ** ppxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
/**
* @cond !DOC_EXCLUDE_HEADER_SECTION
* stream_buffer.h
diff --git a/components/freertos/FreeRTOS-Kernel/include/freertos/task.h b/components/freertos/FreeRTOS-Kernel/include/freertos/task.h
index 43c5fa310e..2c016eb596 100644
--- a/components/freertos/FreeRTOS-Kernel/include/freertos/task.h
+++ b/components/freertos/FreeRTOS-Kernel/include/freertos/task.h
@@ -1852,6 +1852,38 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lin
*/
TaskHandle_t xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
+/**
+ * @cond !DOC_EXCLUDE_HEADER_SECTION
+ * task. h
+ * @code{c}
+ * BaseType_t xTaskGetStaticBuffers( TaskHandle_t xTask,
+ * StackType_t ** ppuxStackBuffer,
+ * StaticTask_t ** ppxTaskBuffer );
+ * @endcode
+ * @endcond
+ *
+ * Retrieve pointers to a statically created task's data structure
+ * buffer and stack buffer. These are the same buffers that are supplied
+ * at the time of creation.
+ *
+ * @param xTask The task for which to retrieve the buffers.
+ *
+ * @param ppuxStackBuffer Used to return a pointer to the task's stack buffer.
+ *
+ * @param ppxTaskBuffer Used to return a pointer to the task's data structure
+ * buffer.
+ *
+ * @return pdTRUE if buffers were retrieved, pdFALSE otherwise.
+ *
+ * \defgroup xTaskGetStaticBuffers xTaskGetStaticBuffers
+ * \ingroup TaskUtils
+ */
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ BaseType_t xTaskGetStaticBuffers( TaskHandle_t xTask,
+ StackType_t ** ppuxStackBuffer,
+ StaticTask_t ** ppxTaskBuffer ) PRIVILEGED_FUNCTION;
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
/**
* @cond !DOC_EXCLUDE_HEADER_SECTION
* task.h
diff --git a/components/freertos/FreeRTOS-Kernel/include/freertos/timers.h b/components/freertos/FreeRTOS-Kernel/include/freertos/timers.h
index fed9b380b1..00c9f5179b 100644
--- a/components/freertos/FreeRTOS-Kernel/include/freertos/timers.h
+++ b/components/freertos/FreeRTOS-Kernel/include/freertos/timers.h
@@ -1314,6 +1314,26 @@ TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
*/
TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
+/**
+ * BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer,
+ * StaticTimer_t ** ppxTimerBuffer );
+ *
+ * Retrieve pointer to a statically created timer's data structure
+ * buffer. This is the same buffer that is supplied at the time of
+ * creation.
+ *
+ * @param xTimer The timer for which to retrieve the buffer.
+ *
+ * @param ppxTimerBuffer Used to return a pointer to the timers's data
+ * structure buffer.
+ *
+ * @return pdTRUE if the buffer was retrieved, pdFALSE otherwise.
+ */
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer,
+ StaticTimer_t ** ppxTimerBuffer ) PRIVILEGED_FUNCTION;
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+
/** @cond !DOC_EXCLUDE_HEADER_SECTION */
/*
diff --git a/components/freertos/FreeRTOS-Kernel/queue.c b/components/freertos/FreeRTOS-Kernel/queue.c
index 2c3c76f20f..69da28f732 100644
--- a/components/freertos/FreeRTOS-Kernel/queue.c
+++ b/components/freertos/FreeRTOS-Kernel/queue.c
@@ -417,6 +417,55 @@ BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
#endif /* configSUPPORT_STATIC_ALLOCATION */
/*-----------------------------------------------------------*/
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+
+ BaseType_t xQueueGenericGetStaticBuffers( QueueHandle_t xQueue,
+ uint8_t ** ppucQueueStorage,
+ StaticQueue_t ** ppxStaticQueue )
+ {
+ BaseType_t xReturn;
+ Queue_t * const pxQueue = xQueue;
+
+ configASSERT( pxQueue );
+ configASSERT( ppxStaticQueue );
+
+ #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
+ {
+ /* Check if the queue was statically allocated. */
+ if( pxQueue->ucStaticallyAllocated == ( uint8_t ) pdTRUE )
+ {
+ if( ppucQueueStorage != NULL )
+ {
+ *ppucQueueStorage = ( uint8_t * ) pxQueue->pcHead;
+ }
+
+ *ppxStaticQueue = ( StaticQueue_t * ) pxQueue;
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+ }
+ #else /* configSUPPORT_DYNAMIC_ALLOCATION */
+ {
+ /* Queue must have been statically allocated. */
+ if( ppucQueueStorage != NULL )
+ {
+ *ppucQueueStorage = ( uint8_t * ) pxQueue->pcHead;
+ }
+
+ *ppxStaticQueue = ( StaticQueue_t * ) pxQueue;
+ xReturn = pdTRUE;
+ }
+ #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
+
+ return xReturn;
+ }
+
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+/*-----------------------------------------------------------*/
+
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength,
diff --git a/components/freertos/FreeRTOS-Kernel/stream_buffer.c b/components/freertos/FreeRTOS-Kernel/stream_buffer.c
index fa9a3ce251..d67f091cba 100644
--- a/components/freertos/FreeRTOS-Kernel/stream_buffer.c
+++ b/components/freertos/FreeRTOS-Kernel/stream_buffer.c
@@ -387,6 +387,34 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
#endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
/*-----------------------------------------------------------*/
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ BaseType_t xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffer,
+ uint8_t ** ppucStreamBufferStorageArea,
+ StaticStreamBuffer_t ** ppxStaticStreamBuffer )
+ {
+ BaseType_t xReturn;
+ const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer;
+
+ configASSERT( pxStreamBuffer );
+ configASSERT( ppucStreamBufferStorageArea );
+ configASSERT( ppxStaticStreamBuffer );
+
+ if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) != ( uint8_t ) 0 )
+ {
+ *ppucStreamBufferStorageArea = pxStreamBuffer->pucBuffer;
+ *ppxStaticStreamBuffer = ( StaticStreamBuffer_t * ) pxStreamBuffer;
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+
+ return xReturn;
+ }
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+/*-----------------------------------------------------------*/
+
void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer )
{
StreamBuffer_t * pxStreamBuffer = xStreamBuffer;
diff --git a/components/freertos/FreeRTOS-Kernel/tasks.c b/components/freertos/FreeRTOS-Kernel/tasks.c
index 32d054dda1..5478fef96b 100644
--- a/components/freertos/FreeRTOS-Kernel/tasks.c
+++ b/components/freertos/FreeRTOS-Kernel/tasks.c
@@ -2899,6 +2899,53 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char
#endif /* INCLUDE_xTaskGetHandle */
/*-----------------------------------------------------------*/
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+
+ BaseType_t xTaskGetStaticBuffers( TaskHandle_t xTask,
+ StackType_t ** ppuxStackBuffer,
+ StaticTask_t ** ppxTaskBuffer )
+ {
+ BaseType_t xReturn;
+ TCB_t * pxTCB;
+
+ configASSERT( ppuxStackBuffer != NULL );
+ configASSERT( ppxTaskBuffer != NULL );
+
+ pxTCB = prvGetTCBFromHandle( xTask );
+
+ #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 )
+ {
+ if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB )
+ {
+ *ppuxStackBuffer = pxTCB->pxStack;
+ *ppxTaskBuffer = ( StaticTask_t * ) pxTCB;
+ xReturn = pdTRUE;
+ }
+ else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY )
+ {
+ *ppuxStackBuffer = pxTCB->pxStack;
+ *ppxTaskBuffer = NULL;
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+ }
+ #else /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 */
+ {
+ *ppuxStackBuffer = pxTCB->pxStack;
+ *ppxTaskBuffer = ( StaticTask_t * ) pxTCB;
+ xReturn = pdTRUE;
+ }
+ #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE == 1 */
+
+ return xReturn;
+ }
+
+#endif /* configSUPPORT_STATIC_ALLOCATION */
+/*-----------------------------------------------------------*/
+
#if ( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
diff --git a/components/freertos/FreeRTOS-Kernel/timers.c b/components/freertos/FreeRTOS-Kernel/timers.c
index 448e183bb2..d68ab1e371 100644
--- a/components/freertos/FreeRTOS-Kernel/timers.c
+++ b/components/freertos/FreeRTOS-Kernel/timers.c
@@ -512,6 +512,30 @@
}
/*-----------------------------------------------------------*/
+ #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+ BaseType_t xTimerGetStaticBuffer( TimerHandle_t xTimer,
+ StaticTimer_t ** ppxTimerBuffer )
+ {
+ BaseType_t xReturn;
+ Timer_t * pxTimer = xTimer;
+
+ configASSERT( ppxTimerBuffer != NULL );
+
+ if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) != 0 )
+ {
+ *ppxTimerBuffer = ( StaticTimer_t * ) pxTimer;
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+
+ return xReturn;
+ }
+ #endif /* configSUPPORT_STATIC_ALLOCATION */
+/*-----------------------------------------------------------*/
+
const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
{
Timer_t * pxTimer = xTimer;
diff --git a/components/freertos/esp_additions/idf_additions.c b/components/freertos/esp_additions/idf_additions.c
new file mode 100644
index 0000000000..ee47b98a76
--- /dev/null
+++ b/components/freertos/esp_additions/idf_additions.c
@@ -0,0 +1,275 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "sdkconfig.h"
+#include
+#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 ) */
diff --git a/components/freertos/esp_additions/include/freertos/idf_additions.h b/components/freertos/esp_additions/include/freertos/idf_additions.h
index 22aac424b7..a917b97595 100644
--- a/components/freertos/esp_additions/include/freertos/idf_additions.h
+++ b/components/freertos/esp_additions/include/freertos/idf_additions.h
@@ -18,6 +18,12 @@
#include "sdkconfig.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 "esp_heap_caps.h"
#ifdef __cplusplus
extern "C" {
@@ -28,15 +34,17 @@
*
* Todo: Move IDF FreeRTOS SMP related additions to this header as well (see
* IDF-7201)
+ * Todo: Add these SMP related additions to docs once they are combined with
+ * IDF FreeRTOS.
* -------------------------------------------------------------------------- */
-#if CONFIG_FREERTOS_SMP || __DOXYGEN__
+#if CONFIG_FREERTOS_SMP
/**
* @brief Create a new task that is pinned to a particular core
*
* Helper function to create a task that is pinned to a particular core, or has
- * no affinity. In other wrods, the created task will have an affinity mask of:
+ * no affinity. In other words, the created task will have an affinity mask of:
* - (1 << xCoreID) if it is pinned to a particular core
* - Set to tskNO_AFFINITY if it has no affinity
*
@@ -119,7 +127,7 @@
TaskHandle_t xTaskGetIdleTaskHandleForCPU( BaseType_t xCoreID );
/**
- * @brief Get the current core affintiy of a particular task
+ * @brief Get the current core affinity of a particular task
*
* Helper function to get the core affinity of a particular task. If the task is
* pinned to a particular core, the core ID is returned. If the task is not
@@ -133,16 +141,18 @@
*/
BaseType_t xTaskGetAffinity( TaskHandle_t xTask );
-#endif // CONFIG_FREERTOS_SMP || __DOXYGEN__
+#endif // CONFIG_FREERTOS_SMP
/* -----------------------------------------------------------------------------
* TLSP Deletion Callback related API additions
*
* Todo: Move IDF FreeRTOS TLSP Deletion Callback related additions to this
* header as well (see IDF-7201)
+ * Todo: Add these SMP related additions to docs once they are combined with
+ * IDF FreeRTOS.
* -------------------------------------------------------------------------- */
-#if CONFIG_FREERTOS_SMP || __DOXYGEN__
+#if CONFIG_FREERTOS_SMP
#if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
@@ -180,7 +190,244 @@
TlsDeleteCallbackFunction_t pvDelCallback );
#endif // CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS
-#endif // CONFIG_FREERTOS_SMP || __DOXYGEN__
+#endif // CONFIG_FREERTOS_SMP
+
+/* -----------------------------------------------------------------------------
+ * Creation With Memory Caps
+ *
+ * Helper functions to create various FreeRTOS objects (e.g., queues,
+ * semaphores) with specific memory capabilities (e.g., MALLOC_CAP_INTERNAL).
+ * -------------------------------------------------------------------------- */
+
+#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
+
+/* ---------------------- Queue ------------------------- */
+
+/**
+ * @brief Creates a queue with specific memory capabilities
+ *
+ * This function is similar to xQueueCreate(), except that it allows the memory
+ * allocated for the queue to have specific capabilities (e.g.,
+ * MALLOC_CAP_INTERNAL).
+ *
+ * @note A queue created using this function must only be deleted using
+ * vQueueDeleteWithCaps()
+ * @param uxQueueLength The maximum number of items that the queue can contain.
+ * @param uxItemSize The number of bytes each item in the queue will require.
+ * @param uxMemoryCaps Memory capabilities of the queue's memory (see
+ * esp_heap_caps.h)
+ * @return Handle to the created queue or NULL on failure.
+ */
+ QueueHandle_t xQueueCreateWithCaps( UBaseType_t uxQueueLength,
+ UBaseType_t uxItemSize,
+ UBaseType_t uxMemoryCaps );
+
+/**
+ * @brief Deletes a queue previously created using xQueueCreateWithCaps()
+ *
+ * @param xQueue A handle to the queue to be deleted.
+ */
+ void vQueueDeleteWithCaps( QueueHandle_t xQueue );
+
+/* -------------------- Semaphore ----------------------- */
+
+/** @cond */ /* Doxygen command to hide this from docs */
+ SemaphoreHandle_t xSemaphoreCreateGenericWithCaps( UBaseType_t uxMaxCount,
+ UBaseType_t uxInitialCount,
+ const uint8_t ucQueueType,
+ UBaseType_t uxMemoryCaps );
+/** @endcond */
+
+/**
+ * @brief Creates a binary semaphore with specific memory capabilities
+ *
+ * This function is similar to vSemaphoreCreateBinary(), except that it allows
+ * the memory allocated for the binary semaphore to have specific capabilities
+ * (e.g., MALLOC_CAP_INTERNAL).
+ *
+ * @note A binary semaphore created using this function must only be deleted
+ * using vSemaphoreDeleteWithCaps()
+ * @param uxMemoryCaps Memory capabilities of the binary semaphore's memory (see
+ * esp_heap_caps.h)
+ * @return Handle to the created binary semaphore or NULL on failure.
+ */
+ static inline SemaphoreHandle_t xSemaphoreCreateBinaryWithCaps( UBaseType_t uxMemoryCaps )
+ {
+ return xSemaphoreCreateGenericWithCaps( 0, 0, queueQUEUE_TYPE_BINARY_SEMAPHORE, uxMemoryCaps );
+ }
+
+/**
+ * @brief Creates a counting semaphore with specific memory capabilities
+ *
+ * This function is similar to xSemaphoreCreateCounting(), except that it allows
+ * the memory allocated for the counting semaphore to have specific capabilities
+ * (e.g., MALLOC_CAP_INTERNAL).
+ *
+ * @note A counting semaphore created using this function must only be deleted
+ * using vSemaphoreDeleteWithCaps()
+ * @param uxMaxCount The maximum count value that can be reached.
+ * @param uxInitialCount The count value assigned to the semaphore when it is
+ * created.
+ * @param uxMemoryCaps Memory capabilities of the counting semaphore's memory
+ * (see esp_heap_caps.h)
+ * @return Handle to the created counting semaphore or NULL on failure.
+ */
+ static inline SemaphoreHandle_t xSemaphoreCreateCountingWithCaps( UBaseType_t uxMaxCount,
+ UBaseType_t uxInitialCount,
+ UBaseType_t uxMemoryCaps )
+ {
+ return xSemaphoreCreateGenericWithCaps( uxMaxCount, uxInitialCount, queueQUEUE_TYPE_COUNTING_SEMAPHORE, uxMemoryCaps );
+ }
+
+/**
+ * @brief Creates a mutex semaphore with specific memory capabilities
+ *
+ * This function is similar to xSemaphoreCreateMutex(), except that it allows
+ * the memory allocated for the mutex semaphore to have specific capabilities
+ * (e.g., MALLOC_CAP_INTERNAL).
+ *
+ * @note A mutex semaphore created using this function must only be deleted
+ * using vSemaphoreDeleteWithCaps()
+ * @param uxMemoryCaps Memory capabilities of the mutex semaphore's memory (see
+ * esp_heap_caps.h)
+ * @return Handle to the created mutex semaphore or NULL on failure.
+ */
+ static inline SemaphoreHandle_t xSemaphoreCreateMutexWithCaps( UBaseType_t uxMemoryCaps )
+ {
+ return xSemaphoreCreateGenericWithCaps( 0, 0, queueQUEUE_TYPE_MUTEX, uxMemoryCaps );
+ }
+
+/**
+ * @brief Creates a recursive mutex with specific memory capabilities
+ *
+ * This function is similar to xSemaphoreCreateRecursiveMutex(), except that it
+ * allows the memory allocated for the recursive mutex to have specific
+ * capabilities (e.g., MALLOC_CAP_INTERNAL).
+ *
+ * @note A recursive mutex created using this function must only be deleted
+ * using vSemaphoreDeleteWithCaps()
+ * @param uxMemoryCaps Memory capabilities of the recursive mutex's memory (see
+ * esp_heap_caps.h)
+ * @return Handle to the created recursive mutex or NULL on failure.
+ */
+ static inline SemaphoreHandle_t xSemaphoreCreateRecursiveMutexWithCaps( UBaseType_t uxMemoryCaps )
+ {
+ return xSemaphoreCreateGenericWithCaps( 0, 0, queueQUEUE_TYPE_RECURSIVE_MUTEX, uxMemoryCaps );
+ }
+
+/**
+ * @brief Deletes a semaphore previously created using one of the
+ * xSemaphoreCreate...WithCaps() functions
+ *
+ * @param xSemaphore A handle to the semaphore to be deleted.
+ */
+ void vSemaphoreDeleteWithCaps( SemaphoreHandle_t xSemaphore );
+
+/* ------------ Stream & Message Buffers ---------------- */
+
+/** @cond */ /* Doxygen command to hide this from docs */
+ StreamBufferHandle_t xStreamBufferGenericCreateWithCaps( size_t xBufferSizeBytes,
+ size_t xTriggerLevelBytes,
+ BaseType_t xIsMessageBuffer,
+ UBaseType_t uxMemoryCaps );
+
+ void vStreamBufferGenericDeleteWithCaps( StreamBufferHandle_t xStreamBuffer,
+ BaseType_t xIsMessageBuffer );
+/** @endcond */
+
+/**
+ * @brief Creates a stream buffer with specific memory capabilities
+ *
+ * This function is similar to xStreamBufferCreate(), except that it allows the
+ * memory allocated for the stream buffer to have specific capabilities (e.g.,
+ * MALLOC_CAP_INTERNAL).
+ *
+ * @note A stream buffer created using this function must only be deleted using
+ * vStreamBufferDeleteWithCaps()
+ * @param xBufferSizeBytes The total number of bytes the stream buffer will be
+ * able to hold at any one time.
+ * @param xTriggerLevelBytes The number of bytes that must be in the stream
+ * buffer before unblocking
+ * @param uxMemoryCaps Memory capabilities of the stream buffer's memory (see
+ * esp_heap_caps.h)
+ * @return Handle to the created stream buffer or NULL on failure.
+ */
+ static inline StreamBufferHandle_t xStreamBufferCreateWithCaps( size_t xBufferSizeBytes,
+ size_t xTriggerLevelBytes,
+ UBaseType_t uxMemoryCaps )
+ {
+ return xStreamBufferGenericCreateWithCaps( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, uxMemoryCaps );
+ }
+
+/**
+ * @brief Deletes a stream buffer previously created using
+ * xStreamBufferCreateWithCaps()
+ *
+ * @param xStreamBuffer A handle to the stream buffer to be deleted.
+ */
+ static inline void vStreamBufferDeleteWithCaps( StreamBufferHandle_t xStreamBuffer )
+ {
+ vStreamBufferGenericDeleteWithCaps( xStreamBuffer, pdFALSE );
+ }
+
+/**
+ * @brief Creates a message buffer with specific memory capabilities
+ *
+ * This function is similar to xMessageBufferCreate(), except that it allows the
+ * memory allocated for the message buffer to have specific capabilities (e.g.,
+ * MALLOC_CAP_INTERNAL).
+ *
+ * @note A message buffer created using this function must only be deleted using
+ * vMessageBufferDeleteWithCaps()
+ * @param xBufferSizeBytes The total number of bytes (not messages) the message
+ * buffer will be able to hold at any one time.
+ * @param uxMemoryCaps Memory capabilities of the message buffer's memory (see
+ * esp_heap_caps.h)
+ * @return Handle to the created message buffer or NULL on failure.
+ */
+ static inline MessageBufferHandle_t xMessageBufferCreateWithCaps( size_t xBufferSizeBytes,
+ UBaseType_t uxMemoryCaps )
+ {
+ return ( MessageBufferHandle_t ) xStreamBufferGenericCreateWithCaps( xBufferSizeBytes, ( size_t ) 0, pdTRUE, uxMemoryCaps );
+ }
+
+/**
+ * @brief Deletes a stream buffer previously created using
+ * xMessageBufferCreateWithCaps()
+ *
+ * @param xMessageBuffer A handle to the message buffer to be deleted.
+ */
+ static inline void vMessageBufferDeleteWithCaps( MessageBufferHandle_t xMessageBuffer )
+ {
+ vStreamBufferGenericDeleteWithCaps( ( StreamBufferHandle_t ) xMessageBuffer, pdTRUE );
+ }
+
+/* ------------------ Event Groups ---------------------- */
+
+/**
+ * @brief Creates an event group with specific memory capabilities
+ *
+ * This function is similar to xEventGroupCreate(), except that it allows the
+ * memory allocated for the event group to have specific capabilities (e.g.,
+ * MALLOC_CAP_INTERNAL).
+ *
+ * @note An event group created using this function must only be deleted using
+ * vEventGroupDeleteWithCaps()
+ * @param uxMemoryCaps Memory capabilities of the event group's memory (see
+ * esp_heap_caps.h)
+ * @return Handle to the created event group or NULL on failure.
+ */
+ EventGroupHandle_t xEventGroupCreateWithCaps( UBaseType_t uxMemoryCaps );
+
+/**
+ * @brief Deletes an event group previously created using
+ * xEventGroupCreateWithCaps()
+ *
+ * @param xEventGroup A handle to the event group to be deleted.
+ */
+ void vEventGroupDeleteWithCaps( EventGroupHandle_t xEventGroup );
+
+#endif /* if ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
#ifdef __cplusplus
}
diff --git a/components/freertos/linker_common.lf b/components/freertos/linker_common.lf
index 7cbb6e17af..425b10d362 100644
--- a/components/freertos/linker_common.lf
+++ b/components/freertos/linker_common.lf
@@ -34,6 +34,12 @@ entries:
tasks:prvTaskPriorityRaise (default)
tasks:prvTaskPriorityRestore (default)
+ # ------------------------------------------------------------------------------------------------------------------
+ # idf_additions.c
+ # Placement Rules: Functions always in flash as they are never called from an ISR
+ # ------------------------------------------------------------------------------------------------------------------
+ idf_additions (default)
+
# ------------------------------------------------------------------------------------------------------------------
# app_startup.c
# Placement Rules: Functions always in flash as they are never called from an ISR
diff --git a/components/freertos/test_apps/freertos/misc/test_idf_additions.c b/components/freertos/test_apps/freertos/misc/test_idf_additions.c
new file mode 100644
index 0000000000..38cf692cef
--- /dev/null
+++ b/components/freertos/test_apps/freertos/misc/test_idf_additions.c
@@ -0,0 +1,139 @@
+/*
+ * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "sdkconfig.h"
+#include "freertos/FreeRTOS.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/idf_additions.h"
+#include "esp_memory_utils.h"
+#include "unity.h"
+
+/*
+Test ...Create...WithCaps() functions
+
+Purpose:
+ - Test that the ___Create___WithCaps() functions create objects using with correct memory capabilities
+
+Procedure:
+ - Create different FreeRTOS objects (e.g. queues, event groups etc) using the various ___Create___WithCaps()
+ functions with (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) capabilities.
+ - Call the ___GetStaticBuffers() functions to get the address of the memory of the created objects
+ - Check that the memory has (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT) capabilities by calling esp_ptr_in_dram()
+
+Expected:
+ - ___Create___WithCaps() should create objects in DRAM
+*/
+
+#define OBJECT_MEMORY_CAPS (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)
+
+TEST_CASE("IDF additions: Queue creation with memory caps", "[freertos]")
+{
+ QueueHandle_t queue_handle;
+ uint8_t *queue_storage;
+ StaticQueue_t *queue_obj;
+
+ // Create queue with caps
+ queue_handle = xQueueCreateWithCaps(5, sizeof(uint32_t), OBJECT_MEMORY_CAPS);
+ TEST_ASSERT_NOT_EQUAL(NULL, queue_handle);
+ // Get the queue's memory
+ TEST_ASSERT_EQUAL(pdTRUE, xQueueGetStaticBuffers(queue_handle, &queue_storage, &queue_obj));
+ TEST_ASSERT(esp_ptr_in_dram(queue_storage));
+ TEST_ASSERT(esp_ptr_in_dram(queue_obj));
+ // Free the queue
+ vQueueDeleteWithCaps(queue_handle);
+}
+
+TEST_CASE("IDF additions: Semaphore creation with memory caps", "[freertos]")
+{
+ SemaphoreHandle_t sem_handle;
+ StaticSemaphore_t *sem_obj;
+
+ // Create binary semaphore with caps
+ sem_handle = xSemaphoreCreateBinaryWithCaps(OBJECT_MEMORY_CAPS);
+ TEST_ASSERT_NOT_EQUAL(NULL, sem_handle);
+ // Get the binary semaphore's memory
+ TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreGetStaticBuffer(sem_handle, &sem_obj));
+ TEST_ASSERT(esp_ptr_in_dram(sem_obj));
+ // Free the binary semaphore
+ vSemaphoreDeleteWithCaps(sem_handle);
+
+ // Create counting semaphore with caps
+ sem_handle = xSemaphoreCreateCountingWithCaps(4, 0, OBJECT_MEMORY_CAPS);
+ TEST_ASSERT_NOT_EQUAL(NULL, sem_handle);
+ // Get the counting semaphore's memory
+ TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreGetStaticBuffer(sem_handle, &sem_obj));
+ TEST_ASSERT(esp_ptr_in_dram(sem_obj));
+ // Free the counting semaphore
+ vSemaphoreDeleteWithCaps(sem_handle);
+
+ // Create mutex semaphore with caps
+ sem_handle = xSemaphoreCreateMutexWithCaps(OBJECT_MEMORY_CAPS);
+ TEST_ASSERT_NOT_EQUAL(NULL, sem_handle);
+ // Get the mutex semaphore's memory
+ TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreGetStaticBuffer(sem_handle, &sem_obj));
+ TEST_ASSERT(esp_ptr_in_dram(sem_obj));
+ // Free the mutex semaphore
+ vSemaphoreDeleteWithCaps(sem_handle);
+
+ // Create recursive mutex with caps
+ sem_handle = xSemaphoreCreateRecursiveMutexWithCaps(OBJECT_MEMORY_CAPS);
+ TEST_ASSERT_NOT_EQUAL(NULL, sem_handle);
+ // Get the recursive mutex's memory
+ TEST_ASSERT_EQUAL(pdTRUE, xSemaphoreGetStaticBuffer(sem_handle, &sem_obj));
+ TEST_ASSERT(esp_ptr_in_dram(sem_obj));
+ // Free the recursive mutex
+ vSemaphoreDeleteWithCaps(sem_handle);
+}
+
+TEST_CASE("IDF additions: Stream & message buffer creation with memory caps", "[freertos]")
+{
+ StreamBufferHandle_t stream_buffer_handle;
+ uint8_t *stream_buffer_storage;
+ StaticStreamBuffer_t *stream_buffer_obj;
+
+ // Create stream buffer with caps
+ stream_buffer_handle = xStreamBufferCreateWithCaps(16, 0, OBJECT_MEMORY_CAPS);
+ TEST_ASSERT_NOT_EQUAL(NULL, stream_buffer_handle);
+ // Get the stream buffer's memory
+ TEST_ASSERT_EQUAL(pdTRUE, xStreamBufferGetStaticBuffers(stream_buffer_handle, &stream_buffer_storage, &stream_buffer_obj));
+ TEST_ASSERT(esp_ptr_in_dram(stream_buffer_storage));
+ TEST_ASSERT(esp_ptr_in_dram(stream_buffer_obj));
+ // Free the stream buffer
+ vStreamBufferDelete(stream_buffer_handle);
+
+ MessageBufferHandle_t msg_buffer_handle;
+ uint8_t *msg_buffer_storage;
+ StaticMessageBuffer_t *msg_buffer_obj;
+
+ // Create message buffer with caps
+ msg_buffer_handle = xMessageBufferCreateWithCaps(16, OBJECT_MEMORY_CAPS);
+ TEST_ASSERT_NOT_EQUAL(NULL, msg_buffer_handle);
+ // Get the message buffer's memory
+ TEST_ASSERT_EQUAL(pdTRUE, xMessageBufferGetStaticBuffers(msg_buffer_handle, &msg_buffer_storage, &msg_buffer_obj));
+ TEST_ASSERT(esp_ptr_in_dram(msg_buffer_storage));
+ TEST_ASSERT(esp_ptr_in_dram(msg_buffer_obj));
+ // Free the message buffer
+ vMessageBufferDelete(msg_buffer_handle);
+}
+
+TEST_CASE("IDF additions: Event group creation with memory caps", "[freertos]")
+{
+ EventGroupHandle_t evt_group_handle;
+ StaticEventGroup_t *evt_group_obj;
+
+ // Create event group with caps
+ evt_group_handle = xEventGroupCreateWithCaps(OBJECT_MEMORY_CAPS);
+ TEST_ASSERT_NOT_EQUAL(NULL, evt_group_handle);
+ // Get the event group's memory
+ TEST_ASSERT_EQUAL(pdTRUE, xEventGroupGetStaticBuffer(evt_group_handle, &evt_group_obj));
+ TEST_ASSERT(esp_ptr_in_dram(evt_group_obj));
+ // Free the event group
+ vEventGroupDelete(evt_group_handle);
+}
diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile
index 284ede346c..97d8a5f309 100644
--- a/docs/doxygen/Doxyfile
+++ b/docs/doxygen/Doxyfile
@@ -191,6 +191,7 @@ INPUT = \
$(PROJECT_PATH)/components/fatfs/diskio/diskio_sdmmc.h \
$(PROJECT_PATH)/components/fatfs/diskio/diskio_wl.h \
$(PROJECT_PATH)/components/fatfs/vfs/esp_vfs_fat.h \
+ $(PROJECT_PATH)/components/freertos/esp_additions/include/freertos/idf_additions.h \
$(PROJECT_PATH)/components/freertos/FreeRTOS-Kernel/include/freertos/event_groups.h \
$(PROJECT_PATH)/components/freertos/FreeRTOS-Kernel/include/freertos/message_buffer.h \
$(PROJECT_PATH)/components/freertos/FreeRTOS-Kernel/include/freertos/queue.h \
diff --git a/docs/en/api-reference/system/freertos_additions.rst b/docs/en/api-reference/system/freertos_additions.rst
index c3d54aea1b..4e40499589 100644
--- a/docs/en/api-reference/system/freertos_additions.rst
+++ b/docs/en/api-reference/system/freertos_additions.rst
@@ -430,6 +430,12 @@ When implementing TLSP callbacks, users should note the following:
- The callback **must never attempt to block or yield** and critical sections should be kept as short as possible
- The callback is called shortly before a deleted task's memory is freed. Thus, the callback can either be called from :cpp:func:`vTaskDelete` itself, or from the idle task.
+.. ----------------------------------------------- IDF Additional API --------------------------------------------------
+
+IDF Additional API
+------------------
+
+The :component_file:`freertos/esp_additions/include/freertos/idf_additions.h` header contains FreeRTOS related helper functions added by ESP-IDF. Users can include this header via ``#include "freertos/idf_additions.h"``.
.. ------------------------------------------ Component Specific Properties --------------------------------------------
@@ -455,3 +461,8 @@ Hooks API
^^^^^^^^^
.. include-build-file:: inc/esp_freertos_hooks.inc
+
+Additional API
+^^^^^^^^^^^^^^
+
+.. include-build-file:: inc/idf_additions.inc