ESP Serial Flasher is a portable C library for programming and interacting with Espressif SoCs from other host microcontrollers.
This library enables you to program Espressif SoCs from various host platforms using different communication interfaces. It provides a unified API that abstracts the underlying communication protocol, making it easy to integrate ESP device programming into your projects. In this context, the host (flashing/programming device running this library) controls the target (the ESP-series SoC being programmed). It serves a similar purpose to esptool, but is designed for embedded hosts without a PC or Python runtime or on less powerful single board computers.
- Connection and identification: Connect to targets, autodetect chip family, read MAC address, retrieve security info.
- Flash operations: Write, read, erase, detect flash size, and optionally verify data via MD5.
- RAM download and execution: Load binaries to RAM and run them.
- Registers and control: Read/write registers, change transmission rate, reset the target.
- UART - Universal asynchronous communication
- USB CDC ACM - USB virtual serial port
- SPI - Serial Peripheral Interface (RAM download only)
- SDIO - Secure Digital Input/Output (experimental)
Note
SDIO interface is experimental and currently supported only with ESP32-P4 as host and ESP32-C6 as target. The implementation uses a custom stub that will be made available as part of the migration to esp-flasher-stub.
- STM32 microcontrollers
- Raspberry Pi SBC
- ESP32 series microcontrollers
- Zephyr OS compatible devices
- Raspberry Pi Pico (RP2040)
Target | UART | SPI | SDIO | USB CDC ACM |
---|---|---|---|---|
ESP8266 | ✅ | ❌ | ❌ | ❌ |
ESP32 | ✅ | ❌ | 🚧 | ❌ |
ESP32-S2 | ✅ | ❌ | ❌ | ❌ |
ESP32-S3 | ✅ | ✅ | ❌ | ✅ |
ESP32-C2 | ✅ | ✅ | ❌ | ❌ |
ESP32-C3 | ✅ | ✅ | ❌ | ✅ |
ESP32-H2 | ✅ | ✅ | ❌ | ✅ |
ESP32-C6 | ✅ | ❌ | ✅ | ✅ |
ESP32-C5 | ✅ | ❌ | 🚧 | ✅ |
ESP32-P4 | ✅ | 🚧 | ❌ | ✅ |
Legend: ✅ Supported | ❌ Not supported | 🚧 Under development
Note
Stub support: ESP8266, ESP32-C5, and ESP32-P4 stub support is under development
- Public headers: include/esp_loader.h and include/esp_loader_io.h define the stable public API of this library.
- Examples and helpers: examples/common/ contains helper utilities used by the examples; not part of the library API, but can be used as a reference.
To use ESP Serial Flasher, you need:
Different host platforms require specific setup procedures:
- ESP32 series: Works with ESP-IDF v4.3 or later
- STM32: Requires STM32 HAL libraries and ARM toolchain
- Zephyr: Integrates as Zephyr module with specific Kconfig options
- Raspberry Pi Pico: Uses Pico SDK
- Raspberry Pi: Requires pigpio library
- Custom platforms: ESP Serial Flasher can be used as a git submodule with your own custom platform implementation
For detailed setup instructions, see Platform Setup Guide.
For implementing custom platform support, see Supporting New Platforms Guide, particularly the sections on using ESP Serial Flasher as an external library and implementation steps.
#include "esp_loader.h"
esp_loader_error_t err;
// Initialize and connect
esp_loader_connect_args_t config = ESP_LOADER_CONNECT_DEFAULT();
err = esp_loader_connect(&config);
if (err != ESP_LOADER_SUCCESS) {
printf("Connection failed: %s\n", esp_loader_error_string(err));
return err;
}
// Flash binary (example: 64KB at 0x10000)
const uint32_t addr = 0x10000;
const size_t size = 65536;
const size_t block_size = 4096;
// Variable holding your binary image. Typical sources:
// - Read from storage (SD card, filesystem, flash)
// - Received over a link (UART/SPI/USB/Wi‑Fi) into a RAM buffer
// - Compiled-in C array generated from a .bin
const uint8_t *data = /* pointer to your firmware image buffer */;
err = esp_loader_flash_start(addr, size, block_size);
if (err != ESP_LOADER_SUCCESS) return err;
// Write data in chunks
size_t offset = 0;
while (offset < size) {
size_t chunk = MIN(block_size, size - offset);
err = esp_loader_flash_write(data + offset, chunk);
if (err != ESP_LOADER_SUCCESS) return err;
offset += chunk;
}
esp_loader_reset_target();
return err
For complete implementation examples, see the examples directory:
- ESP32 Example - ESP32 family as host
- STM32 Example - STM32 as host
- Raspberry Pi Example - Raspberry Pi as host
- Zephyr Example - Zephyr OS integration
- Raspberry Pi Pico Example - RP2040 as host
- ESF Demo - End-to-end demo flashing ESP targets from an embedded host (M5Stack Dial) over USB CDC ACM; includes SD card image selection and on-device progress UI
- esptool documentation - Contains most of the information on how the communication with the chip works, what is and is not possible etc.
- YouTube Tutorial published 9th September 2024 - Comprehensive guide covering library usage, internals, and custom port implementation
ESP Serial Flasher provides several configuration options to customize its behavior. These options are set as CMake cache variables.
The most common configuration options:
# Enable SPI interface instead of UART
cmake -DSERIAL_FLASHER_INTERFACE_SPI=1 ..
# Disable MD5 verification
cmake -DMD5_ENABLED=0 ..
# Set custom retry count
cmake -DSERIAL_FLASHER_WRITE_BLOCK_RETRIES=5 ..
Choose one interface (UART is default):
SERIAL_FLASHER_INTERFACE_UART
- UART communication (default)SERIAL_FLASHER_INTERFACE_SPI
- SPI communicationSERIAL_FLASHER_INTERFACE_USB
- USB CDC ACMSERIAL_FLASHER_INTERFACE_SDIO
- SDIO (experimental)
For complete configuration reference, see Configuration Documentation.
Each communication interface has specific hardware connection requirements and pin configurations. For complete wiring diagrams, pin assignments, and interface-specific setup instructions, see Hardware Connections Guide.
We welcome contributions! Before starting work on new features or significant changes, please open an issue to discuss your proposal.
For detailed contribution guidelines, see CONTRIBUTING.md.
If you want to add support for a new host platform, see Supporting New Host Platforms Guide.
This project is licensed under the Apache 2.0 License - see the LICENSE file for details.
The following limitations are currently known:
- Binary image size must be known before flashing
- ESP8266 targets require
MD5_ENABLED=0
due to ROM bootloader limitations - SPI interface only supports RAM download operations
- SDIO interface is experimental with limited platform support
- Only one target can be flashed at a time (library holds state in static variables)
- Communication interface must be selected at compile time (no runtime switching)
For additional limitations and current issues, see the GitHub Issues page.