ESP Memory Usage Optimization

[中文]

Note

Although this document is primarily aimed at memory optimization for the ESP32-C2 chip, most of the optimization items are applicable to all ESP series chips. Therefore, this document can also be referred to when optimizing memory on other ESP chips.

Introduction

The ESP32-C2 chip has a physical memory of 256 KB. However, in actual testing, when compiling the BLE + Wi-Fi coexistence example bleprph_wifi_coex according to the IDF guide document, the remaining memory after running is only 24 KB. This makes it quite difficult to develop complex applications on the ESP32-C2.

The cause of this issue is that the ESP32-C2 is configured by default for performance priority, with many basic components compiled into IRAM to increase running speed. However, for low-cost solutions like the ESP32-C2, most scenarios only require simple control operations. For such applications, users can significantly optimize memory, and in the case of deep optimization, they can optimize more than 100 KB of memory.

This document optimizes the memory of ESP32-C2 on the ESP-IDF release/v5.5 branch, and explains the impact of these optimizations on memory and how to enable these optimizations.

Warning

Some memory optimization methods listed in this document may reduce system performance and stability. Sufficient performance and stability testing should be conducted after optimization to ensure the application meets its requirements.

Obtaining Current Free Memory

Before optimizing memory, it is necessary to first understand the current memory usage. For static memory usage, you can use the idf.py size and idf.py size-components commands to analyze memory after compilation.

For runtime memory usage, the current remaining memory and the smallest remaining heap memory size since system startup can be obtained respectively through the esp_get_free_heap_size() and esp_get_minimum_free_heap_size() functions. For more details, refer to ESP-IDF Heap Memory Description.

ESP32-C2 Memory Test Results

The following data compares the remaining memory of ESP32-C2 using the ESP-IDF example in the default configuration (i.e., the default configuration after using idf.py set-target esp32c2) at tag v5.5-beta1, and after optimizing memory through various configuration items.

Test Scenario Description

  • Wi-Fi station : Prints remaining memory after the GOT IP event is triggered.

  • Wi-Fi station + 1TLS(MQTTS) : Use the mqtt/ssl example, print remaining memory after the MQTT_EVENT_DATA event is triggered.

  • bleprph_wifi_coex : Initializes nimble and starts BLE broadcasting after the WiFi GOT_IP event is triggered, and prints the remaining memory.

  • bleprph_wifi_coex + mbedtls + power_save : Integrates https_mbedtls and power_save features based on bleprph_wifi_coex, and prints remaining memory after connecting to the https server.

Comparison of Memory Usage in Default Configuration

ESP32-C2 Remaining Memory Comparison

Test case

Default configuration (KB)

Optimized configuration (KB)

station

95

169

WiFi station + 1TLS(MQTTS)

55

152

bleprph_wifi_coex

24

125

bleprph_wifi_coex + mbedtls + power_save

Insufficient memory

115

Note

This document is solely for explaining the memory optimization process and effects of ESP32-C2. For more statistics on memory usage under different chips and scenarios, please refer to Memory Usage Comparison.

Optimization Strategy

The optimization strategy in this article is based on a self-implemented test case bleprph_wifi_coex + mbedtls + power_save demo, which includes common scenarios such as Wi-Fi + BLE + HTTPS + power save automatic sleep. The specific demo and memory strategy configuration items can be referred to this link. Before any optimization is performed, a reset will be triggered due to insufficient memory during execution.

Comparison of Optimization Solutions

Comparison of Remaining Memory under Different Optimization Schemes

Optimized solution

v5.4.1 (bytes)

v5.5 (bytes)

Description

No optimization

Insufficient memory

Insufficient memory

Default configuration after using idf.py set-target esp32c2

Basic optimization

62840

60212

Optimize the configuration items according to the memory optimization section

Advanced Optimization

91976

90576

Continue to optimize on the basis of basic optimization, applicable to v5.4.x and previous versions.

v5.5 Deeply Optimized

118096

Deeply optimize using the new features of v5.5

Note

You haven’t provided any text to translate. Please provide the text you want translated.

  1. No optimization: This is the default configuration after using idf.py set-target esp32c2, only ensuring the functionality is available (such as enabling Bluetooth, PM and other basic configurations), without any specific memory usage optimization.

  2. Basic Optimization: Fully optimized according to the ESP-IDF Memory Optimization Section, involving the placement of various functions from IRAM to flash, reducing WiFi buffer and optimizing mbedtls configuration, etc.

  3. Advanced Optimization: Based on basic optimization, further in-depth optimization is carried out in combination with the documentation, especially suitable for v5.4.x and previous versions. At this time, the memory usage data represents the “final optimization” results under these versions.

  4. v5.5 Deep Optimization: This continues to optimize based on advanced optimization, but only targets v5.5 and later versions of ESP-IDF. This optimization allows more code to be placed in flash by utilizing new features (such as flash suspend), thereby freeing up IRAM and minimizing memory usage to the greatest extent.

Basic Optimization

The ESP-IDF Programming Guide provides a series of memory optimization methods, mainly including IRAM optimization and heap memory optimization. IRAM optimization primarily places functions of components such as FreeRTOS, Wi-Fi, heap, etc., into flash; heap memory optimization mainly reduces the number of static memory applications by components such as Wi-Fi, lwip, etc. Through these configuration item optimizations (refer to sdkconfig.defaults.opt.1), the available memory can be increased to 62 KB after all functions have been executed.

Advanced Optimization

On top of the basic optimization, further optimization is carried out, mainly including the following:

  1. Enable CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY

    After enabling CONFIG_SPI_FLASH_AUTO_SUSPEND, by enabling CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY, all the code of the Bluetooth controller will be placed in the flash, which will then release about 20 KB of memory space.

  2. Enable Compilation Optimization Option

    • CONFIG_COMPILER_OPTIMIZATION_SIZE

    • CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS

    These compilation optimizations can continue to free up about 8 KB of memory space.

After enabling all the above configurations (basic optimization + advanced optimization) (specific configuration items can be referred to sdkconfig.defaults.opt.2), the available memory increases to 90 KB.

v5.5 Deep Optimization

In ESP-IDF v5.5 version, we have deeply optimized the IRAM usage, which allows most IRAM functions to be placed in flash, especially when enabling the CONFIG_SPI_FLASH_AUTO_SUSPEND configuration. For a detailed list of all such configurations, please refer to sdkconfig.flash_auto_suspend_iram_reduction.

After enabling all these optimization options (specific configurations can be referred to sdkconfig.defaults.opt.3), it can save an additional 20 KB of memory compared to version v5.4.2.

In v5.5, the available memory can reach 118 KB after connecting to the HTTPS server, of which the .text segment of IRAM occupies 10050 Bytes.

Based on testing with version v5.4.2, with the same optimization configuration, the available memory after connecting to the HTTPS server is 95 KB, of which the .text segment of IRAM occupies 31206 Bytes.

Comparison of IRAM text sections

The memory consumption data in the IRAM .text segment obtained using the idf.py size command is as follows:

Comparison of IRAM .text Segment Memory Usage

Optimized solution

v5.4.1 (bytes)

v5.5 (bytes)

No optimization

93592

100616

Basic optimization

56384

60088

Advanced Optimization

36130

35912

v5.5 Deeply Optimized

9742

Other chips use

Although memory optimization is mainly for the ESP32-C2 chip, other new chips such as ESP32-C61 and ESP32-C5 can also be optimized. Based on the default configuration, approximately 80 KB of memory can be added.