From 4e7cd2e7066c1b9abb7d2e80826a2fef859f8bb5 Mon Sep 17 00:00:00 2001 From: Darian Leung Date: Thu, 6 Apr 2023 22:36:58 +0800 Subject: [PATCH] freertos: Add wrapper functions to create objects with capabilities This commit adds various ...WithCaps() functions to create FreeRTOS objects with specific memory capabilities. --- components/freertos/CMakeLists.txt | 1 + .../freertos/esp_additions/idf_additions.c | 275 ++++++++++++++++++ .../include/freertos/idf_additions.h | 255 +++++++++++++++- components/freertos/linker_common.lf | 6 + docs/doxygen/Doxyfile | 1 + .../system/freertos_additions.rst | 11 + 6 files changed, 545 insertions(+), 4 deletions(-) create mode 100644 components/freertos/esp_additions/idf_additions.c 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/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 3b5a7b347e..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,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 } 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/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