Просмотр исходного кода

freertos: Add wrapper functions to create objects with capabilities

This commit adds various ...WithCaps() functions to create FreeRTOS objects
with specific memory capabilities.
Darian Leung 2 лет назад
Родитель
Сommit
4e7cd2e706

+ 1 - 0
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"

+ 275 - 0
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 <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 ) */

+ 251 - 4
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,9 +34,11 @@
  *
  * 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
@@ -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
     }

+ 6 - 0
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

+ 1 - 0
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 \

+ 11 - 0
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