People have already solved similiar type of problems before: See Upload littlefs.bin to ESP8266 boards.
The firmware files PlatformIO generates will be saved in .pio/build/<environment name>/firmware.bin
.
With ESP32 you have to careful though, as not only your application image gets flashed technically, but also the bootloader, the partition table and other things. You can see exactly how PlatformIO flashes the binary for your project when you invoke the project task Advanced → Verbose Upload.
For example, with
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
that is
CURRENT: upload_protocol = esptool
BeforeUpload(["upload"], [".pio/build/esp32dev/firmware.bin"])
Auto-detected: /dev/ttyACM0
"/home/max/.platformio/penv/bin/python" "/home/max/.platformio/packages/tool-esptoolpy/esptool.py" --chip esp32 --port "/dev/ttyACM0" --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 /home/max/temp/simple_esp32/.pio/build/esp32dev/bootloader.bin 0x8000 /home/max/temp/simple_esp32/.pio/build/esp32dev/partitions.bin 0xe000 /home/max/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin 0x10000 .pio/build/esp32dev/firmware.bin
esptool.py v4.4
Serial port /dev/ttyACM0
Connecting.......
So the critical command is basically
esptool.py --chip esp32 --port “/dev/ttyACM0” --baud 460800 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 […]bootloader.bin 0x8000 […]partitions.bin 0xe000 […]boot_app0.bin 0x10000 […]firmware.bin
(on Windows, /dev/ttyACM0
will be a COM device, aka the serial port where the dev board is connected to, like COM9
)
If you the hardware is non-changing, then details like flash mode, frequency and isze will always be same.
So what people usually do is:
- Save every involved individual binary file
or - combine all binary files (with filler data in between the non-defined addresses) to one single flash image
Then they usually convert the esptool.py
tool to a native Windows Exe file to lose the dependency on having the customer install Python (and all esptool dependencies). They then write a batch (.bat
) file tha invokes the flashing command (aka esptool.exe ) and bundle the new binaries in that folder.
The alternative to that is to use Espressif’s official GUI flashing tool avaiable from Tools | Espressif Systems.
which, as expected, wants you to give it all binary files it is supposed to flash along with the address where it’s supposed to go.
There’s also more GUI download tools like GitHub - Grovkillen/ESP_Easy_Flasher: A wrapper for ESPTOOL.exe + PowerShell to make flashing/programming ESP Easy units more streamline, these might expect the merged imaged though.
Note that the image merging can be facilitated through either the Espressif GUI after filling in the binaries and addresses
or esptool.py, too.
max@XXXXX:~/temp/simple_esp32$ source ~/.platformio/penv/bin/activate
(penv) max@XXXXXX:~/temp/simple_esp32$ ~/.platformio/packages/tool-esptoolpy/esptool.py --help
usage: esptool [-h] [--chip {auto,esp8266,esp32,esp32s2,esp32s3beta2,esp32s3,esp32c3,esp32c6beta,esp32h2beta1,esp32h2beta2,esp32c2,esp32c6}] [--port PORT] [--baud BAUD]
[--before {default_reset,usb_reset,no_reset,no_reset_no_sync}] [--after {hard_reset,soft_reset,no_reset,no_reset_stub}] [--no-stub] [--trace] [--override-vddsdio [{1.8V,1.9V,OFF}]]
[--connect-attempts CONNECT_ATTEMPTS]
{load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,elf2image,read_mac,chip_id,flash_id,read_flash_status,write_flash_status,read_flash,verify_flash,erase_flash,erase_region,merge_bin,get_security_info,version}
...
esptool.py v4.4 - Espressif chips ROM Bootloader Utility
positional arguments:
{load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,elf2image,read_mac,chip_id,flash_id,read_flash_status,write_flash_status,read_flash,verify_flash,erase_flash,erase_region,merge_bin,get_security_info,version}
Run esptool.py {command} -h for additional help
load_ram Download an image to RAM and execute
dump_mem Dump arbitrary memory to disk
read_mem Read arbitrary memory location
write_mem Read-modify-write to arbitrary memory location
write_flash Write a binary blob to flash
run Run application code in flash
image_info Dump headers from an application image
make_image Create an application image from binary files
elf2image Create an application image from ELF file
read_mac Read MAC address from OTP ROM
chip_id Read Chip ID from OTP ROM
flash_id Read SPI flash manufacturer and device ID
read_flash_status Read SPI flash status register
write_flash_status Write SPI flash status register
read_flash Read SPI flash content
verify_flash Verify a binary blob against flash
erase_flash Perform Chip Erase on SPI flash
erase_region Erase a region of the flash
merge_bin Merge multiple raw binary files into a single file for later flashing
get_security_info Get some security-related data
version Print esptool version