diff --git a/cli/firmware/flash.go b/cli/firmware/flash.go index d34bf419..6d4484d8 100644 --- a/cli/firmware/flash.go +++ b/cli/firmware/flash.go @@ -42,6 +42,7 @@ var ( commonFlags arguments.Flags // contains fqbn and address module string retries uint8 + fwFile string ) // NewFlashCommand creates a new `flash` command @@ -53,13 +54,15 @@ func NewFlashCommand() *cobra.Command { Example: "" + " " + os.Args[0] + " firmware flash --fqbn arduino:samd:mkr1000 --address COM10 --module WINC1500@19.5.2\n" + " " + os.Args[0] + " firmware flash -b arduino:samd:mkr1000 -a COM10 -m WINC15000\n" + - " " + os.Args[0] + " firmware flash -b arduino:samd:mkr1000 -a COM10\n", + " " + os.Args[0] + " firmware flash -b arduino:samd:mkr1000 -a COM10\n" + + " " + os.Args[0] + " firmware flash -b arduino:samd:mkr1000 -a COM10 -i firmware.bin\n", Args: cobra.NoArgs, Run: runFlash, } commonFlags.AddToCommand(command) command.Flags().StringVarP(&module, "module", "m", "", "Firmware module ID, e.g.: WINC1500, NINA") command.Flags().Uint8Var(&retries, "retries", 9, "Number of retries in case of upload failure (default 9)") + command.Flags().StringVarP(&fwFile, "input-file", "i", "", "Path of the firmware to upload") return command } @@ -87,24 +90,35 @@ func runFlash(cmd *cobra.Command, args []string) { // Normalize module name moduleName = strings.ToUpper(moduleName) - var firmware *firmwareindex.IndexFirmware - if moduleVersion == "" { - firmware = board.LatestFirmware + var firmwareFilePath *paths.Path + var err error + // If a local firmware file has been specified + if fwFile != "" { + firmwareFilePath = paths.New(fwFile) + if !firmwareFilePath.Exist() { + feedback.Errorf("firmware file not found in %s", firmwareFilePath) + os.Exit(errorcodes.ErrGeneric) + } } else { - firmware = board.GetFirmware(moduleVersion) - } - logrus.Debugf("module name: %s, firmware version: %s", firmware.Module, firmware.Version.String()) - if firmware == nil { - feedback.Errorf("Error getting firmware for board: %s", commonFlags.Fqbn) - os.Exit(errorcodes.ErrGeneric) - } - - firmwareFile, err := download.DownloadFirmware(firmware) - if err != nil { - feedback.Errorf("Error downloading firmware from %s: %s", firmware.URL, err) - os.Exit(errorcodes.ErrGeneric) + // Download the firmware + var firmware *firmwareindex.IndexFirmware + if moduleVersion == "" { + firmware = board.LatestFirmware + } else { + firmware = board.GetFirmware(moduleVersion) + } + logrus.Debugf("module name: %s, firmware version: %s", firmware.Module, firmware.Version.String()) + if firmware == nil { + feedback.Errorf("Error getting firmware for board: %s", commonFlags.Fqbn) + os.Exit(errorcodes.ErrGeneric) + } + firmwareFilePath, err = download.DownloadFirmware(firmware) + if err != nil { + feedback.Errorf("Error downloading firmware from %s: %s", firmware.URL, err) + os.Exit(errorcodes.ErrGeneric) + } + logrus.Debugf("firmware file downloaded in %s", firmwareFilePath.String()) } - logrus.Debugf("firmware file downloaded in %s", firmwareFile.String()) loaderSketchPath, err := download.DownloadSketch(board.LoaderSketch) if err != nil { @@ -116,7 +130,7 @@ func runFlash(cmd *cobra.Command, args []string) { loaderSketch := strings.ReplaceAll(loaderSketchPath.String(), loaderSketchPath.Ext(), "") for retry := 1; retry <= int(retries); retry++ { - err = updateFirmware(board, loaderSketch, moduleName, uploadToolDir, firmwareFile) + err = updateFirmware(board, loaderSketch, moduleName, uploadToolDir, firmwareFilePath) if err == nil { logrus.Info("Operation completed: success! :-)") break diff --git a/docs/usage.md b/docs/usage.md index 497f8b8a..a0df3972 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -22,6 +22,13 @@ like: ./arduino-fwuploader firmware flash -b arduino:samd:mkr1000 -a /dev/ttyACM0 -m WINC1500@19.6.1 ``` +Or if you want upload a local firmware you can use the `-i` or `--input-file` flag followed by the path of that +firmware. + +``` +./arduino-fwuploader firmware flash -i custom_fw.bin -b arduino:samd:mkr1000 -a /dev/ttyACM0 +``` + There is a retry mechanism because the flashing process uses serial communication, which sometimes can be a bit unreliable. The retry flag is set by default to 9 retries, but it's possible to overwrite it for whatever reason. For example to update a Nano RP2040 Connect with the retry set to 2 you can use: