AVR Basics: Reading (and writing) flash contents

Programming on a target board

From our forums comes this interesting question:

   “Is it possible to download the contents of an ATmega168/328, essentially backing it up so that it can somehow be restored later?

For example: Let’s say I have lost the source code to a very useful program currently residing on a 328, but I need to flash it with a different sketch temporarily, then restore that original sketch. This would be useful in the case that the chip was soldered directly onto a board – a big mess to try to replace.
Is this possible in some way, perhaps by altering an ISP programmer?”

The answer is that yes indeed, it is possible– with a couple of exceptions that are worth mentioning. And on occasion, it’s even very useful.

Reading out the flash memory is straightforward with an AVR ISP programmer, such as the USBtinyISP, using avrdude from the command line.

 

You’ll need to have a copy of the AVR toolchain– or at least avrdude –installed on your computer. There are easy installers available for Mac (Crosspack) and Windows (MHV AVR Tools) that include this software, along with the other open source tools for AVR development. Linux packages for AVR development are also available.

 

Reading the flash

To read out the contents of the flash memory of your AVR, you just need to hook up your ISP programmer to the target board, and run an appropriate avrdude command to read out the flash. For “dumping” out the contents of an ATmega328P, for example, you might use the command:

 

avrdude -p m328p -P usb -c usbtiny -U flash:r:flash.bin:r

 

Where, “atmega328p” is the name of the chip, written exactly as found in the avrdude documentation, “-P usb” means that we’re using a usb-connected programmer, and “usbtiny” is the programmer type (again, taken from the list in the documentation).

 

The real heart of the command is the last part, -U flash:r:”flash.bin”:r. This tells avrdude to read the contents of the flash (“flash:r”), save it to a file named “flash.bin,” and specifies the format (“:r”), in this case raw binary.

Writing the flash

To write the contents of that file, “flash.bin,” we use a similar command, only now telling it to write the contents “flash:w…”:

 

avrdude -p m328p -P usb -c usbtiny -U flash:w:flash.bin

 

Again, the exact command line needs to be tailored to your particular chip, programmer, and file name.

Applications

So, when would this kind of method be useful? Yes, it’s possible that you’ve lost the source code to a piece of software– but perhaps that’s an esoteric case. We have actually found this method to be very helpful in daily use as a sort of “disk image” file.

You can, for example, read and write the full flash contents of an Arduino device that has both the Arduino bootloader and a program on top of that. Then, deploying an additional copy of that program becomes as simple as executing a single command to write the flash file. For “production programming” — that is, making many clones of an AVR program –it has the added benefits of being fast and reliably consistent, as compared with individually compiling and installing firmware for each device.

Caveats

As we mentioned earlier, there are a couple of exceptions that are worth mentioning:
1.) It is possible to intentionally lock the contents of the flash memory, such that the contents cannot be read out*. You can do this by setting the lock bits of the AVR according to the values listed in the datasheet, and the lock bits cannot be reset except by erasing the whole device.
*There are known ways of getting around this, so please don’t consider lock bits sufficient defense if you are worried about someone stealing your code as a means of industrial espionage.

 

2.) These commands, as written, only back up the contents of the flash (program) memory. Reading out the EEPROM or fuse byte values can be done in similar ways. You can read more about the avrdude command line options in the avrdude documentation, or in the tutorial at Adafruit.

For production programming, the single avrdude statement can set the fuse bytes and also write the flash, or a makefile can be written to give multiple avrdude statements, for sequencing the order of writing flash and fuse and/or lock bits.

6 thoughts on “AVR Basics: Reading (and writing) flash contents

  1. if you’ve got the arduino software, you’ve got avrdude already. it’ll be at arduino-00xx/hardware/tools/avrdude, if you happen to be running arduino version xx. so, if you can figure out where your arduino software is installed, you can run it from there.

  2. You might want to add that while the lock bits prevent reading the actual flash memory contents, you won’t get an error message. The binary file will be created just as it would without the lock bits set, but it contains nonsense (or, more precisely, the lower 8 bits of word address of the memory location). So you will have to open the binary file with a hex editor (I recommend frhed for windows and dhex for linux/console, if you’re using KDE then khexedit might be a good choice). If it contains a pattern like

    00 00 01 01 02 02 03 03 04 04

    and so on, the AVR is most probably locked.

    1. If there was a way to "get around" the lock bits, that would sorta defeat the purpose of the lock bits, no?

      You can re-program the chip and disable the lock bits, but it’ll wipe out whatever’s on there in the process. If you’re trying to get code from a locked chip, ask the programmer if they’re willing to share the code.

      1. Wendell mentions that it isn’t fool-proof, so I’m fairly certain that it’s not impossible. However, that sort of thing smacks of cracking and piracy, so is not likely the sort of thing to be found here.

        The "Evil" part of their name seems to be mostly for marketing. :)


        I think I am, therefore I am… I think

  3. Yes, this.

    Since pretty much most of the digital hardware and software put out by EMSL is open-source, it’s kind of a moot point, and if someone is looking for a way to hack something that’s copy-protected, I doubt they’ll find the answers here…

Comments are closed.