Minimizing Binary Size - ESP32 (original) (raw)

[中文]

The ESP-IDF build system compiles all source files in the project and ESP-IDF, but only functions and variables that are actually referenced by the program are linked into the final binary. In some cases, it is necessary to reduce the total size of the firmware binary, e.g., in order to fit it into the available flash partition size.

The first step to reducing the total firmware binary size is measuring what is causing the size to increase.

Measuring Static Sizes

To optimize both the firmware binary size and the memory usage, it is necessary to measure statically-allocated RAM (data, bss), code (text), and read-only data (rodata) in your project. The idf.py sub-commands size, size-components, and size-files can be used to examine statically-allocated RAM usage at different levels of detail. For more information, please see the IDF Size tool.

Linker Map File

Note

This is an advanced analysis method, but it can be very useful. Feel free to skip ahead to Reducing Overall Size and possibly come back to this later.

The idf.py size analysis tools all work by parsing the GNU binutils linker map file, which is a summary of everything the linker did when it created (i.e., linked) the final firmware binary file.

Linker map files themselves are plain text files, so it is possible to read them and find out exactly what the linker did. However, they are also very complex and long, often exceeding 100,000 lines.

The map file itself is broken into parts and each part has a heading. The parts are:

Note

Linker map files are generated by the GNU binutils linker ld, not ESP-IDF. You can find additional information online about the linker map file format. This quick summary is written from the perspective of ESP-IDF build system in particular.

Reducing Overall Size

The following configuration options reduces the final binary size of almost any ESP-IDF project:

Note

In addition to the many configuration items shown here, there are a number of configuration options where changing the option from the default increases binary size. These are not noted here. Where the increase is significant is usually noted in the configuration item help text.

Targeted Optimizations

The following binary size optimizations apply to a particular component or a function:

Wi-Fi

ADC

Bluetooth NimBLE

If using NimBLE-based Host APIs then the following modifications can reduce binary size:

lwIP IPv6

lwIP IPv4

Picolibc instead of Newlib

By default, ESP-IDF uses the Newlib C library, and it also has experimental support for the Picolibc C library.

Picolibc C library provides smaller printf family functions and can reduce the binary size by up to 30 KB, depending on your application.

To switch to linking against the Picolibc C library, please enable the configuration options CONFIG_IDF_EXPERIMENTAL_FEATURES and CONFIG_LIBC_PICOLIBC.

Newlib Nano Formatting

By default, ESP-IDF uses Newlib "full" formatting for I/O functions (printf(), scanf(), etc.)

Enabling the config option CONFIG_LIBC_NEWLIB_NANO_FORMAT will switch Newlib to the "Nano" formatting mode. This is smaller in code size, and a large part of the implementation is compiled into the ESP32 ROM, so it does not need to be included in the binary at all.

The exact difference in binary size depends on which features the firmware uses, but 25 KB ~ 50 KB is typical.

Enabling "Nano" formatting reduces the stack usage of each function that calls printf() or another string formatting function, see Determining Stack Size.

"Nano" formatting does not support 64-bit integers, or C99 formatting features. For a full list of restrictions, search for --enable-newlib-nano-formatted-io in the Newlib README file.

MbedTLS Features

Under Component Config > mbedTLS, there are multiple mbedTLS features enabled default, some of which can be disabled if not needed to save code size.

These include:

The help text for each option has some more information for reference.

Important

It is strongly not recommended to disable all these mbedTLS options. Only disable options of which you understand the functionality and are certain that it is not needed in the application. In particular:

If depending on third party clients or servers, always pay attention to announcements about future changes to supported TLS features. If not, the ESP32 device may become inaccessible if support changes.

Note

Not every combination of mbedTLS compile-time config is tested in ESP-IDF. If you find a combination that fails to compile or function as expected, please report the details on GitHub.

VFS

Virtual Filesystem Component feature in ESP-IDF allows multiple filesystem drivers and file-like peripheral drivers to be accessed using standard I/O functions (open, read, write, etc.) and C library functions (fopen, fread, fwrite, etc.). When filesystem or file-like peripheral driver functionality is not used in the application, this feature can be fully or partially disabled. VFS component provides the following configuration options:

Bootloader Size

This document deals with the size of an ESP-IDF app binary only, and not the ESP-IDF Second Stage Bootloader.

For a discussion of ESP-IDF bootloader binary size, see Bootloader Size.

IRAM Binary Size

If the IRAM section of a binary is too large, this issue can be resolved by reducing IRAM memory usage. See Optimizing IRAM Usage.