Skip to content

Conversation

@stefanrueger
Copy link
Collaborator

Fixes #1817

This PR handles r/w/v of multi-memory files that use a flat address space (as in .elf). Apparently Microchip use these

New functionality includes

  • Reading multi-memory .hex files to write single memories
  • Reading multi-memory .srec files to write single memories
  • Writing to a list of memories such as flash,ee,fuses from multi-memory files
  • Introducing all as an abbreviation for a list of all memories except submemories
  • Introducing ALL as an abbreviation for a list of all memories a part has
  • Introducing etc as the same as all: can use sig,etc which puts signature first in list (looks nicer than sig,all)
  • Enabling lists using an \ (without) operator as in all\bootrow
  • Automatically verifying when writing to multiple memories via -U [all | <list> | <list>\<list>]:w:file.hex:i
  • Verifying a multi-memory file against a multi-memory file later on via -U [<list>|all]:v:...
  • Reading a list of memories to write a multi-memory file (se we can create our own multi-memory files)
  • Reading all memories to write a multi-memory file as backup
  • Checking the signature of part against the multi-memory file signature section to avoid overwriting the wrong part
  • New terminal command backup <memlist> <file>[:format]
  • New terminal command restore <memlist> <file>[:format]
  • New terminal command verify <memlist> <file>[:format]

In order to be able to test the new functionality, this PR also provides options -xinit for the dryrun programmer.

$ avrdude -c dryrun -xhelp
avrdude -c dryrun extended options:
  -xinit     Initialise memories with human-readable patterns (1, 2, 3)
  -xrandom   Initialise memories with random code/values (1, 3)
  -xseed=<n> Seed random number generator with <n>, default time(NULL)
  -xhelp     Show this help menu and exit
Notes:
  (1) -xinit and -xrandom randomly configure flash wrt boot/data/code length
  (2) Patterns can best be seen with fixed-width font on -U flash:r:-:I
  (3) Choose, eg, -xseed=1 for reproducible flash configuration and output

That is kinda fun, particularly, when you view the generated outputs using the :I format (.hex with comments). Try

$ avrdude -qq -c dryrun -p 16eb28 -xinit -xseed=7 -UALL:r:-:I  | more

So, feel free to do your worst to try to break the new, rewritten, update mechanism.

It is crucial not to skip empty flash memory: otherwise the output file
cannot distinguish between flash having been deliberately dropped by the
user or it having been empty.
... to avoid tears when mistakenly restoring a backup from another part

$ avrdude -c dryrun -p t167 -U all:r:backup.hex:I

avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e9487 (probably t167)

avrdude: processing -U all:r:backup.hex:r
         reading multiple memories ...
         eeprom      | ################################################## | 100% 0.00s
         flash       | ################################################## | 100% 0.00s
         lfuse       | ################################################## | 100% 0.00s
         hfuse       | ################################################## | 100% 0.00s
         efuse       | ################################################## | 100% 0.00s
         lock        | ################################################## | 100% 0.00s
         signature   | ################################################## | 100% 0.00s
         calibration | ################################################## | 100% 0.00s
         writing 16904 bytes to output file backup.hex

avrdude done.  Thank you.

$ avrdude -c urclock -p m328p -b 115200 -P /dev/ttyUSB0 -U all:v:backup.hex:I

avrdude -c urclock -p m328p -b 115200 -P /dev/ttyUSB0 -U all:v:backup.hex
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e950f (probably m328p)

avrdude: processing -U all:v:backup.hex:i
avrdude: verifying 16904 bytes of multiple memories against input file backup.hex
avrdude error: signature of ATmega328P does not match file (ATtiny167, ATA5505, ATA6617C, ATA664251)
        use -F to override this check

avrdude done.  Thank you.

$ avrdude -c dryrun -p m328p -U all:w:backup.hex:I -F

avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e950f (probably m328p)

avrdude: processing -U all:w:backup.hex:I
avrdude: reading 16904 bytes for multiple memories from input file backup.hex
avrdude: 512 bytes eeprom in 1 section [0, 0x1ff]: 128 pages and 0 pad bytes
         writing 512 bytes to eeprom ...
         writing | ################################################## | 100% 0.00s
         reading | ################################################## | 100% 0.00s
         512 bytes of eeprom verified
avrdude: 16384 bytes flash in 1 section [0, 0x3fff]: 128 pages and 0 pad bytes
         writing 16384 bytes to flash ...
         writing | ################################################## | 100% 0.00s
         reading | ################################################## | 100% 0.00s
         16384 bytes of flash verified
avrdude: 1 byte lfuse in 1 section [0, 0]
         writing 1 byte to lfuse (0x62), 1 byte written, 1 verified
avrdude: 1 byte hfuse in 1 section [0, 0]
         writing 1 byte to hfuse (0xdf), 1 byte written, 1 verified
avrdude: 1 byte efuse in 1 section [0, 0]
         writing 1 byte to efuse (0xff), 1 byte written, 1 verified
avrdude: 1 byte lock in 1 section [0, 0]
         writing 1 byte to lock (0xff), 1 byte written, 1 verified

avrdude done.  Thank you.
@mcuee mcuee added the enhancement New feature or request label Jun 29, 2024
@mcuee
Copy link
Collaborator

mcuee commented Jun 30, 2024

Nice feature.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1828.exe -C .\avrdude_pr1828.conf -qq -c dryrun -xhelp
avrdude_pr1828 -c dryrun extended options:
  -xinit     Initialise memories with human-readable patterns (1, 2, 3)
  -xrandom   Initialise memories with random code/values (1, 3)
  -xseed=<n> Seed random number generator with <n>, default time(NULL)
  -xhelp     Show this help menu and exit
Notes:
  (1) -xinit and -xrandom randomly configure flash wrt boot/data/code length
  (2) Patterns can best be seen with fixed-width font on -U flash:r:-:I
  (3) Choose, eg, -xseed=1 for reproducible flash configuration and output

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1828.exe -C .\avrdude_pr1828.conf -qq -c dryrun -p m328p -xinit -xseed=7 -UALL:r:-:I
:02000004008179
:2000000054686520717569636B2062726F776E20666F78206A756D7073206F76657220740E // 810000> The quick brown fox jumps over t eeprom
:200020006865206C617A7920646F672E2054686520717569636B2062726F776E20666F7858 // 810020> he lazy dog. The quick brown fox
:20004000206A756D7073206F76657220746865206C617A7920646F672E2054686520717565 // 810040>  jumps over the lazy dog. The qu
:2000600069636B2062726F776E20666F78206A756D7073206F76657220746865206C617AA1 // 810060> ick brown fox jumps over the laz
:200080007920646F672E2054686520717569636B2062726F776E20666F78206A756D7073DD // 810080> y dog. The quick brown fox jumps
:2000A000206F76657220746865206C617A7920646F672E2054686520717569636B20627229 // 8100a0>  over the lazy dog. The quick br
:2000C0006F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E6B // 8100c0> own fox jumps over the lazy dog.
:2000E0002054686520717569636B2062726F776E20666F78206A756D7073206F7665722082 // 8100e0>  The quick brown fox jumps over
:20010000746865206C617A7920646F672E2054686520717569636B2062726F776E20666F7B // 810100> the lazy dog. The quick brown fo
:2001200078206A756D7073206F76657220746865206C617A7920646F672E20546865207181 // 810120> x jumps over the lazy dog. The q
:200140007569636B2062726F776E20666F78206A756D7073206F76657220746865206C61C5 // 810140> uick brown fox jumps over the la
:200160007A7920646F672E20FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC // 810160> zy dog. ........................
......
:207FE000204020202020204020202020404020204020402020404020202020402020202061 // 07fe0>  @     @    @@  @ @  @@    @
:02000004008278
:01000000629D                                                               // 820000> 0x62 lfuse
:02000004008278
:01000100DD21                                                               // 820001> 0xdd hfuse
:02000004008278
:01000200FFFE                                                               // 820002> 0xff efuse
:02000004008377
:01000000FF00                                                               // 830000> 0xff lock
:02000004008476
:030000001E950F3B                                                           // 840000> 0x1e 0x95 0x0f signature (ATmega328P, ATA6614Q, LGT8F328P)
:02000004008476
:0100030055A7                                                               // 840003> 0x55 calibration
:00000001FF

@mcuee
Copy link
Collaborator

mcuee commented Jun 30, 2024

I like the "ALL" option as well.

PS C:\work\avr\avrdude_test\avrdude_bin> .\avrdude_pr1828.exe -C .\avrdude_pr1828.conf -qq -c usbasp -p m168p -UALL:r:readall_m168p.hex:I

 MINGW64 /c/work/avr/avrdude_test/avrdude_bin
$ head readall_m168p.hex
:02000004008179
:20000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00 // 810000> ................................ eeprom
:20002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 // 810020> ................................
:20004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 // 810040> ................................
:20006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 // 810060> ................................
:20008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 // 810080> ................................
:2000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 // 8100a0> ................................
:2000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 // 8100c0> ................................
:2000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 // 8100e0> ................................
:20010000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF // 810100> ................................

$ tail -n 15 readall_m168p.hex
:203FC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF01 // 03fc0> ................................
:203FE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE1 // 03fe0> ................................
:02000004008278
:01000000F708                                                               // 820000> 0xf7 lfuse
:02000004008278
:01000100DD21                                                               // 820001> 0xdd hfuse
:02000004008278
:01000200FC01                                                               // 820002> 0xfc efuse
:02000004008377
:01000000FF00                                                               // 830000> 0xff lock
:02000004008476
:030000001E940B40                                                           // 840000> 0x1e 0x94 0x0b signature (ATmega168P, ATmega168PA, LGT8F168P)
:02000004008476
:01000300BC40                                                               // 840003> 0xbc calibration
:00000001FF

@MCUdude
Copy link
Collaborator

MCUdude commented Jun 30, 2024

@stefanrueger -mem or /mem is now working, but I still can't to that with the signature memory:

$ ./avrdude -cdryrun -patmega8535 -UALL,/eeprom:w:/Users/hans/Downloads/m8535_backup.hex
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e9308 (probably m8535)

avrdude: processing -U ALL,/eeprom:w:/Users/hans/Downloads/m8535_backup.hex:i
avrdude: reading 8714 bytes for multiple memories from input file /Users/hans/Downloads/m8535_backup.hex
avrdude: 8192 bytes flash in 1 section [0, 0x1fff]: 128 pages and 0 pad bytes
         writing 8192 bytes to flash ...
         writing | ################################################## | 100% 0.00 s 
         reading | ################################################## | 100% 0.00 s 
         8192 bytes of flash verified
avrdude: 1 byte lfuse in 1 section [0, 0]
         writing 1 byte to lfuse (0xbf), 1 byte written, 1 verified
avrdude: 1 byte hfuse in 1 section [0, 0]
         writing 1 byte to hfuse (0xc2), 1 byte written, 1 verified
avrdude: 1 byte lock in 1 section [0, 0]
         writing 1 byte to lock (0xff), 1 byte written, 1 verified

avrdude done.  Thank you.

$ ./avrdude -cdryrun -patmega8515 -UALL,-signature:w:/Users/hans/Downloads/m8535_backup.hex
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e9306 (probably m8515)

avrdude: processing -U ALL,-signature:w:/Users/hans/Downloads/m8535_backup.hex:i
avrdude: reading 8714 bytes for multiple memories from input file /Users/hans/Downloads/m8535_backup.hex
avrdude error: signature of ATmega8515 does not match file (ATmega8535)
        use -F to override this check

avrdude done.  Thank you.

@MCUdude
Copy link
Collaborator

MCUdude commented Jun 30, 2024

Here is the output when writing a multimem file to the ATmega4809, when specifying the fuses in the program itself, like so. It took me a while to figure out how the struct should look like, due to the reserved memories in there, so we should mention this in the docs.

FUSES = 
{
    0x01, // WDTCFG
    0x02, // BODCFG
    0x03, // OSCCFG
    0xFF,
    0xFF,
    0x06, // SYSCFG0
    0x07, // SYSCFG1
    0x08, // APPEND
    0x09, // BOOTEND
};
$ ./avrdude -cdryrun -patmega4809 -UALL:w:/var/folders/50/f9myvbw51nbgddp3cc57tzp40000gn/T/arduino_build_887794/Blink.ino.hex
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e9651 (probably m4809)

avrdude: processing -U ALL:w:/var/folders/50/f9myvbw51nbgddp3cc57tzp40000gn/T/arduino_build_887794/Blink.ino.hex:i
avrdude: reading 761 bytes for multiple memories from input file /var/folders/50/f9myvbw51nbgddp3cc57tzp40000gn/T/arduino_build_887794/Blink.ino.hex
avrdude warning: /var/folders/50/f9myvbw51nbgddp3cc57tzp40000gn/T/arduino_build_887794/Blink.ino.hex has no data for eeprom, skipping ...
avrdude: 752 bytes flash in 1 section [0, 0x2ef]: 6 pages and 16 pad bytes
         writing 752 bytes to flash ...
         writing | ################################################## | 100% 0.00 s 
         reading | ################################################## | 100% 0.00 s 
         752 bytes of flash verified
avrdude: 9 bytes fuses in 1 section [0, 8]
         writing 9 bytes to fuses ..., 9 bytes written, 9 verified
avrdude: 1 byte fuse0/wdtcfg in 1 section [0, 0]
         writing 1 byte to fuse0/wdtcfg (0x01), 1 byte written, 1 verified
avrdude: 1 byte fuse1/bodcfg in 1 section [0, 0]
         writing 1 byte to fuse1/bodcfg (0x02), 1 byte written, 1 verified
avrdude: 1 byte fuse2/osccfg in 1 section [0, 0]
         writing 1 byte to fuse2/osccfg (0x03), 1 byte written, 1 verified
avrdude: 1 byte fuse5/syscfg0 in 1 section [0, 0]
         writing 1 byte to fuse5/syscfg0 (0x06), 1 byte written, 1 verified
avrdude: 1 byte fuse6/syscfg1 in 1 section [0, 0]
         writing 1 byte to fuse6/syscfg1 (0x07), 1 byte written, 1 verified
avrdude: 1 byte fuse7/append in 1 section [0, 0]
         writing 1 byte to fuse7/append (0x08), 1 byte written, 1 verified
avrdude: 1 byte fuse8/bootend in 1 section [0, 0]
         writing 1 byte to fuse8/bootend (0x09), 1 byte written, 1 verified
avrdude warning: /var/folders/50/f9myvbw51nbgddp3cc57tzp40000gn/T/arduino_build_887794/Blink.ino.hex has no data for lock, skipping ...
avrdude warning: /var/folders/50/f9myvbw51nbgddp3cc57tzp40000gn/T/arduino_build_887794/Blink.ino.hex has no data for userrow/usersig, skipping ...

avrdude done.  Thank you.

Is it necessary to mention all the memories the file didn't contain, with the full filename and everything? The hex file was compiled using Arduino IDE, and I feel the output is a bit verbose.

How about something like this? Way less text, but no critical information have been left out

$ ./avrdude -cdryrun -patmega4809 -UALL:w:/var/folders/50/f9myvbw51nbgddp3cc57tzp40000gn/T/arduino_build_887794/Blink.ino.hex
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e9651 (probably m4809)

avrdude: processing -U ALL:w:/var/folders/50/f9myvbw51nbgddp3cc57tzp40000gn/T/arduino_build_887794/Blink.ino.hex:i
avrdude: reading 761 bytes for multiple memories from input file
avrdude: input file has no data for eeprom, skipping ...
avrdude: 752 bytes flash in 1 section [0, 0x2ef]: 6 pages and 16 pad bytes
         writing 752 bytes to flash ...
         writing | ################################################## | 100% 0.00 s 
         reading | ################################################## | 100% 0.00 s 
         752 bytes of flash verified
avrdude: 9 bytes fuses in 1 section [0, 8]
         writing 9 bytes to fuses ..., 9 bytes written, 9 verified
avrdude: 1 byte fuse0/wdtcfg in 1 section [0, 0]
         writing 1 byte to fuse0/wdtcfg (0x01), 1 byte written, 1 verified
avrdude: 1 byte fuse1/bodcfg in 1 section [0, 0]
         writing 1 byte to fuse1/bodcfg (0x02), 1 byte written, 1 verified
avrdude: 1 byte fuse2/osccfg in 1 section [0, 0]
         writing 1 byte to fuse2/osccfg (0x03), 1 byte written, 1 verified
avrdude: 1 byte fuse5/syscfg0 in 1 section [0, 0]
         writing 1 byte to fuse5/syscfg0 (0x06), 1 byte written, 1 verified
avrdude: 1 byte fuse6/syscfg1 in 1 section [0, 0]
         writing 1 byte to fuse6/syscfg1 (0x07), 1 byte written, 1 verified
avrdude: 1 byte fuse7/append in 1 section [0, 0]
         writing 1 byte to fuse7/append (0x08), 1 byte written, 1 verified
avrdude: 1 byte fuse8/bootend in 1 section [0, 0]
         writing 1 byte to fuse8/bootend (0x09), 1 byte written, 1 verified
avrdude: input file has no data for lock, skipping ...
avrdude: input file has no data for userrow/usersig, skipping ...

avrdude done.  Thank you.

@stefanrueger
Copy link
Collaborator Author

@MCUdude @dl8dtl @mcuee Thanks all round for tests and comments.

/mem

I have had second thoughts. / is not a good notation for but not as in set theory /set means universe \ set. Now -mem and \mem (instead of /mem) can be used as list-element and they mean remove mem from list so far, eg, ALL,-bootrow

but I still can't [suppress the signature check by removing from the list] the signature memory

Correct. The signature check is triggered by the presence of a signature in the file, and not by the presence of the signature memory in the memory list. This has the advantage that writing to fuses or any other memory of a part from a multi-memory file (as in -U fuses:w:mm-file.hex:i) triggers the sanity check. Otherwise one would need to always add signature to the memory list if the sanity check was required. Also, the creator of a multi-memory .hex or srec file can leave out the signature on file creation to prevent this sanity check, eg, if the file only contains EEPROM and sigrow which might be SW-agnostic.

I have, however, written a function avr_sig_compatible() that closely models SW-compatibility of AVR parts and knows about exceptions of parts with different signatures tht are SW-compatible: @MCUdude, please review commit cfaee38.

Is it necessary to mention all the memories the file didn't contain, with the full filename and everything?

Sure, the full pathname is not needed. I have reduced that now to the filename component of the path. I feel that AVRDUDE should warn whenever the file didn't contain requested memories: in the example the user explicitly asked for ALL memories to be set/checked, so they should receive a warning if something they asked for is not available. The user can reduce the warnings by only specifying what's in the file, eg, flash,fuses. And yes, ALL means all memories of the part, not all memories of the file. It must be the former otherwise what would -U ALL:r:file mean when the file does not (yet) exist?

Let me know if I have missed some of the comments and/or any problems where this PR breaks something.

And, yes, once this PR is settled, I will (as always) contribute documentation. It would be great if @MCUdude could contribute examples how to generate multi-memory .hex files by compiling sketches in Arduino (I don't use that environment).

@MCUdude
Copy link
Collaborator

MCUdude commented Jul 1, 2024

@MCUdude, please review commit cfaee38.

The commit looks good! Tested with ATmega324A/P/PA.It only compares devices that are truly SW compatible. So even though a hex file compiled for the ATmega88 will work on the ATmega168, they aren't back to back compatible, and will fail the test.

Sure, the full pathname is not needed. I have reduced that now to the filename component of the path.

Thanks! The output looks suddenly much better. And a warning is fine by me.

It would be great if @MCUdude could contribute examples how to generate multi-memory .hex files by compiling sketches in Arduino (I don't use that environment).

Sure! I can provide examples for classic AVRs and AVRs with UPDI. Embedding the fuses is pretty straight forward, but I haven't figured out how/if it's possible to embed EEPROM content as well.

AVRDUDE will happily generate all sorts of file formats from multiple
memories, but only understands hex, srec and elf files.
@stefanrueger
Copy link
Collaborator Author

stefanrueger commented Jul 2, 2024

@MCUdude Thanks for checking

a hex file compiled for the ATmega88 will work on the ATmega168, they aren't back to back compatible, and will fail the test

Yes, this is deliberate. For example, if an application for the ATmega88 makes use of the urclock metadata and urboot write_page() function located at FLASHEND-4+1 there might be tears if that binary is put on an ATmega168 as FLASHEND differs in both parts... If a user restores a binary image from an m88 to an m168 they really should be affirming with -F that they know what they are doing even though more often that not this is likely to be OK.

I have in the meantime found (and fixed) an error: AVRDUDE erases the chip automatically if one of the -U options writes to flash; this has now been extended to also check memory lists for writing to a flash memory.

Also added documentation.

Would like to merge soon, unless there are further comments. We can still put examples how to generate multi-memory .hex files by compiling sketches into the documentation later on.

Generally, to generate multi-memory files for distribution I recommend to carefully prepare everything in a chip as it should be and then use -U all:r:distro.hex. This allows one to use the config terminal command to set/check the fuses.

@stefanrueger
Copy link
Collaborator Author

Some dryrun tests

$ cat mkcheck 

#!/usr/bin/env bash

# Check using randomly generated files
for i in {1..4}; do
  # Create random contens, backup to srec file
  avrdude -qq -c dryrun -p 64dd28 -xrandom -xseed=$i -U ALL:r:/tmp/backup.srec:s && echo $i Backup srec OK
  # Create same random contens, backup to hex file
  avrdude -qq -c dryrun -p 64dd28 -xrandom -xseed=$i -U ALL:r:/tmp/backup.hex:I && echo $i Backup hex OK
  # Restore from hex file and compare against srec
  avrdude -qq -c dryrun -p 64dd28 -U ALL:w:/tmp/backup.hex:I -U ALL:v:/tmp/backup.srec && echo $i hex vs srec OK
  # Restore from srec file and compare against hex file
  avrdude -qq -c dryrun -p 64dd28 -U ALL:w:/tmp/backup.srec:s -U ALL:v:/tmp/backup.hex:I && echo $i srec vs hex OK
  echo
done

$ ./mkcheck 

1 Backup srec OK
1 Backup hex OK
1 hex vs srec OK
1 srec vs hex OK

2 Backup srec OK
2 Backup hex OK
2 hex vs srec OK
2 srec vs hex OK

3 Backup srec OK
3 Backup hex OK
3 hex vs srec OK
3 srec vs hex OK

4 Backup srec OK
4 Backup hex OK
4 hex vs srec OK
4 srec vs hex OK

Some real tests

############
# Create a non-trivial random file
#
$avrdude -p 64dd28 -c dryrun -xinit -xseed=7 -UALL:r:64dd28.bak

avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e961b (probably 64dd28)

avrdude: processing -U ALL:r:64dd28.bak:I
         reading multiple memories ...
         eeprom          | ################################################## | 100% 0.00 s 
         flash           | ################################################## | 100% 0.00 s 
         fuses           | ################################################## | 100% 0.00 s 
         fuse0/wdtcfg    | ################################################## | 100% 0.00 s 
         fuse1/bodcfg    | ################################################## | 100% 0.00 s 
         fuse2/osccfg    | ################################################## | 100% 0.00 s 
         fuse5/syscfg0   | ################################################## | 100% 0.00 s 
         fuse6/syscfg1   | ################################################## | 100% 0.00 s 
         fuse7/codesize  | ################################################## | 100% 0.00 s 
         fuse8/bootsize  | ################################################## | 100% 0.00 s 
         lock            | ################################################## | 100% 0.00 s 
         prodsig/sigrow  | ################################################## | 100% 0.00 s 
         signature       | ################################################## | 100% 0.00 s 
         tempsense       | ################################################## | 100% 0.00 s 
         sernum          | ################################################## | 100% 0.00 s 
         userrow/usersig | ################################################## | 100% 0.00 s 
         sib             | ################################################## | 100% 0.01 s 
         writing 66034 bytes to output file 64dd28.bak

avrdude done.  Thank you.


############
# Write that file to a *real* device
#
$ avrdude -p 64dd28 -c serialupdi -UALL:w:64dd28.bak

avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e961b (probably 64dd28)
avrdude: Note: carrying out an erase cycle as flash memory needs programming (-U ALL:w:...)
         specify the -D option to disable this feature
avrdude: erasing chip

avrdude: processing -U ALL:w:64dd28.bak:i
avrdude: reading 66004 bytes for multiple memories from input file 64dd28.bak
avrdude: 256 bytes eeprom in 1 section [0, 0xff]
         writing 256 bytes to eeprom ...
         writing | ################################################## | 100% 10.26 s 
         reading | ################################################## | 100% 1.06 s 
         256 bytes of eeprom verified
avrdude: 65536 bytes flash in 1 section [0, 0xffff]: 128 pages and 0 pad bytes
         writing 65536 bytes to flash ...
         writing | ################################################## | 100% 9.91 s 
         reading | ################################################## | 100% 8.96 s 
         65536 bytes of flash verified
avrdude: 16 bytes fuses in 1 section [0, 15]
         writing 16 bytes to fuses ..., 16 bytes written, 16 verified
avrdude: 1 byte fuse0/wdtcfg in 1 section [0, 0]
         writing 1 byte to fuse0/wdtcfg (0x00), 1 byte written, 1 verified
avrdude: 1 byte fuse1/bodcfg in 1 section [0, 0]
         writing 1 byte to fuse1/bodcfg (0x00), 1 byte written, 1 verified
avrdude: 1 byte fuse2/osccfg in 1 section [0, 0]
         writing 1 byte to fuse2/osccfg (0x00), 1 byte written, 1 verified
avrdude: 1 byte fuse5/syscfg0 in 1 section [0, 0]
         writing 1 byte to fuse5/syscfg0 (0xd0), 1 byte written, 1 verified
avrdude: 1 byte fuse6/syscfg1 in 1 section [0, 0]
         writing 1 byte to fuse6/syscfg1 (0x08), 1 byte written, 1 verified
avrdude: 1 byte fuse7/codesize in 1 section [0, 0]
         writing 1 byte to fuse7/codesize (0x1e), 1 byte written, 1 verified
avrdude: 1 byte fuse8/bootsize in 1 section [0, 0]
         writing 1 byte to fuse8/bootsize (0x15), 1 byte written, 1 verified
avrdude: 4 bytes lock in 1 section [0, 3]
         writing 4 bytes to lock ..., 4 bytes written, 4 verified
avrdude: 32 bytes userrow/usersig in 1 section [0, 0x1f]: 1 page and 0 pad bytes
         writing 32 bytes to userrow/usersig ..., 32 bytes written, 32 verified

avrdude done.  Thank you.


############
# Make a backup from the *real* device
#
$ avrdude -p 64dd28 -c serialupdi -UALL:r:64dd28-real.bak
avrdude: AVR device initialized and ready to accept instructions
avrdude: device signature = 0x1e961b (probably 64dd28)

avrdude: processing -U ALL:r:64dd28-real.bak:I
         reading multiple memories ...
         eeprom          | ################################################## | 100% 1.06 s 
         flash           | ################################################## | 100% 10.64 s 
         fuses           | ################################################## | 100% 0.07 s 
         fuse0/wdtcfg    | ################################################## | 100% 0.00 s 
         fuse1/bodcfg    | ################################################## | 100% 0.00 s 
         fuse2/osccfg    | ################################################## | 100% 0.00 s 
         fuse5/syscfg0   | ################################################## | 100% 0.00 s 
         fuse6/syscfg1   | ################################################## | 100% 0.00 s 
         fuse7/codesize  | ################################################## | 100% 0.00 s 
         fuse8/bootsize  | ################################################## | 100% 0.00 s 
         lock            | ################################################## | 100% 0.02 s 
         prodsig/sigrow  | ################################################## | 100% 0.03 s 
         signature       | ################################################## | 100% 0.02 s 
         tempsense       | ################################################## | 100% 0.02 s 
         sernum          | ################################################## | 100% 0.07 s 
         userrow/usersig | ################################################## | 100% 0.01 s 
         sib             | ################################################## | 100% 0.00 s 
         writing 66034 bytes to output file 64dd28-real.bak

avrdude done.  Thank you.


############
# Compare backup from real part with the backup from dryrun part
# Only sigrow differs (as expected)
#
$ diff 64dd28-real.bak 64dd28.bak 

2078c2078
< :200000001E961BFF00040A0DFFFFFFFFFFFFFFFF4222536151005917011001030000000011 // 840000> ................B"SaQ.Y......... prodsig/sigrow
---
> :200000001E961BFF54545454FFFFFFFFFFFFFFFF5554535251504F4E4D4C4B4A49484746F2 // 840000> ....TTTT........UTSRQPONMLKJIHGF prodsig/sigrow
2080,2081c2080,2081
< :200040007467F400CBAE58FFFFFFDDFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3C // 840040> tgt.K.X...]~....................
< :20006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAA55AA55FFFFFFFF9E // 840060> ........................*U*U....
---
> :20004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 // 840040> ................................
> :20006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 // 840060> ................................
2085c2085
< :0400040000040A0DDD                                                         // 840004> 0x00 0x04 0x0a 0x0d tempsense
---
> :0400040054545454A8                                                         // 840004> 0x54 0x54 0x54 0x54 tempsense
2087c2087
< :1000100042225361510059170110010300000000F2                                 // 840010> B"SaQ.Y......... sernum
---
> :100010005554535251504F4E4D4C4B4A4948474608                                 // 840010> UTSRQPONMLKJIHGF sernum
2091c2091
< :201000004156522020202020503A32443A312D334D32202841332E4B5630304B2E30290040 // 841000> AVR     P:2D:1-3M2 (A3.KV00K.0). sib
---
> :20100000535353535353535353535353535353535353535353535353535353535353535370 // 841000> SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS sib

@stefanrueger stefanrueger merged commit 3ea3868 into avrdudes:main Jul 4, 2024
@stefanrueger stefanrueger deleted the multi-memory-input branch July 4, 2024 16:17
@MCUdude
Copy link
Collaborator

MCUdude commented Jul 4, 2024

@stefanrueger you mentioned that you wanted to include a few Arduino examples on how the fuses could be added to the the docs.

Arduino sketch for ATmega4809 to store fuses in the output hex file:

#include <avr/fuse.h>

FUSES = {
  0x00, // WDTCFG
  0x00, // BODCFG
  0x7E, // OSCCFG
  0xFF, // Reserved
  0xFF, // Reserved
  0xF6, // SYSCFG0
  0xFF, // SYSCFG1
  0x00, // APPEND
  0x00, // BOOTEND
};

void setup() {
}

void loop() {
}

Arduino sketch for ATmega328P to store fuses in the output hex file:

#include <avr/fuse.h>

FUSES = {
  0x62, // LFUSE
  0xD9, // HFUSE
  0xFF, // EFUSE
};

void setup() {
}

void loop() {
}

@mcuee mcuee added this to the AVRDUDE 8.0 milestone Jul 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multi-memory files

4 participants