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.
This commit is contained in:
Sudeep Mohanty
2025-07-15 10:28:20 +02:00
committed by BOT
parent 26c19928a9
commit fe2ee39a99
11 changed files with 50 additions and 60 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -1,2 +1 @@
CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y
CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH=y

View File

@@ -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.

View File

@@ -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
---------

View File

@@ -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`

View File

@@ -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` 选项来恢复之前的行为。
核心转储
--------

View File

@@ -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

View File

@@ -1,3 +1,2 @@
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y
CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH=y