ESP-IDF Firmware Size Analysis Tool
esp-idf-size is a Python library and command-line tool for analyzing the firmware size of projects built with the Espressif ESP-IDF framework. It parses map files generated by the linker to provide detailed insights into memory usage by components, archives, files, and symbols. As of version 2.1.0, it's actively maintained with several releases per year.
Warnings
- breaking Starting with v2.0.0, the 'NG' (Next Generation) implementation became the default behavior. The `--ng` command-line flag and `ESP_IDF_SIZE_NG` environment variable are no longer supported and should be removed. The `--legacy` mode has also been removed.
- breaking For programmatic users, import paths for the core functionality changed in v2.0.0 due to the 'NG' implementation becoming default. Objects previously imported from `esp_idf_size.ng` (e.g., `esp_idf_size.ng.size_report.SizeReport`) now reside directly under `esp_idf_size` (e.g., `esp_idf_size.size_report.SizeReport`).
- gotcha Map files must be opened using UTF-8 encoding. Issues with non-UTF-8 characters in map files (e.g., in symbol names or paths) can lead to parsing errors or incorrect reports.
Install
-
pip install esp-idf-size
Imports
- IdfSize
from esp_idf_size.core import IdfSize
- SizeReport
from esp_idf_size.size_report import SizeReport
Quickstart
# Assuming you have an ESP-IDF project built, with a map file.
# The map file is typically found in build/<chip>/<project_name>.map
# e.g., build/esp32/hello-world.map
# Example using a placeholder map file path
import os
# Replace with the actual path to your .map file
# For demonstration, we'll use a dummy file path
map_file_path = os.environ.get('ESP_IDF_MAP_FILE', 'path/to/your/project/build/esp32/firmware.map')
if not os.path.exists(map_file_path):
print(f"Warning: Map file not found at '{map_file_path}'.")
print("Please replace 'path/to/your/project/build/esp32/firmware.map' ")
print("with the actual path to your ESP-IDF project's .map file.")
print("You can also set the ESP_IDF_MAP_FILE environment variable.")
else:
# Command line usage (most common)
print(f"\nRunning CLI tool on: {map_file_path}")
os.system(f"idf_size {map_file_path}")
# Programmatic usage (example for v2.0.0+)
try:
from esp_idf_size.core import IdfSize
# Create a dummy map file for programmatic example if not exists
if not os.path.exists(map_file_path):
with open(map_file_path, 'w') as f:
f.write(".text 0x40080000 0x100 app_start.o\n")
f.write(".rodata 0x3f400000 0x50 main.o\n")
f.write(".dram0.data 0x3f800000 0x20 data.o\n")
f.write(".flash.text 0x10000 0x80 bootloader.o\n")
f.write("0x42000000-0x42010000 iram_loader.text\n")
print("Created a dummy map file for programmatic example.")
idf_size_analyzer = IdfSize(map_file=map_file_path)
size_report = idf_size_analyzer.parse_and_get_size_report()
print("\nProgrammatic size report (excerpt):")
print(f"Total Flash Size: {size_report.total_flash_size_with_bootloader} bytes")
print(f"Total IRAM Size: {size_report.total_iram_size} bytes")
# print(size_report.to_json())
# Clean up dummy map file
if not os.environ.get('ESP_IDF_MAP_FILE') and os.path.exists(map_file_path):
os.remove(map_file_path)
print(f"Cleaned up dummy map file: {map_file_path}")
except ImportError:
print("\nCould not import esp_idf_size.core.IdfSize. Ensure esp-idf-size is installed.")
except Exception as e:
print(f"\nAn error occurred during programmatic analysis: {e}")