diff --git a/avr.c b/avr.c index 06cffe4c..b52222ae 100644 --- a/avr.c +++ b/avr.c @@ -186,7 +186,7 @@ unsigned char avr_read_byte ( int fd, struct avrpart * p, fprintf(stderr, "%s: avr_read_byte(); internal error: invalid memtype=%d\n", progname, memtype); - exit(1); + return -1; break; } @@ -201,8 +201,10 @@ unsigned char avr_read_byte ( int fd, struct avrpart * p, /* - * read the entirety of the specified memory type into the - * corresponding buffer of the avrpart pointed to by 'p'. + * Read the entirety of the specified memory type into the + * corresponding buffer of the avrpart pointed to by 'p'. + * + * Return the number of bytes read, or -1 if an error occurs. */ int avr_read ( int fd, struct avrpart * p, AVRMEM memtype ) { @@ -231,7 +233,7 @@ int avr_read ( int fd, struct avrpart * p, AVRMEM memtype ) default: fprintf(stderr, "%s: avr_read(); internal error: invalid memtype=%d\n", progname, memtype); - exit(1); + return -1; break; } @@ -259,7 +261,7 @@ int avr_read ( int fd, struct avrpart * p, AVRMEM memtype ) fprintf ( stderr, "\n" ); - return 0; + return bi; } @@ -298,7 +300,7 @@ int avr_write_byte ( int fd, struct avrpart * p, AVRMEM memtype, fprintf(stderr, "%s: avr_write_byte(); internal error: invalid memtype=%d\n", progname, memtype); - exit(1); + return -1; break; } @@ -345,11 +347,13 @@ int avr_write_byte ( int fd, struct avrpart * p, AVRMEM memtype, /* * Write the whole memory region (flash or eeprom, specified by * 'memtype') from the corresponding buffer of the avrpart pointed to - * by 'p'. All of the memory is updated, however, input data of 0xff - * is not actually written out, because empty flash and eeprom - * contains 0xff, and you can't actually write 1's, only 0's. + * by 'p'. Write up to 'size' bytes from the buffer. Data is only + * written if the new data value is different from the existing data + * value. Data beyond 'size' bytes is not affected. + * + * Return the number of bytes written, or -1 if an error occurs. */ -int avr_write ( int fd, struct avrpart * p, AVRMEM memtype ) +int avr_write ( int fd, struct avrpart * p, AVRMEM memtype, int size ) { unsigned char data, memt; unsigned short start, end, i, bi; @@ -357,6 +361,7 @@ int avr_write ( int fd, struct avrpart * p, AVRMEM memtype ) int rc; unsigned char * buf; int bufsize; + int wsize; start = 0; @@ -364,22 +369,39 @@ int avr_write ( int fd, struct avrpart * p, AVRMEM memtype ) case AVR_FLASH : buf = p->flash; bufsize = p->flash_size; + wsize = bufsize; + if (size < wsize) { + bufsize = size; + } end = start+bufsize/2; memt = AVR_FLASH_LO; break; case AVR_EEPROM : buf = p->eeprom; bufsize = p->eeprom_size; + wsize = bufsize; + if (size < wsize) { + bufsize = size; + } end = start+bufsize; memt = memtype; break; default: fprintf(stderr, "%s: avr_write(); internal error: invalid memtype=%d\n", progname, memtype); - exit(1); + return -1; break; } + /* were we asked to write out more data than the device can hold? */ + if (wsize < size) { + fprintf(stderr, + "%s: WARNING: %d bytes requested, but memory region is only %d bytes\n" + "%sOnly %d bytes will actually be written\n", + progname, size, bufsize, + progbuf, bufsize); + } + bi = 0; for (i=start; iflash == NULL) { fprintf(stderr, "%s: can't alloc buffer for flash size of %d bytes\n", progname, p->flash_size); - exit(1); + return -1; } p->eeprom = (unsigned char *) malloc(p->eeprom_size); if (p->eeprom == NULL) { fprintf(stderr, "%s: can't alloc buffer for eeprom size of %d bytes\n", progname, p->eeprom_size); - exit(1); + return -1; } return 0; } -int avr_verify(struct avrpart * p, struct avrpart * v, AVRMEM memtype) +/* + * Verify up to 'size' bytes of p against v. Return the number of + * bytes verified, or -1 if they don't match. + */ +int avr_verify(struct avrpart * p, struct avrpart * v, AVRMEM memtype, int size) { int i; unsigned char * buf1, * buf2; - int size; + int vsize; switch (memtype) { case AVR_FLASH: buf1 = p->flash; buf2 = v->flash; - size = p->flash_size; + vsize = p->flash_size; break; case AVR_EEPROM: buf1 = p->eeprom; buf2 = v->eeprom; - size = p->eeprom_size; + vsize = p->eeprom_size; break; default: @@ -591,6 +617,17 @@ int avr_verify(struct avrpart * p, struct avrpart * v, AVRMEM memtype) return -1; } + if (vsize < size) { + fprintf(stderr, + "%s: WARNING: requested verification for %d bytes\n" + "%s%s memory region only contains %d bytes\n" + "%sOnly %d bytes will be verified.\n", + progname, size, + progbuf, avr_memtstr(memtype), vsize, + progbuf, vsize); + size = vsize; + } + for (i=0; i bufsize) @@ -111,6 +112,7 @@ int b2ihex ( unsigned char * inbuf, int bufsize, fprintf ( outf, "%02X\n", cksum ); nextaddr += n; + nbytes += n; } /* advance to next 'recsize' bytes */ @@ -129,7 +131,7 @@ int b2ihex ( unsigned char * inbuf, int bufsize, cksum = -cksum; fprintf ( outf, "%02X\n", cksum ); - return 0; + return nbytes; } @@ -138,16 +140,16 @@ int ihex2b ( char * infile, FILE * inf, { unsigned char buffer [ MAX_LINE_LEN ]; unsigned char * buf; - unsigned int prevaddr, nextaddr; + unsigned int nextaddr; unsigned int b; - int n; + int n, nbytes; int i, j; unsigned int cksum, rectype; int lineno; lineno = 0; - prevaddr = 0; buf = outbuf; + nbytes = 0; while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) { lineno++; @@ -194,6 +196,8 @@ int ihex2b ( char * infile, FILE * inf, cksum += b; } + nbytes += n; + /*----------------------------------------------------------------- read the cksum value from the record and compare it with our computed value @@ -221,13 +225,12 @@ int ihex2b ( char * infile, FILE * inf, if (rectype == 1) { /* end of record */ - return 0; + return nbytes; } - prevaddr = nextaddr + n; - } + } /* while */ - return 0; + return nbytes; } @@ -250,7 +253,7 @@ int fileio_rbin ( struct fioparms * fio, return -1; } - if (rc < size) { + if (rc < 0 || (fio->op == FIO_WRITE && rc < size)) { fprintf(stderr, "%s: %s error %s %s: %s; %s %d of the expected %d bytes\n", progname, fio->iodesc, fio->dir, filename, strerror(errno), @@ -270,14 +273,14 @@ int fileio_ihex ( struct fioparms * fio, switch (fio->op) { case FIO_WRITE: rc = b2ihex(buf, size, 32, 0, filename, f); - if (rc) { + if (rc < 0) { return -1; } break; case FIO_READ: rc = ihex2b(filename, f, buf, size); - if (rc) + if (rc < 0) return -1; break; @@ -288,7 +291,7 @@ int fileio_ihex ( struct fioparms * fio, break; } - return 0; + return rc; } @@ -397,13 +400,12 @@ int fmt_autodetect ( char * fname ) int fileio ( int op, char * filename, FILEFMT format, - struct avrpart * p, AVRMEM memtype ) + struct avrpart * p, AVRMEM memtype, int size ) { int rc; FILE * f; char * fname; unsigned char * buf; - int size; struct fioparms fio; int i; @@ -434,12 +436,14 @@ int fileio ( int op, char * filename, FILEFMT format, switch (memtype) { case AVR_EEPROM: buf = p->eeprom; - size = p->eeprom_size; + if (fio.op == FIO_READ) + size = p->eeprom_size; break; case AVR_FLASH: buf = p->flash; - size = p->flash_size; + if (fio.op == FIO_READ) + size = p->flash_size; break; default: diff --git a/fileio.h b/fileio.h index 4cf5ef2c..87477bc0 100644 --- a/fileio.h +++ b/fileio.h @@ -59,6 +59,6 @@ char * fmtstr ( FILEFMT format ); int fileio_setparms ( int op, struct fioparms * fp ); int fileio ( int op, char * filename, FILEFMT format, - struct avrpart * p, AVRMEM memtype ); + struct avrpart * p, AVRMEM memtype, int size ); #endif diff --git a/main.c b/main.c index f3fb7d96..7ad73eff 100644 --- a/main.c +++ b/main.c @@ -83,7 +83,7 @@ void usage ( void ) { fprintf(stderr, "\nUsage: %s -p partno [-e] [-E exitspec[,exitspec]] [-f format] [-F]\n" - " %s[-i filename] [-m memtype] [-o filename] [-P parallel] [-t]\n\n", + " %s[-i filename] [-m memtype] [-o filename] [-P parallel] [-t]\n\n", progname, progbuf); #if 0 @@ -143,6 +143,7 @@ int main ( int argc, char * argv [] ) struct avrpart * v, ap2; /* used for verify */ int readorwrite; /* true if a chip read/write op was selected */ int ppidata; /* cached value of the ppi data register */ + int vsize=-1; /* number of bytes to verify */ /* options / operating mode variables */ int memtype; /* AVR_FLASH or AVR_EEPROM */ @@ -463,16 +464,17 @@ int main ( int argc, char * argv [] ) fprintf(stderr, "%s: reading %s memory:\n", progname, avr_memtstr(memtype)); rc = avr_read ( fd, p, memtype ); - if (rc) { + if (rc < 0) { fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n", progname, avr_memtstr(memtype), rc); exitrc = 1; goto main_exit; } + size = rc; fprintf(stderr, "%s: writing output file \"%s\"\n", progname, outputf); - rc = fileio(FIO_WRITE, outputf, filefmt, p, memtype); + rc = fileio(FIO_WRITE, outputf, filefmt, p, memtype, size); if (rc < 0) { fprintf(stderr, "%s: terminating\n", progname); exitrc = 1; @@ -487,7 +489,7 @@ int main ( int argc, char * argv [] ) */ fprintf(stderr, "%s: reading input file \"%s\"\n", progname, inputf); - rc = fileio(FIO_READ, inputf, filefmt, p, memtype ); + rc = fileio(FIO_READ, inputf, filefmt, p, memtype, -1); if (rc < 0) { fprintf(stderr, "%s: terminating\n", progname); exitrc = 1; @@ -502,23 +504,28 @@ int main ( int argc, char * argv [] ) progname, avr_memtstr(memtype)); if (!nowrite) { - rc = avr_write ( fd, p, memtype ); + rc = avr_write ( fd, p, memtype, size ); } else { /* * test mode, don't actually write to the chip, output the buffer * to stdout in intel hex instead */ - rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, memtype); + rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, memtype, size); } - if (rc) { + if (rc < 0) { fprintf ( stderr, "%s: failed to write flash memory, rc=%d\n", progname, rc ); exitrc = 1; goto main_exit; } + vsize = rc; + + fprintf(stderr, "%s: %d bytes of %s written\n", progname, + vsize, avr_memtstr(memtype)); + } if (!doread && verify) { @@ -531,23 +538,24 @@ int main ( int argc, char * argv [] ) fprintf(stderr, "%s: reading on-chip %s data:\n", progname, avr_memtstr(memtype)); rc = avr_read ( fd, v, memtype ); - if (rc) { + if (rc < 0) { fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n", progname, avr_memtstr(memtype), rc); exitrc = 1; goto main_exit; } - - fprintf(stderr, "%s: verifying\n", progname); - rc = avr_verify(p, v, memtype); - if (rc) { + + fprintf(stderr, "%s: verifying ...\n", progname); + rc = avr_verify(p, v, memtype, vsize); + if (rc < 0) { fprintf(stderr, "%s: verification error; content mismatch\n", progname); exitrc = 1; goto main_exit; } - fprintf(stderr, "%s: data verified\n", progname); + fprintf(stderr, "%s: %d bytes of %s verified\n", + progname, rc, avr_memtstr(memtype)); }