Closed sblantipodi closed 2 years ago
Please have a look at what I do in ESPEasy to generate the bin files. (a newer version of what you've been using)
It is using esptool.py to generate a bin file. Make sure to correctly set the flash mode in your board definition files. (see here for the board definitions used in ESPEasy) This is especially critical for 16M units.
I also reverted to version 3.3 of esptool.py since version 4 does by default add some checksum which may become invalid if the used flash tool decides to set the flash size and frequency based on what it detects instead of what is set in the board definition.
About QIO being needed... Are you sure about that its actually needed? I've not seen boards that won't work on slower settings like DIO even though the flash chip is capable of handling QIO and also wired for it.
Hi @TD-er thank you for your very kind answer, I really appreciate it. I want to target to normal ESP32 4MB boards.
my platformio.ini
file is as simple as this:
[env:glowwormluciferinfull_esp32]
platform = espressif32@5.1.0
board = esp32dev
board_build.mcu = esp32
board_build.flash_mode = dio
board_build.f_flash = 40000000L
framework = arduino
board_build.filesystem = littlefs
board_build.f_cpu = 240000000L
monitor_port = COM11
upload_port = COM11
lib_ldf_mode = deep
extra_scripts = post:platformio_version_increment/esp32_create_factory_bin_post.py
I copied and pasted your python script here https://github.com/letscontrolit/ESPEasy/blob/mega/tools/pio/post_esp32.py in my platformio_version_increment/esp32_create_factory_bin_post.py
this is the output of your script:
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM: [== ] 20.0% (used 65676 bytes from 327680 bytes)
Flash: [======== ] 77.3% (used 1013329 bytes from 1310720 bytes)
Building .pio/build/glowwormluciferinfull_esp32/firmware.bin
esptool.py v3.3
Creating esp32 image...
Merged 25 ELF sections
Successfully created esp32 image.
esp32_create_combined_bin([".pio/build/glowwormluciferinfull_esp32/firmware.bin"], [".pio/build/glowwormluciferinfull_esp32/firmware.elf"])
Generating combined binary for serial flashing
Offset | File
- 0x1000 | /home/runner/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/bin/bootloader_dio_40m.bin
- 0x8000 | /home/runner/work/glow_worm_luciferin/glow_worm_luciferin/currentbranch/.pio/build/glowwormluciferinfull_esp32/partitions.bin
- 0xe000 | /home/runner/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin
- 0x10000 | /home/runner/work/glow_worm_luciferin/glow_worm_luciferin/currentbranch/.pio/build/glowwormluciferinfull_esp32/firmware.bin
Using esptool.py arguments: --chip esp32 merge_bin -o /home/runner/work/glow_worm_luciferin/glow_worm_luciferin/currentbranch/.pio/build/glowwormluciferinfull_esp32/firmware-factory.bin --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 /home/runner/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/bin/bootloader_dio_40m.bin 0x8000 /home/runner/work/glow_worm_luciferin/glow_worm_luciferin/currentbranch/.pio/build/glowwormluciferinfull_esp32/partitions.bin 0xe000 /home/runner/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin 0x10000 /home/runner/work/glow_worm_luciferin/glow_worm_luciferin/currentbranch/.pio/build/glowwormluciferinfull_esp32/firmware.bin
esptool.py v3.3
Wrote 0x108ce0 bytes to file /home/runner/work/glow_worm_luciferin/glow_worm_luciferin/currentbranch/.pio/build/glowwormluciferinfull_esp32/firmware-factory.bin, ready to flash to offset 0x0
It generates the factory.bin but once I try to flash it with esp web tools 9.0.3 I got a boot loop:
rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 188777542, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:QIO, clock div:1
load:0x3fff0030,len:1344
load:0xeccddede,len:-321921060
1162 mmu set 00010000, pos 00010000
1162 mmu set 00020000, pos 00020000
1162 mmu set 00030000, pos 00030000
1162 mmu set 00040000, pos 00040000
1162 mmu set 00050000, pos 00050000
1162 mmu set 00060000, pos 00060000
1162 mmu set 00070000, pos 00070000
1162 mmu set 00080000, pos 00080000
1162 mmu set 00090000, pos 00090000
1162 mmu set 000a0000, pos 000a0000
1162 mmu set 000b0000, pos 000b0000
1162 mmu set 000c0000, pos 000c0000
1162 mmu set 000d0000, pos 000d0000
1162 mmu set 000e0000, pos 000e0000
1162 mmu set 000f0000, pos 000f0000
1162 mmu set 00100000, pos 00100000
1162 mmu set 00110000, pos 00110000
1162 mmu�ets Jun 8 2016 00:22:57
I tried it with many devices like the Lolin D32, ESP32 dev kit and TinyPICO.
Any suggestions? :)
Thanks!!!!!
Can you flash it directly from PlatformIO and check the esptools.py output to see what flags it sets (e.g. 0x0340 or something like this, not behind my dev PC right now)
@TD-er I narrowed the problem. it seems that most boards work with both DIO 40000000L and QIO 80000000L when flashing using PlatformIO
TinyPICO works only with QIO 80000000L when flashing using PlatformIO
Esp Web Tools does not work with QIO 80000000L at all in my case.
here the output of the flash from platformio when using DIO 40000000L
Building .pio\build\glowwormluciferinfull_esp32\firmware.bin
esptool.py v3.3
Creating esp32 image...
Merged 25 ELF sections
Successfully created esp32 image.
esp32_create_combined_bin([".pio\build\glowwormluciferinfull_esp32\firmware.bin"], [".pio\build\glowwormluciferinfull_esp32\firmware.elf"])
Generating combined binary for serial flashing
Offset | File
- 0x1000 | C:\Users\perin\.platformio\packages\framework-arduinoespressif32\tools\sdk\esp32\bin\bootloader_dio_40m.bin
- 0x8000 | C:\dev\dpsoftware\ArduinoRaspberry\PUBLIC\glow_worm_luciferin\.pio\build\glowwormluciferinfull_esp32\partitions.bin
- 0xe000 | C:\Users\perin\.platformio\packages\framework-arduinoespressif32\tools\partitions\boot_app0.bin
- 0x10000 | C:\dev\dpsoftware\ArduinoRaspberry\PUBLIC\glow_worm_luciferin\.pio\build\glowwormluciferinfull_esp32/firmware.bin
Using esptool.py arguments: --chip esp32 merge_bin -o C:\dev\dpsoftware\ArduinoRaspberry\PUBLIC\glow_worm_luciferin\.pio\build\glowwormluciferinfull_esp32/firmware-factory.bin --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 C:\Users\perin\.platformio\packages\framework-arduinoespressif32\tools\sdk\esp32\bin\bootloader_dio_40m.bin 0x8000 C:\dev\dpsoftware\ArduinoRaspberry\PUBLIC\glow_worm_luciferin\.pio\build\glowwormluciferinfull_esp32\partitions.bin 0xe000 C:\Users\perin\.platformio\packages\framework-arduinoespressif32\tools\partitions\boot_app0.bin 0x10000 C:\dev\dpsoftware\ArduinoRaspberry\PUBLIC\glow_worm_luciferin\.pio\build\glowwormluciferinfull_esp32/firmware.bin
esptool.py v3.3
Flash params set to 0x0220
Wrote 0x111580 bytes to file C:\dev\dpsoftware\ArduinoRaspberry\PUBLIC\glow_worm_luciferin\.pio\build\glowwormluciferinfull_esp32/firmware-factory.bin, ready to flash to offset 0x0
If I use QIO 80000000L it's the same but the flash params, this are the flash params: Flash params set to 0x002f
If I use QIO 80000000L I can flash Lolin D32, ESP32 dev kit, quindor esp32 and TinyPICO without problems using PlatformIO.
the solution seems to use QIO 80000000L everywhere but ESP Web Tools seems to not work well with QIO 80000000L. it never work if I set QIO 80000000L
Esp Web Tools works with DIO 40000000L but in this way I can't flash TinyPICO for example...
is there a solution to have a firmware that can run on all ESP32 4MB boards?
When you flash using esptool.py, the tool detects what is available and patches the flags while flashing.
See: Flash params set to 0x0220
As can be seen in the esptool.py source code this describes flash mode, flash size and flash frequency.
Flash mode 0x02 = dio. What's more concerning is that the frequency apparently is far from standard (or I'm looking at the wrong data) Flash frequency seems to be 12MHz
So my advice is to write the firmware to a device using PlatformIO and then use esptool.py to read the entire flash back into a single file. If you flash that file again using the web tools, it should work.
You can also try to use these flash mode and frequency settings to generate the bin file using the PIO script which uses esptool to generate the combined bin file and see if that will work.
So my advice is to write the firmware to a device using PlatformIO and then use esptool.py to read the entire flash back into a single file. If you flash that file again using the web tools, it should work.
My build are triggered via a git tag and they publish factory binaries to the server via a GitHub Action. there is no device connected to the server that creates the factory bin. I can do this try but it will not help solving my problem.
If I flash via PlatformIO using QIO, 80MHz, 4MB, Flash params is set to 0x002f and PlatformIO uses 0x002f on every boards I flash (LolinD32, TinyPICO, ESP32 Dev Kit, Quindor ESP32)
QIO, 80MHz, 4MB seems to be the best bet to target most of the 4MB boards with this new arduino core. can't understand why it worked before and now it does not work anymore with the new arduino core :)
Does ESP Web Tools support 0x002f (QIO, 80MHz, 4MB) ???
Does ESP Web Tools support 0x002f (QIO, 80MHz, 4MB) ???
webtools does support anything and nothing, as it does not patch the bin while flashing. So you must make sure the bin is OK.
My build are triggered via a git tag and they publish factory binaries to the server via a GitHub Action. there is no device connected to the server that creates the factory bin. I can do this try but it will not help solving my problem.
That's exactly what I intended, it is for debugging and validating the hypothesis about what's causing these issues. My hypothesis is that the files need to be patched when flashing, but since the webtool isn't doing that we must find out what the values should be so you can define them in PlatformIO and/or your board definitions.
@TD-er we've switched to esptool.js, which is a port of esptool.py maintained by Espressif. It mimics the esptool.py logic.
@sblantipodi can you confirm that you run the latest version of ESP Web Tools?
@TD-er we've switched to esptool.js, which is a port of esptool.py maintained by Espressif. It mimics the esptool.py logic.
OK, so the latest version (which I have not yet tried) should be able to patch the bin again on the fly while flashing?
@TD-er I'll try to understand how to download the firmware from the device and I'll report back.
@balloob sure, I update on every new release. using 9.0.3 now. https://sblantipodi.github.io/glow_worm_luciferin/beta.html
thanks a billion for all the kind help.
@TD-er yes. It should follow the same logic as esptool.py. Espressif wants to keep the esptool.js port 1:1 the same as esptool.py (including how functions are broken out etc).
@TD-er yes. It should follow the same logic as esptool.py. Espressif wants to keep the esptool.js port 1:1 the same as esptool.py (including how functions are broken out etc).
Great! Then I can think of a few more feature requests ;)
@TD-er I tried what you suggested.
esptool -b 921600 --port COM11 read_flash 0x00000 0x400000 flash_4M.bin
I then uploaded the downloaded flash_4M.bin
file with ESP Web Tools and it works no problem.
your hypothesis was correct.
Great! Now you need to perform a diff on the first few kB of the downloaded file and the one you created during build. Not sure at what address, but it is quite far in the beginning (from my memory, around byte 108???) you'll find a difference in 2 bytes. Try to match these by changing the board flash parameters in PlatformIO.
@TD-er thank you so much for all the help! I really appreciate it.
I wrote a simple java program to detect the difference between the two firmware:
public static void main(String... args) {
File file = new File("C:/Users/perin/Desktop/firmware_from_the_device.bin");
File file2 = new File("C:/Users/perin/Desktop/firmware_from_esp_web_tools.bin");
FileInputStream fileInputStream;
FileInputStream fileInputStream2;
byte[] bFile = new byte[(int) file.length()];
byte[] bFile2 = new byte[(int) file2.length()];
try {
fileInputStream = new FileInputStream(file);
fileInputStream2 = new FileInputStream(file2);
fileInputStream.read(bFile);
fileInputStream2.read(bFile2);
fileInputStream.close();
fileInputStream2.close();
for (int i = 0; i < 10_000; i++) {
if (bFile[i] != bFile2[i]) {
System.out.println("Found a difference at byte in position #" + i);
System.out.println("Firmware downloaded from the microcontroller, byte=" + bFile[i]);
System.out.println("Firmware produced by ESP Web Tools, byte=" + bFile2[i]);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
it seems that the first 10_000 bytes are identical. the only difference found in the first 10_000 bytes are at byte #4098.
this is the output of the program:
Found a difference at byte in position #4098
Firmware downloaded from the microcontroller, byte=2
Firmware produced by ESP Web Tools, byte=0
is this what you expect? am I following a red herring?
if this is what you expect, what should I change in platformio.ini to try to match that byte?
the only flash params I know that I can change are these ones:
board_build.flash_mode = qio
board_build.f_flash = 80000000L
board_upload.flash_size=4MB
are there something else that I can try to change to match that bytes?
OK, maybe this position 108 I had in mind was ESP8266 specific. So it seems there is only 1 byte different.
This means only 1 parameter needs to be changed, but I am not sure whether it is the frequency or the flash mode.
Let's first assume the flash mode.
Please change qio
to dio
, based on this:
@TD-er the minimum common denominator for all my 4MB boards to work well when uploading from PlatformIO is board_build.flash_mode = qio board_build.f_flash = 80000000L
DIO does not work well on TinyPICO so the firmware I downloaded from the device (TinyPICO) that worked well used QIO 80MHz.
now I changed my platformio.ini from QIO to DIO, now the first 4100 bytes are identical so no more differences in position 4098 but after 4100 bytes there are a lot of differences now.
in any case the produced firmware with DIO does not work on TinyPICO but works well on Lolin D32 (tried it from the ESP Web Tools).
Based on the partition table you posted:
Generating combined binary for serial flashing
Offset | File
- 0x1000 | C:\Users\perin\.platformio\packages\framework-arduinoespressif32\tools\sdk\esp32\bin\bootloader_dio_40m.bin
- 0x8000 | C:\dev\dpsoftware\ArduinoRaspberry\PUBLIC\glow_worm_luciferin\.pio\build\glowwormluciferinfull_esp32\partitions.bin
- 0xe000 | C:\Users\perin\.platformio\packages\framework-arduinoespressif32\tools\partitions\boot_app0.bin
- 0x10000 | C:\dev\dpsoftware\ArduinoRaspberry\PUBLIC\glow_worm_luciferin\.pio\build\glowwormluciferinfull_esp32/firmware.bin
Using esptool.py arguments: --chip esp32 merge_bin -o C:\dev\dpsoftware\ArduinoRaspberry\PUBLIC\glow_worm_luciferin\.pio\build\glowwormluciferinfull_esp32/firmware-factory.bin --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 C:\Users\perin\.platformio\packages\framework-arduinoespressif32\tools\sdk\esp32\bin\bootloader_dio_40m.bin 0x8000 C:\dev\dpsoftware\ArduinoRaspberry\PUBLIC\glow_worm_luciferin\.pio\build\glowwormluciferinfull_esp32\partitions.bin 0xe000 C:\Users\perin\.platformio\packages\framework-arduinoespressif32\tools\partitions\boot_app0.bin 0x10000 C:\dev\dpsoftware\ArduinoRaspberry\PUBLIC\glow_worm_luciferin\.pio\build\glowwormluciferinfull_esp32/firmware.bin
Starting at 0x1000 (4096 decimal) is this:
bootloader_dio_40m.bin
So this does suggest your build is assuming 40 MHz flash
But you're telling the flasher and build process to use 80 MHz.
Please try it with 40 MHz and dio
as that's what's being linked in your build.
As I said before, it makes little sense why you must use QIO and DIO should not work. The other way around makes a lot more sense.
@TD-er
this lines
0x1000 | C:\Users\perin\.platformio\packages\framework-arduinoespressif32\tools\sdk\esp32\bin\bootloader_dio_40m.bin
changes accordingly to what I set in platformio.ini
if I use DIO 40MHz, I see this:
0x1000 | C:\Users\perin\.platformio\packages\framework-arduinoespressif32\tools\sdk\esp32\bin\bootloader_dio_40m.bin
if I use QIO 80MHz, I see this:
0x1000 | C:\Users\perin\.platformio\packages\framework-arduinoespressif32\tools\sdk\esp32\bin\bootloader_qio_80m.bin
I don't understand why TinyPICO does not work with DIO but only works with QIO. this small snippet, https://gist.github.com/sblantipodi/7c09855aad9e6882efabbf12fd05f68b fails badly in reading writing little fs when using DIO, this problem is true even when flashing via PlatformIO directly to the device.
the strange thing is that the problem happen only when using espressif32@5.1.0 and not when using espressif32@5.0.0
ESP Web Tools never work well with firmware that uses QIO neither by using espressif32@5.1.0 or espressif32@5.0.0.
I think that we have multiple problems here...
the only solution I have at the moment is to use espressif32@5.0.0 with DIO 40MHz. this works well even when using ESP Web Tools.
but this is not a solution to me.
I just looked at the Espressif32 PIO 5.1.0 release notes With this in the additional notes:
This release introduces an additional build step that merges all the primary binaries (partitions, bootloaders and the firmware itself) into a single image before debugging or uploading via debug probes. It's a required modification as the latest Arduino core v2.0.4 is shipped with prebuilt bootloaders that don't have proper default file headers anymore. This inconsistency results in bootloops if the firmware is flashed via OpenOCD because OpenOCD has no mechanisms to determine what flash memory settings were used. The only major side effect of this change is that the gaps (e.g. Non-volatile Storage section) between binaries may be erased while debugging or uploading via debug probes. In such cases, it's recommended to use uploading via serial port.
So I guess there is something seriously different here. Maybe best to wait for a 5.1.x release and perhaps also report it with PlatformIO?
Maybe best to wait for a 5.1.x release and perhaps also report it with PlatformIO?
done it here: https://github.com/platformio/platform-espressif32/issues/877
there is still a problem. ESP Web Tools does not work with QIO even when using espressif32@5.0.0.
Well, i had to update how the factory Tasmota firmware is build for core 2.0.4.
See working pio script https://github.com/arendst/Tasmota/blob/development/pio-tools/post_esp32.py
@TD-er this is needed too to flash correct bootloaders for QIO
and QOUT
.
Since 2.0.4. there is NO default setting anywhere for flash mode and frequency. So if no tool does set here valid values it will 100% end in a crash. So i highly recommend to use esptool.py and let do the firmware generating job. esptool.py needs to be feed with ALL settings here.
@sblantipodi With the change i added (this is done in platformio code the same way) ESP-Web-Tools is working for all build variants.
It is "just" building the factory firmware correct.
@TD-er yes. It should follow the same logic as esptool.py. Espressif wants to keep the esptool.js port 1:1 the same as esptool.py (including how functions are broken out etc).
@balloob It is not 1:1, i had to revert to v8.x since espressif.js is not able to recognize/flash device via CDC/JTAG (inbuilt "USBmodem") connection. The old version does work with these devices too.
Can you open an issue on esptool.js to track that, and note what errors you see.
Can you open an issue on esptool.js to track that, and note what errors you see.
Will do, back on PC not until tomorrow.
@TD-er esptool.py v4.1 can be used, but this needs a not backwards compatible change in platform espressif32. My latest fork version uses esptool.py v4.1. The needed change
I see a lot of beautiful minds on this issue, except for mine obviously. xD
I reduced the Jason2866 script to be more "compliant" with smaller projects like mine.
Import("env")
env = DefaultEnvironment()
platform = env.PioPlatform()
from genericpath import exists
import sys
from os.path import join
sys.path.append(join(platform.get_package_dir("tool-esptoolpy")))
import esptool
FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32")
variants_dir = join(FRAMEWORK_DIR, "variants", "luciferin")
def esp32_create_combined_bin(source, target, env):
#print("Generating combined binary for serial flashing")
# factory_offset = -1 # error code value - currently unused
app_offset = 0x10000 # default value for "old" scheme
fs_offset = -1 # error code value
new_file_name = env.subst("$BUILD_DIR/${PROGNAME}-factory.bin")
sections = env.subst(env.get("FLASH_EXTRA_IMAGES"))
firmware_name = env.subst("$BUILD_DIR/${PROGNAME}.bin")
chip = env.get("BOARD_MCU")
flash_size = env.BoardConfig().get("upload.flash_size", "4MB")
flash_freq = env.BoardConfig().get("build.f_flash", "40000000L")
flash_freq = str(flash_freq).replace("L", "")
flash_freq = str(int(int(flash_freq) / 1000000)) + "m"
flash_mode = env.BoardConfig().get("build.flash_mode", "dout")
if flash_mode == "qio":
flash_mode = "dio"
elif flash_mode == "qout":
flash_mode = "dout"
cmd = [
"--chip",
chip,
"merge_bin",
"-o",
new_file_name,
"--flash_mode",
flash_mode,
"--flash_freq",
flash_freq,
"--flash_size",
flash_size,
]
print(" Offset | File")
for section in sections:
sect_adr, sect_file = section.split(" ", 1)
print(f" - {sect_adr} | {sect_file}")
cmd += [sect_adr, sect_file]
# "main" firmware to app0 - mandatory
print(f" - {hex(app_offset)} | {firmware_name}")
cmd += [hex(app_offset), firmware_name]
if(fs_offset != -1):
fs_bin = join(env.subst("$BUILD_DIR"),"littlefs.bin")
if exists(fs_bin):
before_reset = env.BoardConfig().get("upload.before_reset", "default_reset")
after_reset = env.BoardConfig().get("upload.after_reset", "hard_reset")
print(f" - {hex(fs_offset)}| {fs_bin}")
cmd += [hex(fs_offset), fs_bin]
env.Replace(
UPLOADERFLAGS=[
"--chip", chip,
"--port", '"$UPLOAD_PORT"',
"--baud", "$UPLOAD_SPEED",
"--before", before_reset,
"--after", after_reset,
"write_flash", "-z",
"--flash_mode", "${__get_board_flash_mode(__env__)}",
"--flash_freq", "${__get_board_f_flash(__env__)}",
"--flash_size", flash_size
],
UPLOADCMD='"$PYTHONEXE" "$UPLOADER" $UPLOADERFLAGS ' + " ".join(cmd[7:])
)
print("Will use custom upload command for flashing operation to add file system defined for this build target.")
# print('Using esptool.py arguments: %s' % ' '.join(cmd))
esptool.main(cmd)
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", esp32_create_combined_bin)
It now works awesome!
I'm honored to be helped by you guys! Bye!
PS: I'll wait to see if there is something else from you before closing the issue :) Thanks!!!
Hi all, as soon as I update Arduino Core from 2.0.3 to 2.0.4 and PlatformIO from 5.0.0 to 5.1.0 my Little FS is corrupted after flashing my firmware with esp web tools.
this is my simple json:
and this is the script that I use to create a factory bin.
It worked well before but now it is broken... As soon as I flash the firmware with Arduino core 2.0.4, LittleFS got corrupted. It works well with Arduino core 2.0.3. I think that this can be related to flash mode (QIO is now needed for some boards), is there a way to specify the flash mode with esp web tools?
Any suggestions will be really appreciated :)
Thanks Davide