Description
I'm trying to burn an Arduino bootloader on an Arduino UNO
board with the Atmel-ICE
probe. Unfortunately, avrdude
throws an error message when verifying the bytes.
1. Hardware setup
My hardware setup looks like this:
By the way - I'm working on a 64-bit Windows 10 PC.
2. Atmel-ICE driver
At first I thought that the Atmel-ICE
doesn't require installation, because Windows recognizes it as an HID-device. However, I quickly learned that avrdude
- launched by the Arduino IDE - needs another driver to interact with the Atmel-ICE
. Therefore, I installed the libusb-win32
driver with Zadig (just as suggested on the GitHub thread #4368):
The driver installation succeeded, and I observe a change in the Windows Device Manager. The Atmel-ICE
probe no longer appears as an HID-device but as a libusb-win32
device instead:
I believe the Atmel-ICE
is now ready to be used with avrdude
.
3. Software setup
I'm running a fresh-installed Arduino IDE (version 1.8.13) on a Windows 10 PC. First I activate maximal verbosity for the console output (File
> Preferences
> Show verbose output
). Next, I select the probe: Tools
> Programmer
> Atmel-ICE (AVR)
Next I select my board: Tools
> Board
> Arduino AVR Boards
> Arduino UNO
Finally, I burn the bootloader: Tools
> Burn Bootloader
In the console output, I can see two avrdude
commands being launched.
3.1 First avrdude command
The first avrdude
command looks like this:
avrdude -CC:\Program Files (x86)\.../avrdude.conf
-v
-patmega328p
-catmelice_isp
-Pusb
-e
-Ulock:w:0x3F:m
-Uefuse:w:0xFD:m
-Uhfuse:w:0xDE:m
-Ulfuse:w:0xFF:m
the output for this command is:
avrdude: Version 6.3-20190619
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch
System wide configuration file is "C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf"
Using Port : usb
Using Programmer : atmelice_isp
avrdude: usbhid_open(): No device found
avrdude: usbdev_open(): Found Atmel-ICE CMSIS-DAP, serno: J42700007942
avrdude: Found CMSIS-DAP compliant device, using EDBG protocol
AVR Part : ATmega328P
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC2
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
Programmer Type : JTAG3_ISP
Description : Atmel-ICE (ARM/AVR) in ISP mode
Vtarget : 5.0 V
SCK period : 125.00 us
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: erasing chip
avrdude: reading input file "0x3F"
avrdude: writing lock (1 bytes):
Writing | ################################################## | 100% 0.00s
avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x3F:
avrdude: load data lock data from input file 0x3F:
avrdude: input file 0x3F contains 1 bytes
avrdude: reading on-chip lock data:
Reading | ################################################## | 100% 0.01s
avrdude: verifying ...
avrdude: WARNING: invalid value for unused bits in fuse "lock", should be set to 1 according to datasheet
This behaviour is deprecated and will result in an error in future version
You probably want to use 0xff instead of 0x3f (double check with your datasheet first).
avrdude: 1 bytes of lock verified
avrdude: reading input file "0xFD"
avrdude: writing efuse (1 bytes):
Writing | ################################################## | 100% 0.09s
avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against 0xFD:
avrdude: load data efuse data from input file 0xFD:
avrdude: input file 0xFD contains 1 bytes
avrdude: reading on-chip efuse data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying ...
avrdude: 1 bytes of efuse verified
avrdude: reading input file "0xDE"
avrdude: writing hfuse (1 bytes):
Writing | ################################################## | 100% 0.09s
avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0xDE:
avrdude: load data hfuse data from input file 0xDE:
avrdude: input file 0xDE contains 1 bytes
avrdude: reading on-chip hfuse data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: reading input file "0xFF"
avrdude: writing lfuse (1 bytes):
Writing | ################################################## | 100% 0.09s
avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xFF:
avrdude: load data lfuse data from input file 0xFF:
avrdude: input file 0xFF contains 1 bytes
avrdude: reading on-chip lfuse data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying ...
avrdude: 1 bytes of lfuse verified
avrdude done. Thank you.
That looks good.
3.2 Second avrdude command
The second avrdude
command is:
avrdude -CC:\Program Files (x86)\.../avrdude.conf
-v
-patmega328p
-catmelice_isp
-Pusb
-Uflash:w:C:\Program Files (x86)\.../optiboot_atmega328.hex:i
-Ulock:w:0x0F:m
with the following output:
avrdude: Version 6.3-20190619
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch
System wide configuration file is "C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf"
Using Port : usb
Using Programmer : atmelice_isp
avrdude: usbhid_open(): No device found
avrdude: usbdev_open(): Found Atmel-ICE CMSIS-DAP, serno: J42700007942
avrdude: Found CMSIS-DAP compliant device, using EDBG protocol
AVR Part : ATmega328P
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC2
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
Programmer Type : JTAG3_ISP
Description : Atmel-ICE (ARM/AVR) in ISP mode
Vtarget : 5.0 V
SCK period : 125.00 us
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "C:\Program Files (x86)\Arduino\hardware\arduino\avr/bootloaders/optiboot/optiboot_atmega328.hex"
avrdude: writing flash (32768 bytes):
Writing | ################################################## | 100% -0.00s
avrdude: 32768 bytes of flash written
avrdude: verifying flash memory against C:\Program Files (x86)\Arduino\hardware\arduino\avr/bootloaders/optiboot/optiboot_atmega328.hex:
avrdude: load data flash data from input file C:\Program Files (x86)\Arduino\hardware\arduino\avr/bootloaders/optiboot/optiboot_atmega328.hex:
avrdude: input file C:\Program Files (x86)\Arduino\hardware\arduino\avr/bootloaders/optiboot/optiboot_atmega328.hex contains 32768 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% -0.00s
avrdude: verifying ...
avrdude: 32768 bytes of flash verified
avrdude: reading input file "0x0F"
avrdude: writing lock (1 bytes):
Error while burning bootloader.
Writing | ################################################## | 100% 0.00s
avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x0F:
avrdude: load data lock data from input file 0x0F:
avrdude: input file 0x0F contains 1 bytes
avrdude: reading on-chip lock data:
Reading | ################################################## | 100% 0.01s
avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0000
0xff != 0x0f
avrdude: verification error; content mismatch
avrdude done. Thank you.
3.3 The error message
As you can see, avrdude
throws this error message:
avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0000
0xff != 0x0f
avrdude: verification error; content mismatch
What should I do to solve this?
Activity
matthijskooijman commentedon Dec 28, 2020
What seems to be happening is that the second command tries to set the lock bits so that the bootloader or sketch cannot overwrite bootloader, but for some reason, that fails.
There have been some issues with verification of fuses and lock bytes wrt the bits that are unused (some programmers read them back as 0, some as 1), but the avrdude version that you are using has been patched by Arduino to ignore these unused bytes entirely when verifiying. In this case, I think that the upper two bits are unused and the lower six (0x3F) are used. The second avrdude programs a value of 0x0F, so that's lock bit 4 and 5 set (0 is set, 1 is cleared), but the value read back is 0xFF, which has lock bit 4 and 5 cleared (0). Also, bit 6 and 7 are different, but those are unused bits, so that's ok.
I'm not sure why setting the lock bits fails, though...
kristofmulier commentedon Dec 28, 2020
Hi @matthijskooijman ,
Thank you very much for your insights! I'm new to the Arduino ecosystem and AVR chips, so I'm not completely following your explanations. However - after reading your reply - it looks like there must be a workaround. Do you have a suggestion, things I could try? I don't mind playing around in the
cmd
console ;-)I believe there is no Hardware issue. The same error message appears when I try to burn the bootloader into my other
Arduino UNO SMD
board (I've got an smd and a dip version).PS: By the way - the reason I'm diving into Arduino has everything to do with this new free IDE for microcontrollers: Embeetle IDE (see https://embeetle.com). I'm currently in the process of adding Arduino support there.
matthijskooijman commentedon Dec 28, 2020
If you have specific questions, just ask.
Well, it looks like the bootloader was flashed succesfully, it's just the lock bits that could not be set for some reason. So I'd expect that your board works, it's just not as well-protected as it should.
You could also try running avrdude manually to read the lock byte back, to see if it the write really failed, or it's just the verify that fails somehow (maybe the lock bytes only take effect after a reset or so?). For that, I think you can use this command (haven't fully tested it though):
I'm not 100% sure that using
-
for "write to stdout" works, if not you might end up with a file called-
. Also, replace theavrdude.conf
argument with the full path.If you haven't already, check out arduino-cli, that's a convenient CLI tool that can handle the entire Arduino build process and might be useful to use as a backend for other IDEs (it's not yet used directly by the Java IDE yet, that still uses arduino-builder, but that again includes parts of arduino-cli).
kristofmulier commentedon Dec 28, 2020
Hi @matthijskooijman ,
Thank you very much for your reply!
I just tried something. I entered the exact same commands that the Arduino IDE prints in its console into a Windows terminal.
1. Same commands - but in Windows Terminal
I opened a Windows Terminal and entered the two
avrdude
commands just as I see them in the Arduino IDE console.1.1 First avrdude command
The first command I entered is this one:
Restyled and reformatted, it looks like this (see also my original post):
The output is exactly the same as before (see my original post), with a few exceptions. After printing the table with memory info,
avrdude
prints this line:avrdude: AVR device initialized and ready to accept instructions
In the original output (from the Arduino IDE console), the following is printed right after that line:
In the Windows terminal output, I see this instead:
Another difference is all the way at the end of the output. The original output (from the Arduino IDE console, see original post) ends like this:
While the Windows terminal outputs this:
1.2 Second avrdude command
The second
avrdude
command I enter is this one:Restyled and reformatted, it looks like this (see also my original post):
avrdude -C C:/Program Files (x86)/.../avrdude.conf -v -patmega328p -catmelice_isp -Pusb -Uflash:w:"C:/Program Files (x86)/.../optiboot_atmega328.hex":i -Ulock:w:0x0F:m
The output is the same as before, with the exception that the output in the Arduino IDE ends like this:
and the output in the Windows terminal ends like this:
2. Conclusions?
I don't know what to conclude from this. How is it possible that the same
avrdude
commands give a different results when they run in the Arduino IDE console compared to manually entering them in the Windows terminal?One thing that comes to my mind is a timing issue. In the Arduino IDE, they run rapidly one after the other. When I enter them manually, there is considerably more time between them. However, that doesn't explain the difference in the output of the first command.
To test the timing-issue-theory, I put both commands in a
.bat
file. I ran the.bat
file, and it worked. As both commands now run from the.bat
file, there is almost no time in between them. This should mimic the behaviour of the Arduino IDE console very close.3. Additional question
Well - it seems like it does work in the Windows console, and that's what ultimately matters to me (of course, it would be nice if it gets fixed in the Arduino IDE as well).
However, the following output scares me a little (it's at the end of the output for the second command):
Especially this phrase:
"This behaviour is deprecated and will result in an error in future version"
I assume it has to do with the last flag in the second command:
-Ulock:w:0x0F:m
. Should I change that flag into:-Ulock:w:0xCF:m
? The output suggests to look into the datasheet. However, I am not familiar with this chip, so I have no idea where to look in the datasheet.matthijskooijman commentedon Dec 28, 2020
Hm, interesting. I had also noticed that the warning appears the first time but not the second time, but re-reading the avrdude patch (https://github.com/arduino/avrdude-build-script/blob/master/avrdude-6.3-patches/80-Avoid-failing-fuse-check-if-different-bits-are-reserved.patch) I see that the patch is only shown when verification succeeds (with only differences in the unused bits), not when verification fails. So the main difference is that your manual run succeeds, while the IDE run somehow does not. I'm not sure why your manual run shows more (debug) output wrt "safemode" (extra fuse comparisons after programming).
This relates to the unused lock bits I mentioned before. Originally, you'd need 0x0F for some programmers and 0xCF for others. With an Arduino-specific patch, the unused bits are ignored, but also this warning was added to encourage users of the avrdude binary to switch to 0xCF instead. In this case, that means changing the lock byte values in the
boards.txt
file of the AVR core. It seems we already made these changes for fuse bytes (#5182) but not for the lock bytes (see #6601).So this is something we should fix in
boards.txt
, but I don't think this causes your problem.Hm, so maybe not a timing problem between both commands, then.
However, what you said reminded me of lock-byte timing issue I had observed with the JTAGICE3 years ago. I did a bit of digging and found my bug report: https://savannah.nongnu.org/bugs/?func=detailitem&item_id=42267 This was fixed in avrdude also years ago, but the "fix" was adding a bit of a delay, so maybe the delay isn't always enough somehow? In the report it was also suggested that adding more -v options could slow down things enough to fix them, so maybe you could try editing
platform.txt
and add two or three more -v options to the second avrdude command as ran by the IDE, here: https://github.com/arduino/ArduinoCore-avr/blob/60f0d0b125e06dbf57b800192c80e5f60d681438/platform.txt#L121kristofmulier commentedon Dec 29, 2020
Hi @matthijskooijman ,
You make an interesting analysis there 👍
Basically, there are two issues at hand:
1. Unused lock bits
The unused lock bits issue is indicated by the warning:
As you say, this issue is most probably not causing the
avrdude
crash I experience in the Arduino IDE. It's an unrelated problem. However, it's still worthwile to fix it for our implementation in Embeetle IDE. Do you suggest we use the flag-Ulock:w:0x0F:m
or rather-Ulock:w:0xCF:m
? I'm referring to the following setup:The warning suggests to check the datasheet first before deciding. Unfortunately, I have not enough experience with AVR microcontrollers to make an informed decision here. I hope you can give me a suggestion.
2. avrdude crash in Arduino IDE
You're absolutely right about this:
Very intriguing, indeed.
Interesting observation!
I just added a
-v
option at the end of line 121 inplatform.txt
:The error persisted. Even with two
-v
flags. But adding a third(!) one solved the issue. The bootloader burn procedure seems to work now in Arduino IDE! However, the verbosity is ridiculous. The output is more than 1100 lines and around 650.000 characters. You can download the output file here (I've put it on our server):https://embeetle.com/downloads/misc/extremely_verbose_output.txt
Shouldn't this be fixed in a proper way in
avrdude
? Do you have a suggestion how to go on from here?matthijskooijman commentedon Dec 29, 2020
You should use
0xCF
for the 328p, that has the unused bits set to 1.Note that this does assume using the Arduino-patched version of avrdude, since upstream has not merged this patch yet. Without this patch,
0x0F
will fail to verify on some programmers and0xCF
will fail to verify on others.Hm, you testing suggests that maybe the delay put into avrdude is not enough somehow. IIRC they put in 10ms while (later) Atmel suggested they use 20ms, so maybe the delay should be extended, then.
I'll dig out my JTAGICE3 (which is very similar to the Atmel ICE) and see if I can reproduce this in the coming days. I'll also see if I can build a custom avrdude with a bit more delay, to see if that solves the problem reliably. If so, we can provide a patch to avrdude upstream, see if they want to merge that (and in the meanwhile, probably apply the patch in the Arduino version too).
kristofmulier commentedon Dec 29, 2020
Hi @matthijskooijman ,
That's a great idea!
Please let me know if you can't reproduce the issue with the
JTAGICE3
. In that case, I'd like to send you the funds to buy a newAtmel-ICE
for this test. I can send the funds over PayPal or any other way you like.kristofmulier commentedon Dec 29, 2020
Hi @matthijskooijman ,
Some more interesting news. I just tried to run the two
avrdude
commands from the console in Embeetle IDE, and I've got the exact same problem as in Arduino IDE. So there must be a subtle (timing?) difference when entering these commands directly in a Windows terminal vs invoking them from another software. I don't know how Arduino IDE invokes its console commands, but Embeetle does it from Python with a subprocess.In Embeetle IDE, I added an artificial wait time (up to several seconds) between both
avrdude
command invocations - but the error persists.However, just like in Arduino IDE, the bootloader burning works when I add three(!)
-v
flags to the second command. Unfortunately, that is not a viable solution. It overloads the user with extremely verbose output.Thanks a lot for your help :-)
matthijskooijman commentedon Dec 29, 2020
If I can't, I'll probably try to send you a custom avrdude build to test, probably easier. Also, I have access to an Atmel ICE in the office of a customer, but due to Corona I'm not yet sure when I'll be there again. In any case, thanks for the offer!
Thinking on this a bit more, I suspect that the output handling might be difference here. Probably outputting to a console is slightly slower than to a pipe (as used by the IDE), leading to this difference in timing. You could try running in the console with output redirected to a file, I'd guess that would break it.
kristofmulier commentedon Dec 29, 2020
Hi @matthijskooijman ,
The offer for a new Atmel-ICE still stands. It's the least I can do for your generous help! I could purchase it on Farnell and send it to your address directly - so you'd have it in one day.
That could very well be true!
Unfortunately, that's not possible in Embeetle IDE. I mean - it would be possible, but it would require too much code refactoring.
PS: please drop me a mail so we can stay in contact:
kristof@embeetle.com
Hope to hear from you soon!
matthijskooijman commentedon Dec 29, 2020
I meant in the windows terminal, where until now your manual avrdude call did not break.
I'd rather keep this on github as much as possible, for others to read, contribute and for public history. If you do need to contact me privately, my e-mail is in my github profile.
kristofmulier commentedon Dec 29, 2020
Hi @matthijskooijman ,
I just tried your suggestion (to redirect the output to a file) in the Windows terminal:
All output is now redirected to files
file.txt
anderrfile.txt
. It's a bit weird, butfile.txt
is totally empty. Seems likeavrdude
likes to write everything to itsstderr
channel. Anyway, this is howerrfile.txt
ends:That looks fine - no errors.
PS: I dropped you a mail, just to open a communication channel (and to see if I don't end up in your SPAM folder).
22 remaining items