From 0775e02d27f2c8eaf0ac08d545cb9f3fc913938b Mon Sep 17 00:00:00 2001 From: "Brian S. Dean" Date: Fri, 26 Jan 2001 17:22:40 +0000 Subject: [PATCH] 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/avrdude@52 81a1dc3b-b13d-400b-aceb-764788c761c2 --- avr.c | 8 +- fileio.c | 222 ++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 159 insertions(+), 71 deletions(-) diff --git a/avr.c b/avr.c index 5413a91d..69decd01 100644 --- a/avr.c +++ b/avr.c @@ -489,7 +489,6 @@ char * avr_memtstr ( AVRMEM memtype ) } - int avr_initmem ( struct avrpart * p ) { 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 - * bytes verified, or -1 if they don't match. + * Verify the memory buffer of p with that of v. The byte range of v, + * 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) { diff --git a/fileio.c b/fileio.c index 44642a53..041740d2 100644 --- a/fileio.c +++ b/fileio.c @@ -29,7 +29,9 @@ /* $Id$ */ +#include #include +#include #include #include #include @@ -38,6 +40,17 @@ #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 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; jreclen; 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, unsigned char * outbuf, int bufsize ) { - unsigned char buffer [ MAX_LINE_LEN ]; + char buffer [ MAX_LINE_LEN ]; unsigned char * buf; - unsigned int nextaddr; - unsigned int b; - int n, nbytes; - int i, j; - unsigned int cksum, rectype; + unsigned int nextaddr, baseaddr; + int nbytes; + int i; int lineno; + int len; + struct ihexrec ihex; + int rc; lineno = 0; buf = outbuf; nbytes = 0; + baseaddr = 0; while (fgets((char *)buffer,MAX_LINE_LEN,inf)!=NULL) { lineno++; + len = strlen(buffer); + if (buffer[len-1] == '\n') + buffer[--len] = 0; if (buffer[0] != ':') continue; - if (sscanf((char *)&buffer[1], - "%02x%04x%02x", &n, &nextaddr, &rectype) != 3) { + rc = ihex_readrec(&ihex, buffer); + if (rc < 0) { fprintf(stderr, "%s: invalid record at line %d of \"%s\"\n", progname, lineno, infile); - exit(1); + return -1; } - - if ((rectype != 0) && (rectype != 1)) { - fprintf(stderr, - "%s: don't know how to deal with rectype=%d " - "at line %d of %s\n", - progname, rectype, 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); + 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; } - /* start computing a checksum */ - cksum = n + ((nextaddr >> 8 ) & 0x0ff) + (nextaddr & 0x0ff) + rectype; + switch (ihex.rectyp) { - for (i=0; i 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; } - fprintf(stderr, "^\n"); + for (i=0; i