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
This commit is contained in:
parent
3d43a61bcc
commit
c06319e33c
77
avr.c
77
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; i<end; i++) {
|
||||
|
@ -392,7 +414,7 @@ int avr_write ( int fd, struct avrpart * p, AVRMEM memtype )
|
|||
fprintf(stderr, " ***failed; ");
|
||||
nl = 1;
|
||||
}
|
||||
|
||||
|
||||
if (memtype == AVR_FLASH) {
|
||||
/* high byte of flash */
|
||||
data = buf[bi++];
|
||||
|
@ -409,7 +431,7 @@ int avr_write ( int fd, struct avrpart * p, AVRMEM memtype )
|
|||
|
||||
fprintf ( stderr, "\n" );
|
||||
|
||||
return 0;
|
||||
return bi;
|
||||
}
|
||||
|
||||
|
||||
|
@ -552,37 +574,41 @@ int avr_initmem ( struct avrpart * p )
|
|||
if (p->flash == 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<size; i++) {
|
||||
if (buf1[i] != buf2[i]) {
|
||||
fprintf(stderr,
|
||||
|
@ -602,7 +639,7 @@ int avr_verify(struct avrpart * p, struct avrpart * v, AVRMEM memtype)
|
|||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
|
|
5
avr.h
5
avr.h
|
@ -90,7 +90,7 @@ int avr_read ( int fd, struct avrpart * p, AVRMEM memtype );
|
|||
int avr_write_byte ( int fd, struct avrpart * p, AVRMEM memtype,
|
||||
unsigned short addr, unsigned char data );
|
||||
|
||||
int avr_write ( int fd, struct avrpart * p, AVRMEM memtype );
|
||||
int avr_write ( int fd, struct avrpart * p, AVRMEM memtype, int size );
|
||||
|
||||
int avr_program_enable ( int fd );
|
||||
|
||||
|
@ -108,7 +108,8 @@ char * avr_memtstr ( AVRMEM memtype );
|
|||
|
||||
int avr_initmem ( struct avrpart * p );
|
||||
|
||||
int avr_verify(struct avrpart * p, struct avrpart * v, AVRMEM memtype);
|
||||
int avr_verify(struct avrpart * p, struct avrpart * v, AVRMEM memtype,
|
||||
int size);
|
||||
|
||||
void avr_display ( FILE * f, struct avrpart * p, char * prefix );
|
||||
|
||||
|
|
40
fileio.c
40
fileio.c
|
@ -81,7 +81,7 @@ int b2ihex ( unsigned char * inbuf, int bufsize,
|
|||
{
|
||||
unsigned char * buf;
|
||||
unsigned int nextaddr;
|
||||
int n;
|
||||
int n, nbytes;
|
||||
int i;
|
||||
unsigned char cksum;
|
||||
|
||||
|
@ -92,8 +92,9 @@ int b2ihex ( unsigned char * inbuf, int bufsize,
|
|||
}
|
||||
|
||||
nextaddr = startaddr;
|
||||
buf = inbuf;
|
||||
nbytes = 0;
|
||||
|
||||
buf = inbuf;
|
||||
while (bufsize) {
|
||||
n = recsize;
|
||||
if (n > 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:
|
||||
|
|
2
fileio.h
2
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
|
||||
|
|
34
main.c
34
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));
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue