📄 main.c
字号:
/* * 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: main.c,v 1.71 2003/03/12 00:06:45 bdean Exp $ *//* * Code to program an Atmel AVR AT90S device using the parallel port. * * For parallel port connected programmers, the pin definitions can be * changed via a config file. See the config file for instructions on * how to add a programmer definition. * */#include "ac_cfg.h"#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <fcntl.h>#include <limits.h>#include <string.h>#include <time.h>#include <unistd.h>#include <ctype.h>#include <sys/types.h>#include <sys/stat.h>#include "avr.h"#include "config.h"#include "confwin.h"#include "fileio.h"#include "par.h"#include "pindefs.h"#include "ppi.h"#include "term.h"/* Get VERSION from ac_cfg.h */char * version = VERSION;int verbose; /* verbose output */char * progname;char progbuf[PATH_MAX]; /* temporary buffer of spaces the same length as progname; used for lining up multiline messages */PROGRAMMER * pgm = NULL;/* * global options */int do_cycles; /* track erase-rewrite cycles *//* * usage message */void usage(void){ fprintf(stderr, "Usage: %s [options]\n" "Options:\n" " -p <partno> Required. Specify AVR device.\n" " -C <config-file> Specify location of configuration file.\n" " -c <programmer> Specify programmer type.\n" " -P <port> Specify connection port.\n" " -F Override invalid signature check.\n" " -e Perform a chip erase.\n" " -m <memtype> Memory type to operate on.\n" " -i <filename> Write device. Specify an input file.\n" " -o <filename> Read device. Specify an output file.\n" " -f <format> Specify the file format.\n" " -n Do not write anything to the device.\n" " -V Do not verify.\n" " -t Enter terminal mode.\n" " -E <exitspec>[,<exitspec>] List programmer exit specifications.\n" " -v Verbose output. -v -v for more.\n" " -? Display this usage.\n" "\navrdude project: <URL:http://savannah.nongnu.org/projects/avrdude>\n" ,progname);}/* * parse the -E string */int getexitspecs(char *s, int *set, int *clr){ char *cp; while ((cp = strtok(s, ","))) { if (strcmp(cp, "reset") == 0) { *clr |= par_getpinmask(pgm->pinno[PIN_AVR_RESET]); } else if (strcmp(cp, "noreset") == 0) { *set |= par_getpinmask(pgm->pinno[PIN_AVR_RESET]); } else if (strcmp(cp, "vcc") == 0) { if (pgm->pinno[PPI_AVR_VCC]) *set |= pgm->pinno[PPI_AVR_VCC]; } else if (strcmp(cp, "novcc") == 0) { if (pgm->pinno[PPI_AVR_VCC]) *clr |= pgm->pinno[PPI_AVR_VCC]; } else { return -1; } s = 0; /* strtok() should be called with the actual string only once */ } return 0;}int read_config(char * file){ FILE * f; f = fopen(file, "r"); if (f == NULL) { fprintf(stderr, "%s: can't open config file \"%s\": %s\n", progname, file, strerror(errno)); return -1; } lineno = 1; infile = file; yyin = f; yyparse(); fclose(f); return 0;}void programmer_display(char * p){ fprintf(stderr, "%sProgrammer Type : %s\n", p, pgm->type); fprintf(stderr, "%sDescription : %s\n", p, pgm->desc); pgm->display(pgm, p);}void verify_pin_assigned(int pin, char * desc){ if (pgm->pinno[pin] == 0) { fprintf(stderr, "%s: error: no pin has been assigned for %s\n", progname, desc); exit(1); }}PROGRAMMER * locate_programmer(LISTID programmers, char * configid){ LNODEID ln1, ln2; PROGRAMMER * p = NULL; char * id; int found; found = 0; for (ln1=lfirst(programmers); ln1 && !found; ln1=lnext(ln1)) { p = ldata(ln1); for (ln2=lfirst(p->id); ln2 && !found; ln2=lnext(ln2)) { id = ldata(ln2); if (strcasecmp(configid, id) == 0) found = 1; } } if (found) return p; return NULL;}AVRPART * locate_part(LISTID parts, char * partdesc){ LNODEID ln1; AVRPART * p = NULL; int found; found = 0; for (ln1=lfirst(parts); ln1 && !found; ln1=lnext(ln1)) { p = ldata(ln1); if ((strcasecmp(partdesc, p->id) == 0) || (strcasecmp(partdesc, p->desc) == 0)) found = 1; } if (found) return p; return NULL;}void list_parts(FILE * f, char * prefix, LISTID parts){ LNODEID ln1; AVRPART * p; for (ln1=lfirst(parts); ln1; ln1=lnext(ln1)) { p = ldata(ln1); fprintf(f, "%s%-4s = %-15s [%s:%d]\n", prefix, p->id, p->desc, p->config_file, p->lineno); } return;}void list_programmers(FILE * f, char * prefix, LISTID programmers){ LNODEID ln1; PROGRAMMER * p; for (ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) { p = ldata(ln1); fprintf(f, "%s%-8s = %-30s [%s:%d]\n", prefix, (char *)ldata(lfirst(p->id)), p->desc, p->config_file, p->lineno); } return;}/* * main routine */int main(int argc, char * argv []){ int rc; /* general return code checking */ int exitrc; /* exit code for main() */ int i; /* general loop counter */ int ch; /* options flag */ int size; /* size of memory region */ int len; /* length for various strings */ struct avrpart * p; /* which avr part we are programming */ struct avrpart * v; /* 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 */ AVRMEM * sig; /* signature data */ struct stat sb; /* options / operating mode variables */ char * memtype; /* "flash", "eeprom", etc */ int doread; /* 1=reading AVR, 0=writing AVR */ int erase; /* 1=erase chip, 0=don't */ char * outputf; /* output file name */ char * inputf; /* input file name */ int ovsigck; /* 1=override sig check, 0=don't */ char * port; /* device port (/dev/xxx) */ int terminal; /* 1=enter terminal mode, 0=don't */ FILEFMT filefmt; /* FMT_AUTO, FMT_IHEX, FMT_SREC, FMT_RBIN */ int nowrite; /* don't actually write anything to the chip */ int verify; /* perform a verify operation */ int ppisetbits; /* bits to set in ppi data register at exit */ int ppiclrbits; /* bits to clear in ppi data register at exit */ char * exitspecs; /* exit specs string from command line */ char * programmer; /* programmer id */ char * partdesc; /* part id */ char sys_config[PATH_MAX]; /* system wide config file */ char usr_config[PATH_MAX]; /* per-user config file */ int cycles; /* erase-rewrite cycles */ int set_cycles; /* value to set the erase-rewrite cycles to */ char * e; /* for strtol() error checking */ char * homedir; progname = rindex(argv[0],'/'); if (progname) progname++; else progname = argv[0]; default_parallel[0] = 0; default_serial[0] = 0; init_config(); partdesc = NULL; readorwrite = 0; port = default_parallel; outputf = NULL; inputf = NULL; doread = 1; memtype = "flash"; erase = 0; p = NULL; ovsigck = 0; terminal = 0; filefmt = FMT_AUTO; nowrite = 0; verify = 1; /* on by default */ ppisetbits = 0; ppiclrbits = 0; exitspecs = NULL; pgm = NULL; programmer = default_programmer; verbose = 0; do_cycles = 0; set_cycles = -1; #if defined(__CYGWIN__) win_sys_config_set(sys_config); win_usr_config_set(usr_config); #else strcpy(sys_config, CONFIG_DIR); i = strlen(sys_config); if (i && (sys_config[i-1] != '/')) strcat(sys_config, "/"); strcat(sys_config, "avrdude.conf"); usr_config[0] = 0; homedir = getenv("HOME"); if (homedir != NULL) { strcpy(usr_config, homedir); i = strlen(usr_config); if (i && (usr_config[i-1] != '/')) strcat(usr_config, "/"); strcat(usr_config, ".avrduderc"); } #endif len = strlen(progname) + 2; for (i=0; i<len; i++) progbuf[i] = ' '; progbuf[i] = 0; /* * check for no arguments */ if (argc == 1) { usage(); return 0; } /* * process command line arguments */ while ((ch = getopt(argc,argv,"?c:C:eE:f:Fi:m:no:p:P:tvVyY:")) != -1) { switch (ch) { case 'c': /* programmer id */ programmer = optarg; break; case 'C': /* system wide configuration file */ strncpy(sys_config, optarg, PATH_MAX); sys_config[PATH_MAX-1] = 0; break; case 'm': /* select memory type to operate on */ if ((strcasecmp(optarg,"e")==0)||(strcasecmp(optarg,"eeprom")==0)) { memtype = "eeprom"; } else if ((strcasecmp(optarg,"f")==0)|| (strcasecmp(optarg,"flash")==0)) { memtype = "flash"; } else { memtype = optarg; } readorwrite = 1; break; case 'F': /* override invalid signature check */ ovsigck = 1; break; case 'n': nowrite = 1; break; case 'o': /* specify output file */ if (inputf || terminal) { fprintf(stderr,"%s: -i, -o, and -t are incompatible\n\n", progname); return 1; } doread = 1; outputf = optarg; if (filefmt == FMT_AUTO) filefmt = FMT_RBIN; break; case 'p' : /* specify AVR part */ partdesc = optarg; break; case 'e': /* perform a chip erase */ erase = 1; break; case 'E': exitspecs = optarg; break; case 'i': /* specify input file */ if (outputf || terminal) { fprintf(stderr,"%s: -o, -i, and -t are incompatible\n\n", progname); return 1; } doread = 0; inputf = optarg; break; case 'f': /* specify file format */ if (strlen(optarg) != 1) { fprintf(stderr, "%s: invalid file format \"%s\"\n", progname, optarg); usage(); exit(1); } switch (optarg[0]) { case 'a' : filefmt = FMT_AUTO; break; case 'i' : filefmt = FMT_IHEX; break; case 'r' : filefmt = FMT_RBIN; break; case 's' : filefmt = FMT_SREC; break; break; default : fprintf(stderr, "%s: invalid file format \"%s\"\n\n", progname, optarg); usage(); exit(1); } break; case 't': /* enter terminal mode */ if (!((inputf == NULL)||(outputf == NULL))) { fprintf(stderr, "%s: terminal mode is not compatible with -i or -o\n\n", progname); usage(); exit(1); } terminal = 1; break; case 'P': port = optarg; break; case 'v': verbose++; break; case 'V': verify = 0; break; case 'y': do_cycles = 1; break; case 'Y': set_cycles = strtol(optarg, &e, 0); if ((e == optarg) || (*e != 0)) { fprintf(stderr, "%s: invalid cycle count '%s'\n", progname, optarg); exit(1); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -