bugAVR Downloader/UploaDEr - Bugs: bug #30061, stk500 skips writing blocks of...


You are not allowed to post comments on this tracker with your current authentication level.

bug #30061: stk500 skips writing blocks of 0xff, even if the part/page wasn't erased

Submitted by:  None
Submitted on:  Mon 07 Jun 2010 03:36:06 AM UTC  
Votes:  1  
Category:  None Severity:  3 - Normal
Priority:  5 - Normal Item Group:  None
Status:  Invalid Privacy:  Public
Assigned to:  Joerg Wunsch <joerg_wunsch> Originator Name:  Adam Wolf
Originator Email:  -email is unavailable- Open/Closed:  Closed
Release:  None Programmer hardware: 
Device type: 

( Jump to the original submission)

Thu 15 Sep 2011 04:21:46 PM UTC, comment #7: 

p.s.: This is supposed to be fixed now by the recent introduction of
memory region tagging: only those memory regions where actual content
has been read for from a file are written to now.

You're welcome to test the fix, but you'll have to use the SVN trunk
by now for checking.

Joerg Wunsch <joerg_wunsch>
Project AdministratorIn charge of this item.
Tue 16 Aug 2011 03:14:20 PM UTC, comment #6: 

Upon re-reading, I see the "with auto-erase off" being
mentioned.  In that case, it's simply a usage error.
Trying to write data onto a device that is not guaranteed to
be erased is asking for trouble.  If it were not operating
using a bootloader, but plain ISP mode, the result would be
for any of the actual written pages to become the logical
AND between the previous and the current data values.

Joerg Wunsch <joerg_wunsch>
Project AdministratorIn charge of this item.
Tue 16 Aug 2011 03:10:59 PM UTC, comment #5: 

Closing as invalid, as I see the problem as being in the
Arduino bootloader.  When being requested to perform a
"chip erase", the bootloader should eventually erase all
application pages, to do its best of simulating the requested
chip erase.

Joerg Wunsch <joerg_wunsch>
Project AdministratorIn charge of this item.
Tue 08 Jun 2010 04:18:48 AM UTC, comment #4: 

My guess is that the problem lies in the Arduino bootloader.

Remember, the STK500 protocol does not have any "page erase"
command, but a bootloader can only perform page erases
(otherwise, it would ultimately erase itself).

So, when AVRDUDE starts, it sends a "device erase" to the
STK500 (i.e., to the Arduino bootloader).  The expectation
for a bootloader would be that it emulates a device erase
as much as possible, e.g. it erases the entire application
area.  Of course, AVRDUDE does not care about /when/ the
programmer actually performs the erase, but the result should
look /as if/ a device erase has happened.  Now, I guess the
bootloader defers erasing each page until actual data arrive
for the page itself, but AVRDUDE (in the assumption the device
has been erased already anyway) does not send page data for
pages entirely consisting of 0xff.  As the bootloader deferred
erasing the pages, you are now hosed: it skips erasing some

IMHO, the bootloader should simply erase the entire
application area by the time it is told to erase the device.
There's not much point in deferring the job.

Joerg Wunsch <joerg_wunsch>
Project AdministratorIn charge of this item.
Mon 07 Jun 2010 10:49:59 PM UTC, comment #3: 

Sorry about this!  It's a little tricky when isolating issues where results from the previous test can show up in the current one.

Anyway, I'm still a little confused, but I believe my issue is not actually with avrdude, but with the Arduino IDE.

However, could you help explain one thing?  If I have a large array in progmem filled with 0xFF, the array doesn't get written.  If I change one of the 0xFF's to 0xFE, setting one of the bits to 0, the entire page around the byte appears to be written correctly.

Does this sound right?

I looked at the verbose output from avrdude when writing both files, one with an 0xFE and one without, and it looks like the one with exclusively 0xFF's in the progmem array doesn't actually send the page consisting of 0xFFs.  This pointed me to the stk500_is_page_empty function.  When I commented it out and rebuilt, it appeared to work but after further testing tonight, it appears it does not.

Given your comment from earlier today, I am still a little confused as to why the array is "correctly" written when there's a single 0 bit thrown in the middle.

Adam Wolf <adamwolf>
Mon 07 Jun 2010 04:04:26 PM UTC, comment #2: 

I'll do some more testing when I get home tonight.

Adam Wolf <adamwolf>
Mon 07 Jun 2010 04:16:22 AM UTC, comment #1: 

I'm afraid you have to elaborate a little more:

This is standard EPROM behaviour, you can only write a '1'
bit by erasing the memory.  A normal write cycle can only
write a '0' bit, or it does not change the cell if it is
trying to write a '1' bit.  Thus, writing pages that consist
of only 0xFF is essentially a no-op, and can always be
skipped.  Obviously, if the page does have prior contents,
and the file has 0xFF, without erasing it, this will result
in a verification error if verification is enabled.

For the STK500 algorithm, there is no option to page erase
the memory, only a device erase is supported.  With the
current AVR architecture, only bootloaders could perform a
page erase, but as there is no corresponding STK500 command,
AVRDUDE has no means to tell a bootloader that a page erase
is required.

Joerg Wunsch <joerg_wunsch>
Project AdministratorIn charge of this item.
Mon 07 Jun 2010 03:36:06 AM UTC, original submission:  

I noticed that when writing many blocks of 0xff to an atmega328p (with auto-erase off), sometimes a big stretch didn't actually write, and the values were preserved from the last program.

I noticed if I changed even one bit in the area to a 0, the block would actually write.

I tracked it down-- in stk500_paged_write in stk500.c, there's a check for stk500_is_page_empty.  If the whole page consists of 0xFF, the page isn't written.

To me, to do this correctly, you'd have to take into account if the page was actually set to all 0xff.  I tested it by commenting out the entire

    /* Only skip on empty page if programming flash. */
    if (flash) {
      if (stk500_is_page_empty(addr, block_size, m->buf)) {


Making this change fixed my issue.

Is this intended behavior, and just part of what disabling auto-erase means?

I was thinking a more optimal fix might be to skip writing blank pages if you know the page has been erased, but I wasn't quite sure of how you folks would want that implemented.



Attached Files
file #22326:  30061.fix.patch added by wyattn (631B - Took the change above and coded it up to be a little more documented. Tested and works with AVRdude version 5.10.)


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by wyattn (Voted in favor of this item)
  • -email is unavailable- added by wyattn (Updated the item)
  • -email is unavailable- added by adamwolf (Posted a comment)
  • -email is unavailable- added by joerg_wunsch (Posted a comment)
  • -email is unavailable- added by None (Submitted the item)

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 1 encouragement so far.

    Only logged-in users can vote.




    Follow 6 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2011-08-16 joerg_wunsch StatusNeed Info => Invalid
        Assigned toNone => joerg_wunsch
        Open/ClosedOpen => Closed
    2011-01-07 wyattn Carbon-Copy- => Added wyattn
    2010-12-31 wyattn Attached File- => Added 30061.fix.patch, #22326
    2010-06-07 joerg_wunsch StatusNone => Need Info

    Back to the top

    Powered by Savane 3.7