Closed stefanrueger closed 2 months ago
Hello, as usual, I would ask for verbose output ('-vvvv') for each of these commands, I need to see the exact communication happening. I must say this looks very, very weird and I don't think I could replicate it easily...
OK, here the output of $ avrdude -vvvq -p 64ea28 -c serialupdi
when the target is an AVR16EB28
And here the output of avrdude -vvvvq -p 64ea28 -c serialupd
Thanks for looking into this
And, just for comparison, the output when the command line is corrected to -c 16eb28
and therefore matches the target:
avrdude -vvvq -p 16eb28 -c serialupdi
And here the output when the target was switched to an AVR64EA28 (and matches with the following command line):
avrdude -vvvq -p 64ea28 -c serialupdi
@stefanrueger sorry, but I don't have good news for you, this is something that can't really be fixed.
See, the problem is that when initiating connection with the MCU using SerialUPDI the signature is read from arbitrary location in memory. For AVR16EBxx chips SIGROW memory is at 0x1080, while for AVR64EAxx chips it's 0x1100. This is why when you specify incorrect part but with identical memory map (and most of these guys use 0x1100: https://github.com/avrdudes/avrdude/blob/main/src/avrdude.conf.in#L20263) then AVRDUDE reads the correct signature and responds with reasonable error proposing correct part.
In your case it reads from a totally different memory (0x1100 in AVR16EBxx is BOOTROW), gets meaningless data and doesn't know how to recover from this, nor is able to suggest anything else. If there was any way to ask the chip for its memory map, we could do it instead, but unfortunately, no such option is available AFAIK.
Let me know if my explanation is not clear, I will try to explain it better.
@dbuchwald Great analysis. Thanks. OK, it's like writing the title of a book onto one of two different page numbers (or more than two ... depending on how many different memory layouts Microchip is going to entertain in future), which makes it a bit hard for the reader to figure out what the title of the book is.
@askn37 Do you have more insight into how, given a UPDI chip, the signature can be read unambiguously? Is there some info in the sib
that could help?
0x1080 is used as memory address for the AVR-DU and AVR-EB parts: run avrdude -p*/St | grep signature.*off | grep 0x1080 | grep -v " "
. It's 0x1100 for all other UPDI parts.
AFAIK, only the AVR-DU and AVR-EB has their signature at 0x1080, and these are the only chips with NVMv4 and NVMv5. So the SIB could be read to determine the NVM version, and then figure out the correct address if Avrdude is reading the signature as 0xffffff.
BTW this is also a problem for jtag3 based programmers as well:
$ ./avrdude -cpkobn_updi -pavr64dd32 -t
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0xffffff (probably .avr8x) (retrying)
avrdude: device signature = 0xffffff (probably .avr8x) (retrying)
avrdude: device signature = 0xffffff (probably .avr8x)
avrdude error: Yikes! Invalid device signature.
avrdude error: expected signature for AVR64DD32 is 1E 96 1A
Double check connections and try again, or use -F to override
this check.
avrdude done. Thank you.
Hanss-MacBook-Pro:src hans$ ./avrdude -cpkobn_updi -pavr16eb32 -t
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e943e (probably avr16eb32)
avrdude: processing -t interactive terminal
avrdude> read sib
When taking a closer look at the jtag3 and serialupdi source code, it appears that these programmers reads the SIB before reading the device signature. So after a failed signature read attempt (signature does not start with 0x1e), we may use the NVM version number to find the correct offset for the signature/prodsig memory.
When trying to read an AVR16EB32 when an AVR128DA32 is connected, I'm getting this weird signature. So a check against 0x1e may be a suitable solution.
$ ./avrdude -cserialupdi -pavr16eb32 -P /dev/cu.usbserial-1410
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x242f34
avrdude error: expected signature for AVR16EB32 is 1E 94 3E
double check chip or use -F to override this check
avrdude done. Thank you.
This problem of poor part selection cannot be solved unless you read UPDI_SIB before reading PROD_SIGNATURE to determine the NVM version.
Currently, the only protocols (as far as I know) that actually support this are SerialUPDI and JTAGmk3. Microchip has added modern UPDI support to these, but it is not documented. On the other hand, older protocols such as JTAGmk2 and STK600 do not define a mechanism to return UPDI_SIB to AVRDUDE and are not maintained by Microchip at all.
Older programmers will need their own extensions to add modern support. For example, JTAG2UPDI and UPDI4AVR firmware read UPDI_SIB before reading PROD_SIG to assist with subsequent operations. This is because there is no publicly known mechanism for AVRDUDE to inform firmware of the NVM version.
For UPDI4AVR only, with a small change to avrdude.conf, you can signal the NVM version and control information via unused areas in the device descriptor to support correct high-voltage programming. This is really something special.
My take on the idea to base the error message on the NVM controller version is that we shouldn't do it. Given all the inconsistencies between latest AVR chips and their respective NVM controllers I wouldn't be surprised if that wasn't the last case we saw. All of these "ifs/elses" will end up being unmanageable spaghetti that nobody understands and everyone is afraid to remove even after NVM v3/v5 chips are no longer produced nor sold. I see that kind of tech debt in my work daily and I see how it gradually slows down value delivery to a grinding halt.
That being said, if you want me to implement this feature I will do so, it's just that my instinct tells me it's not a good idea.
Thanks all round @dbuchwald @MCUdude @askn37 for input. I feel we definitely have to do something, if only to change the error message to add "check whether the part is correctly specified". Right now, one of the recommendations is -F
which can lead to tears as programming would proceed under wrong assumptions. It is amazing that Microchip finds new and innovative ways beyond the known reuse of signatures to make it hard to use them for part identification.
I also feel that AVRDUDE could give better advice than telling the user to specify the correct part number (the gadget housing the MCU may be difficult to open, the printing on the MCU illegible, the user may simply misremember but be convinced it is the wrong part).
When given the wrong -p
UPDI part, the UPDI programmers read (correctly, without problems and without encountering an error) three bytes, but possibly from the wrong memory (0x1100 vs 0x1080). Fun fact: as the other memory is at least in one case writable (bootrow) one could therefore spoof this MCU to be a different one. Normally, however, one wouldn't expect a valid UPDI signature in the wrong place. So, some instance outside the individual -c
programmer code (say, the avr_signature()
function in avr.c
might well check whether what the -c
programmer code read without error is a plausible signature, eg, check against known full signatures, check first byte against all known first bytes (currently only 1e
and ed
). If not, see what would happen if the specified UPDI part was a different one with another signature memory address.
Another fun fact: There must have been a similar problem in the past b/c there is code in main.c
that reads sib
and makes a comparison with the AVR_FAMILY
:
https://github.com/avrdudes/avrdude/blob/a3e4c8083e38b257915881999c16e2e4438ec6d1/src/main.c#L1575-L1603
Anyone know what this was about?
Anyone know what this was about?
The family ID is pretty much useless. It started out with tinyAVR
and megaAVR
, but when the AVR-DA were introduced they used " AVR" (that's four leading spaces). Later they "fixed" this error, and the later generations are now "AVR " (that's four trailing spaces). Why they couldn't use the actual family name is unclear, but it's way too late to change now.
I suggest mentioning that the user should double check the -p
part name and try again if Avrdude is able to read a signature, but it's incorrect, if trying to communicate with a UPDI part.
I have a perfectly set up programmer (a shiny new SerialUPDI since you asked) that's connected to an AVR-Ex part.
If I mistype which part it is, I get the following misleading error message:
Actually, it's a different part, and as soon as I type the correct line it works:
Notwithstanding that the error was between the chair and the keyboard, why could AVRDUDE not read the signature and could AVRDUDE have done any better in its error message? @dbuchwald might have some insights.