arduino / Arduino

Arduino IDE 1.x
https://www.arduino.cc/en/software
Other
14.17k stars 7.02k forks source link

Boards get bricked when uploading sketch on Linux #9408

Closed Twilight-Logic closed 3 years ago

Twilight-Logic commented 5 years ago

When I try to upload a sketch a 32u4 Micro board on Linux, the board gets bricked each time and has to be recovered using an AVR programmer. Have tested with IDE version 1.8.8, 1.8.9 and 1.8.10. The problem does not seem to happen on Windows.

On Linux the board is assigned serial port /dev/ttyACM0. The problem happens with new boards with standard bootloader. I am currently using the IDE Export Compiled Binary and uploading the version with the bootlloader using an AVR programmer to get around the problem.

Status of USB and serial before the upload:

$ lsusb
Bus 002 Device 007: ID 2341:8037 Arduino SA
Bus 002 Device 006: ID 413c:2010 Dell Computer Corp. Keyboard
Bus 002 Device 004: ID 413c:1003 Dell Computer Corp. Keyboard Hub
Bus 002 Device 003: ID 046d:c03d Logitech, Inc. M-BT96a Pilot Optical Mouse
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

$ ls /dev/ttyA*
/dev/ttyACM0

The test sketch that I am using:

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println("Hello :-)");
  delay(1000);
}

Output during compile and upload (excessive duplication removed):

Arduino: 1.8.9 (Linux), Board: "Arduino/Genuino Micro"

Sketch uses 3598 bytes (12%) of program storage space. Maximum is 28672 bytes.
Global variables use 161 bytes (6%) of dynamic memory, leaving 2399 bytes for local variables. Maximum is 2560 bytes.

avrdude: butterfly_recv(): programmer is not responding
avrdude: error: programmer did not respond to command: write block
 ***failed;  
 .....
 ***failed;  
avrdude: Error: butterfly programmer uses avr_write_page() but does not
provide a cmd() method.
 *** page 127 (addresses 0x0000 - 0x007f) failed to write

 ***failed;  
.....
 ***failed;  
avrdude: Error: butterfly programmer uses avr_write_page() but does not
provide a cmd() method.
 *** page 127 (addresses 0x0080 - 0x00ff) failed to write

 ***failed;  
.....
 ***failed;  
avrdude: Error: butterfly programmer uses avr_write_page() but does not
provide a cmd() method.
 *** page 127 (addresses 0x0100 - 0x017f) failed to write

 ***failed;  
.....
 ***failed;  
avrdude: Error: butterfly programmer uses avr_write_page() but does not
provide a cmd() method.
 *** page 127 (addresses 0x0180 - 0x01ff) failed to write

 ***failed;  
.....
 ***failed;  
avrdude: Error: butterfly programmer uses avr_write_page() but does not
provide a cmd() method.
 *** page 127 (addresses 0x0200 - 0x027f) failed to write

 ***failed;  
.....
 ***failed;  
avrdude: Error: butterfly programmer uses avr_write_page() but does not
provide a cmd() method.
 *** page 127 (addresses 0x0280 - 0x02ff) failed to write

 ***failed;  
.....
 ***failed;  
avrdude: Error: butterfly programmer uses avr_write_page() but does not
provide a cmd() method.
 *** page 127 (addresses 0x0300 - 0x037f) failed to write

 ***failed;  
.....
 ***failed;  
avrdude: Error: butterfly programmer uses avr_write_page() but does not
provide a cmd() method.
 *** page 127 (addresses 0x0380 - 0x03ff) failed to write

 ***failed;  
.....
 ***failed;  
avrdude: Error: butterfly programmer uses avr_write_page() but does not
provide a cmd() method.
 *** page 127 (addresses 0x0400 - 0x047f) failed to write

 ***failed;  
.....
 ***failed;  
avrdude: Error: butterfly programmer uses avr_write_page() but does not
provide a cmd() method.
 *** page 127 (addresses 0x0480 - 0x04ff) failed to write

 ***failed;  
.....
 ***failed;  
avrdude: Error: butterfly programmer uses avr_write_page() but does not
provide a cmd() method.
 *** page 127 (addresses 0x0500 - 0x057f) failed to write

 ***failed;  
.....
 ***failed;  

.....

 ***failed;  
 ***failed;  
avrdude: Error: butterfly programmer uses avr_write_page() but does not
provide a cmd() method.
 *** page 13 (addresses 0x0d8e - 0x0e0d) failed to write

avrdude: butterfly_recv(): programmer is not responding
avrdude: butterfly_recv(): programmer is not responding
avrdude: verification error, first mismatch at byte 0x002a
         0x2b != 0x75
avrdude: verification error; content mismatch
avrdude: verification error; content mismatch

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Status of USB/serial after the upload has failed:

$ lsusb
Bus 002 Device 006: ID 413c:2010 Dell Computer Corp. Keyboard
Bus 002 Device 004: ID 413c:1003 Dell Computer Corp. Keyboard Hub
Bus 002 Device 003: ID 046d:c03d Logitech, Inc. M-BT96a Pilot Optical Mouse
Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

$ ls /dev/ttyA*
ls: cannot access '/dev/ttyA*': No such file or directory

After the board is bricked, plugging in the board does nothing and shows nothing in dmesg. Its as if it hasn't been connected. Different USB cables have been tried (all work in Windows) and the board is connected directly to the USB port and not indirectly via a USB hub. As mentioned above, the board can be recovered with an AVR programmer by using the Burn Bootloader feature in the Tools menu within the IDE.

matthijskooijman commented 5 years ago

I suspect the board is not actually bricked, but the failed upload breaks the sketch and prevents an automatic restart into the bootloader (which is handled by the sketch when its serial port is opened at 1200bps). You can probably recover using a manual reset just before starting the upload (using the reset button, which should keep the bootloader active for a dozen or so seconds, indicated by the slowly pulsating led).

Having said that, the failed upload is still problematic of course. I'm not quite sure what would cause all these errors, haven't seen them before.

On a hunch: Could it be that modemmanager is interfering with the serial port? It is known to mess with serial ports by probing them and a recent change has inadvertedly made it more aggressive towards Arduino boards. The best way to test this is to (temporarily) remove modemmanager, since probing can (I think) be autostarted from udev even when not running.

Twilight-Logic commented 5 years ago

My apologies if I have used the term 'bricked' incorrectly, and it may perhaps have been more accurate to say inaccessible via the serial port. No amount of playing with reset will allow it to be accessed. This has been tried ad nauseam with various timings but with no result.

I am not familiar with modemmanager but will investigate further and report back.

matthijskooijman commented 5 years ago

My apologies if I have used the term 'bricked' incorrectly,

No problem :-)

No amount of playing with reset will allow it to be accessed.

Did you check dmesg when pressing the reset button? If the bootloader still functions normally, I would expect that to at least create a serial port (for a dozen or so seconds, until the bootloader quits again).

Twilight-Logic commented 5 years ago

Indeed it does come up as /dev/ttyACM0 for about 8 seconds after reset, then it disappears. Here is the dmesg output:

[  413.384345] usb 2-1.6: Product: Arduino Micro   
[  413.384348] usb 2-1.6: Manufacturer: Arduino LLC
[  413.384865] cdc_acm 2-1.6:1.0: ttyACM0: USB ACM device
[  420.989299] usb 2-1.6: USB disconnect, device number 16
[  421.221044] usb 2-1.6: new full-speed USB device number 17 using ehci-pci
[  421.301003] usb 2-1.6: device descriptor read/64, error -32
[  421.488971] usb 2-1.6: device descriptor read/64, error -32
[  421.680942] usb 2-1.6: new full-speed USB device number 18 using ehci-pci
[  421.760931] usb 2-1.6: device descriptor read/64, error -32
[  421.948919] usb 2-1.6: device descriptor read/64, error -32
[  422.057052] usb 2-1-port6: attempt power cycle
[  422.660777] usb 2-1.6: new full-speed USB device number 19 using ehci-pci
[  423.076714] usb 2-1.6: device not accepting address 19, error -32
[  423.156712] usb 2-1.6: new full-speed USB device number 20 using ehci-pci
[  423.572654] usb 2-1.6: device not accepting address 20, error -32
[  423.572806] usb 2-1-port6: unable to enumerate USB device

However, I have now also investigated ModemManager. It was indeed running on my system, having been installed by default. I recovered by Micro board and then disabled ModemManager on my Linux Mint 19.2 machine with:

systemctl stop ModemManager

I then tried the upload again and this time it was successful. I tried it a couple of times more and it worked each time consistently, so evidently ModemManager was interfering with the process. Since I don't need it (there is no modem of any kind attached to this machine) I have now disabled it with:

systemctl disable ModemManager

Thank you for assistance with this issue.