espflasher

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 18, 2026 License: BSD-3-Clause Imports: 13 Imported by: 0

Documentation

Overview

Package espflasher provides a Go library for flashing firmware to Espressif ESP8266 and ESP32-family microcontrollers over a serial (UART) connection. It implements the serial bootloader protocol used by the ESP ROM bootloader, supporting the following chip families:

  • ESP8266
  • ESP32
  • ESP32-S2
  • ESP32-S3
  • ESP32-C2 (ESP8684)
  • ESP32-C3
  • ESP32-C5
  • ESP32-C6
  • ESP32-H2

Quick Start

To flash a .bin file to a connected ESP device:

flasher, err := espflasher.New("/dev/ttyUSB0", nil)
if err != nil {
    log.Fatal(err)
}
defer flasher.Close()

data, _ := os.ReadFile("firmware.bin")
err = flasher.FlashImage(data, 0x0, nil)
if err != nil {
    log.Fatal(err)
}
flasher.Reset()

Architecture

The library is organized in layers:

  • SLIP: Serial Line Internet Protocol framing (slip.go)
  • Protocol: ROM bootloader command/response protocol (protocol.go)
  • Chip: Per-target chip definitions and detection (chip.go, target_*.go)
  • Image: Firmware image header parsing and patching (image.go)
  • Stub: Stub loader for advanced operations like erase and read (stub.go)
  • Flasher: High-level flash/verify/reset API (flasher.go)

The protocol uses SLIP framing over serial UART. Commands are sent as request packets with an opcode, and the device responds with status. Flash writes can optionally use zlib-compressed data for faster transfers.

Index

Constants

View Source
const (
	FlashModeQIO  byte = 0x00 // Quad I/O (fastest, 4-bit addr + 4-bit data)
	FlashModeQOUT byte = 0x01 // Quad Output (4-bit data only)
	FlashModeDIO  byte = 0x02 // Dual I/O (2-bit addr + 2-bit data)
	FlashModeDOUT byte = 0x03 // Dual Output (2-bit data, most compatible)
)

Flash mode constants for the ESP image header (byte offset 2). These control how the SPI flash chip is accessed.

View Source
const Version = "0.6.0"

Version is the current version of the espflasher library.

Variables

This section is empty.

Functions

This section is empty.

Types

type ChipDetectError

type ChipDetectError struct {
	MagicValue uint32
}

ChipDetectError is returned when chip auto-detection fails.

func (*ChipDetectError) Error

func (e *ChipDetectError) Error() string

type ChipType

type ChipType int

ChipType identifies the ESP chip family.

const (
	ChipESP8266 ChipType = iota
	ChipESP32
	ChipESP32S2
	ChipESP32S3
	ChipESP32C2
	ChipESP32C3
	ChipESP32C5
	ChipESP32C6
	ChipESP32H2
	ChipAuto // Auto-detect chip type
)

func (ChipType) String

func (c ChipType) String() string

String returns the human-readable chip name.

type CommandError

type CommandError struct {
	OpCode  byte
	Status  byte
	ErrCode byte
}

CommandError is returned when the ROM bootloader returns a non-zero status.

func (*CommandError) Error

func (e *CommandError) Error() string

type Flasher

type Flasher struct {
	// contains filtered or unexported fields
}

Flasher manages the connection to an ESP device and provides high-level flash operations.

func New

func New(portName string, opts *FlasherOptions) (*Flasher, error)

New creates a new Flasher connected to the given serial port.

It opens the serial port, enters the bootloader, syncs with the device, and detects the chip type. On success, the Flasher is ready for flash operations.

If opts is nil, DefaultOptions() is used.

Example:

f, err := espflasher.New("/dev/ttyUSB0", nil)
if err != nil {
    log.Fatal(err)
}
defer f.Close()

func (*Flasher) ChipName

func (f *Flasher) ChipName() string

ChipName returns the detected chip name (e.g. "ESP32-S3").

func (*Flasher) ChipType

func (f *Flasher) ChipType() ChipType

ChipType returns the detected chip type.

func (*Flasher) Close

func (f *Flasher) Close() error

Close releases the serial port and associated resources.

func (*Flasher) EraseFlash

func (f *Flasher) EraseFlash() error

EraseFlash erases the entire flash memory. This operation can take a significant amount of time (30-120 seconds). Requires the stub loader to be running.

func (*Flasher) EraseRegion

func (f *Flasher) EraseRegion(offset, size uint32) error

EraseRegion erases a region of flash memory. Requires the stub loader to be running. Both offset and size must be aligned to the flash sector size (4096 bytes).

func (*Flasher) FlashID

func (f *Flasher) FlashID() (uint8, uint16, error)

FlashID reads the SPI flash chip manufacturer and device ID. Returns (manufacturer_id, device_id, error).

func (*Flasher) FlashImage

func (f *Flasher) FlashImage(data []byte, offset uint32, progress ProgressFunc) error

FlashImage writes a firmware image to flash at the given offset.

The data should be a raw .bin file (not ELF). The offset is typically 0x0 for a merged/combined binary, or a specific address like 0x10000 for the application partition.

If progress is non-nil, it will be called periodically with the number of bytes transferred so far.

Example:

data, _ := os.ReadFile("firmware.bin")
err := f.FlashImage(data, 0x0, func(cur, total int) {
    fmt.Printf("\r%d/%d bytes", cur, total)
})

func (*Flasher) FlashImages

func (f *Flasher) FlashImages(images []ImagePart, progress ProgressFunc) error

FlashImages writes multiple firmware images to flash at their respective offsets. This is useful for flashing bootloader + partition table + application in one go.

Each entry is a (data, offset) pair.

Example:

images := []espflasher.ImagePart{
    {Data: bootloader, Offset: 0x1000},
    {Data: partTable, Offset: 0x8000},
    {Data: app, Offset: 0x10000},
}
err := f.FlashImages(images, progress)

func (*Flasher) GetMD5 added in v0.6.0

func (f *Flasher) GetMD5(offset, size uint32) (string, error)

GetMD5 returns the MD5 hash of a flash region. Requires the stub loader to be running.

func (*Flasher) GetSecurityInfo added in v0.6.0

func (f *Flasher) GetSecurityInfo() (*SecurityInfo, error)

GetSecurityInfo returns security-related information from the device.

func (*Flasher) ReadFlash added in v0.6.0

func (f *Flasher) ReadFlash(offset, size uint32) ([]byte, error)

ReadFlash reads data from flash memory. Requires the stub loader to be running.

func (*Flasher) ReadRegister

func (f *Flasher) ReadRegister(addr uint32) (uint32, error)

ReadRegister reads a 32-bit register from the device.

func (*Flasher) Reset

func (f *Flasher) Reset()

Reset performs a hard reset of the device, causing it to run user code.

func (*Flasher) WriteRegister

func (f *Flasher) WriteRegister(addr, value uint32) error

WriteRegister writes a 32-bit value to a register on the device.

type FlasherOptions

type FlasherOptions struct {
	// BaudRate is the initial baud rate for serial communication.
	// Default: 115200.
	BaudRate int

	// FlashBaudRate is the baud rate used during flash data transfer.
	// If set and higher than BaudRate, the flasher will switch to this rate
	// after connecting. Set to 0 to keep the initial baud rate.
	// Default: 460800.
	FlashBaudRate int

	// ChipType forces a specific chip type instead of auto-detection.
	// Default: ChipAuto (auto-detect).
	ChipType ChipType

	// ResetMode controls how the chip is reset to enter bootloader.
	// Default: ResetDefault.
	ResetMode ResetMode

	// ConnectAttempts is the number of connection attempts before failing.
	// Default: 7.
	ConnectAttempts int

	// Compress enables zlib compression for flash data transfer.
	// Significantly faster for large images. Requires stub loader or
	// ESP32+ ROM bootloader.
	// Default: true.
	Compress bool

	// FlashMode sets the SPI flash access mode in the image header.
	// Valid values: "qio", "qout", "dio", "dout".
	// Empty string or "keep" preserves the value from the binary.
	// Most ESP32 boards work with "dio"; some need "dout".
	FlashMode string

	// FlashFreq sets the SPI flash clock frequency in the image header.
	// Valid values are chip-specific, e.g. "80m", "40m", "26m", "20m".
	// Empty string or "keep" preserves the value from the binary.
	FlashFreq string

	// FlashSize sets the flash chip size in the image header.
	// Valid values: "1MB", "2MB", "4MB", "8MB", "16MB", etc.
	// Empty string or "keep" preserves the value from the binary.
	FlashSize string

	// Logger receives informational messages during flashing.
	// If nil, messages are discarded silently.
	Logger Logger
}

FlasherOptions configures the Flasher behavior.

func DefaultOptions

func DefaultOptions() *FlasherOptions

DefaultOptions returns FlasherOptions with sensible defaults.

type ImagePart

type ImagePart struct {
	// Data is the raw binary data to flash.
	Data []byte

	// Offset is the flash address to write to (e.g. 0x0, 0x1000, 0x10000).
	Offset uint32
}

ImagePart represents a firmware image segment with its flash offset.

type Logger

type Logger interface {
	// Logf logs a formatted informational message.
	Logf(format string, args ...interface{})
}

Logger is the interface for receiving progress and status messages.

type ParsedFlags added in v0.5.0

type ParsedFlags struct {
	SecureBootEn               bool
	SecureBootAggressiveRevoke bool
	SecureDownloadEnable       bool
	SecureBootKeyRevoke0       bool
	SecureBootKeyRevoke1       bool
	SecureBootKeyRevoke2       bool
	SoftDisJtag                bool
	HardDisJtag                bool
	DisUSB                     bool
	DisDownloadDcache          bool
	DisDownloadIcache          bool
}

type ProgressFunc

type ProgressFunc func(current, total int)

ProgressFunc is called with progress updates during flashing. current is the bytes transferred so far, total is the total bytes.

type ResetMode

type ResetMode int

ResetMode defines how the ESP chip should be reset.

const (
	// ResetDefault uses the classic DTR/RTS reset sequence to enter bootloader.
	ResetDefault ResetMode = iota

	// ResetNoReset does not perform any hardware reset.
	// The chip must already be in bootloader mode.
	ResetNoReset

	// ResetUSBJTAG uses the USB-JTAG/Serial reset sequence (ESP32-S3, ESP32-C3, etc.).
	ResetUSBJTAG

	// ResetAuto tries multiple reset strategies in sequence.
	// First attempts DTR/RTS classic reset, then USB-JTAG, then no-signal.
	// Useful when the interface type is unknown.
	ResetAuto
)

func (ResetMode) String added in v0.6.0

func (r ResetMode) String() string

String returns the string representation of the ResetMode.

type SecurityInfo added in v0.5.0

type SecurityInfo struct {
	Flags         uint32
	FlashCryptCnt uint8
	KeyPurposes   [7]uint8
	ChipID        *uint32
	APIVersion    *uint32
	ParsedFlags   ParsedFlags
}

type StdoutLogger

type StdoutLogger struct {
	W io.Writer
}

StdoutLogger is a simple Logger implementation that writes to an io.Writer.

func (*StdoutLogger) Logf

func (l *StdoutLogger) Logf(format string, args ...interface{})

Logf implements the Logger interface.

type SyncError

type SyncError struct {
	Attempts int
}

SyncError is returned when the device cannot be synced.

func (*SyncError) Error

func (e *SyncError) Error() string

type TimeoutError

type TimeoutError struct {
	Op string
}

TimeoutError is returned when a response is not received within the timeout.

func (*TimeoutError) Error

func (e *TimeoutError) Error() string

type UnsupportedCommandError

type UnsupportedCommandError struct {
	Command string
}

UnsupportedCommandError is returned for commands not supported by the current ROM/stub.

func (*UnsupportedCommandError) Error

func (e *UnsupportedCommandError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL