flasher

module
v0.0.0-...-dbfeb7d Latest Latest
Warning

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

Go to latest
Published: Aug 27, 2026 License: Apache-2.0

README

flasher

A pure-Go toolkit for talking to and flashing Espressif ESP32 chips over serial — no Python, no esptool, no esp-idf. Library-first, cross-platform (Linux/macOS/Windows), with a thin CLI on top.

Rust has espflash, Python has esptool, C has esp-serial-flasher — Go had no maintained, library-grade option. This fills that gap, so any Go program (a CLI, a provisioning service, a GUI) can drive an ESP32 with zero external toolchain.

Validated end-to-end on the ESP32-C6: identity/security readout, serial monitor, and a full bootloader + partition-table + app flash that boots.

Install

go install github.com/fdelbos/flasher/cmd/flasher@latest

or build from a checkout: go build ./cmd/flasher.

CLI

All commands auto-detect the serial port if you don't name one (it prefers known ESP/USB-UART vendor IDs: CP210x, CH34x, FTDI, Espressif).

flasher list

List available USB serial devices.

$ flasher list
/dev/cu.usbserial-110      10C4:EA60  Silicon Labs CP210x
flasher chip-info [port]

Connect over the ROM bootloader (no firmware flashed) and print identity.

$ flasher chip-info
board id (mac):   fc012cfe77bc
board id (eui64): fc012cfffefe77bc
WiFi MAC:         fc:01:2c:fe:77:bc
BLE MAC:          fc:01:2c:fe:77:be
chip id:       13 (esp32c6)
  • board id (mac) — the factory base MAC as plain hex; recommended unique board id.
  • board id (eui64) — the same value in EUI-64 form (ff fe inserted).
  • MACs are derived from the base MAC (C6 four-address scheme: STA=base, AP=+1, BT/BLE=+2, ETH=+3), verified against the firmware's own BLE_INIT log.
flasher info [port]

Everything in chip-info, plus the security / lockdown state decoded from GET_SECURITY_INFO — read-only, no flashing. Useful to verify Secure Boot / Flash Encryption status (now and after you provision).

security:
  secure boot:      disabled
  flash encryption: disabled
  secure download:  disabled
  key revoke:       0:false 1:false 2:false
  raw flags:        0x00000000   crypt_cnt: 0x00
  key slots:
    block 0: USER/empty
    ...
flasher monitor [flags] [port]

Watch serial output. Non-interactive; quits cleanly on Ctrl-C.

flasher monitor                          # attach WITHOUT resetting the device
flasher monitor --reset                   # reset first, capture boot logs
flasher monitor --out boot.log --reset    # also write output to a file
flasher monitor --baud 115200             # default baud is 115200

By default monitor opens the port with DTR/RTS deasserted, so attaching does not reboot a running board. --reset opts into a reboot to capture boot logs.

flasher flash [flags] <build-dir>

Flash an esp-idf build, replacing idf.py flash. Reads <build-dir>/flasher_args.json and writes exactly the images it lists, at their offsets, verifying each region with the chip's own MD5. Partitions not in flash_files (e.g. NVS) are left untouched.

flasher flash ./build                 # auto-detect port, stub + compression, 921600 baud
flasher flash --dry-run ./build       # print the plan, write nothing
flasher flash --port /dev/cu.usbserial-110 --baud 115200 ./build
$ flasher flash ./build
chip: esp32c6   flash: dio / 8MB / 80m
plan:
  0x000000  bootloader/bootloader.bin              22448 bytes
  0x010000  partition_table/partition-table.bin      3072 bytes
  0x071000  ota_data_initial.bin                    8192 bytes
  0x080000  lock.bin                             2132688 bytes
writing ...
  verified (md5) ok
done. resetting into app.

Build half stays esp-idf/cmake; this replaces only the flash + monitor half. Uploads Espressif's flasher stub and streams compressed (FLASH_DEFL) by default — a 2 MB app flashes in ~20s. Falls back to ROM mode if the stub won't load.

flasher erase [flags]

Erase flash (uses the stub).

flasher erase                          # erase the whole chip
flasher erase --region 0x80000:0x10000 # erase a 4 KiB-aligned region (offset:size, hex ok)
flasher read [--port P] <offset> <size> <file>

Dump a flash region to a file (uses the stub), MD5-verified.

flasher read 0x0 0x6000 bootloader.bin

Library

The esp package is the reusable core; the CLI is a thin front-end over it.

t, _ := esp.OpenSerial("/dev/cu.usbserial-110", esp.ROMBaud)
l := esp.NewLoader(t)
defer l.Close()

l.Connect(ctx)                       // reset into ROM bootloader + SYNC
macs, _ := l.MACs()                  // identity from eFuse
si, _ := l.SecurityInfo()            // secure-boot / flash-encryption state
l.WriteFlash(0x80000, appBytes, nil) // erase + program + MD5 verify
l.HardReset()

Design notes:

  • Transport interface — the loader runs over anything (OpenSerial, a network bridge, a test double), not welded to one serial library.
  • Errors are returned, never os.Exit/log.Fatal — front-ends decide policy.
  • Progress callbacks on long operations so a GUI can show a bar.

Layout

esp/         ROM/serial protocol: SLIP, reset+SYNC, registers, identity,
             security, flashing (stub + compressed), erase, read, monitor;
             the Transport interface.
partition/   flasher_args.json + partition-table.bin parsing.
bundle/      portable, OTA-ready flash-archive format (pack/unpack).
nvs/         pure-Go NVS partition image generation (see nvs/FORMAT.md).
cmd/flasher/ the CLI.

Roadmap

  • eFuse / Secure Boot v2 + Flash Encryption provisioning.
  • NVS: CSV input + cross-page blob chunking + encrypted NVS.
  • More chip targets (ESP32 / S3 / C3 / H2).

License

Apache-2.0. Protocol reimplemented from public documentation; the flasher stubs (when added) originate from Espressif's esp-flasher-stub (Apache-2.0 / MIT), attribution retained.

Directories

Path Synopsis
Package bundle is a portable, self-describing flash archive: a gzip-compressed tar holding a manifest plus the firmware images.
Package bundle is a portable, self-describing flash archive: a gzip-compressed tar holding a manifest plus the firmware images.
cmd
flasher command
Command flasher is a pure-Go ESP serial-bootloader tool (no esptool / esp-idf).
Command flasher is a pure-Go ESP serial-bootloader tool (no esptool / esp-idf).
Package nvs generates ESP-IDF NVS partition images in pure Go — a replacement for nvs_partition_gen.py.
Package nvs generates ESP-IDF NVS partition images in pure Go — a replacement for nvs_partition_gen.py.
Package partition reads esp-idf build metadata — flasher_args.json and partition-table.bin — so a flash can be replayed exactly without esptool/esp-idf.
Package partition reads esp-idf build metadata — flasher_args.json and partition-table.bin — so a flash can be replayed exactly without esptool/esp-idf.

Jump to

Keyboard shortcuts

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