From fe2ee39a994132feb5b7d858c758dec0fdf8fabb Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Tue, 15 Jul 2025 10:28:20 +0200 Subject: [PATCH] feat(esp_ringbuf): Place Ring buffer in flash by default The following updates have been made in this commit: - The commit places ring buffer code in flash memory by default. - CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH has been removed. - CONFIG_RINGBUF_IN_IRAM is added and can be used to restore the previous memory placement. --- .../i2c_test_apps/sdkconfig.ci.iram_safe | 1 + components/esp_ringbuf/Kconfig | 14 ++-- components/esp_ringbuf/linker.lf | 69 +++++++------------ .../test_apps/main/test_ringbuf_target.c | 4 +- .../test_apps/sdkconfig.ci.ringbuf_flash | 1 - docs/en/api-guides/performance/ram-usage.rst | 2 +- .../release-6.x/6.0/system.rst | 7 ++ .../api-guides/performance/ram-usage.rst | 2 +- .../release-6.x/6.0/system.rst | 7 ++ ...dkconfig.flash_auto_suspend_iram_reduction | 2 - .../sdkconfig.ci.func_in_flash_with_Os | 1 - 11 files changed, 50 insertions(+), 60 deletions(-) diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/sdkconfig.ci.iram_safe b/components/esp_driver_i2c/test_apps/i2c_test_apps/sdkconfig.ci.iram_safe index 373ce42664..f9c35a9ecd 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/sdkconfig.ci.iram_safe +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/sdkconfig.ci.iram_safe @@ -6,3 +6,4 @@ CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y CONFIG_I2C_ISR_IRAM_SAFE=y CONFIG_FREERTOS_IN_IRAM=y +CONFIG_RINGBUF_IN_IRAM=y diff --git a/components/esp_ringbuf/Kconfig b/components/esp_ringbuf/Kconfig index b0258c19b7..4947558d7e 100644 --- a/components/esp_ringbuf/Kconfig +++ b/components/esp_ringbuf/Kconfig @@ -1,17 +1,18 @@ menu "ESP Ringbuf" - - config RINGBUF_PLACE_FUNCTIONS_INTO_FLASH - bool "Place non-ISR ringbuf functions into flash" + config RINGBUF_IN_IRAM + bool "Place ring buffer functions in IRAM" default n help - Place non-ISR ringbuf functions (like xRingbufferCreate/xRingbufferSend) into flash. - This frees up IRAM, but the functions can no longer be called when the cache is disabled. + Place ring buffer functions in IRAM for better performance. + By default, ring buffer functions are placed in Flash to save IRAM. + Enable this option if you need maximum performance for ring buffer operations. + Note: This option increases IRAM usage. config RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH bool "Place ISR ringbuf functions into flash" - depends on RINGBUF_PLACE_FUNCTIONS_INTO_FLASH + depends on !RINGBUF_IN_IRAM default n help Place ISR ringbuf functions (like xRingbufferSendFromISR/xRingbufferReceiveFromISR) into flash. @@ -21,5 +22,4 @@ menu "ESP Ringbuf" This option is not compatible with ESP-IDF drivers which are configured to run the ISR from an IRAM context, e.g. CONFIG_UART_ISR_IN_IRAM. - endmenu diff --git a/components/esp_ringbuf/linker.lf b/components/esp_ringbuf/linker.lf index 6af6b56d24..bc1c734291 100644 --- a/components/esp_ringbuf/linker.lf +++ b/components/esp_ringbuf/linker.lf @@ -1,49 +1,28 @@ [mapping:esp_ringbuf] archive: libesp_ringbuf.a entries: - * (noflash_text) - if RINGBUF_PLACE_FUNCTIONS_INTO_FLASH = y: - ringbuf: prvGetCurMaxSizeNoSplit (default) - ringbuf: prvGetCurMaxSizeAllowSplit (default) - ringbuf: prvGetCurMaxSizeByteBuf (default) - ringbuf: prvInitializeNewRingbuffer (default) - ringbuf: prvReceiveGeneric (default) - ringbuf: prvSendAcquireGeneric (default) - ringbuf: prvGetFreeSize (default) - ringbuf: vRingbufferDelete (default) - ringbuf: vRingbufferGetInfo (default) - ringbuf: vRingbufferReturnItem (default) - ringbuf: xRingbufferAddToQueueSetRead (default) - ringbuf: xRingbufferCreate (default) - ringbuf: xRingbufferCreateStatic (default) - ringbuf: xRingbufferCreateNoSplit (default) - ringbuf: xRingbufferReceive (default) - ringbuf: xRingbufferReceiveSplit (default) - ringbuf: xRingbufferReceiveUpTo (default) - ringbuf: xRingbufferRemoveFromQueueSetRead (default) - ringbuf: xRingbufferSend (default) - ringbuf: xRingbufferSendAcquire (default) - ringbuf: xRingbufferSendComplete (default) - ringbuf: xRingbufferPrintInfo (default) - ringbuf: xRingbufferGetMaxItemSize (default) - ringbuf: xRingbufferGetCurFreeSize (default) + if RINGBUF_IN_IRAM = y: + * (noflash_text) # All functions in IRAM + else: + * (default) # All functions in Flash - if RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH = y: - ringbuf: prvReturnItemByteBuf (default) - ringbuf: prvReturnItemDefault (default) - ringbuf: prvGetItemByteBuf (default) - ringbuf: prvGetItemDefault (default) - ringbuf: prvCopyItemAllowSplit (default) - ringbuf: prvCopyItemByteBuf (default) - ringbuf: prvCopyItemNoSplit (default) - ringbuf: prvAcquireItemNoSplit (default) - ringbuf: prvCheckItemFitsByteBuffer (default) - ringbuf: prvCheckItemFitsDefault (default) - ringbuf: prvCheckItemAvail (default) - ringbuf: prvSendItemDoneNoSplit (default) - ringbuf: prvReceiveGenericFromISR (default) - ringbuf: xRingbufferSendFromISR (default) - ringbuf: xRingbufferReceiveFromISR (default) - ringbuf: xRingbufferReceiveSplitFromISR (default) - ringbuf: xRingbufferReceiveUpToFromISR (default) - ringbuf: vRingbufferReturnItemFromISR (default) + # Always keep ISR functions in IRAM unless explicitly placed in Flash + if RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH = n: + ringbuf: prvReturnItemByteBuf (noflash_text) + ringbuf: prvReturnItemDefault (noflash_text) + ringbuf: prvGetItemByteBuf (noflash_text) + ringbuf: prvGetItemDefault (noflash_text) + ringbuf: prvCopyItemAllowSplit (noflash_text) + ringbuf: prvCopyItemByteBuf (noflash_text) + ringbuf: prvCopyItemNoSplit (noflash_text) + ringbuf: prvAcquireItemNoSplit (noflash_text) + ringbuf: prvCheckItemFitsByteBuffer (noflash_text) + ringbuf: prvCheckItemFitsDefault (noflash_text) + ringbuf: prvCheckItemAvail (noflash_text) + ringbuf: prvSendItemDoneNoSplit (noflash_text) + ringbuf: prvReceiveGenericFromISR (noflash_text) + ringbuf: xRingbufferSendFromISR (noflash_text) + ringbuf: xRingbufferReceiveFromISR (noflash_text) + ringbuf: xRingbufferReceiveSplitFromISR (noflash_text) + ringbuf: xRingbufferReceiveUpToFromISR (noflash_text) + ringbuf: vRingbufferReturnItemFromISR (noflash_text) diff --git a/components/esp_ringbuf/test_apps/main/test_ringbuf_target.c b/components/esp_ringbuf/test_apps/main/test_ringbuf_target.c index 62c75f47fb..640545eb2a 100644 --- a/components/esp_ringbuf/test_apps/main/test_ringbuf_target.c +++ b/components/esp_ringbuf/test_apps/main/test_ringbuf_target.c @@ -133,7 +133,7 @@ TEST_CASE("Test ring buffer ISR", "[esp_ringbuf][qemu-ignore]") * tested. */ -#if !CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH && !CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH +#if CONFIG_RINGBUF_IN_IRAM && !CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH /* -------------------------- Test ring buffer IRAM ------------------------- */ static IRAM_ATTR __attribute__((noinline)) bool iram_ringbuf_test(void) @@ -159,7 +159,7 @@ TEST_CASE("Test ringbuffer functions work with flash cache disabled", "[esp_ring { TEST_ASSERT(iram_ringbuf_test()); } -#endif /* !CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH && !CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH */ +#endif /* CONFIG_RINGBUF_IN_IRAM && !CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH */ /* ------------------------ Test ring buffer 0 Item Size ----------------------- * The following test case tests that sending/acquiring an item/bytes of 0 size diff --git a/components/esp_ringbuf/test_apps/sdkconfig.ci.ringbuf_flash b/components/esp_ringbuf/test_apps/sdkconfig.ci.ringbuf_flash index 5b8198abb7..5720a764f4 100644 --- a/components/esp_ringbuf/test_apps/sdkconfig.ci.ringbuf_flash +++ b/components/esp_ringbuf/test_apps/sdkconfig.ci.ringbuf_flash @@ -1,2 +1 @@ -CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH=y diff --git a/docs/en/api-guides/performance/ram-usage.rst b/docs/en/api-guides/performance/ram-usage.rst index 1da3b29306..5110fc79b4 100644 --- a/docs/en/api-guides/performance/ram-usage.rst +++ b/docs/en/api-guides/performance/ram-usage.rst @@ -180,7 +180,7 @@ The following options will reduce IRAM usage of some ESP-IDF features: .. list:: - Disable :ref:`CONFIG_FREERTOS_IN_IRAM` if enabled to place FreeRTOS functions in Flash instead of IRAM. By default, FreeRTOS functions are already placed in Flash to save IRAM. - - Enable :ref:`CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH`. Provided these functions are not incorrectly used from ISRs, this option is safe to enable in all configurations. + - Disable :ref:`CONFIG_RINGBUF_IN_IRAM` if enabled to place ring buffer functions in Flash instead of IRAM. By default, ring buffer functions are already placed in Flash to save IRAM. - Enable :ref:`CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH`. This option is not safe to use if the ISR ringbuf functions are used from an IRAM interrupt context, e.g., if :ref:`CONFIG_UART_ISR_IN_IRAM` is enabled. For the ESP-IDF drivers where this is the case, you can get an error at run-time when installing the driver in question. :SOC_WIFI_SUPPORTED: - Disabling Wi-Fi options :ref:`CONFIG_ESP_WIFI_IRAM_OPT` and/or :ref:`CONFIG_ESP_WIFI_RX_IRAM_OPT` options frees available IRAM at the cost of Wi-Fi performance. :CONFIG_ESP_ROM_HAS_SPI_FLASH: - Enabling :ref:`CONFIG_SPI_FLASH_ROM_IMPL` frees some IRAM but means that esp_flash bugfixes and new flash chip support are not available, see :doc:`/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom` for details. diff --git a/docs/en/migration-guides/release-6.x/6.0/system.rst b/docs/en/migration-guides/release-6.x/6.0/system.rst index b9a84d4f4e..3af03b139e 100644 --- a/docs/en/migration-guides/release-6.x/6.0/system.rst +++ b/docs/en/migration-guides/release-6.x/6.0/system.rst @@ -102,6 +102,13 @@ To reduce IRAM usage, the default placement for most FreeRTOS functions has been When deciding whether to enable ``CONFIG_FREERTOS_IN_IRAM``, consider conducting performance testing to measure the actual impact on your specific use case. Performance differences between Flash and IRAM configurations can vary depending on flash cache efficiency, API usage patterns, and system load. A baseline performance test is provided in ``components/freertos/test_apps/freertos/performance/test_freertos_api_performance.c`` that measures the execution time of commonly used FreeRTOS APIs. This test can help you evaluate the performance impact of memory placement for your target hardware and application requirements. +Ring Buffer +----------- + +**Memory Placement** + +To reduce IRAM usage, the default placement for `esp_ringbuf` functions has been changed from IRAM to Flash. Consequently, the ``CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH`` option has been removed. This change saves a significant amount of IRAM but may have a slight performance impact. For performance-critical applications, the previous behavior can be restored by enabling the new :ref:`CONFIG_RINGBUF_IN_IRAM` option. + Core Dump --------- diff --git a/docs/zh_CN/api-guides/performance/ram-usage.rst b/docs/zh_CN/api-guides/performance/ram-usage.rst index 945cb07119..33893d3832 100644 --- a/docs/zh_CN/api-guides/performance/ram-usage.rst +++ b/docs/zh_CN/api-guides/performance/ram-usage.rst @@ -180,7 +180,7 @@ IRAM 优化 .. list:: - 如果启用了 :ref:`CONFIG_FREERTOS_IN_IRAM`,可以禁用它以将 FreeRTOS 函数放置在 Flash 中而不是 IRAM 中。默认情况下,FreeRTOS 函数已经被放置在 Flash 中以节省 IRAM。 - - 启用 :ref:`CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH`。只要没有从 ISR 中错误地调用这些函数,就可以在所有配置中安全启用此选项。 + - 如果启用了 :ref:`CONFIG_RINGBUF_IN_IRAM`,可以禁用它以将环形缓冲区函数放置在 Flash 中而不是 IRAM 中。默认情况下,环形缓冲区函数已经被放置在 Flash 中以节省 IRAM。 - 启用 :ref:`CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH`。如果从 IRAM 中的中断上下文中使用 ISR ringbuf 函数,例如启用了 :ref:`CONFIG_UART_ISR_IN_IRAM`,则无法安全使用此选项。在此情况下,安装 ESP-IDF 相关驱动程序时,将在运行时报错。 :SOC_WIFI_SUPPORTED: - 禁用 Wi-Fi 选项 :ref:`CONFIG_ESP_WIFI_IRAM_OPT` 和/或 :ref:`CONFIG_ESP_WIFI_RX_IRAM_OPT` 会释放可用 IRAM,但会牺牲部分 Wi-Fi 性能。 :CONFIG_ESP_ROM_HAS_SPI_FLASH: - 启用 :ref:`CONFIG_SPI_FLASH_ROM_IMPL` 选项可以释放一些 IRAM,但此时 esp_flash 错误修复程序及新的 flash 芯片支持将失效,详情请参阅 :doc:`/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom`。 diff --git a/docs/zh_CN/migration-guides/release-6.x/6.0/system.rst b/docs/zh_CN/migration-guides/release-6.x/6.0/system.rst index c7c13a0c52..1a34f2de98 100644 --- a/docs/zh_CN/migration-guides/release-6.x/6.0/system.rst +++ b/docs/zh_CN/migration-guides/release-6.x/6.0/system.rst @@ -102,6 +102,13 @@ FreeRTOS 在决定是否启用 ``CONFIG_FREERTOS_IN_IRAM`` 时,建议进行性能测试以测量对特定用例的实际影响。Flash 和 IRAM 配置之间的性能差异可能因 Flash 缓存效率、API 使用模式和系统负载而异。 在 ``components/freertos/test_apps/freertos/performance/test_freertos_api_performance.c`` 中提供了基准性能测试,用于测量常用 FreeRTOS API 的执行时间。此测试可帮助您评估内存布局对目标硬件和应用程序要求的性能影响。 +环形缓冲区 +---------- + +**内存布局** + +为了减少 IRAM 的使用,`esp_ringbuf` 函数的默认位置已从 IRAM 更改为 Flash。因此,``CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH`` 选项已被移除。此举可节省大量 IRAM,但可能会对性能造成轻微影响。对于性能要求严苛的应用程序,可通过启用新增的 :ref:`CONFIG_RINGBUF_IN_IRAM` 选项来恢复之前的行为。 + 核心转储 -------- diff --git a/tools/test_apps/configs/sdkconfig.flash_auto_suspend_iram_reduction b/tools/test_apps/configs/sdkconfig.flash_auto_suspend_iram_reduction index 0e1236fa14..795eec787c 100644 --- a/tools/test_apps/configs/sdkconfig.flash_auto_suspend_iram_reduction +++ b/tools/test_apps/configs/sdkconfig.flash_auto_suspend_iram_reduction @@ -37,8 +37,6 @@ CONFIG_GDMA_ISR_HANDLER_IN_IRAM=n # CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY=y # System -CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y -CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH=y CONFIG_LIBC_LOCKS_PLACE_IN_IRAM=n CONFIG_HAL_ASSERTION_SILENT=y diff --git a/tools/test_apps/system/build_test/sdkconfig.ci.func_in_flash_with_Os b/tools/test_apps/system/build_test/sdkconfig.ci.func_in_flash_with_Os index f5f9deabd3..08c97cdef5 100644 --- a/tools/test_apps/system/build_test/sdkconfig.ci.func_in_flash_with_Os +++ b/tools/test_apps/system/build_test/sdkconfig.ci.func_in_flash_with_Os @@ -1,3 +1,2 @@ CONFIG_COMPILER_OPTIMIZATION_SIZE=y -CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH=y