avr.c: Update a comment.
fileio.c: Properly handle all the Intel Hex record types that I can find information about. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@52 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
87e20f7e9e
commit
616921e905
|
@ -489,7 +489,6 @@ char * avr_memtstr ( AVRMEM memtype )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int avr_initmem ( struct avrpart * p )
|
int avr_initmem ( struct avrpart * p )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -508,8 +507,11 @@ int avr_initmem ( struct avrpart * p )
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verify up to 'size' bytes of p against v. Return the number of
|
* Verify the memory buffer of p with that of v. The byte range of v,
|
||||||
* bytes verified, or -1 if they don't match.
|
* may be a subset of p. The byte range of p should cover the whole
|
||||||
|
* chip's memory size.
|
||||||
|
*
|
||||||
|
* 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 avr_verify(struct avrpart * p, struct avrpart * v, AVRMEM memtype, int size)
|
||||||
{
|
{
|
||||||
|
|
224
avrdude/fileio.c
224
avrdude/fileio.c
|
@ -29,7 +29,9 @@
|
||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -38,6 +40,17 @@
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define IHEX_MAXDATA 256
|
||||||
|
|
||||||
|
struct ihexrec {
|
||||||
|
unsigned char reclen;
|
||||||
|
unsigned short loadofs;
|
||||||
|
unsigned char rectyp;
|
||||||
|
unsigned char data[IHEX_MAXDATA];
|
||||||
|
unsigned char cksum;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
extern char * progname;
|
extern char * progname;
|
||||||
extern char progbuf[];
|
extern char progbuf[];
|
||||||
|
|
||||||
|
@ -135,101 +148,174 @@ int b2ihex ( unsigned char * inbuf, int bufsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ihex_readrec ( struct ihexrec * ihex, char * rec )
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
char buf[8];
|
||||||
|
int offset, len;
|
||||||
|
char * e;
|
||||||
|
unsigned char cksum;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
len = strlen(rec);
|
||||||
|
offset = 1;
|
||||||
|
cksum = 0;
|
||||||
|
|
||||||
|
/* reclen */
|
||||||
|
if (offset + 2 > len)
|
||||||
|
return -1;
|
||||||
|
for (i=0; i<2; i++)
|
||||||
|
buf[i] = rec[offset++];
|
||||||
|
buf[i] = 0;
|
||||||
|
ihex->reclen = strtoul(buf, &e, 16);
|
||||||
|
if (e == buf || *e != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* load offset */
|
||||||
|
if (offset + 4 > len)
|
||||||
|
return -1;
|
||||||
|
for (i=0; i<4; i++)
|
||||||
|
buf[i] = rec[offset++];
|
||||||
|
buf[i] = 0;
|
||||||
|
ihex->loadofs = strtoul(buf, &e, 16);
|
||||||
|
if (e == buf || *e != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* record type */
|
||||||
|
if (offset + 2 > len)
|
||||||
|
return -1;
|
||||||
|
for (i=0; i<2; i++)
|
||||||
|
buf[i] = rec[offset++];
|
||||||
|
buf[i] = 0;
|
||||||
|
ihex->rectyp = strtoul(buf, &e, 16);
|
||||||
|
if (e == buf || *e != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
cksum = ihex->reclen + ((ihex->loadofs >> 8 ) & 0x0ff) +
|
||||||
|
(ihex->loadofs & 0x0ff) + ihex->rectyp;
|
||||||
|
|
||||||
|
/* data */
|
||||||
|
for (j=0; j<ihex->reclen; j++) {
|
||||||
|
if (offset + 2 > len)
|
||||||
|
return -1;
|
||||||
|
for (i=0; i<2; i++)
|
||||||
|
buf[i] = rec[offset++];
|
||||||
|
buf[i] = 0;
|
||||||
|
ihex->data[j] = strtoul(buf, &e, 16);
|
||||||
|
if (e == buf || *e != 0)
|
||||||
|
return -1;
|
||||||
|
cksum += ihex->data[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cksum */
|
||||||
|
if (offset + 2 > len)
|
||||||
|
return -1;
|
||||||
|
for (i=0; i<2; i++)
|
||||||
|
buf[i] = rec[offset++];
|
||||||
|
buf[i] = 0;
|
||||||
|
ihex->cksum = strtoul(buf, &e, 16);
|
||||||
|
if (e == buf || *e != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
rc = -cksum & 0x000000ff;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int ihex2b ( char * infile, FILE * inf,
|
int ihex2b ( char * infile, FILE * inf,
|
||||||
unsigned char * outbuf, int bufsize )
|
unsigned char * outbuf, int bufsize )
|
||||||
{
|
{
|
||||||
unsigned char buffer [ MAX_LINE_LEN ];
|
char buffer [ MAX_LINE_LEN ];
|
||||||
unsigned char * buf;
|
unsigned char * buf;
|
||||||
unsigned int nextaddr;
|
unsigned int nextaddr, baseaddr;
|
||||||
unsigned int b;
|
int nbytes;
|
||||||
int n, nbytes;
|
int i;
|
||||||
int i, j;
|
|
||||||
unsigned int cksum, rectype;
|
|
||||||
int lineno;
|
int lineno;
|
||||||
|
int len;
|
||||||
|
struct ihexrec ihex;
|
||||||
|
int rc;
|
||||||
|
|
||||||
lineno = 0;
|
lineno = 0;
|
||||||
buf = outbuf;
|
buf = outbuf;
|
||||||
nbytes = 0;
|
nbytes = 0;
|
||||||
|
baseaddr = 0;
|
||||||
|
|
||||||
while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
|
while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) {
|
||||||
lineno++;
|
lineno++;
|
||||||
|
len = strlen(buffer);
|
||||||
|
if (buffer[len-1] == '\n')
|
||||||
|
buffer[--len] = 0;
|
||||||
if (buffer[0] != ':')
|
if (buffer[0] != ':')
|
||||||
continue;
|
continue;
|
||||||
if (sscanf((char *)&buffer[1],
|
rc = ihex_readrec(&ihex, buffer);
|
||||||
"%02x%04x%02x", &n, &nextaddr, &rectype) != 3) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "%s: invalid record at line %d of \"%s\"\n",
|
fprintf(stderr, "%s: invalid record at line %d of \"%s\"\n",
|
||||||
progname, lineno, infile);
|
progname, lineno, infile);
|
||||||
exit(1);
|
return -1;
|
||||||
|
}
|
||||||
|
else if (rc != ihex.cksum) {
|
||||||
|
fprintf(stderr, "%s: ERROR: checksum mismatch at line %d of \"%s\"\n",
|
||||||
|
progname, lineno, infile);
|
||||||
|
fprintf(stderr, "%s: checksum=0x%02x, computed checksum=0x%02x\n",
|
||||||
|
progname, ihex.cksum, rc);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rectype != 0) && (rectype != 1)) {
|
switch (ihex.rectyp) {
|
||||||
|
|
||||||
|
case 0: /* data record */
|
||||||
|
nextaddr = ihex.loadofs + baseaddr;
|
||||||
|
if (nextaddr + ihex.reclen > bufsize) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: ERROR: address 0x%04x out of range at line %d of %s\n",
|
||||||
|
progname, nextaddr+ihex.reclen, lineno, infile);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (i=0; i<ihex.reclen; i++) {
|
||||||
|
buf[nextaddr+i] = ihex.data[i];
|
||||||
|
}
|
||||||
|
nbytes += ihex.reclen;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: /* end of file record */
|
||||||
|
return nbytes;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: /* extended segment address record */
|
||||||
|
baseaddr = (ihex.data[0] << 8 | ihex.data[1]) << 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: /* start segment address record */
|
||||||
|
/* we don't do anything with the start address */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: /* extended linear address record */
|
||||||
|
baseaddr = (ihex.data[0] << 8 | ihex.data[1]) << 16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5: /* start linear address record */
|
||||||
|
/* we don't do anything with the start address */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%s: don't know how to deal with rectype=%d "
|
"%s: don't know how to deal with rectype=%d "
|
||||||
"at line %d of %s\n",
|
"at line %d of %s\n",
|
||||||
progname, rectype, lineno, infile);
|
progname, ihex.rectyp, lineno, infile);
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n && ((nextaddr + n) > bufsize)) {
|
|
||||||
fprintf(stderr, "%s: address 0x%04x out of range at line %d of %s\n",
|
|
||||||
progname, nextaddr+n, lineno, infile);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
break;
|
||||||
|
|
||||||
/* start computing a checksum */
|
|
||||||
cksum = n + ((nextaddr >> 8 ) & 0x0ff) + (nextaddr & 0x0ff) + rectype;
|
|
||||||
|
|
||||||
for (i=0; i<n; i++) {
|
|
||||||
if (sscanf((char *)&buffer[i*2+9], "%02x", &b) != 1) {
|
|
||||||
fprintf(stderr, "%s: can't scan byte number %d at line %d of %s\n",
|
|
||||||
progname, i, lineno, infile);
|
|
||||||
/* display the buffer and the position of the scan error */
|
|
||||||
fprintf(stderr, "%s", buffer);
|
|
||||||
for (j=0; j<9+2*i; j++) {
|
|
||||||
fprintf(stderr, " ");
|
|
||||||
}
|
|
||||||
fprintf(stderr, "^\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[nextaddr + i] = b;
|
|
||||||
cksum += b;
|
|
||||||
}
|
|
||||||
|
|
||||||
nbytes += n;
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------
|
|
||||||
read the cksum value from the record and compare it with our
|
|
||||||
computed value
|
|
||||||
-----------------------------------------------------------------*/
|
|
||||||
if (sscanf((char *)&buffer[n*2+9], "%02x", &b) != 1) {
|
|
||||||
fprintf(stderr, "%s: can't scan byte number %d at line %d of %s\n",
|
|
||||||
progname, i, lineno, infile);
|
|
||||||
/* display the buffer and the position of the scan error */
|
|
||||||
fprintf(stderr, "%s", buffer);
|
|
||||||
for (j=0; j<9+2*i; j++) {
|
|
||||||
fprintf(stderr, " ");
|
|
||||||
}
|
|
||||||
fprintf(stderr, "^\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
cksum = -cksum & 0xff;
|
|
||||||
if (cksum != b) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"%s: WARNING: cksum error for line %d of \"%s\": computed=%02x "
|
|
||||||
"found=%02x\n",
|
|
||||||
progname, lineno, infile, cksum, b);
|
|
||||||
/* return -1; */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rectype == 1) {
|
|
||||||
/* end of record */
|
|
||||||
return nbytes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: WARNING: no end of file record found for Intel Hex "
|
||||||
|
"file \"%s\"\n",
|
||||||
|
progname, infile);
|
||||||
|
|
||||||
return nbytes;
|
return nbytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue