From ed6799eb9f4a932e05b0f28b9c5c757f2504222f Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 8 May 2023 16:31:16 +0200 Subject: [PATCH 1/3] Force serial-port-waiting in some upload without port --- commands/upload/upload.go | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/commands/upload/upload.go b/commands/upload/upload.go index b9c4f248656..9fe96414fea 100644 --- a/commands/upload/upload.go +++ b/commands/upload/upload.go @@ -361,11 +361,24 @@ func runProgramAction(pme *packagemanager.Explorer, uploadProperties.Set("build.project_name", sketchName) } + // Force port wait to make easier to unbrick boards like the Arduino Leonardo, or similar with native USB, + // when a sketch causes a crash and the native USB serial port is lost. + // See https://github.com/arduino/arduino-cli/issues/1943 for the details. + // + // In order to trigger the forced serial-port-wait the following conditions must be met: + // - No upload port specified (protocol == "default") + // - "upload.wait_for_upload_port" == true (developers requested the touch + port wait) + // - "upload.tool.serial" not defained, or + // "upload.tool.serial" is the same as "upload.tool.default" + forcedSerialPortWait := port.Protocol == "default" && // this is the value when no port is specified + uploadProperties.GetBoolean("upload.wait_for_upload_port") && + (!uploadProperties.ContainsKey("upload.tool.serial") || + uploadProperties.Get("upload.tool.serial") == uploadProperties.Get("upload.tool.default")) + // If not using programmer perform some action required // to set the board in bootloader mode actualPort := port - if programmer == nil && !burnBootloader && port.Protocol == "serial" { - + if programmer == nil && !burnBootloader && (port.Protocol == "serial" || forcedSerialPortWait) { // Perform reset via 1200bps touch if requested and wait for upload port also if requested. touch := uploadProperties.GetBoolean("upload.use_1200bps_touch") wait := false @@ -425,7 +438,7 @@ func runProgramAction(pme *packagemanager.Explorer, if actualPort.Address != "" { // Set serial port property uploadProperties.Set("serial.port", actualPort.Address) - if actualPort.Protocol == "serial" { + if actualPort.Protocol == "serial" || actualPort.Protocol == "default" { // This must be done only for serial ports portFile := strings.TrimPrefix(actualPort.Address, "/dev/") uploadProperties.Set("serial.port.file", portFile) From 43eb3f852db687534e860c922b632f6622ee0bc9 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 8 May 2023 17:50:15 +0200 Subject: [PATCH 2/3] Updated upload-mock integration tests --- arduino/serialutils/serialutils.go | 2 ++ .../upload_mock/upload_mock_test.go | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/arduino/serialutils/serialutils.go b/arduino/serialutils/serialutils.go index fdb57aa204f..dab4523a09d 100644 --- a/arduino/serialutils/serialutils.go +++ b/arduino/serialutils/serialutils.go @@ -106,6 +106,8 @@ func Reset(portToTouch string, wait bool, cb *ResetProgressCallbacks, dryRun boo } if strings.HasSuffix(emulatedPort, "999") { emulatedPort += "0" + } else if emulatedPort == "" { + emulatedPort = "newport" } return res, nil } diff --git a/internal/integrationtest/upload_mock/upload_mock_test.go b/internal/integrationtest/upload_mock/upload_mock_test.go index ec0875d8706..d88fa84a91d 100644 --- a/internal/integrationtest/upload_mock/upload_mock_test.go +++ b/internal/integrationtest/upload_mock/upload_mock_test.go @@ -161,12 +161,24 @@ func TestUploadSketch(t *testing.T) { Programmer: "", Output: "Performing 1200-bps touch reset on serial port /dev/ttyACM999\nWaiting for upload port...\nUpload port found on /dev/ttyACM9990\n\"{data_dir}/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude\" \"-C{data_dir}/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf\" -v -V -patmega32u4 -cavr109 \"-P/dev/ttyACM9990\" -b57600 -D \"-Uflash:w:{build_dir}/{sketch_name}.ino.hex:i\"\n", }, + { + Fqbn: "arduino:avr:leonardo", + UploadPort: "", + Programmer: "", + Output: "Skipping 1200-bps touch reset: no serial port selected!\nWaiting for upload port...\nUpload port found on newport\n\"{data_dir}/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude\" \"-C{data_dir}/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf\" -v -V -patmega32u4 -cavr109 \"-Pnewport\" -b57600 -D \"-Uflash:w:{build_dir}/{sketch_name}.ino.hex:i\"\n", + }, { Fqbn: "arduino:avr:micro", UploadPort: "/dev/ttyACM999", Programmer: "", Output: "Performing 1200-bps touch reset on serial port /dev/ttyACM999\nWaiting for upload port...\nUpload port found on /dev/ttyACM9990\n\"{data_dir}/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude\" \"-C{data_dir}/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf\" -v -V -patmega32u4 -cavr109 \"-P/dev/ttyACM9990\" -b57600 -D \"-Uflash:w:{build_dir}/{sketch_name}.ino.hex:i\"\n", }, + { + Fqbn: "arduino:avr:micro", + UploadPort: "", + Programmer: "", + Output: "Skipping 1200-bps touch reset: no serial port selected!\nWaiting for upload port...\nUpload port found on newport\n\"{data_dir}/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude\" \"-C{data_dir}/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf\" -v -V -patmega32u4 -cavr109 \"-Pnewport\" -b57600 -D \"-Uflash:w:{build_dir}/{sketch_name}.ino.hex:i\"\n", + }, { Fqbn: "arduino:avr:circuitplay32u4cat", UploadPort: "/dev/ttyACM999", @@ -502,6 +514,16 @@ func TestUploadSketch(t *testing.T) { "win32": "Performing 1200-bps touch reset on serial port /dev/ttyACM0\nWaiting for upload port...\nNo upload port found, using /dev/ttyACM0 as fallback\n\"{data_dir}/packages/arduino/tools/bossac/1.7.0-arduino3/bossac.exe\" -i -d --port=ttyACM0 -U true -i -e -w -v \"{build_dir}/{sketch_name}.ino.bin\" -R\n", }, }, + { + Fqbn: "arduino:samd:mkr1000", + UploadPort: "", + Programmer: "", + Output: map[string]string{ + "darwin": "Skipping 1200-bps touch reset: no serial port selected!\nWaiting for upload port...\nUpload port found on newport\n\"{data_dir}/packages/arduino/tools/bossac/1.7.0-arduino3/bossac\" -i -d --port=newport -U true -i -e -w -v \"{build_dir}/{sketch_name}.ino.bin\" -R\n", + "linux": "Skipping 1200-bps touch reset: no serial port selected!\nWaiting for upload port...\nUpload port found on newport\n\"{data_dir}/packages/arduino/tools/bossac/1.7.0-arduino3/bossac\" -i -d --port=newport -U true -i -e -w -v \"{build_dir}/{sketch_name}.ino.bin\" -R\n", + "win32": "Skipping 1200-bps touch reset: no serial port selected!\nWaiting for upload port...\nUpload port found on newport\n\"{data_dir}/packages/arduino/tools/bossac/1.7.0-arduino3/bossac.exe\" -i -d --port=newport -U true -i -e -w -v \"{build_dir}/{sketch_name}.ino.bin\" -R\n", + }, + }, { Fqbn: "arduino:samd:mkr1000", UploadPort: "/dev/ttyACM999", From cbdb3b0565f91f6f7bccf6465495b31e07a51dd1 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 15 May 2023 16:34:26 +0200 Subject: [PATCH 3/3] Force 'default' protool if no port is specified in gRPC Upload --- commands/upload/upload.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/commands/upload/upload.go b/commands/upload/upload.go index 9fe96414fea..a390e450887 100644 --- a/commands/upload/upload.go +++ b/commands/upload/upload.go @@ -195,7 +195,10 @@ func runProgramAction(pme *packagemanager.Explorer, if burnBootloader && programmerID == "" { return &arduino.MissingProgrammerError{} } - + if port == nil { + // For no-port uploads use "default" protocol + port = &rpc.Port{Protocol: "default"} + } logrus.WithField("port", port).Tracef("Upload port") fqbn, err := cores.ParseFQBN(fqbnIn)