⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileio.c

📁 AVR的USB文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * avrdude - A Downloader/Uploader for AVR device programmers * Copyright (C) 2000, 2001, 2002, 2003  Brian S. Dean <bsd@bsdhome.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//* $Id: fileio.c,v 1.22 2003/02/20 03:53:49 bdean Exp $ */#include "ac_cfg.h"#include <limits.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <ctype.h>#include "avr.h"#include "fileio.h"#define IHEX_MAXDATA 256#define MAX_LINE_LEN 256  /* max line length for ASCII format input files */struct ihexrec {  unsigned char    reclen;  unsigned int     loadofs;  unsigned char    rectyp;  unsigned char    data[IHEX_MAXDATA];  unsigned char    cksum;};extern char * progname;extern char   progbuf[];int b2ihex(unsigned char * inbuf, int bufsize,              int recsize, int startaddr,             char * outfile, FILE * outf);int ihex2b(char * infile, FILE * inf,             unsigned char * outbuf, int bufsize);int b2srec(unsigned char * inbuf, int bufsize,            int recsize, int startaddr,           char * outfile, FILE * outf);int srec2b(char * infile, FILE * inf,             unsigned char * outbuf, int bufsize);int ihex_readrec(struct ihexrec * ihex, char * rec);int srec_readrec(struct ihexrec * srec, char * rec);            int fileio_rbin(struct fioparms * fio,                  char * filename, FILE * f, unsigned char * buf, int size);int fileio_ihex(struct fioparms * fio,                   char * filename, FILE * f, unsigned char * buf, int size);int fileio_srec(struct fioparms * fio,                  char * filename, FILE * f, unsigned char * buf, int size);int fmt_autodetect(char * fname);char * fmtstr(FILEFMT format){  switch (format) {    case FMT_AUTO : return "auto-detect"; break;    case FMT_SREC : return "Motorola S-Record"; break;    case FMT_IHEX : return "Intel Hex"; break;    case FMT_RBIN : return "raw binary"; break;    default       : return "invalid format"; break;  };}int b2ihex(unsigned char * inbuf, int bufsize,            int recsize, int startaddr,           char * outfile, FILE * outf){  unsigned char * buf;  unsigned int nextaddr;  int n, nbytes, n_64k;  int i;  unsigned char cksum;  if (recsize > 255) {    fprintf(stderr, "%s: recsize=%d, must be < 256\n",              progname, recsize);    return -1;  }  n_64k    = 0;  nextaddr = startaddr;  buf      = inbuf;  nbytes   = 0;  while (bufsize) {    n = recsize;    if (n > bufsize)      n = bufsize;    if ((nextaddr + n) > 0x10000)      n = 0x10000 - nextaddr;    if (n) {      cksum = 0;      fprintf(outf, ":%02X%04X00", n, nextaddr);      cksum += n + ((nextaddr >> 8) & 0x0ff) + (nextaddr & 0x0ff);      for (i=0; i<n; i++) {        fprintf(outf, "%02X", buf[i]);        cksum += buf[i];      }      cksum = -cksum;      fprintf(outf, "%02X\n", cksum);            nextaddr += n;      nbytes   += n;    }    if (nextaddr >= 0x10000) {      int lo, hi;      /* output an extended address record */      n_64k++;      lo = n_64k & 0xff;      hi = (n_64k >> 8) & 0xff;      cksum = 0;      fprintf(outf, ":02000004%02X%02X", hi, lo);      cksum += 2 + 0 + 4 + hi + lo;      cksum = -cksum;      fprintf(outf, "%02X\n", cksum);      nextaddr = 0;    }    /* advance to next 'recsize' bytes */    buf += n;    bufsize -= n;  }  /*-----------------------------------------------------------------    add the end of record data line    -----------------------------------------------------------------*/  cksum = 0;  n = 0;  nextaddr = 0;  fprintf(outf, ":%02X%04X01", n, nextaddr);  cksum += n + ((nextaddr >> 8) & 0x0ff) + (nextaddr & 0x0ff) + 1;  cksum = -cksum;  fprintf(outf, "%02X\n", cksum);  return nbytes;}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;}/* * Intel Hex to binary buffer * * Given an open file 'inf' which contains Intel Hex formated data, * parse the file and lay it out within the memory buffer pointed to * by outbuf.  The size of outbuf, 'bufsize' is honored; if data would * fall outsize of the memory buffer outbuf, an error is generated. * * Return the maximum memory address within 'outbuf' that was written. * If an error occurs, return -1. * * */int ihex2b(char * infile, FILE * inf,             unsigned char * outbuf, int bufsize){  char buffer [ MAX_LINE_LEN ];  unsigned char * buf;  unsigned int nextaddr, baseaddr, maxaddr;  int i;  int lineno;  int len;  struct ihexrec ihex;  int rc;  lineno   = 0;  buf      = outbuf;  baseaddr = 0;  maxaddr  = 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;    rc = ihex_readrec(&ihex, buffer);    if (rc < 0) {      fprintf(stderr, "%s: invalid record at line %d of \"%s\"\n",              progname, lineno, infile);      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;    }    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];        }        if (nextaddr+ihex.reclen > maxaddr)          maxaddr = nextaddr+ihex.reclen;        break;      case 1: /* end of file record */        return maxaddr;        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,                 "%s: don't know how to deal with rectype=%d "                 "at line %d of %s\n",                progname, ihex.rectyp, lineno, infile);        return -1;        break;    }  } /* while */  fprintf(stderr,           "%s: WARNING: no end of file record found for Intel Hex "          "file \"%s\"\n",          progname, infile);  return maxaddr;}int b2srec(unsigned char * inbuf, int bufsize,            int recsize, int startaddr,           char * outfile, FILE * outf){  unsigned char * buf;  unsigned int nextaddr, stopaddr;  int n, nbytes, addr_width;  int i;  unsigned char cksum;  unsigned char startf, stopf ,emptyf;  char * tmpl=0;  if (recsize > 255) {    fprintf(stderr, "%s: ERROR: recsize=%d, must be < 256\n",            progname, recsize);    return -1;  }  buf = inbuf;  nextaddr = 0;      stopaddr = 0;  startf = 0;  stopf = 0;  /* search for ranges of 'real' data */       for (i=startaddr; i<bufsize; i++) {    if (buf[i] == 0xff) {      if (startf == 0)         continue;      else if (stopf == 0) {        stopf = 1;        stopaddr = i;      }    }    else {      if (startf == 0) {        startf = 1;        nextaddr = i;        while (nextaddr % recsize != 0)          nextaddr --;      }      else if (stopf == 1) {        stopf = 0;        stopaddr = bufsize;      }    }  }  nbytes = i;   bufsize = stopaddr - nextaddr;  addr_width = 0;  while (bufsize) {    n = recsize;    if (n > bufsize)       n = bufsize;    if (n) {      cksum = 0;      if (nextaddr + n <= 0xffff) {        addr_width = 2;        tmpl="S1%02X%04X";      }      else if (nextaddr + n <= 0xffffff) {        addr_width = 3;        tmpl="S2%02X%06X";      }      else if (nextaddr + n <= 0xffffffff) {        addr_width = 4;        tmpl="S3%02X%08X";      }      else {        fprintf(stderr, "%s: ERROR: address=%d, out of range\n",                progname, nextaddr);        return -1;      }      /* skip the lines filled with 0xff */       emptyf = 1;      for (i=nextaddr; i<nextaddr + n; i++) {        if (buf[i] != 0xff) {          emptyf=0;          break;        }      }      if (emptyf != 1) {	        fprintf(outf, tmpl, n + addr_width + 1, nextaddr);		        cksum += n + addr_width + 1;        for (i=addr_width; i>0; i--)           cksum += (nextaddr >> (i-1) * 8) & 0xff;        for (i=nextaddr; i<nextaddr + n; i++) {          fprintf(outf, "%02X", buf[i]);          cksum += buf[i];        }        cksum = 0xff - cksum;        fprintf(outf, "%02X\n", cksum);      }      nextaddr += n;    }    /* advance to next 'recsize' bytes */    bufsize -= n;  }  /*-----------------------------------------------------------------    add the end of record data line    -----------------------------------------------------------------*/  cksum = 0;  n = 0;  nextaddr = 0;  if (startaddr <= 0xffff) {    addr_width = 2;    tmpl="S9%02X%04X";  }  else if (startaddr <= 0xffffff) {    addr_width = 3;    tmpl="S9%02X%06X";  }  else if (startaddr <= 0xffffffff) {    addr_width = 4;    tmpl="S9%02X%08X";

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -