From c06319e33cee8660f768ecdc3656eb70d6a166f2 Mon Sep 17 00:00:00 2001 From: "Brian S. Dean" Date: Sat, 20 Jan 2001 16:34:28 +0000 Subject: [PATCH] Return error codes instead of exiting, thus making sure that we exit only via main() so that the exitspecs are properly applied. When reading input data from a file, remember how many bytes were read and write and verify only that many bytes. Don't complain when an input file size is smaller than the memory size we are programming. This is normal. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@44 81a1dc3b-b13d-400b-aceb-764788c761c2 --- avr.c | 77 +++++++++++++++++++++++++++++++++++++++++--------------- avr.h | 5 ++-- fileio.c | 40 ++++++++++++++++------------- fileio.h | 2 +- main.c | 34 +++++++++++++++---------- 5 files changed, 104 insertions(+), 54 deletions(-) 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)); }