How to use esptool.exe to upload application (firmware.bin) and spiffs.bin?

I found out how to upload firmware.bin and spiffs.bin using espota.exe in thread ESP32 OTA update using simplest method?

Now I want to know how to do the same thing with esptool.exe. To recap the use case: I have a ‘customer’ (no money involved I’m doing free work for a STEM charity) who is computer literate, but I don’t want them to have to install an IDE. If the target’s WiFi isn’t working, they’d need to use a USB cable to update the target.

I did a verbose upload from the PlatformIO drop down options and saw the command line used for upload. After copying the necessary files into the same temp folder where I put esptool.exe I found this command line worked fine:

.\esptool.exe --chip esp32 --port “COM3” --baud 460800 --before default-reset --after hard-reset write-flash -z --flash-mode dio --flash-freq 40m --flash-size detect 0x1000 bootloader_dio_40m.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin

Is there a way I can just upload firmware.bin without having to upload bootloader_dio_40m.bin, partitions.bin and boot_app0.bin?

How do I upload spiffs.bin with esptool.exe?

I saw this here

I tried adding “0x110000 spiffs.bin“, without the quotes, to the end of my working command line from above, but got:

I don’t see a “verbose file system update” in the PlatformIO menu. How can I see that in order to know what command line PlatformIO is using to do a file system upload?

TIA for any responses.

The correct addresses depend on your used partition table (documentation).

You could manually calculate the absolute address of for your filesystem binary based on your selected partition table CSV file, but..

The simplest way is to simply sniff what exact esptool command PlatformIO uses when uploading the firmware and SPIFFS and replicate it.

On a PlatformIO Core CLI:

pio run -v -t upload
pio run -v -t uploadfs

Should give you, in the respective last lines of output, the esptool command, in which you can see the needed addrseses.

Yes. You can merge the bootloader, partition table, firmware, filesystem, etc. into a single flash_image.bin file and only flash that at the start address of flash. The esptool.py merge-bin command is exacty made for that. Of course, you need to know the individual files and their addresses for this to work.

>"C:\Users\Max\.platformio\penv\Scripts\python.exe" esptool.py merge-bin --help
Warning: DEPRECATED: 'esptool.py' is deprecated. Please use 'esptool' instead. The '.py' suffix will be removed in a future major release.
esptool v5.1.0

 Usage: esptool.py merge-bin [OPTIONS] <address> <filename>...

 Merge multiple raw binary files into a single flashable file.

╭─ UF2 options ────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --chunk-size   INTEGER  Specify the used data part of the 512 byte UF2 block. A common value is 256. By default the  │
│                         largest possible value will be used.                                                         │
│ --md5-disable           Disable MD5 checksum in UF2 output.                                                          │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ RAW options ────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --target-offset  -t  INTEGER                                         Target offset where the output file will be     │
│                                                                      flashed.                                        │
│ --pad-to-size        [256KB|512KB|1MB|2MB|4MB|8MB|16MB|32MB|64MB|12  If set, the final binary file will be padded    │
│                      8MB]                                            with 0xFF bytes up to this flash size.          │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Flash options ──────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --flash-freq  -ff  [keep|80m|60m|48m|40m|30m|26m|24m|20m|16m|15m|1  SPI flash memory frequency.                      │
│                    2m]                                                                                               │
│ --flash-mode  -fm  [keep|qio|qout|dio|dout]                         SPI flash memory mode.                           │
│ --flash-size  -fs  [keep|256KB|512KB|1MB|2MB|2MB-c1|4MB|4MB-c1|8MB  SPI flash memory size. ESP8266-only sizes:       │
│                    |16MB|32MB|64MB|128MB]                           256KB, 512KB, 2MB-c1, 4MB-c1.                    │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Arguments ──────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ *  ADDR-FILENAME  <address> <filename>...  [required]                                                                │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ *  --output  -o  TEXT           Output filename. [required]                                                          │
│    --format  -f  [raw|uf2|hex]  Format of the output file.                                                           │
│    --help    -h                 Show this message and exit.                                                          │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

Thank you very much for the quick and thorough response Max.

I probably won’t have time to try this until early next week. When I’ve tried it I’ll update this thread.