Skip to content

Conversation

@brianignacio5
Copy link
Collaborator

@brianignacio5 brianignacio5 commented Dec 10, 2025

Replace the old reader.readAsBinaryString to use reader.readAsArrayBuffer(file); instead allowing user to use UInt8Array for files instead of string.

Fix #219
Fix #229

Description

This pull request refactors the firmware flashing workflow to consistently use Uint8Array for binary image data instead of strings. This change improves type safety, performance, and compatibility with modern web APIs. The update touches multiple areas, including file handling, firmware image classes, and the main flashing logic. It also adds better error logging and updates MD5 hash calculation for binary data.

Binary image data handling and type safety:

  • Refactored all firmware image classes (ESP32FirmwareImage, ESP8266ROMFirmwareImage, ESP8266V2FirmwareImage, ESP32S2FirmwareImage, ESP32S3FirmwareImage, ESP32C3FirmwareImage) to accept and process Uint8Array instead of strings. The loadFromFile methods now handle both Uint8Array and string inputs, converting as needed. ([[1]](https://github.com/espressif/esptool-js/pull/226/files#diff-cb8f3ca2232e60e52ce55bcea56211c937fbb15d93f6f7b0c9834b0bde6607bbL43-R43), [[2]](https://github.com/espressif/esptool-js/pull/226/files#diff-cb8f3ca2232e60e52ce55bcea56211c937fbb15d93f6f7b0c9834b0bde6607bbL54-R56), [[3]](https://github.com/espressif/esptool-js/pull/226/files#diff-fe7be74db67cb782f352691f2c1260d0f8847db03a0d9cf5b9197e5d5c67dbf4L10-R10), [[4]](https://github.com/espressif/esptool-js/pull/226/files#diff-fe7be74db67cb782f352691f2c1260d0f8847db03a0d9cf5b9197e5d5c67dbf4L21-R22), [[5]](https://github.com/espressif/esptool-js/pull/226/files#diff-fe7be74db67cb782f352691f2c1260d0f8847db03a0d9cf5b9197e5d5c67dbf4L51-R51), [[6]](https://github.com/espressif/esptool-js/pull/226/files#diff-fe7be74db67cb782f352691f2c1260d0f8847db03a0d9cf5b9197e5d5c67dbf4L62-R63), [[7]](https://github.com/espressif/esptool-js/pull/226/files#diff-3e3b9a4fb5a60a561e65244d8b4e06b18654430df28ae7acab669324a9694cdbL15-R20), [[8]](https://github.com/espressif/esptool-js/pull/226/files#diff-3e3b9a4fb5a60a561e65244d8b4e06b18654430df28ae7acab669324a9694cdbL24-R34), [[9]](https://github.com/espressif/esptool-js/pull/226/files#diff-3e3b9a4fb5a60a561e65244d8b4e06b18654430df28ae7acab669324a9694cdbL33-R48))
  • Updated the loadFirmwareImage function and related type annotations to support Uint8Array | string for image data, ensuring all image loading is done with binary-safe types. ([[1]](https://github.com/espressif/esptool-js/pull/226/files#diff-bc708f2006b74482b85e56e07e24d033a3916a4b9a10fd10b4cea2732f57e66fL20-R27), [[2]](https://github.com/espressif/esptool-js/pull/226/files#diff-bc708f2006b74482b85e56e07e24d033a3916a4b9a10fd10b4cea2732f57e66fR83-R94))

File reading and UI integration:

  • Changed file reading in the TypeScript example (index.ts) to use readAsArrayBuffer and convert the result to Uint8Array, updating all downstream references to use binary data. ([[1]](https://github.com/espressif/esptool-js/pull/226/files#diff-86a9903e156e927494bb34e6a8a5af426ba2201cec729680b9cd916609be5718R72-R79), [[2]](https://github.com/espressif/esptool-js/pull/226/files#diff-86a9903e156e927494bb34e6a8a5af426ba2201cec729680b9cd916609be5718L423-R430))
  • Updated the MD5 hash calculation to work with binary data by converting Uint8Array to a Latin1 string before hashing. ([examples/typescript/src/index.tsR447-R460](https://github.com/espressif/esptool-js/pull/226/files#diff-86a9903e156e927494bb34e6a8a5af426ba2201cec729680b9cd916609be5718R447-R460))

Firmware flashing logic improvements:

  • Refactored the core flashing logic in ESPLoader to work with Uint8Array throughout: image padding, compression, block writing, and SHA digest recalculation now operate on binary data, removing legacy string conversions and improving correctness. ([[1]](https://github.com/espressif/esptool-js/pull/226/files#diff-9c5587f99fb0aa42042f10b8d0d9e019be9130ded25135b21bddd818c86a3873L1342-R1353), [[2]](https://github.com/espressif/esptool-js/pull/226/files#diff-9c5587f99fb0aa42042f10b8d0d9e019be9130ded25135b21bddd818c86a3873L1366-R1368), [[3]](https://github.com/espressif/esptool-js/pull/226/files#diff-9c5587f99fb0aa42042f10b8d0d9e019be9130ded25135b21bddd818c86a3873L1383-R1391), [[4]](https://github.com/espressif/esptool-js/pull/226/files#diff-9c5587f99fb0aa42042f10b8d0d9e019be9130ded25135b21bddd818c86a3873L1409-R1464), [[5]](https://github.com/espressif/esptool-js/pull/226/files#diff-9c5587f99fb0aa42042f10b8d0d9e019be9130ded25135b21bddd818c86a3873L1476-R1485), [[6]](https://github.com/espressif/esptool-js/pull/226/files#diff-9c5587f99fb0aa42042f10b8d0d9e019be9130ded25135b21bddd818c86a3873L1485-R1494), [[7]](https://github.com/espressif/esptool-js/pull/226/files#diff-9c5587f99fb0aa42042f10b8d0d9e019be9130ded25135b21bddd818c86a3873L1498-R1509), [[8]](https://github.com/espressif/esptool-js/pull/226/files#diff-9c5587f99fb0aa42042f10b8d0d9e019be9130ded25135b21bddd818c86a3873L1520-R1531), [[9]](https://github.com/espressif/esptool-js/pull/226/files#diff-9c5587f99fb0aa42042f10b8d0d9e019be9130ded25135b21bddd818c86a3873L1529-R1546), [[10]](https://github.com/espressif/esptool-js/pull/226/files#diff-9c5587f99fb0aa42042f10b8d0d9e019be9130ded25135b21bddd818c86a3873L1552-R1565))

Error logging and UI feedback:

  • Added eslint-disable-next-line no-console comments and improved error logging for UI actions (connect, erase, program) to provide better feedback during failures. ([[1]](https://github.com/espressif/esptool-js/pull/226/files#diff-86a9903e156e927494bb34e6a8a5af426ba2201cec729680b9cd916609be5718R114), [[2]](https://github.com/espressif/esptool-js/pull/226/files#diff-86a9903e156e927494bb34e6a8a5af426ba2201cec729680b9cd916609be5718R126), [[3]](https://github.com/espressif/esptool-js/pull/226/files#diff-86a9903e156e927494bb34e6a8a5af426ba2201cec729680b9cd916609be5718R151), [[4]](https://github.com/espressif/esptool-js/pull/226/files#diff-86a9903e156e927494bb34e6a8a5af426ba2201cec729680b9cd916609be5718R447-R460))

Flash options and compatibility:

  • Updated flash options to include flashMode: "keep" and flashFreq: "keep" for compatibility and user feedback during flashing. ([examples/typescript/src/index.tsR447-R460](https://github.com/espressif/esptool-js/pull/226/files#diff-86a9903e156e927494bb34e6a8a5af426ba2201cec729680b9cd916609be5718R447-R460))

Testing

Use the examples/typescript to flash a set of binaries to your Espressif device.

Checklist

Before submitting a Pull Request, please ensure the following:

  • 🚨 This PR does not introduce breaking changes.
  • All CI checks (GH Actions) pass.
  • Documentation is updated as needed.
  • Tests are updated or added as necessary.
  • Code is well-commented, especially in complex areas.
  • Git history is clean — commits are squashed to the minimum necessary.

@brianignacio5 brianignacio5 self-assigned this Dec 10, 2025
@brianignacio5
Copy link
Collaborator Author

PTAL @RushikeshPatange as it changes the input from string to UInt8Array

@github-actions
Copy link

github-actions bot commented Dec 10, 2025

Download the artifacts for this pull request:

@fabkury
Copy link

fabkury commented Dec 20, 2025

Summary

We tested PR #226 (Uint8Array support) for flashing ESP32-P4 devices. The data corruption persists. Firmware data is verified correct immediately before calling writeFlash(), but the device fails to boot with "invalid magic byte" errors after flashing.

Test Setup

Firmware Files

File Address Size Magic Byte
bootloader.bin 0x2000 23,584 bytes 0xE9 ✓
partition-table.bin 0x8000 3,072 bytes 0xAA ✓
ota_data_initial.bin 0x10000 8,192 bytes 0xFF ✓
p3a.bin 0x20000 1,807,904 bytes 0xE9 ✓
storage.bin 0x1020000 1,048,576 bytes 0xFF ✓
network_adapter.bin 0x1120000 1,167,040 bytes 0xE9 ✓

Key Finding: Data Correct Before Write, Corrupted After

We added verification logging immediately before calling writeFlash():

[02:05:07] Verifying firmware data...
[02:05:07]   bootloader.bin: 23584 bytes, first 8: [e9 03 02 5f da 9e f2 4f], magic: 0xe9
[02:05:07]   partition-table.bin: 3072 bytes, first 8: [aa 50 01 02 00 90 00 00], magic: 0xaa
[02:05:07]   ota_data_initial.bin: 8192 bytes, first 8: [ff ff ff ff ff ff ff ff], magic: 0xff
[02:05:07]   p3a.bin: 1807904 bytes, first 8: [e9 07 02 5f 0e 04 f0 4f], magic: 0xe9
[02:05:07]   storage.bin: 1048576 bytes, first 8: [ff ff ff ff ff ff ff ff], magic: 0xff
[02:05:07]   network_adapter.bin: 1167040 bytes, first 8: [e9 05 02 20 d4 03 80 40], magic: 0xe9

All magic bytes are correct (0xE9 for app images). The Uint8Array data is valid.

Flash appears to succeed:

[02:05:07] Flash params set to 25f
[02:05:07] Compressed 1807904 bytes to 1031971...
[02:05:08] Writing at 0x20000... (1%)
...
[02:05:34] Wrote 1807904 bytes (1031971 compressed) at 0x20000 in 25.776 seconds.

But the device fails to boot:

E (119) esp_image: image at 0x20000 has invalid magic byte (nothing flashed here?)
E (127) boot: OTA app partition slot 0 is not bootable

What We Tested

Approach Result
Official esptool-js 0.5.7 with binary strings ❌ "Image doesn't look like an image file" warning, data corrupted
Official esptool-js 0.5.7 with ISO-8859-1 string encoding ❌ Checksum failure in bootloader
PR #226 build with native Uint8Array ❌ Data correct before write, corrupted after (this report)
PR #226 with compress: false ❌ "Yet to handle Non Compressed writes" error

Conclusion

The corruption occurs inside esptool-js during the compressed write operation. PR #226's Uint8Array support does not fix this for ESP32-P4.

The same firmware files flash correctly with Python esptool:

python -m esptool --chip esp32p4 -p COM5 -b 460800 write_flash \
  --flash-mode dio --flash-freq 80m --flash-size 32MB --force @flash_args

Request

Could you investigate where the data corruption occurs in the compressed write path for ESP32-P4? We're happy to provide additional testing or logs if needed.

Repository with test case: https://github.com/fabkury/p3a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ESP32-P4 Flash Settings Not Applied fileArray option for writeFlash

3 participants