fix(mesh): standalone erase_flash unsupported in --no-stub ROM mode
Real esptool output on a live Heltec V4 exposed the next layer of the --no-stub fix: "A fatal error occurred: ESP32-S3 ROM does not support function erase_flash." The ESP32-S3 ROM bootloader only implements per-sector erase (used internally as write_flash streams data), not a bulk full-chip-erase opcode — that's a stub-firmware-only feature, and Debian's esptool package ships without the stub (hence --no-stub in the first place). write_flash's own --erase-all flag gets the same "erase everything before writing" outcome our "always erase before write" default requires, but via the per-sector mechanism the ROM bootloader actually supports — one esptool invocation instead of a separate erase_flash + write_flash pair. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
76d14c3bf9
commit
0ca8f25b1b
@ -686,15 +686,25 @@ const ESPTOOL_CHIP: &str = "esp32s3";
|
||||
/// first hiccup, retry once at a conservative baud before giving up.
|
||||
const ESPTOOL_FALLBACK_BAUD: &str = "115200";
|
||||
|
||||
/// A standalone `erase_flash` (full-chip erase via a single ROM opcode) does
|
||||
/// NOT work with --no-stub — confirmed live 2026-07-23 against a real
|
||||
/// Heltec V4: "A fatal error occurred: ESP32-S3 ROM does not support
|
||||
/// function erase_flash." The ESP32-S3 ROM bootloader only implements
|
||||
/// per-sector erase (used internally as write_flash goes), not a bulk
|
||||
/// full-chip erase opcode — that's a stub-firmware-only feature, and
|
||||
/// Debian's esptool package has no stub (see esptool_global_args' doc
|
||||
/// comment). `write_flash --erase-all` gets the same "erase everything
|
||||
/// first" outcome our "always erase before write" default requires, but via
|
||||
/// the per-sector mechanism the ROM bootloader actually supports, as one
|
||||
/// esptool invocation instead of two.
|
||||
async fn esptool_erase_and_write(path: &str, image: &Path, job: &Arc<FlashJob>) -> Result<()> {
|
||||
job.set_stage(FlashStage::Erasing).await;
|
||||
esptool_with_retry(path, &["erase_flash"], job)
|
||||
.await
|
||||
.context("esptool erase_flash failed")?;
|
||||
|
||||
job.set_stage(FlashStage::Writing).await;
|
||||
let image_str = image.to_string_lossy().to_string();
|
||||
esptool_with_retry(path, &["write_flash", "0x0", &image_str], job)
|
||||
esptool_with_retry(
|
||||
path,
|
||||
&["write_flash", "--erase-all", "0x0", &image_str],
|
||||
job,
|
||||
)
|
||||
.await
|
||||
.context("esptool write_flash failed")?;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user