From b09107e9afe3d351a0a8b17f94239e935dcfcf69 Mon Sep 17 00:00:00 2001 From: "Brian S. Dean" Date: Thu, 22 May 2003 02:33:17 +0000 Subject: [PATCH] Optimize flash memory handling a little bit by ignoring 0xff data that resides above the last non-0xff data value in the address space. Only do this for flash memory since writing a 0xff to flash is a no-op. This has the affect of creating smaller output files when dumping memory contents from flash if the program in flash does not consume the whole memory space. It also results in shorter programming times when avrdude is asked to load a file into flash that has lots of 0xff filled data past the last non-0xff data value. I think this is basically where Alexey was going with his s-record routine, but this should have a similar affect for all the I/O routines. The main difference is that Alexey's also optimized 0xff from the beginning of the address space and was not limited to flash. I think that these optimizations should be limited to the flash since it is currently the only memory that treats 0xff as special. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@331 81a1dc3b-b13d-400b-aceb-764788c761c2 --- avr.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- avr.h | 2 ++ fileio.c | 14 +++++++++++--- 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/avr.c b/avr.c index 0bf18a0f..0ee7285d 100644 --- a/avr.c +++ b/avr.c @@ -352,6 +352,33 @@ int avr_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem, } +/* + * Return the number of "interesting" bytes in a memory buffer, + * "interesting" being defined as up to the last non-0xff data + * value. This is useful for determining where to stop when dealing + * with "flash" memory, since writing 0xff to flash is typically a + * no-op. Always return an even number since flash is word addressed. + */ +int avr_mem_hiaddr(AVRMEM * mem) +{ + int i, n; + + /* return the highest non-0xff address regardless of how much + memory was read */ + for (i=mem->size-1; i>0; i--) { + if (mem->buf[i] != 0xff) { + n = i+1; + if (n & 0x01) + return n+1; + else + return n; + } + } + + return 0; +} + + /* * Read the entirety of the specified memory type into the * corresponding buffer of the avrpart pointed to by 'p'. If size = @@ -381,6 +408,11 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, size = mem->size; } + /* + * start with all 0xff + */ + memset(buf, 0xff, size); + if ((strcmp(mem->desc, "flash")==0) || (strcmp(mem->desc, "eeprom")==0)) { if (pgm->paged_load != NULL) { /* @@ -389,11 +421,19 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, * instead */ if (mem->paged) { - return pgm->paged_load(pgm, p, mem, mem->page_size, size); + rc = pgm->paged_load(pgm, p, mem, mem->page_size, size); + if (rc < 0) + return rc; } else { - return pgm->paged_load(pgm, p, mem, pgm->page_size, size); + rc = pgm->paged_load(pgm, p, mem, pgm->page_size, size); + if (rc < 0) + return rc; } + if (strcasecmp(mem->desc, "flash") == 0) + return avr_mem_hiaddr(mem); + else + return rc; } } @@ -428,7 +468,10 @@ int avr_read(PROGRAMMER * pgm, AVRPART * p, char * memtype, int size, fprintf(stderr, "\n"); } - return i; + if (strcasecmp(mem->desc, "flash") == 0) + return avr_mem_hiaddr(mem); + else + return i; } diff --git a/avr.h b/avr.h index ecd39e64..c1c00ae3 100644 --- a/avr.h +++ b/avr.h @@ -84,4 +84,6 @@ int avr_get_cycle_count(PROGRAMMER * pgm, AVRPART * p, int * cycles); int avr_put_cycle_count(PROGRAMMER * pgm, AVRPART * p, int cycles);; +int avr_mem_hiaddr(AVRMEM * mem); + #endif diff --git a/fileio.c b/fileio.c index 19591747..d40e757b 100644 --- a/fileio.c +++ b/fileio.c @@ -933,9 +933,7 @@ int fileio(int op, char * filename, FILEFMT format, if (fio.op == FIO_READ) { /* 0xff fill unspecified memory */ - for (i=0; i 0) { + if ((op == FIO_READ) && (strcasecmp(mem->desc, "flash") == 0)) { + /* + * if we are reading flash, just mark the size as being the + * highest non-0xff byte + */ + rc = avr_mem_hiaddr(mem); + } + } + return rc; }