diff --git a/src/main.c b/src/main.c index f6ddcf26..4ec7609c 100644 --- a/src/main.c +++ b/src/main.c @@ -18,16 +18,15 @@ */ /* - * Code to program an Atmel AVR device through one of the supported - * programmers. + * Program an Atmel AVR device through one of the supported programmers * - * 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. + * 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. * */ -/* For AVRDUDE_FULL_VERSION and possibly others */ +// For AVRDUDE_FULL_VERSION and possibly others #include #include @@ -44,6 +43,7 @@ #include #include #include + #if !defined(WIN32) #include #endif @@ -53,152 +53,162 @@ #include "config.h" #include "developer_opts.h" -char * progname = "avrdude"; +char *progname = "avrdude"; static const char *avrdude_message_type(int msglvl) { - switch(msglvl) { - case MSG_EXT_ERROR: return "OS error"; - case MSG_ERROR: return "error"; - case MSG_WARNING: return "warning"; - case MSG_INFO: return "info"; - case MSG_NOTICE: return "notice"; - case MSG_NOTICE2: return "notice2"; - case MSG_DEBUG: return "debug"; - case MSG_TRACE: return "trace"; - case MSG_TRACE2: return "trace2"; - default: return "unknown msglvl"; + switch (msglvl) { + case MSG_EXT_ERROR: + return "OS error"; + case MSG_ERROR: + return "error"; + case MSG_WARNING: + return "warning"; + case MSG_INFO: + return "info"; + case MSG_NOTICE: + return "notice"; + case MSG_NOTICE2: + return "notice2"; + case MSG_DEBUG: + return "debug"; + case MSG_TRACE: + return "trace"; + case MSG_TRACE2: + return "trace2"; + default: + return "unknown msglvl"; } } - /* * Core messaging routine for msg_xyz(), [pli]msg_xyz() and term_out() * See #define lines in avrdude.h of how it is normally called * * Named that way as there used to be a now gone different avrdude_message() */ -int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, int msgmode, int msglvl, const char *format, ...) { - int rc = 0; - va_list ap; +int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, + int msgmode, int msglvl, const char *format, ...) { - static struct { // Memorise whether last print ended at beginning of line - FILE *fp; - int bol; // Are we at the beginning of a line for this fp stream? - } bols[5+1]; // Cater for up to 5 different FILE pointers plus one catch-all + int rc = 0; + va_list ap; - size_t bi = 0; // bi is index to bols[] array - for(bi=0; bi < sizeof bols/sizeof*bols -1; bi++) { // Note the -1, so bi is valid after loop - if(!bols[bi].fp) { // First free space - bols[bi].fp = fp; // Insert fp in first free space - bols[bi].bol = 1; // Assume beginning of line on first use + static struct { // Memorise whether last print ended at beginning of line + FILE *fp; + int bol; // Are we at the beginning of a line for this fp stream? + } bols[5 + 1]; // Cater for up to 5 different FILE pointers plus one catch-all + + size_t bi = 0; // bi is index to bols[] array + + for(bi = 0; bi < sizeof bols/sizeof *bols - 1; bi++) { // Note the -1, so bi is valid after loop + if(!bols[bi].fp) { // First free space + bols[bi].fp = fp; // Insert fp in first free space + bols[bi].bol = 1; // Assume beginning of line on first use + } + if(bols[bi].fp == fp) + break; + } + + if(msglvl <= MSG_ERROR) // Serious error? Free progress bars (if any) + report_progress(1, -1, NULL); + + if(msgmode & MSG2_FLUSH) { + fflush(stdout); + fflush(stderr); + } + // Reduce effective verbosity level by number of -q above one when printing to stderr + if((quell_progress < 2 || fp != stderr? verbose: verbose + 1 - quell_progress) >= msglvl) { + if(msgmode & MSG2_LEFT_MARGIN && !bols[bi].bol) { + fprintf(fp, "\n"); + bols[bi].bol = 1; + } + // Keep vertical tab at start of format string as conditional new line + if(*format == '\v') { + format++; + if(!bols[bi].bol) { + fprintf(fp, "\n"); + bols[bi].bol = 1; } - if(bols[bi].fp == fp) - break; } - if(msglvl <= MSG_ERROR) // Serious error? Free progress bars (if any) - report_progress(1, -1, NULL); + if(msgmode & (MSG2_PROGNAME | MSG2_TYPE)) { + if(msgmode & MSG2_PROGNAME) { + fprintf(fp, "%s", progname); + bols[bi].bol = 0; + } + if(msgmode & MSG2_TYPE) { + const char *mt = avrdude_message_type(msglvl); - if(msgmode & MSG2_FLUSH) { - fflush(stdout); - fflush(stderr); - } + if(bols[bi].bol) + fprintf(fp, "%c%s", msgmode & (MSG2_UCFIRST)? toupper(*mt & 0xff): *mt, mt + 1); + else + fprintf(fp, " %s", mt); + bols[bi].bol = 0; + } + if(verbose >= MSG_NOTICE2) { + const char *bfname = strrchr(file, '/'); // Only print basename - // Reduce effective verbosity level by number of -q above one when printing to stderr - if ((quell_progress < 2 || fp != stderr? verbose: verbose+1-quell_progress) >= msglvl) { - if(msgmode & MSG2_LEFT_MARGIN && !bols[bi].bol) { - fprintf(fp, "\n"); - bols[bi].bol = 1; - } - - // Keep vertical tab at start of format string as conditional new line - if(*format == '\v') { - format++; - if(!bols[bi].bol) { - fprintf(fp, "\n"); - bols[bi].bol = 1; - } - } - - if(msgmode & (MSG2_PROGNAME | MSG2_TYPE)) { - if(msgmode & MSG2_PROGNAME) { - fprintf(fp, "%s", progname); - bols[bi].bol = 0; - } - if(msgmode & MSG2_TYPE) { - const char *mt = avrdude_message_type(msglvl); - if(bols[bi].bol) - fprintf(fp, "%c%s", msgmode & (MSG2_UCFIRST)? toupper(*mt & 0xff): *mt, mt+1); - else - fprintf(fp, " %s", mt); - bols[bi].bol = 0; - } - if(verbose >= MSG_NOTICE2) { - const char *bfname = strrchr(file, '/'); // Only print basename #if defined (WIN32) - if(!bfname) - bfname = strrchr(file, '\\'); + if(!bfname) + bfname = strrchr(file, '\\'); #endif - bfname = bfname? bfname+1: file; - if(msgmode & MSG2_FUNCTION) - fprintf(fp, " %s()", func); - if(msgmode & MSG2_FILELINE) - fprintf(fp, " %s %d", bfname, lno); - } - fprintf(fp, ": "); - } else if(msgmode & MSG2_INDENT1) { - fprintf(fp, "%*s", (int) strlen(progname)+1, ""); - bols[bi].bol = 0; - } else if(msgmode & MSG2_INDENT2) { - fprintf(fp, "%*s", (int) strlen(progname)+2, ""); - bols[bi].bol = 0; - } - // Figure out whether this print will leave us at beginning of line + bfname = bfname? bfname + 1: file; + if(msgmode & MSG2_FUNCTION) + fprintf(fp, " %s()", func); + if(msgmode & MSG2_FILELINE) + fprintf(fp, " %s %d", bfname, lno); + } + fprintf(fp, ": "); + } else if(msgmode & MSG2_INDENT1) { + fprintf(fp, "%*s", (int) strlen(progname) + 1, ""); + bols[bi].bol = 0; + } else if(msgmode & MSG2_INDENT2) { + fprintf(fp, "%*s", (int) strlen(progname) + 2, ""); + bols[bi].bol = 0; + } + // Figure out whether this print will leave us at beginning of line - // Determine required size first - va_start(ap, format); - rc = vsnprintf(NULL, 0, format, ap); - va_end(ap); + // Determine required size first + va_start(ap, format); + rc = vsnprintf(NULL, 0, format, ap); + va_end(ap); - if(rc < 0) // Some errror? - return 0; + if(rc < 0) // Some errror? + return 0; - rc++; // Accommodate terminating nul - char *p = mmt_malloc(rc); - va_start(ap, format); - rc = vsnprintf(p, rc, format, ap); - va_end(ap); + rc++; // Accommodate terminating nul + char *p = mmt_malloc(rc); - if(rc < 0) { - mmt_free(p); - return 0; - } + va_start(ap, format); + rc = vsnprintf(p, rc, format, ap); + va_end(ap); - if(*p) { // Finally: print! - if(bols[bi].bol && (msgmode & MSG2_UCFIRST)) - fprintf(fp, "%c%s", toupper(*p & 0xff), p+1); - else - fprintf(fp, "%s", p); - bols[bi].bol = p[strlen(p)-1] == '\n'; - } - mmt_free(p); + if(rc < 0) { + mmt_free(p); + return 0; } - if(msgmode & MSG2_FLUSH) - fflush(fp); + if(*p) { // Finally: print! + if(bols[bi].bol && (msgmode & MSG2_UCFIRST)) + fprintf(fp, "%c%s", toupper(*p & 0xff), p + 1); + else + fprintf(fp, "%s", p); + bols[bi].bol = p[strlen(p) - 1] == '\n'; + } + mmt_free(p); + } - return rc; + if(msgmode & MSG2_FLUSH) + fflush(fp); + + return rc; } - -struct list_walk_cookie -{ - FILE *f; - const char *prefix; +struct list_walk_cookie { + FILE *f; + const char *prefix; }; - libavrdude_context *cx; // Context pointer, eventually the only global variable static LISTID updates = NULL; @@ -207,32 +217,25 @@ static LISTID extended_params = NULL; static LISTID additional_config_files = NULL; -static PROGRAMMER * pgm; +static PROGRAMMER *pgm; -/* - * global options - */ +// Global options int verbose; // Verbose output int quell_progress; // Quell progress report and un-verbose output int ovsigck; // 1 = override sig check, 0 = don't const char *partdesc; // Part -p string const char *pgmid; // Programmer -c string -static char usr_config[PATH_MAX]; // Per-user config file +static char usr_config[PATH_MAX]; // Per-user config file -/* - * usage message - */ -static void usage(void) -{ +// Usage message +static void usage(void) { char *home = getenv("HOME"); size_t l = home? strlen(home): 0; char *cfg = home && str_casestarts(usr_config, home)? - mmt_sprintf("~/%s", usr_config+l+(usr_config[l]=='/')): - mmt_sprintf("%s", usr_config); + mmt_sprintf("~/%s", usr_config + l + (usr_config[l] == '/')): mmt_sprintf("%s", usr_config); - msg_error( - "Usage: %s [options]\n" + msg_error("Usage: %s [options]\n" "Options:\n" " -p Specify AVR device; -p ? lists all known parts\n" " -p / Run developer options for matched AVR devices,\n" @@ -273,10 +276,11 @@ static void usage(void) mmt_free(cfg); } - // Potentially shorten copy of prog description if it's the suggested mode static void pmshorten(char *desc, const char *modes) { - struct { const char *end, *mode; } pairs[] = { + struct { + const char *end, *mode; + } pairs[] = { {" in parallel programming mode", "HVPP"}, {" in PP mode", "HVPP"}, {" in high-voltage serial programming mode", "HVSP"}, @@ -294,10 +298,11 @@ static void pmshorten(char *desc, const char *modes) { }; size_t len = strlen(desc); - for(size_t i=0; i elen && str_caseeq(desc+len-elen, pairs[i].end) && str_eq(modes, pairs[i].mode)) { - desc[len-elen] = 0; + + if(len > elen && str_caseeq(desc + len - elen, pairs[i].end) && str_eq(modes, pairs[i].mode)) { + desc[len - elen] = 0; break; } } @@ -307,7 +312,7 @@ static void list_programmers(FILE *f, const char *prefix, LISTID programmers, in LNODEID ln1; LNODEID ln2; PROGRAMMER *pgm; - int maxlen=0, len; + int maxlen = 0, len; sort_programmers(programmers); @@ -316,9 +321,10 @@ static void list_programmers(FILE *f, const char *prefix, LISTID programmers, in pgm = ldata(ln1); if(!is_programmer(pgm)) continue; - for(ln2=lfirst(pgm->id); ln2; ln2=lnext(ln2)) + for(ln2 = lfirst(pgm->id); ln2; ln2 = lnext(ln2)) if(!pm || !pgm->prog_modes || (pm & pgm->prog_modes)) { const char *id = ldata(ln2); + if(*id == 0 || *id == '.') continue; if((len = strlen(id)) > maxlen) @@ -330,7 +336,7 @@ static void list_programmers(FILE *f, const char *prefix, LISTID programmers, in pgm = ldata(ln1); if(!is_programmer(pgm)) continue; - for(ln2=lfirst(pgm->id); ln2; ln2=lnext(ln2)) { + for(ln2 = lfirst(pgm->id); ln2; ln2 = lnext(ln2)) { // List programmer if pm or prog_modes uninitialised or if they are compatible otherwise if(!pm || !pgm->prog_modes || (pm & pgm->prog_modes)) { const char *id = ldata(ln2); @@ -347,7 +353,7 @@ static void list_programmers(FILE *f, const char *prefix, LISTID programmers, in else fprintf(f, "%s%-*s = %-s", prefix, maxlen, id, desc); if(pm != ~0) - fprintf(f, " via %s", modes); + fprintf(f, " via %s", modes); fprintf(f, "\n"); mmt_free(desc); @@ -356,28 +362,25 @@ static void list_programmers(FILE *f, const char *prefix, LISTID programmers, in } } -static void list_programmer_types_callback(const char *name, const char *desc, - void *cookie) -{ - struct list_walk_cookie *c = (struct list_walk_cookie *)cookie; - fprintf(c->f, "%s%-16s = %-s\n", c->prefix, name, desc); +static void list_programmer_types_callback(const char *name, const char *desc, void *cookie) { + struct list_walk_cookie *c = (struct list_walk_cookie *) cookie; + + fprintf(c->f, "%s%-16s = %-s\n", c->prefix, name, desc); } -static void list_programmer_types(FILE * f, const char *prefix) -{ - struct list_walk_cookie c; +static void list_programmer_types(FILE *f, const char *prefix) { + struct list_walk_cookie c; - c.f = f; - c.prefix = prefix; + c.f = f; + c.prefix = prefix; - walk_programmer_types(list_programmer_types_callback, &c); + walk_programmer_types(list_programmer_types_callback, &c); } - static void list_parts(FILE *f, const char *prefix, LISTID avrparts, int pm) { LNODEID ln1; AVRPART *p; - int maxlen=0, len; + int maxlen = 0, len; sort_avrparts(avrparts); @@ -386,7 +389,7 @@ static void list_parts(FILE *f, const char *prefix, LISTID avrparts, int pm) { p = ldata(ln1); // List part if pm or prog_modes uninitialised or if they are compatible otherwise if(!pm || !p->prog_modes || (pm & p->prog_modes)) { - if(verbose < MSG_NOTICE2 && p->id[0] == '.') // hide ids starting with '.' + if(verbose < MSG_NOTICE2 && p->id[0] == '.') // Hide ids starting with '.' continue; if((len = strlen(p->id)) > maxlen) maxlen = len; @@ -397,7 +400,7 @@ static void list_parts(FILE *f, const char *prefix, LISTID avrparts, int pm) { p = ldata(ln1); // List part if pm or prog_modes uninitialised or if they are compatible otherwise if(!pm || !p->prog_modes || (pm & p->prog_modes)) { - if(verbose < MSG_NOTICE2 && p->id[0] == '.') // hide ids starting with '.' + if(verbose < MSG_NOTICE2 && p->id[0] == '.') // Hide ids starting with '.' continue; if(verbose > 0) fprintf(f, "%s%-*s = %-18s [%s:%d]", prefix, maxlen, p->id, p->desc, p->config_file, p->lineno); @@ -413,35 +416,32 @@ static void list_parts(FILE *f, const char *prefix, LISTID avrparts, int pm) { } } -static void exithook(void) -{ - if (pgm->teardown) - pgm->teardown(pgm); +static void exithook(void) { + if(pgm->teardown) + pgm->teardown(pgm); } -static void cleanup_main(void) -{ - if (updates) { - ldestroy_cb(updates, (void(*)(void*)) free_update); - updates = NULL; - } - if (extended_params) { - ldestroy(extended_params); - extended_params = NULL; - } - if (additional_config_files) { - ldestroy(additional_config_files); - additional_config_files = NULL; - } +static void cleanup_main(void) { + if(updates) { + ldestroy_cb(updates, (void (*)(void *)) free_update); + updates = NULL; + } + if(extended_params) { + ldestroy(extended_params); + extended_params = NULL; + } + if(additional_config_files) { + ldestroy(additional_config_files); + additional_config_files = NULL; + } - cleanup_config(); + cleanup_config(); } -static void replace_backslashes(char *s) -{ +static void replace_backslashes(char *s) { // Replace all backslashes with forward slashes - for (size_t i = 0; i < strlen(s); i++) { - if (s[i] == '\\') { + for(size_t i = 0; i < strlen(s); i++) { + if(s[i] == '\\') { s[i] = '/'; } } @@ -449,9 +449,7 @@ static void replace_backslashes(char *s) // Return whether a part/programmer string is a developer option and if so which type static int dev_opt(const char *str) { - return - !str? 0: - str_eq(str, "*") || str_starts(str, "*/s")? 2: // Print PART DEFINITIONS comment as well + return !str? 0: str_eq(str, "*") || str_starts(str, "*/s")? 2: // Print PART DEFINITIONS comment as well strchr(str, '/') && !locate_part(part_list, str); } @@ -463,32 +461,37 @@ typedef struct { } pgm_distance; static int cmp_pgmid(const void *a, const void *b) { - const pgm_distance *pa = a, *pb = b; + const pgm_distance *pa = a, *pb = b; - int ret = pa->dist - pb->dist; - if(ret) - return ret; - return strcmp(pa->pgmid, pb->pgmid); + int ret = pa->dist - pb->dist; + + if(ret) + return ret; + return strcmp(pa->pgmid, pb->pgmid); } static int suggest_programmers(const char *programmer, LISTID programmers) { - const size_t max_distance = 64; // Don't show suggestions if they are way far out + const size_t max_distance = 64; // Don't show suggestions if they are way far out int nid = 0; // Number of possible programmer ids + for(LNODEID ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) { PROGRAMMER *pgm = ldata(ln1); + if(is_programmer(pgm)) for(LNODEID ln2 = lfirst(pgm->id); ln2; ln2 = lnext(ln2)) nid++; } - pgm_distance *d = mmt_malloc(nid*sizeof*d); + pgm_distance *d = mmt_malloc(nid*sizeof *d); // Fill d[] struct int idx = 0; AVRPART *p = locate_part(part_list, partdesc); + for(LNODEID ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) { PROGRAMMER *pgm = ldata(ln1); + if(!is_programmer(pgm)) continue; for(LNODEID ln2 = lfirst(pgm->id); ln2; ln2 = lnext(ln2)) { @@ -503,9 +506,11 @@ static int suggest_programmers(const char *programmer, LISTID programmers) { } int n = 0, pgmid_maxlen = 0, comp = 0, len; + if(nid) { // Sort list so programmers according to string distance qsort(d, nid, sizeof(*d), cmp_pgmid); - size_t dst = d[nid > 2? 2: nid-1].dist; + size_t dst = d[nid > 2? 2: nid - 1].dist; + if(dst > max_distance) dst = max_distance; for(; n < nid && d[n].dist <= dst; n++) @@ -545,12 +550,15 @@ static void programmer_not_found(const char *programmer, const PROGRAMMER *pgm, // If there were partial matches then they were not unique: count and list them int pmatches = 0, maxlen = 0, len; - for(LNODEID ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) { + + for(LNODEID ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) { PROGRAMMER *pg = ldata(ln1); + if(is_programmer(pg) && (pg->prog_modes & pmode)) - for(LNODEID ln2=lfirst(pg->id); ln2; ln2=lnext(ln2)) { + for(LNODEID ln2 = lfirst(pg->id); ln2; ln2 = lnext(ln2)) { const char *id = (const char *) ldata(ln2); - if(str_casestarts(id, programmer)) { // Partial initial match + + if(str_casestarts(id, programmer)) { // Partial initial match pmatches++; if((len = strlen(id)) > maxlen) maxlen = len; @@ -559,17 +567,20 @@ static void programmer_not_found(const char *programmer, const PROGRAMMER *pgm, } if(pmatches) { pmsg_error("%s is not a unique start of a programmer name; consider:\n", programmer); - for(LNODEID ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) { - PROGRAMMER *pg = ldata(ln1); + for(LNODEID ln1 = lfirst(programmers); ln1; ln1 = lnext(ln1)) { + PROGRAMMER *pg = ldata(ln1); + if(is_programmer(pg) && (pg->prog_modes & pmode)) - for(LNODEID ln2=lfirst(pg->id); ln2; ln2=lnext(ln2)) { + for(LNODEID ln2 = lfirst(pg->id); ln2; ln2 = lnext(ln2)) { const char *id = (const char *) ldata(ln2); + if(str_casestarts(id, programmer)) msg_error(" %-*s = %s\n", maxlen, id, pg->desc); - } + } } } else if(!pgm || !pgm->id || !lsize(pgm->id)) { PROGRAMMER *pg = locate_programmer(programmers, programmer); + if(!pgm && pt && pg && !(pg->prog_modes & pmode)) { pmsg_error("programmer %s and part %s have no programming modes in common\n", programmer, pt->desc); msg_info("use -c? -p %s to see all possible programmers for %s\n", pt->desc, pt->desc); @@ -595,7 +606,6 @@ static void part_not_found(const char *partdesc) { msg_error("\n"); } - #if !defined(WIN32) // Safely concatenate dir/file into dst that has size n static char *concatpath(char *dst, char *dir, char *file, size_t n) { @@ -606,13 +616,13 @@ static char *concatpath(char *dst, char *dir, char *file, size_t n) { size_t len = strlen(dir); // Insufficient space? - if(len + (dir[len-1] != '/') + strlen(file) > n-1) + if(len + (dir[len - 1] != '/') + strlen(file) > n - 1) return NULL; if(dst != dir) strcpy(dst, dir); - if(dst[len-1] != '/') + if(dst[len - 1] != '/') strcat(dst, "/"); strcat(dst, file); @@ -622,46 +632,42 @@ static char *concatpath(char *dst, char *dir, char *file, size_t n) { #endif -/* - * 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 */ - struct avrpart * p; /* which avr part we are programming */ - AVRMEM * sig; /* signature data */ - struct stat sb; - UPDATE * upd; - LNODEID * ln; +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 + struct avrpart *p; // Which avr part we are programming + AVRMEM *sig; // Signature data + struct stat sb; + UPDATE *upd; + LNODEID *ln; - /* options / operating mode variables */ - int erase; /* 1=erase chip, 0=don't */ - int flashread; /* 1=flash is going to be read, 0=no flash reads */ - int calibrate; /* 1=calibrate RC oscillator, 0=don't */ - int no_avrduderc; /* 1=don't load personal conf file */ - char * port; /* device port (/dev/xxx) */ - const char *exitspecs; /* exit specs string from command line */ - int explicit_c; /* 1=explicit -c on command line, 0=not specified there */ - int explicit_e; /* 1=explicit -e on command line, 0=not specified there */ - char sys_config[PATH_MAX]; /* system wide config file */ - char executable_abspath[PATH_MAX]; /* absolute path to avrdude executable */ - char executable_dirpath[PATH_MAX]; /* absolute path to folder with executable */ - bool executable_abspath_found = false; /* absolute path to executable found */ - bool sys_config_found = false; /* 'avrdude.conf' file found */ - char * e; /* for strtod() error checking */ - const char *errstr; /* for str_int() error checking */ - int baudrate; /* override default programmer baud rate */ - int touch_1200bps; /* "touch" serial port prior to programming */ - double bitclock; /* Specify programmer bit clock (JTAG ICE) */ - int ispdelay; /* Specify the delay for ISP clock */ - int init_ok; /* Device initialization worked well */ - int is_open; /* Device open succeeded */ - int ce_delayed; /* Chip erase delayed */ - char * logfile; /* Use logfile rather than stderr for diagnostics */ - enum updateflags uflags = UF_AUTO_ERASE | UF_VERIFY; /* Flags for do_op() */ + // Options/operating mode variables + int erase; // 1=erase chip, 0=don't + int flashread; // 1=flash is going to be read, 0=no flash reads + int calibrate; // 1=calibrate RC oscillator, 0=don't + int no_avrduderc; // 1=don't load personal conf file + char *port; // Device port (/dev/xxx) + const char *exitspecs; // Exit specs string from command line + int explicit_c; // 1=explicit -c on command line, 0=not specified there + int explicit_e; // 1=explicit -e on command line, 0=not specified there + char sys_config[PATH_MAX]; // System wide config file + char executable_abspath[PATH_MAX]; // Absolute path to avrdude executable + char executable_dirpath[PATH_MAX]; // Absolute path to folder with executable + bool executable_abspath_found = false; // Absolute path to executable found + bool sys_config_found = false; // avrdude.conf file found + char *e; // For strtod() error checking + const char *errstr; // For str_int() error checking + int baudrate; // Override default programmer baud rate + int touch_1200bps; // Touch serial port prior to programming + double bitclock; // Specify programmer bit clock (JTAG ICE) + int ispdelay; // Specify the delay for ISP clock + int init_ok; // Device initialization worked well + int is_open; // Device open succeeded + int ce_delayed; // Chip erase delayed + char *logfile; // Use logfile rather than stderr for diagnostics + enum updateflags uflags = UF_AUTO_ERASE | UF_VERIFY; // Flags for do_op() init_cx(NULL); @@ -669,100 +675,98 @@ int main(int argc, char * argv []) _set_printf_count_output(1); #endif - /* - * Set line buffering for file descriptors so we see stdout and stderr - * properly interleaved. - */ - setvbuf(stdout, (char*)NULL, _IOLBF, 0); - setvbuf(stderr, (char*)NULL, _IOLBF, 0); + // Set line buffering for file descriptors so we see stdout and stderr properly interleaved + setvbuf(stdout, (char *) NULL, _IOLBF, 0); + setvbuf(stderr, (char *) NULL, _IOLBF, 0); sys_config[0] = '\0'; progname = strrchr(argv[0], '/'); #if defined (WIN32) - /* take care of backslash as dir sep in W32 */ - if (!progname) + // Take care of backslash as dir sep in W32 + if(!progname) progname = strrchr(argv[0], '\\'); -#endif /* WIN32 */ +#endif // WIN32 - if (progname) + if(progname) progname++; else progname = argv[0]; // Remove trailing .exe if(str_ends(progname, ".exe")) { - progname = mmt_strdup(progname); // Don't write to argv[0] - progname[strlen(progname)-4] = 0; + progname = mmt_strdup(progname); // Don't write to argv[0] + progname[strlen(progname) - 4] = 0; } avrdude_conf_version = ""; default_programmer = ""; - default_parallel = ""; - default_serial = ""; - default_spi = ""; - default_baudrate = 0; - default_bitclock = 0.0; - default_linuxgpio = ""; - allow_subshells = 0; + default_parallel = ""; + default_serial = ""; + default_spi = ""; + default_baudrate = 0; + default_bitclock = 0.0; + default_linuxgpio = ""; + allow_subshells = 0; init_config(); atexit(cleanup_main); msg_debug("$ "); // Record command line when debugging - for(int i=0; iavr_disableffopt = 1; - break; - - case 'e': /* perform a chip erase */ - erase = 1; - explicit_e = 1; - uflags &= ~UF_AUTO_ERASE; - break; - - case 'E': - exitspecs = optarg; - break; - - case 'F': /* override invalid signature check */ - ovsigck = 1; - break; - - case 'l': - logfile = optarg; - break; - - case 'n': - uflags |= UF_NOWRITE; - break; - - case 'N': - no_avrduderc = 1; - break; - - case 'O': /* perform RC oscillator calibration */ - calibrate = 1; - break; - - case 'p': /* specify AVR part */ - partdesc = optarg; - break; - - case 'P': - port = mmt_strdup(optarg); - break; - - case 'q': /* Quell progress output */ - quell_progress++ ; - break; - - case 'r' : - touch_1200bps++; - break; - - case 't': /* enter terminal mode */ - ladd(updates, cmd_update("interactive terminal")); - break; - - case 'T': - ladd(updates, cmd_update(optarg)); - break; - - case 'U': - upd = parse_op(optarg); - if (upd == NULL) { - pmsg_error("unable to parse update operation %s\n", optarg); - exit(1); - } - ladd(updates, upd); - break; - - case 'v': - verbose++; - break; - - case 'V': - uflags &= ~UF_VERIFY; - break; - - case 'x': - ladd(extended_params, optarg); - break; - - case '?': /* help */ - usage(); - exit(0); - break; - - default: - pmsg_error("invalid option -%c\n\n", ch); - usage(); + case 'b': // Override default programmer baud rate + baudrate = str_int(optarg, STR_INT32, &errstr); + if(errstr) { + pmsg_error("invalid baud rate %s specified: %s\n", optarg, errstr); exit(1); - break; + } + break; + + case 'B': // Specify bit clock period + bitclock = strtod(optarg, &e); + if((e == optarg) || bitclock <= 0.0) { + pmsg_error("invalid bit clock period %s\n", optarg); + exit(1); + } + while(*e && isascii(*e & 0xff) && isspace(*e & 0xff)) + e++; + if(*e == 0 || str_caseeq(e, "us")) // us is optional and the default + ; + else if(str_caseeq(e, "m") || str_caseeq(e, "mhz")) + bitclock = 1/bitclock; + else if(str_caseeq(e, "k") || str_caseeq(e, "khz")) + bitclock = 1e3/bitclock; + else if(str_caseeq(e, "hz")) + bitclock = 1e6/bitclock; + else { + pmsg_error("invalid bit clock unit %s\n", e); + exit(1); + } + break; + + case 'i': // Specify isp clock delay + ispdelay = str_int(optarg, STR_INT32, &errstr); + if(errstr || ispdelay == 0) { + pmsg_error("invalid isp clock delay %s specified", optarg); + if(errstr) + msg_error(": %s\n", errstr); + else + msg_error("\n"); + exit(1); + } + break; + + case 'c': // Programmer id + pgmid = optarg; + explicit_c = 1; + break; + + case 'C': // System wide configuration file + if(optarg[0] == '+') { + ladd(additional_config_files, optarg + 1); + } else { + strncpy(sys_config, optarg, PATH_MAX); + sys_config[PATH_MAX - 1] = 0; + } + break; + + case 'D': // Disable auto-erase + uflags &= ~UF_AUTO_ERASE; + // Fall through + + case 'A': // Explicit disabling of trailing-0xff removal + cx->avr_disableffopt = 1; + break; + + case 'e': // Perform a chip erase + erase = 1; + explicit_e = 1; + uflags &= ~UF_AUTO_ERASE; + break; + + case 'E': + exitspecs = optarg; + break; + + case 'F': // Override invalid signature check + ovsigck = 1; + break; + + case 'l': + logfile = optarg; + break; + + case 'n': + uflags |= UF_NOWRITE; + break; + + case 'N': + no_avrduderc = 1; + break; + + case 'O': // Perform RC oscillator calibration + calibrate = 1; + break; + + case 'p': // Specify AVR part + partdesc = optarg; + break; + + case 'P': + port = mmt_strdup(optarg); + break; + + case 'q': // Quell progress output + quell_progress++; + break; + + case 'r': + touch_1200bps++; + break; + + case 't': // Enter terminal mode + ladd(updates, cmd_update("interactive terminal")); + break; + + case 'T': + ladd(updates, cmd_update(optarg)); + break; + + case 'U': + upd = parse_op(optarg); + if(upd == NULL) { + pmsg_error("unable to parse update operation %s\n", optarg); + exit(1); + } + ladd(updates, upd); + break; + + case 'v': + verbose++; + break; + + case 'V': + uflags &= ~UF_VERIFY; + break; + + case 'x': + ladd(extended_params, optarg); + break; + + case '?': // Help + usage(); + exit(0); + break; + + default: + pmsg_error("invalid option -%c\n\n", ch); + usage(); + exit(1); + break; } } - - - - if (logfile != NULL) { + if(logfile != NULL) { FILE *newstderr = freopen(logfile, "w", stderr); - if (newstderr == NULL) { - /* Help! There's no stderr to complain to anymore now. */ + + if(newstderr == NULL) { + // Help! There's no stderr to complain to anymore now printf("Cannot create logfile %s: %s\n", logfile, strerror(errno)); return 1; } } size_t ztest; + if(1 != sscanf("42", "%zi", &ztest) || ztest != 42) pmsg_warning("linked C library does not conform to C99; %s may not work as expected\n", progname); - /* search for system configuration file unless -C conffile was given */ - if (strlen(sys_config) == 0) { + // Search for system configuration file unless -C conffile was given + if(strlen(sys_config) == 0) { /* - * EXECUTABLE ABSPATH - * ------------------ - * Determine the absolute path to avrdude executable. This will be used to - * locate the 'avrdude.conf' file later. + * Executable abspath: Determine the absolute path to avrdude executable. + * This will be used to locate the avrdude.conf file later. */ int executable_dirpath_len; - int executable_abspath_len = wai_getExecutablePath( - executable_abspath, + int executable_abspath_len = wai_getExecutablePath(executable_abspath, PATH_MAX, - &executable_dirpath_len - ); - if ( - (executable_abspath_len != -1) && - (executable_abspath_len != 0) && - (executable_dirpath_len != -1) && - (executable_dirpath_len != 0) - ) { + &executable_dirpath_len); + + if( + (executable_abspath_len != -1) && + (executable_abspath_len != 0) && (executable_dirpath_len != -1) && (executable_dirpath_len != 0) + ) { // All requirements satisfied, executable path was found executable_abspath_found = true; @@ -977,8 +972,7 @@ int main(int argc, char * argv []) replace_backslashes(executable_abspath); - // Define 'executable_dirpath' to be the path to the parent folder of the - // executable. + // Define executable_dirpath to be the path to the parent folder of the executable strcpy(executable_dirpath, executable_abspath); executable_dirpath[executable_dirpath_len] = '\0'; @@ -990,95 +984,95 @@ int main(int argc, char * argv []) } /* - * SYSTEM CONFIG + * System config * ------------- - * Determine the location of 'avrdude.conf'. Check in this order: + * Determine the location of avrdude.conf. Check in this order: * 1. /../etc/avrdude.conf * 2. /avrdude.conf * 3. CONFIG_DIR/avrdude.conf * * When found, write the result into the 'sys_config' variable. */ - if (executable_abspath_found) { + if(executable_abspath_found) { // 1. Check /../etc/avrdude.conf strcpy(sys_config, executable_dirpath); sys_config[PATH_MAX - 1] = '\0'; i = strlen(sys_config); - if (i && (sys_config[i - 1] != '/')) + if(i && (sys_config[i - 1] != '/')) strcat(sys_config, "/"); strcat(sys_config, "../etc/" SYSTEM_CONF_FILE); sys_config[PATH_MAX - 1] = '\0'; - if (access(sys_config, F_OK) == 0) { + if(access(sys_config, F_OK) == 0) { sys_config_found = true; - } - else { + } else { // 2. Check /avrdude.conf strcpy(sys_config, executable_dirpath); sys_config[PATH_MAX - 1] = '\0'; i = strlen(sys_config); - if (i && (sys_config[i - 1] != '/')) + if(i && (sys_config[i - 1] != '/')) strcat(sys_config, "/"); strcat(sys_config, SYSTEM_CONF_FILE); sys_config[PATH_MAX - 1] = '\0'; - if (access(sys_config, F_OK) == 0) { + if(access(sys_config, F_OK) == 0) { sys_config_found = true; } } } - if (!sys_config_found) { + if(!sys_config_found) { // 3. Check CONFIG_DIR/avrdude.conf + #if defined(WIN32) win_set_path(sys_config, sizeof sys_config, SYSTEM_CONF_FILE); #else strcpy(sys_config, CONFIG_DIR); i = strlen(sys_config); - if (i && (sys_config[i - 1] != '/')) + if(i && (sys_config[i - 1] != '/')) strcat(sys_config, "/"); strcat(sys_config, SYSTEM_CONF_FILE); #endif - if (access(sys_config, F_OK) == 0) { + + if(access(sys_config, F_OK) == 0) { sys_config_found = true; } } } // Debug output msg_trace2("sys_config = %s\n", sys_config); - msg_trace2("sys_config_found = %s\n", sys_config_found ? "true" : "false"); + msg_trace2("sys_config_found = %s\n", sys_config_found? "true": "false"); msg_trace2("\n"); - if (quell_progress == 0) + if(quell_progress == 0) terminal_setup_update_progress(); - /* - * Print out an identifying string so folks can tell what version - * they are running - */ + // Print out an identifying string so folks can tell what version they are running pmsg_notice("%s version %s\n", progname, AVRDUDE_FULL_VERSION); pmsg_notice("Copyright see https://github.com/avrdudes/avrdude/blob/main/AUTHORS\n\n"); if(*sys_config) { char *real_sys_config = realpath(sys_config, NULL); + if(real_sys_config) { - pmsg_notice("system wide configuration file is %s\n", real_sys_config); + pmsg_notice("system wide configuration file is %s\n", real_sys_config); } else pmsg_warning("cannot determine realpath() of config file %s: %s\n", sys_config, strerror(errno)); rc = read_config(real_sys_config); - if (rc) { + if(rc) { pmsg_error("unable to process system wide configuration file %s\n", real_sys_config); exit(1); } mmt_free(real_sys_config); } - if (usr_config[0] != 0 && !no_avrduderc) { + if(usr_config[0] != 0 && !no_avrduderc) { int ok = (rc = stat(usr_config, &sb)) >= 0 && (sb.st_mode & S_IFREG); + pmsg_notice("user configuration file %s%s%s\n", ok? "is ": "", usr_config, - rc<0? " does not exist": !(sb.st_mode & S_IFREG)? " is not a regular file, skipping": ""); + rc < 0? " does not exist": !(sb.st_mode & S_IFREG)? " is not a regular file, skipping": ""); if(ok) { rc = read_config(usr_config); - if (rc) { + if(rc) { pmsg_error("unable to process user configuration file %s\n", usr_config); exit(1); } @@ -1090,16 +1084,16 @@ int main(int argc, char * argv []) imsg_warning("does not match Avrdude build version (%s)\n", AVRDUDE_FULL_VERSION); } - if (lsize(additional_config_files) > 0) { + if(lsize(additional_config_files) > 0) { LNODEID ln1; - const char * p = NULL; + const char *p = NULL; - for (ln1=lfirst(additional_config_files); ln1; ln1=lnext(ln1)) { + for(ln1 = lfirst(additional_config_files); ln1; ln1 = lnext(ln1)) { p = ldata(ln1); pmsg_notice("additional configuration file is %s\n", p); rc = read_config(p); - if (rc) { + if(rc) { pmsg_error("unable to process additional configuration file %s\n", p); exit(1); } @@ -1111,8 +1105,8 @@ int main(int argc, char * argv []) if((p = ldata(ln1))->mem) lsort(p->mem, avr_mem_cmp); - // set bitclock from configuration files unless changed by command line - if (default_bitclock > 0 && bitclock == 0.0) { + // Set bitclock from configuration files unless changed by command line + if(default_bitclock > 0 && bitclock == 0.0) { bitclock = default_bitclock; } @@ -1120,8 +1114,8 @@ int main(int argc, char * argv []) pgmid = cache_string(default_programmer); // Developer options to print parts and/or programmer entries of avrdude.conf - int dev_opt_c = dev_opt(pgmid); // -c /[duASsrtiBUPTIJWHQ] - int dev_opt_p = dev_opt(partdesc); // -p /[cdoASsrw*tiBUPTIJWHQ] + int dev_opt_c = dev_opt(pgmid); // -c /[duASsrtiBUPTIJWHQ] + int dev_opt_p = dev_opt(partdesc); // -p /[cdoASsrw*tiBUPTIJWHQ] if(dev_opt_c || dev_opt_p) { // See -c/h and or -p/h dev_output_pgm_part(dev_opt_c, pgmid, dev_opt_p, partdesc); @@ -1129,15 +1123,19 @@ int main(int argc, char * argv []) } PROGRAMMER *dry = locate_programmer(programmers, "dryrun"); + for(LNODEID ln1 = lfirst(part_list); ln1; ln1 = lnext(ln1)) { AVRPART *p = ldata(ln1); + for(LNODEID ln2 = lfirst(programmers); ln2; ln2 = lnext(ln2)) { PROGRAMMER *pgm = ldata(ln2); + if(!is_programmer(pgm)) continue; const char *pnam = pgm->id? ldata(lfirst(pgm->id)): "???"; int pm = pgm->prog_modes & p->prog_modes; - if((pm & (pm-1)) && !str_eq(pnam, "dryrun") && !(dry && pgm->initpgm == dry->initpgm)) + + if((pm & (pm - 1)) && !str_eq(pnam, "dryrun") && !(dry && pgm->initpgm == dry->initpgm)) pmsg_warning("%s and %s share multiple modes (%s)\n", pnam, p->desc, avr_prog_modes(pm)); } } @@ -1157,6 +1155,7 @@ int main(int argc, char * argv []) if(str_eq(partdesc, "?")) { if(pgmid && *pgmid && explicit_c) { PROGRAMMER *pgm = locate_programmer_starts_set(programmers, pgmid, &pgmid, NULL); + if(!pgm || !is_programmer(pgm)) { programmer_not_found(pgmid, pgm, NULL); exit(1); @@ -1176,13 +1175,14 @@ int main(int argc, char * argv []) if(str_eq(pgmid, "?")) { if(partdesc && *partdesc) { AVRPART *p = locate_part(part_list, partdesc); + if(!p) { part_not_found(partdesc); exit(1); } msg_error("\nValid programmers for part %s are:\n", p->desc); list_programmers(stderr, " ", programmers, p->prog_modes); - } else { + } else { msg_error("\nValid programmers are:\n"); list_programmers(stderr, " ", programmers, ~0); } @@ -1205,9 +1205,9 @@ int main(int argc, char * argv []) exit(1); } - p = partdesc && *partdesc? locate_part(part_list, partdesc): NULL; + p = partdesc && *partdesc? locate_part(part_list, partdesc): NULL; pgm = locate_programmer_starts_set(programmers, pgmid, &pgmid, p); - if (pgm == NULL || !is_programmer(pgm)) { + if(pgm == NULL || !is_programmer(pgm)) { programmer_not_found(pgmid, pgm, p); exit(1); } @@ -1220,7 +1220,7 @@ int main(int argc, char * argv []) } } - if (pgm->initpgm) { + if(pgm->initpgm) { pgm->initpgm(pgm); } else { msg_error("\n"); @@ -1228,27 +1228,28 @@ int main(int argc, char * argv []) exit(1); } - if (pgm->setup) { + if(pgm->setup) { pgm->setup(pgm); } - if (pgm->teardown) { + if(pgm->teardown) { atexit(exithook); } - if (lsize(extended_params) > 0) { - if (pgm->parseextparams == NULL) { - for (LNODEID ln = lfirst(extended_params); ln; ln = lnext(ln)) { + if(lsize(extended_params) > 0) { + if(pgm->parseextparams == NULL) { + for(LNODEID ln = lfirst(extended_params); ln; ln = lnext(ln)) { const char *extended_param = ldata(ln); - if (str_eq(extended_param, "help")) { + + if(str_eq(extended_param, "help")) { msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -x help Show this help menu and exit\n"); exit(0); - } - else + } else pmsg_error("programmer does not support extended parameter -x %s, option ignored\n", extended_param); } } else { int rc = pgm->parseextparams(pgm, extended_params); + if(rc == LIBAVRDUDE_EXIT) exit(0); if(rc < 0) { @@ -1258,41 +1259,43 @@ int main(int argc, char * argv []) } } - if (port == NULL) { - switch (pgm->conntype) - { - case CONNTYPE_PARALLEL: - port = mmt_strdup(default_parallel); - break; + if(port == NULL) { + switch (pgm->conntype) { + case CONNTYPE_PARALLEL: + port = mmt_strdup(default_parallel); + break; - case CONNTYPE_SERIAL: - port = mmt_strdup(default_serial); - break; + case CONNTYPE_SERIAL: + port = mmt_strdup(default_serial); + break; - case CONNTYPE_USB: - port = mmt_strdup(DEFAULT_USB); - break; + case CONNTYPE_USB: + port = mmt_strdup(DEFAULT_USB); + break; + + case CONNTYPE_SPI: - case CONNTYPE_SPI: #ifdef HAVE_LINUXSPI - port = mmt_strdup(*default_spi? default_spi: "unknown"); + port = mmt_strdup(*default_spi? default_spi: "unknown"); #else - port = mmt_strdup("unknown"); + port = mmt_strdup("unknown"); #endif - break; - case CONNTYPE_LINUXGPIO: - port = mmt_strdup(default_linuxgpio); - break; + break; - default: - port = mmt_strdup("unknown"); - break; + case CONNTYPE_LINUXGPIO: + port = mmt_strdup(default_linuxgpio); + break; + + default: + port = mmt_strdup("unknown"); + break; } } int is_dryrun = str_eq(pgm->type, "dryrun") || (dry && pgm->initpgm == dry->initpgm); + if((port[0] == 0 || str_eq(port, "unknown")) && !is_dryrun) { msg_error("\n"); pmsg_error("no port has been specified on the command line or in the config file;\n"); @@ -1310,12 +1313,15 @@ int main(int argc, char * argv []) */ bool print_ports = true; SERIALADAPTER *ser = NULL; - if (pgm->conntype == CONNTYPE_SERIAL) { + + if(pgm->conntype == CONNTYPE_SERIAL) { char *portdup = mmt_strdup(port); char *port_tok[4], *tok = portdup; + for(int t = 0, maxt = str_starts(portdup, DEFAULT_USB ":")? 4: 2; t < 4; t++) { char *save = tok && t < maxt? tok: ""; - if(t < maxt-1 && tok && (tok = strchr(tok, ':'))) + + if(t < maxt - 1 && tok && (tok = strchr(tok, ':'))) *tok++ = 0; port_tok[t] = mmt_strdup(save); } @@ -1323,18 +1329,19 @@ int main(int argc, char * argv []) // Use libserialport to find the actual serial port ser = locate_programmer(programmers, port_tok[0]); - if (is_serialadapter(ser)) { + if(is_serialadapter(ser)) { + #ifdef HAVE_LIBSERIALPORT int rv = setport_from_serialadapter(&port, ser, port_tok[1]); - if (rv == -1) { + + if(rv == -1) { pmsg_warning("serial adapter %s", port_tok[0]); - if (port_tok[1][0]) + if(port_tok[1][0]) msg_warning(" with serial number %s", port_tok[1]); - else if (ser->usbsn && ser->usbsn[0]) + else if(ser->usbsn && ser->usbsn[0]) msg_warning(" with serial number %s", ser->usbsn); msg_warning(" not connected to host\n"); - } - else if (rv == -2) + } else if(rv == -2) print_ports = false; if(rv) ser = NULL; @@ -1342,72 +1349,70 @@ int main(int argc, char * argv []) } else if(str_eq(port_tok[0], DEFAULT_USB)) { // Port or usb:[vid]:[pid] int vid, pid; - if (sscanf(port_tok[1], "%x", &vid) > 0 && sscanf(port_tok[2], "%x", &pid) > 0) { + + if(sscanf(port_tok[1], "%x", &vid) > 0 && sscanf(port_tok[2], "%x", &pid) > 0) { int rv = setport_from_vid_pid(&port, vid, pid, port_tok[3]); - if (rv == -1) { - if (port_tok[3][0]) - pmsg_warning("serial adapter with USB VID %s and PID %s and serial number %s not connected\n", port_tok[1], port_tok[2], port_tok[3]); + + if(rv == -1) { + if(port_tok[3][0]) + pmsg_warning("serial adapter with USB VID %s and PID %s and serial number %s not connected\n", port_tok[1], + port_tok[2], port_tok[3]); else pmsg_warning("serial adapter with USB VID %s and PID %s not connected\n", port_tok[1], port_tok[2]); - } - else if (rv == -2) + } else if(rv == -2) print_ports = false; } } - for (int i = 0; i < 4; i++) + for(int i = 0; i < 4; i++) mmt_free(port_tok[i]); if(touch_1200bps && touch_serialport(&port, 1200, touch_1200bps) < 0) goto skipopen; } - // Open the programmer - if (verbose > 0) { + if(verbose > 0) { if(!is_dryrun) pmsg_notice("using port : %s\n", port); pmsg_notice("using programmer : %s\n", pgmid); } - if (baudrate && !pgm->baudrate && !default_baudrate) { // none set - pmsg_notice("setting baud rate : %d\n", baudrate); - pgm->baudrate = baudrate; - } - else if (baudrate && ((pgm->baudrate && pgm->baudrate != baudrate) - || (!pgm->baudrate && default_baudrate != baudrate))) { + if(baudrate && !pgm->baudrate && !default_baudrate) { // None set + pmsg_notice("setting baud rate : %d\n", baudrate); + pgm->baudrate = baudrate; + } else if(baudrate && ((pgm->baudrate && pgm->baudrate != baudrate) + || (!pgm->baudrate && default_baudrate != baudrate))) { pmsg_notice("overriding baud rate : %d\n", baudrate); pgm->baudrate = baudrate; - } - else if (!pgm->baudrate && default_baudrate) { + } else if(!pgm->baudrate && default_baudrate) { pmsg_notice("default baud rate : %d\n", default_baudrate); pgm->baudrate = default_baudrate; - } - else if (ser && ser->baudrate) { + } else if(ser && ser->baudrate) { pmsg_notice("serial baud rate : %d\n", ser->baudrate); pgm->baudrate = ser->baudrate; - } - else if (pgm->baudrate != 0) + } else if(pgm->baudrate != 0) pmsg_notice("programmer baud rate : %d\n", pgm->baudrate); - if (bitclock != 0.0) { + if(bitclock != 0.0) { pmsg_notice("setting bit clk period: %.1f us\n", bitclock); - pgm->bitclock = bitclock * 1e-6; + pgm->bitclock = bitclock*1e-6; } - if (ispdelay != 0) { + if(ispdelay != 0) { pmsg_notice("setting ISP clk delay : %3i us\n", ispdelay); pgm->ispdelay = ispdelay; } rc = pgm->open(pgm, port); - if (rc < 0) { + if(rc < 0) { if(rc == LIBAVRDUDE_EXIT) { exitrc = 0; goto main_exit; } pmsg_error("unable to open port %s for programmer %s\n", port, pgmid); -skipopen: - if (print_ports && pgm->conntype == CONNTYPE_SERIAL) { + skipopen: + if(print_ports && pgm->conntype == CONNTYPE_SERIAL) { + #ifdef HAVE_LIBSERIALPORT list_available_serialports(programmers); if(touch_1200bps == 1) @@ -1415,30 +1420,31 @@ skipopen: #endif } exitrc = 1; - pgm->ppidata = 0; /* clear all bits at exit */ + pgm->ppidata = 0; // Clear all bits at exit goto main_exit; } is_open = 1; - if (partdesc == NULL) { + if(partdesc == NULL) { part_not_found(NULL); exitrc = 1; goto main_exit; } p = locate_part(part_list, partdesc); - if (p == NULL) { + if(p == NULL) { part_not_found(partdesc); exitrc = 1; goto main_exit; } - if (exitspecs != NULL) { - if (pgm->parseexitspecs == NULL) { + if(exitspecs != NULL) { + if(pgm->parseexitspecs == NULL) { pmsg_warning("-E option not supported by this programmer type\n"); exitspecs = NULL; } else { int rc = pgm->parseexitspecs(pgm, exitspecs); + if(rc == LIBAVRDUDE_EXIT) exit(0); if(rc < 0) { @@ -1448,7 +1454,7 @@ skipopen: } } - if (avr_initmem(p) != 0) { + if(avr_initmem(p) != 0) { msg_error("\n"); pmsg_error("unable to initialize memories\n"); exitrc = 1; @@ -1466,24 +1472,25 @@ skipopen: } /* - * Now that we know which part we are going to program, locate any -U - * options using the default memory region, fill in the device-dependent - * default region name ("application" for Xmega parts or "flash" otherwise) - * and check for basic problems with memory names or file access with a - * view to exit before programming. + * Now that we know which part we are going to program, locate any -U options + * using the default memory region, fill in the device-dependent default + * region name ("application" for Xmega parts or "flash" otherwise) and check + * for basic problems with memory names or file access with a view to exit + * before programming. */ int doexit = 0; - for (ln=lfirst(updates); ln; ln=lnext(ln)) { + + for(ln = lfirst(updates); ln; ln = lnext(ln)) { upd = ldata(ln); - if (upd->memstr == NULL && upd->cmdline == NULL) { + if(upd->memstr == NULL && upd->cmdline == NULL) { const char *mtype = p->prog_modes & PM_PDI? "application": "flash"; + pmsg_notice2("defaulting memstr in -U %c:%s option to \"%s\"\n", - (upd->op == DEVICE_READ)? 'r': (upd->op == DEVICE_WRITE)? 'w': 'v', - upd->filename, mtype); + (upd->op == DEVICE_READ)? 'r': (upd->op == DEVICE_WRITE)? 'w': 'v', upd->filename, mtype); upd->memstr = mmt_strdup(mtype); } rc = update_dryrun(p, upd); - if (rc && rc != LIBAVRDUDE_SOFTFAIL) + if(rc && rc != LIBAVRDUDE_SOFTFAIL) doexit = 1; } if(doexit) { @@ -1491,19 +1498,16 @@ skipopen: goto main_exit; } - if (calibrate) { - /* - * perform an RC oscillator calibration - * as outlined in appnote AVR053 - */ - if (pgm->perform_osccal == 0) { + if(calibrate) { + // Perform an RC oscillator calibration as outlined in appnote AVR053 + if(pgm->perform_osccal == 0) { pmsg_error("programmer does not support RC oscillator calibration\n"); exitrc = 1; } else { pmsg_notice2("performing RC oscillator calibration\n"); exitrc = pgm->perform_osccal(pgm); } - if (exitrc) + if(exitrc) pmsg_error("RC calibration unsuccesful\n"); else pmsg_notice("calibration value is now stored in EEPROM at address 0\n"); @@ -1511,7 +1515,7 @@ skipopen: goto main_exit; } - if (verbose > 0 && quell_progress < 2) { + if(verbose > 0 && quell_progress < 2) { avr_display(stderr, pgm, p, progbuf, verbose); msg_notice2("\n"); programmer_display(pgm, progbuf); @@ -1521,25 +1525,21 @@ skipopen: exitrc = 0; - /* - * enable the programmer - */ + // Enable the programmer pgm->enable(pgm, p); // Turn off all the status LEDs and reset LED states led_set(pgm, LED_BEG); - /* - * initialize the chip in preparation for accepting commands - */ + // Initialize the chip in preparation for accepting commands init_ok = (rc = pgm->initialize(pgm, p)) >= 0; - if (!init_ok) { + if(!init_ok) { if(rc == LIBAVRDUDE_EXIT) { exitrc = 0; goto main_exit; } pmsg_error("initialization failed (rc = %d)\n", rc); - if (rc == -2) + if(rc == -2) imsg_error(" - the programmer ISP clock is too fast for the target\n"); else imsg_error(" - double check the connections and try again\n"); @@ -1549,10 +1549,10 @@ skipopen: else imsg_error(" - use -B to set lower the bit clock frequency, e.g. -B 125kHz\n"); - if (str_starts(pgm->type, "pickit5")) + if(str_starts(pgm->type, "pickit5")) imsg_error(" - reset the programmer by unplugging it"); - if (!ovsigck) { + if(!ovsigck) { imsg_error(" - use -F to override this check\n"); exitrc = 1; goto main_exit; @@ -1566,32 +1566,32 @@ skipopen: pmsg_notice("AVR device initialized and ready to accept instructions\n"); /* - * Let's read the signature bytes to make sure there is at least a - * chip on the other end that is responding correctly. A check - * against 0xffffff / 0x000000 should ensure that the signature bytes - * are valid. + * Let's read the signature bytes to make sure there is at least a chip on + * the other end that is responding correctly. A check against + * 0xffffff/0x000000 should ensure that the signature bytes are valid. */ - if(!(p->prog_modes & PM_aWire)) { // not AVR32 + if(!(p->prog_modes & PM_aWire)) { // Not AVR32 int attempt = 0; - int waittime = 10000; /* 10 ms */ + int waittime = 10000; // 10 ms sig_again: usleep(waittime); - if (init_ok) { + if(init_ok) { rc = avr_signature(pgm, p); - if (rc == LIBAVRDUDE_EXIT) { + if(rc == LIBAVRDUDE_EXIT) { exitrc = 0; goto main_exit; } - if (rc != LIBAVRDUDE_SUCCESS) { - if (rc == LIBAVRDUDE_SOFTFAIL && (p->prog_modes & PM_UPDI) && attempt < 1) { + if(rc != LIBAVRDUDE_SUCCESS) { + if(rc == LIBAVRDUDE_SOFTFAIL && (p->prog_modes & PM_UPDI) && attempt < 1) { attempt++; - if (pgm->read_sib) { + if(pgm->read_sib) { // Read SIB and compare FamilyID char sib[AVR_SIBLEN + 1]; + pgm->read_sib(pgm, p, sib); pmsg_notice("System Information Block: %s\n", sib); - if (strncmp(p->family_id, sib, AVR_FAMILYIDLEN)) { + if(strncmp(p->family_id, sib, AVR_FAMILYIDLEN)) { pmsg_warning("received FamilyID: \"%.*s\"\n", AVR_FAMILYIDLEN, sib); imsg_warning("expected FamilyID: \"%s\"\n", p->family_id); } else @@ -1599,7 +1599,7 @@ skipopen: } if(erase) { erase = 0; - if (uflags & UF_NOWRITE) { + if(uflags & UF_NOWRITE) { pmsg_warning("conflicting -e and -n options specified, NOT erasing chip\n"); } else { pmsg_notice("trying to unlock the chip\n"); @@ -1609,7 +1609,7 @@ skipopen: goto sig_again; } } - if (!ovsigck) { + if(!ovsigck) { pmsg_error("double check chip or use -F to override this check\n"); exitrc = 1; goto main_exit; @@ -1625,26 +1625,29 @@ skipopen: } sig = avr_locate_signature(p); - if (sig == NULL) + if(sig == NULL) pmsg_warning("signature memory not defined for device %s\n", p->desc); else { const char *mculist = str_ccmcunames_signature(sig->buf, pgm->prog_modes); + if(!*mculist) { // No matching signatures? - if(p->prog_modes & PM_UPDI) { // UPDI parts have different(!) offsets for signature + if(p->prog_modes & PM_UPDI) { // UPDI parts have different(!) offsets for signature int k, n = 0; // Gather list of known different signature offsets unsigned myoff = sig->offset, offlist[10]; + for(LNODEID ln1 = lfirst(part_list); ln1; ln1 = lnext(ln1)) { AVRMEM *m = avr_locate_signature(ldata(ln1)); + if(m && m->offset != myoff) { - for(k=0; koffset == offlist[k]) break; - if(k == n && k < (int) (sizeof offlist/sizeof*offlist)) + if(k == n && k < (int) (sizeof offlist/sizeof *offlist)) offlist[n++] = m->offset; } } // Now go through the list of other(!) sig offsets and try these - for(k=0; koffset = offlist[k]; if(avr_signature(pgm, p) >= 0) if(*(mculist = str_ccmcunames_signature(sig->buf, pgm->prog_modes))) @@ -1655,28 +1658,30 @@ skipopen: } int ff = 1, zz = 1; - for (i=0; isize; i++) { - if (sig->buf[i] != 0xff) + + for(i = 0; i < sig->size; i++) { + if(sig->buf[i] != 0xff) ff = 0; - if (sig->buf[i] != 0x00) + if(sig->buf[i] != 0x00) zz = 0; } bool signature_matches = sig->size >= 3 && !memcmp(sig->buf, p->signature, 3); int showsig = !signature_matches || ff || zz || verbose > 0; + if(showsig) pmsg_info("device signature =%s", str_cchex(sig->buf, sig->size, 1)); if(*mculist && showsig) msg_info(" (%s)", is_dryrun? p->desc: mculist); - if (ff || zz) { // All three bytes are 0xff or all three bytes are 0x00 - if (++attempt < 3) { + if(ff || zz) { // All three bytes are 0xff or all three bytes are 0x00 + if(++attempt < 3) { waittime *= 5; msg_info(" (retrying)\n"); goto sig_again; } msg_info("\n"); pmsg_error("invalid device signature\n"); - if (!ovsigck) { + if(!ovsigck) { pmsg_error("expected signature for %s is%s\n", p->desc, str_cchex(p->signature, 3, 1)); imsg_error(" - double check connections and try again, or use -F to carry on regardless\n"); exitrc = 1; @@ -1686,8 +1691,8 @@ skipopen: msg_info("\n"); } - if (!signature_matches) { - if (ovsigck) { + if(!signature_matches) { + if(ovsigck) { pmsg_warning("expected signature for %s is%s\n", p->desc, str_cchex(p->signature, 3, 1)); } else { pmsg_error("expected signature for %s is%s\n", p->desc, str_cchex(p->signature, 3, 1)); @@ -1699,12 +1704,12 @@ skipopen: } } - if (uflags & UF_AUTO_ERASE) { + if(uflags & UF_AUTO_ERASE) { if((p->prog_modes & (PM_PDI | PM_UPDI)) && pgm->page_erase && lsize(updates) > 0) { - for(ln=lfirst(updates); ln; ln=lnext(ln)) { + for(ln = lfirst(updates); ln; ln = lnext(ln)) { upd = ldata(ln); if(upd->memstr && upd->op == DEVICE_WRITE && memlist_contains_flash(upd->memstr, p)) { - cx->avr_disableffopt = 1; // Must write full flash file including trailing 0xff + cx->avr_disableffopt = 1; // Must write full flash file including trailing 0xff pmsg_notice("NOT erasing chip as page erase will be used for new flash%s contents;\n", avr_locate_bootrow(p)? "/bootrow": ""); imsg_notice("unprogrammed flash contents remains: use -e for an explicit chip-erase\n"); @@ -1713,14 +1718,13 @@ skipopen: } } else { uflags &= ~UF_AUTO_ERASE; - for(ln=lfirst(updates); ln; ln=lnext(ln)) { + for(ln = lfirst(updates); ln; ln = lnext(ln)) { upd = ldata(ln); if(upd->cmdline && *str_ltrim(upd->cmdline) && str_starts("erase", str_ltrim(upd->cmdline))) break; // -T erase already erases the chip: no auto-erase needed - if(upd->cmdline || (upd->memstr && // Might be reading flash? - (upd->op == DEVICE_READ || upd->op == DEVICE_VERIFY) && - memlist_contains_flash(upd->memstr, p))) + if(upd->cmdline || (upd->memstr && // Might be reading flash? + (upd->op == DEVICE_READ || upd->op == DEVICE_VERIFY) && memlist_contains_flash(upd->memstr, p))) flashread = 1; if(upd->memstr && upd->op == DEVICE_WRITE && memlist_contains_flash(upd->memstr, p)) { @@ -1737,12 +1741,12 @@ skipopen: } } - if (init_ok && erase) { + if(init_ok && erase) { /* - * erase the chip's flash and eeprom memories, this is required - * before the chip can accept new programming + * Erase the chip's flash and eeprom memories, this is required before the + * chip can accept new programming */ - if (uflags & UF_NOWRITE) { + if(uflags & UF_NOWRITE) { if(explicit_e) pmsg_warning("conflicting -e and -n specified, NOT erasing chip\n"); else @@ -1766,12 +1770,13 @@ skipopen: goto main_exit; } - int wrmem = 0, terminal = 0; + if(lsize(updates) <= 1) - uflags |= UF_NOHEADING; - for (ln=lfirst(updates); ln; ln=lnext(ln)) { + uflags |= UF_NOHEADING; + for(ln = lfirst(updates); ln; ln = lnext(ln)) { const AVRMEM *m; + upd = ldata(ln); if(upd->cmdline && wrmem) { // Invalidate cache if device was written to wrmem = 0; @@ -1783,7 +1788,7 @@ skipopen: if((uflags & UF_NOWRITE) && upd->cmdline && !terminal++) pmsg_warning("the terminal ignores option -n, that is, it writes to the device\n"); rc = do_op(pgm, p, upd, uflags); - if (rc && rc != LIBAVRDUDE_SOFTFAIL) { + if(rc && rc != LIBAVRDUDE_SOFTFAIL) { exitrc = 1; break; } else if(rc == 0 && upd->op == DEVICE_WRITE && (m = avr_locate_mem(p, upd->memstr)) && mem_is_in_flash(m)) @@ -1798,7 +1803,7 @@ skipopen: main_exit: // Program complete - if (is_open) { + if(is_open) { // Clear rdy LED and summarise interaction in err, pgm and vfy LEDs led_set(pgm, LED_END); pgm->powerdown(pgm); @@ -1807,19 +1812,20 @@ main_exit: } if(cx->usb_access_error) { - pmsg_info( - "\nUSB access errors detected; this could have many reasons; if it is\n" + pmsg_info("\nUSB access errors detected; this could have many reasons; if it is\n" "USB permission problems, avrdude is likely to work when run as root\n" "but this is not good practice; instead you might want to\n"); + #if 0 && !defined(WIN32) DIR *dir; - if((dir = opendir("/etc/udev/rules.d"))) { // Linux udev land + + if((dir = opendir("/etc/udev/rules.d"))) { // Linux udev land closedir(dir); - imsg_info("run the command below to show udev rules recitifying USB access\n" - "$ %s -c %s/u\n", progname, pgmid); + imsg_info("run the command below to show udev rules recitifying USB access\n" "$ %s -c %s/u\n", progname, pgmid); } else #endif - imsg_info("check out USB port permissions on your OS and set them correctly\n"); + + imsg_info("check out USB port permissions on your OS and set them correctly\n"); } msg_info("\n");