Not Reading an AVR Bootloader From the Application Section

dog lady epic fail

See this post first.

The reason my program fails is because interrupts are disable inside the BLS. Running interrupts in the BLS requires a different lock bit setting than the standard arduino. The arduino boot loader doesn’t use any interrupts, so this lock bit setting is ok.

Since interrupts are disabled inside the BLS, when my program calls the LPM instruction, my timer interrupt never fires. Hence the program never returns from the LPM instruction. It probably continues to execute the boot loader code until it crashes, restarts, starts my program, etc., continuing like this in an endless loop.

As a confirmation of the disabled interrupts and to validate my code, I modified the instruction after the LPM in the BLS to a “RET”, then ran my program without using the timer interrupt. I discovered it now works, with and without the lock bits set.

Here is the section of the boot loader code that I modified:

3de2: 00 23        and  r16, r16
3de4: 39 f4        brne SkipRead        ;.+14 (0x3df4)
3de6: 94 91        lpm  r25, Z+
//we need to insert this return command here
3de8: 08 95  ret
3de8: 80 91 c0 00  lds  r24, UCSR0A      ;0x00C0
3dec: 85 ff        sbrs r24, 0b00000101 ;5
3dee: fc cf        rjmp waituart        ;.-8 (0x3de8)

To accomplish this, I downloaded the entire flash from my arduino (with both my program and a standard boot loader installed). Then I opened the file (Intel Hex format) in a hexeditor program, searched for the LPM instruction, and changed the following four bytes (“9491” to “0895”):

hex editor

Note, I also needed to change the 2 checksum bytes at the end of the line because avrdude complains when we attempt the upload the modified hex code:

avrdude.exe: input file C:\Users\James\168.hex auto detected as Intel Hex
avrdude.exe: ERROR: checksum mismatch at line 991 of "C:\Users\James\168.hex"
avrdude.exe: checksum=0x99, computed checksum=0x0d
avrdude.exe: write to file 'C:\Users\James\168.hex' failed

Luck for me, avrdude also computes and displays the correct checksum, so this was easy to accomplish.

So the answer to my question is, “Yes, maybe.” An LPM instruction in the BLS can read the BLS, it just can’t do it with the method I attempted.

BTW, I’m a little annoyed with my new ATMEL-ICE (~$40). When using debugWire with an arduino, calls into the BLS are prevented, as ATMEL Studio depicts the BLS as solid “FF FF FF…”. However, when you return from the debug session, the bootloader is still there. Furthermore, it seems to take a magical combination of nearly hidden menu selections to get in and out of debug mode. You end up scaring yourself about once per debug session, thinking you bricked the chip. The combination of ATMEL Studio 6.2, debugWire and arduino is very fragile.


About Jim Eli

µC experimenter
This entry was posted in Uncategorized and tagged , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s