# Avrdude Does not Read What it Wrote Correctly

Question

I am getting back into Atmel AVR programming after nearly a decade off. To this end, I am trying to get the usual blinken lights demo working. Unfortunately this does not function, though avrdude reports that it flashed the hex file successfully.

Digging into this a bit more, I find that reading the freshly written flash back yields a different result. The original hex file is:

:100000001DC024C023C022C021C020C01FC01EC0EC
:100010001DC01CC01BC01AC019C018C017C016C014
:1000200015C014C013C012C011C010C00FC00EC044
:100030000DC00CC00BC00AC009C008C011241FBEEF
:10004000CFEFD1E0DEBFCDBF02D012C0D9CF8FE05D
:100050008ABB1BBA9BB38BB389278BBB2FEF84E37F
:100060009CE0215080409040E1F700C00000F2CFBA
:04007000F894FFCF32
:00000001FF


While the read-back hex file comes out as:

:200000001DC024C023C022C021C020C01FC01EC01DC01CC01BC01AC019C018C017C016C010
:2000200015C014C013C012C011C010C00FC00EC00DC00CC00BC00AC009C008C011241FBE63
:20004000CFEFD1E0DEBFCDBF02D012C0D9CF8FE08ABB1BBA9BB38BB389278BBB2FEF84E32C
:140060009CE0215080409040E1F700C00000F2CFF894FFCF5C
:00000001FF


The key items of note here are the programming addresses at the beginning of each line. In the original, the addresses start at 0x10000000 and increment by 0x1000. In the read hex file the base address is 0x20000000, incrementing by 0x2000. Now, the read hex file's lines are twice as long, which should account for the difference in increment magnitude.

What would account for the difference in base address between these two hex files?

I found this question on SO which seems to indicate that the AVR is 16-bit word-addressable instead of 8-bit byte-addressable as is expected by the Intel hex format. That being said, I would have expected avrdude to handle this already since programming hex files to AVR devices is kind of its whole purpose in life.

Additionally, I dumped the symbols from the elf file. As I would have expected, most of the symbols are referenced to base address 0x00000000 (truncated for brevity):

...
0000004e T main
00000070 T _exit
00000070 W exit
00000072 t __stop_program
00000074 T _etext
000001ff W __stack
...


I would have expected one of the records in the hex file to write to 0x00000000 to set the reset jump offset in the IVT.

What is the correct initial offset for program start?

Since neither of these hex files specify a reset vector address there must be an additional mechanism which I am not aware of.

Finally, I have verified that the programmer is actually writing to the chip by erasing the flash and performing a read; I do see the chip return essentially blank. A subsequent program returns the above incorrect hex.

General Information

I am working on Linux using an original STK500v2. Everything is build using a heavily customized makefile based on this post. All the same, the relevant sections are below (please excuse the convoluted variables; this is part of a much larger build system):

AVR_OBJCOPY=@avr-objcopy
AVRDUDE=@avrdude -c stk500v2 -p t441 -P /dev/ttyUSB1
SREC_CAT=@srec_cat

%.hex: $(APP_TARGETS)$(ECHO) " MKHEX  $*"$(AVR_OBJCOPY) -j .text -j .data -O ihex $(BUILD_DIR)/$(ARCH)/$*$(BINARY_SUFFIX) $(BUILD_DIR)/$(ARCH)/$*.flash.hex$(AVR_OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex $(BUILD_DIR)/$(ARCH)/$*$(BINARY_SUFFIX) $(BUILD_DIR)/$(ARCH)/$*.eeprom.hex$(AVR_OBJCOPY) -j .fuse -O ihex $(BUILD_DIR)/$(ARCH)/$*$(BINARY_SUFFIX) $(BUILD_DIR)/$(ARCH)/$*.fuses.hex --change-section-lma .fuse=0$(SREC_CAT) $(BUILD_DIR)/$(ARCH)/$*.fuses.hex -Intel -crop 0x00 0x01 -offset 0x00 -O$(BUILD_DIR)/$(ARCH)/$*.lfuse.hex -Intel
$(SREC_CAT)$(BUILD_DIR)/$(ARCH)/$*.fuses.hex -Intel -crop 0x01 0x02 -offset -0x01 -O $(BUILD_DIR)/$(ARCH)/$*.hfuse.hex -Intel$(SREC_CAT) $(BUILD_DIR)/$(ARCH)/$*.fuses.hex -Intel -crop 0x02 0x03 -offset -0x02 -O$(BUILD_DIR)/$(ARCH)/$*.efuse.hex -Intel
avr-nm -n $(BUILD_DIR)/$(ARCH)/$*$(BINARY_SUFFIX) > $(BUILD_DIR)/$(ARCH)/$*.sym read-fuses:$(AVRDUDE) 2>&1 | grep "Fuses OK" | sed 's:.*($$.*$$).*:\n\1\n:'

write-flash:
$(AVRDUDE) -U flash:w:$(BUILD_DIR)/\$(ARCH)/firmware.flash.hex


I know the STK500 is functional because, infuriatingly, this was working before on this very chunk of silicon.

Edit:

By request: the source for my test program.

#include <avr/io.h>
#include <util/delay.h>

int main(){

DDRA = 0x0F;
PORTA = 0x00;

while (1)
{
PORTA ^= PORTA;
_delay_ms(500);
}
}


Also, for good measure, current fuse settings:

avrdude: safemode: Fuses OK (E:FF, H:DF, L:82)


Edit 2:

For any who see this later, the issue with the program was an XOR fail. PORTA ^= PORTA; should have been PORTA ^= 0x0F;. This post just about sums it up. Remember kids, don't try to be too clever.

• here is the hexfile format description, for anyone doing research ... en.m.wikipedia.org/wiki/Intel_HEX – jsotola Feb 3 at 4:18
• "I am trying to get the usual blinken lights demo working. Unfortunately this does not function" - which AVR? Show us your code for blinking lights. – Bruce Abbott Feb 3 at 4:44