diff --git a/src/serial_console.cpp b/src/serial_console.cpp index ff75e25f..06ecc45d 100644 --- a/src/serial_console.cpp +++ b/src/serial_console.cpp @@ -36,6 +36,8 @@ // flash firmware reserve space, reply "READY ", then // read raw bytes from Serial and // install/boot them as a new app +// flash overwrite same, but reuse the slot already +// uses (grow/move it) instead of prompting // wifi auto connect to the first scanned network with // saved credentials, else print the scan // wifi scan scan and list nearby networks @@ -400,7 +402,7 @@ static void handlePartitionCommand(const std::vector &tokens) { launcherConsolePrintln("ERR unknown partition subcommand"); } -static void handleFlashCommand(const String &name, uint32_t size) { +static void handleFlashCommand(const String &name, uint32_t size, bool overwrite) { if (size == 0) { launcherConsolePrintln("ERR invalid size"); return; @@ -413,12 +415,33 @@ static void handleFlashCommand(const String &name, uint32_t size) { return; } - String label = launcherInstallNextAppLabel(table, name); - std::vector dataPartitions; // app image only, no data partitions LauncherPartitionEntry appEntry; - if (!launcherSelectInstallLayout(table, size, label, dataPartitions, appEntry, error)) { - launcherConsolePrintf("ERR %s\n", error.c_str()); - return; + if (overwrite) { + // Reuse the slot a previous push of this name used, growing it into adjacent + // free space when the image got bigger. A host on the other end of a serial + // link can't answer the on-device "which partition to replace?" menu, so this + // falls back to free space and fails instead of prompting. + String label = launcherPartitionSanitizedAppLabelBase(name); + const LauncherPartitionEntry *old = launcherPartitionFindByLabel(table, label.c_str()); + if (old && launcherPartitionIsReplaceableApp(*old)) { + if (old->size >= size) appEntry = *old; + else launcherPartitionRemoveEntryByOffset(table, old->offset); + } else { + label = launcherInstallNextAppLabel(table, name); + } + if (appEntry.size == 0 && + (!launcherPartitionCreateOtaApp(table, size, label.c_str(), &appEntry, &error) || + !launcherPartitionValidate(table, &error))) { + launcherConsolePrintf("ERR no space for app: %s\n", error.c_str()); + return; + } + } else { + String label = launcherInstallNextAppLabel(table, name); + std::vector dataPartitions; // app image only, no data partitions + if (!launcherSelectInstallLayout(table, size, label, dataPartitions, appEntry, error)) { + launcherConsolePrintf("ERR %s\n", error.c_str()); + return; + } } // Tell the host it's safe to start streaming the raw firmware bytes now. @@ -888,6 +911,7 @@ static void printHelp() { launcherConsolePrintln(" partition edit