I'm currently trying to update a ATmega32M1 Arduino from my embedded linux platform.
As Bootloader I use the one from this awesome project.
The successful workflow so far is the following:
Burn bootloader via ATMEL ICE and Atmel Studio on Win10 machine
Program the applikation via UART from AVR Studio on Win10 machine
Connect Arduino to Linux machine
Check serial communication @57600 Baud is working
Now on to the troublesome part:
invoking avrdude on the linux machine with: /usr/bin/avrdude -C mypath/avrdude.conf -v -v -v -v -p
atmega32m1 -c arduino -P /dev/ttyS3 -b 57600 -D -U flash:w:mypath/app.ino.hex:i
Reset Arduino - since there is no autoreset I implemented a software reset via watchdog
Reset Arduino - alternatively reset by removing power
The avrdude options are adopted from Atmel Studio while programming the application for the first time.
This procedure ends with the following error:
Using Port : /dev/ttyS3
Using Programmer : arduino
Overriding Baud Rate : 57600
avrdude: Send: 0 [30] [20]
avrdude: Send: 0 [30] [20]
avrdude: Send: 0 [30] [20]
avrdude: Recv: . [0d]
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x0d
avrdude: Send: 0 [30] [20]
avrdude: Recv: 7 [37]
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x37
avrdude: Send: 0 [30] [20]
avrdude: Recv: 9 [39]
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x39
avrdude: Send: 0 [30] [20]
avrdude: Recv: 3 [33]
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x33
avrdude: Send: 0 [30] [20]
avrdude: Recv: 9 [39]
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x39
avrdude: Send: 0 [30] [20]
avrdude: Recv: O [4f]
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x4f
avrdude: Send: 0 [30] [20]
avrdude: Recv: . [0a]
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x0a
avrdude: Send: 0 [30] [20]
avrdude: Recv: . [0a]
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x0a
avrdude: Send: 0 [30] [20]
avrdude: Recv: . [0a]
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x0a
avrdude: Send: 0 [30] [20]
avrdude: Recv: . [0a]
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x0a
The responses vary:
Using Port : /dev/ttyS3
Using Programmer : arduino
Overriding Baud Rate : 57600
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x36
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x39
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x4b
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x0a
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x0a
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x0a
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x0a
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x0a
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x0a
To sum things up:
bootloader works the first time for application upload with the win10 machine
serial communications between arduino and linux machine are correct
avrdude commands do work under win 10
This leaves me wondering what might be the source of the "not in sync" errror.
Is this related to the bootloader or avrdude?
Any ideas or suggestions? (Installing the arduino ide is probably not an option due to the linux system being very restricted)
Board not being reset properly (does it blink the led to indicate the bootloader is running) - you have a pretty narrow window to reset the board in with optiboot (unless your version extended that time). In this case, you can upload code only once after burning the bootloader (with no other code on the chip, it will start executing code from address zero, proceed through 30kb of 0xFFFF (a no-op instruction) before hitting the bootloader and running that). Why can't you do autoreset?
Different voltage supplied, and board running off of internal oscillator. Internal oscillator speed changes significantly over the operating voltage range, and will only be close enough to the nominal frequency for UART speed to be correct at certain voltages, otherwise there will be a baud rate mismatch and gibberish will be received/transmitted.
Bootloader not burned correctly - fuses not set to enable bootloader (though this is ruled out if it works from a different system), so you can upload a sketch only once after burning bootloader.
IIRC, Optiboot jumps straight to the application code upon power on.
Concerning an improper reset:
Since I was not sure whether the watchdog triggered reset is enough I also tried simply unplugging the board and then plugging it in again. This is propably the best reset I can do. (Unfortunately this didn't help)
Concerning the bootloader not entering bootloader mode:
I can reprogram the board via uart multiple times from the windows pc, so this should not be the issue.
I only have Rx/Tx and GND Connections available, autoreset needs more pins I guess?
Power supply or a baudrate mismatch can be excluded because serial communications do work flawlessly.
Tomorrow I'll give it another try and keep you updated.
Autoreset, yes - you connect one side of a 0.1uF cap to the DTR or RTS line of the serial adapter, and the other side to the RST pin (there should also be the 10k pullup on reset too, but that's pretty standard).
How did you bootload it if you don't have access to reset? You need reset for ISP programming. You could connect to that pin. Also, you can use the reset button if the board has one.
Worst case, you could solder a flying lead onto reset pin - if you're good at soldering you could add on autoreset pretty quickly (remember to hotglue the wire to something, otherwise it will fatigue and snap right where it connects to PCB). This will at least let you proceed with development on your prototype board (and you'll know to include autoreset in the next rev).
As DrAzzy said, if your optiboot is based on "recent" code, then it uses watchdog reset to start the application, and power-on reset will skip the bootloader. You need an actual "external reset" to start the bootloader - that normally happens via the autoreset circuitry, or you can add a "switch" between the RESET pin and ground.
So it looks to me like your code is running, rather than the bootloader. This isn't really surprising, since there is only a pause of about 1s to see if there are bootloader commands that will cause the bootloader to continue running; it's really set up for auto-reset. It's also possible that "something" is buffering data from before the reset...
Indeed, this is part of the version string printed at the beginning.
I added the autoreset and now it works like a charm - thank you very much for your help!