Skip to content

Commit

Permalink
Revamp terminal output: progress bar, callback and stdout/stderr (#1132)
Browse files Browse the repository at this point in the history
* Print parms output to stdout
* Flush terminal writes and other minor changes
* Prepare terminal for periodic calls to programmer to reset bootloader WDT
* Only show progress reports for memories > 32 bytes or on -vv
* Freeze progress bar on serious error
* Allow cached r/w byte routines to be used in pgm->read_byte and pgm->write_byte
  • Loading branch information
stefanrueger committed Oct 23, 2022
1 parent 34fa2fa commit 5b008a0
Show file tree
Hide file tree
Showing 18 changed files with 423 additions and 357 deletions.
4 changes: 2 additions & 2 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ case "${ostype}" in
# Apple M1 (may be new version of homebrew also)
if [ -d /opt/homebrew ]
then
build_flags="${build_flags} -D CMAKE_C_FLAGS=-I/opt/homebrew/include -D CMAKE_EXE_LINKER_FLAGS=-L/opt/homebrew/Cellar"
build_flags="${build_flags} -D CMAKE_C_FLAGS=-I/opt/homebrew/include -D CMAKE_EXE_LINKER_FLAGS=-L/opt/homebrew/Cellar -D HAVE_LIBREADLINE:FILEPATH=/opt/homebrew/lib/libreadline.dylib"
else
build_flags="${build_flags} -D CMAKE_C_FLAGS=-I/usr/local/include -D CMAKE_EXE_LINKER_FLAGS=-L/usr/local/Cellar"
build_flags="${build_flags} -D CMAKE_C_FLAGS=-I/usr/local/include -D CMAKE_EXE_LINKER_FLAGS=-L/usr/local/Cellar -D HAVE_LIBREADLINE:FILEPATH=/usr/local/lib/libreadline.dylib"
fi
fi
;;
Expand Down
5 changes: 3 additions & 2 deletions src/avr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1036,13 +1036,14 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int
int avr_signature(const PROGRAMMER *pgm, const AVRPART *p) {
int rc;

report_progress (0,1,"Reading");
if(verbose > 1)
report_progress(0, 1, "Reading");
rc = avr_read(pgm, p, "signature", 0);
if (rc < LIBAVRDUDE_SUCCESS) {
pmsg_error("unable to read signature data for part %s, rc=%d\n", p->desc, rc);
return rc;
}
report_progress (1,1,NULL);
report_progress(1, 1, NULL);

return LIBAVRDUDE_SUCCESS;
}
Expand Down
46 changes: 28 additions & 18 deletions src/avrcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ int avr_has_paged_access(const PROGRAMMER *pgm, const AVRMEM *mem) {
}


#define fallback_read_byte (pgm->read_byte != avr_read_byte_cached? pgm->read_byte: avr_read_byte_default)
#define fallback_write_byte (pgm->write_byte != avr_write_byte_cached? pgm->write_byte: avr_write_byte_default)

/*
* Read the page containing addr from the device into buf
* - Caller to ensure buf has mem->page_size bytes
Expand All @@ -141,14 +144,14 @@ int avr_read_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
unsigned char *pagecopy = cfg_malloc("avr_read_page_default()", pgsize);

if(pgsize == 1)
return pgm->read_byte(pgm, p, mem, addr, buf);
return fallback_read_byte(pgm, p, mem, addr, buf);

memcpy(pagecopy, mem->buf + base, pgsize);
if((rc = pgm->paged_load(pgm, p, mem, pgsize, base, pgsize)) >= 0)
memcpy(buf, mem->buf + base, pgsize);
memcpy(mem->buf + base, pagecopy, pgsize);

if(rc < 0) {
if(rc < 0 && pgm->read_byte != avr_read_byte_cached) {
rc = LIBAVRDUDE_SUCCESS;
for(int i=0; i<pgsize; i++) {
if(pgm->read_byte(pgm, p, mem, base+i, pagecopy+i) < 0) {
Expand Down Expand Up @@ -179,7 +182,7 @@ int avr_write_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
unsigned char *pagecopy = cfg_malloc("avr_write_page_default()", pgsize);

if(pgsize == 1)
return pgm->write_byte(pgm, p, mem, addr, *data);
return fallback_write_byte(pgm, p, mem, addr, *data);

memcpy(pagecopy, mem->buf + base, pgsize);
memcpy(mem->buf + base, data, pgsize);
Expand Down Expand Up @@ -261,18 +264,25 @@ static int loadCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p,
static int writeCachePage(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, int base, int nlOnErr) {
// Write modified page cont to device; if unsuccessful try bytewise access
if(avr_write_page_default(pgm, p, mem, base, cp->cont + base) < 0) {
for(int i=0; i < cp->page_size; i++)
if(cp->cont[base+i] != cp->copy[base+i])
if(pgm->write_byte(pgm, p, mem, base+i, cp->cont[base+i]) < 0 ||
pgm->read_byte(pgm, p, mem, base+i, cp->copy+base+i) < 0) {
report_progress(1, -1, NULL);
if(nlOnErr && quell_progress)
msg_info("\n");
pmsg_error("writeCachePage() %s access error at addr 0x%04x\n", mem->desc, base+i);
return LIBAVRDUDE_GENERAL_FAILURE;
}
if(pgm->read_byte != avr_read_byte_cached && pgm->write_byte != avr_write_byte_cached) {
for(int i=0; i < cp->page_size; i++)
if(cp->cont[base+i] != cp->copy[base+i])
if(pgm->write_byte(pgm, p, mem, base+i, cp->cont[base+i]) < 0 ||
pgm->read_byte(pgm, p, mem, base+i, cp->copy+base+i) < 0) {
report_progress(1, -1, NULL);
if(nlOnErr && quell_progress)
msg_info("\n");
pmsg_error("%s access error at addr 0x%04x\n", mem->desc, base+i);
return LIBAVRDUDE_GENERAL_FAILURE;
}

return LIBAVRDUDE_SUCCESS; // Bytewise writes & reads successful
return LIBAVRDUDE_SUCCESS; // Bytewise writes & reads successful
}
report_progress(1, -1, NULL);
if(nlOnErr && quell_progress)
msg_info("\n");
pmsg_error("write %s page error at addr 0x%04x\n", mem->desc, base);
return LIBAVRDUDE_GENERAL_FAILURE;
}
// Read page back from device and update copy to what is on device
if(avr_read_page_default(pgm, p, mem, base, cp->copy + base) < 0) {
Expand Down Expand Up @@ -552,7 +562,7 @@ int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *

// Use pgm->read_byte() if not EEPROM/flash or no paged access
if(!avr_has_paged_access(pgm, mem))
return pgm->read_byte(pgm, p, mem, addr, value);
return fallback_read_byte(pgm, p, mem, addr, value);

// If address is out of range synchronise cache and, if successful, pretend reading a zero
if(addr >= (unsigned long) mem->size) {
Expand Down Expand Up @@ -592,9 +602,9 @@ int avr_read_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *
int avr_write_byte_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char data) {

// Use pgm->read_byte() if not EEPROM/flash or no paged access
// Use pgm->write_byte() if not EEPROM/flash or no paged access
if(!avr_has_paged_access(pgm, mem))
return pgm->write_byte(pgm, p, mem, addr, data);
return fallback_write_byte(pgm, p, mem, addr, data);

// If address is out of range synchronise caches with device and return whether successful
if(addr >= (unsigned long) mem->size)
Expand Down Expand Up @@ -687,7 +697,7 @@ int avr_page_erase_cached(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
return LIBAVRDUDE_GENERAL_FAILURE;

if(mem->page_size == 1) {
if(pgm->write_byte(pgm, p, mem, uaddr, 0xff) < 0)
if(fallback_write_byte(pgm, p, mem, uaddr, 0xff) < 0)
return LIBAVRDUDE_GENERAL_FAILURE;
} else {
if(!pgm->page_erase || pgm->page_erase(pgm, p, mem, uaddr) < 0)
Expand Down
72 changes: 39 additions & 33 deletions src/avrdude.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#ifndef avrdude_h
#define avrdude_h

#include <stdio.h>

#define SYSTEM_CONF_FILE "avrdude.conf"
#if defined(WIN32)
#define USER_CONF_FILE "avrdude.rc"
Expand All @@ -37,7 +39,7 @@ extern int verbose; // verbosity level (-v, -vv, ...)
extern int quell_progress; // quell progress report -q, reduce effective verbosity level (-qq, -qqq)

int avrdude_message(int msglvl, const char *format, ...);
int avrdude_message2(const char *fname, int msgmode, int msglvl, const char *format, ...);
int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, int msgmode, int msglvl, const char *format, ...);

#define MSG_EXT_ERROR (-3) // OS-type error, no -v option, can be suppressed with -qqqqq
#define MSG_ERROR (-2) // Avrdude error, no -v option, can be suppressed with -qqqq
Expand All @@ -50,41 +52,45 @@ int avrdude_message2(const char *fname, int msgmode, int msglvl, const char *for
#define MSG_TRACE2 5 // Displayed with -vvvvv

#define MSG2_PROGNAME 1 // Start by printing progname
#define MSG2_FUNCTION 2 // Print calling function (1st arg) after progname
#define MSG2_TYPE 4 // Print message type after function or progname
#define MSG2_INDENT1 8 // Start by printing indentation of progname+1 blanks
#define MSG2_INDENT2 16 // Start by printing indentation of progname+2 blanks
#define MSG2_FLUSH 32 // Flush before and after printing
#define MSG2_FUNCTION 2 // Print calling function (1st arg) after progname if >= notice
#define MSG2_FILELINE 4 // Print source file and line number after function if >= debug
#define MSG2_TYPE 8 // Print message type after function or progname
#define MSG2_INDENT1 16 // Start by printing indentation of progname+1 blanks
#define MSG2_INDENT2 32 // Start by printing indentation of progname+2 blanks
#define MSG2_FLUSH 64 // Flush before and after printing

// Shortcuts
#define msg_ext_error(...) avrdude_message2(__func__, 0, MSG_EXT_ERROR, __VA_ARGS__)
#define msg_error(...) avrdude_message2(__func__, 0, MSG_ERROR, __VA_ARGS__)
#define msg_warning(...) avrdude_message2(__func__, 0, MSG_WARNING, __VA_ARGS__)
#define msg_info(...) avrdude_message2(__func__, 0, MSG_INFO, __VA_ARGS__)
#define msg_notice(...) avrdude_message2(__func__, 0, MSG_NOTICE, __VA_ARGS__)
#define msg_notice2(...) avrdude_message2(__func__, 0, MSG_NOTICE2, __VA_ARGS__)
#define msg_debug(...) avrdude_message2(__func__, 0, MSG_DEBUG, __VA_ARGS__)
#define msg_trace(...) avrdude_message2(__func__, 0, MSG_TRACE, __VA_ARGS__)
#define msg_trace2(...) avrdude_message2(__func__, 0, MSG_TRACE2, __VA_ARGS__)
#define msg_ext_error(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_EXT_ERROR, __VA_ARGS__)
#define msg_error(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_ERROR, __VA_ARGS__)
#define msg_warning(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_WARNING, __VA_ARGS__)
#define msg_info(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_INFO, __VA_ARGS__)
#define msg_notice(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_NOTICE, __VA_ARGS__)
#define msg_notice2(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_NOTICE2, __VA_ARGS__)
#define msg_debug(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_DEBUG, __VA_ARGS__)
#define msg_trace(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_TRACE, __VA_ARGS__)
#define msg_trace2(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_TRACE2, __VA_ARGS__)

#define pmsg_ext_error(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FUNCTION|MSG2_FILELINE|MSG2_TYPE|MSG2_FLUSH, MSG_EXT_ERROR, __VA_ARGS__)
#define pmsg_error(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FUNCTION|MSG2_FILELINE|MSG2_TYPE|MSG2_FLUSH, MSG_ERROR, __VA_ARGS__)
#define pmsg_warning(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FUNCTION|MSG2_FILELINE|MSG2_TYPE|MSG2_FLUSH, MSG_WARNING, __VA_ARGS__)
#define pmsg_info(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_INFO, __VA_ARGS__)
#define pmsg_notice(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_NOTICE, __VA_ARGS__)
#define pmsg_notice2(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_NOTICE2, __VA_ARGS__)
#define pmsg_debug(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_DEBUG, __VA_ARGS__)
#define pmsg_trace(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_TRACE, __VA_ARGS__)
#define pmsg_trace2(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_TRACE2, __VA_ARGS__)

#define pmsg_ext_error(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FUNCTION|MSG2_TYPE|MSG2_FLUSH, MSG_EXT_ERROR, __VA_ARGS__)
#define pmsg_error(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FUNCTION|MSG2_TYPE|MSG2_FLUSH, MSG_ERROR, __VA_ARGS__)
#define pmsg_warning(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FUNCTION|MSG2_TYPE|MSG2_FLUSH, MSG_WARNING, __VA_ARGS__)
#define pmsg_info(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_INFO, __VA_ARGS__)
#define pmsg_notice(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_NOTICE, __VA_ARGS__)
#define pmsg_notice2(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_NOTICE2, __VA_ARGS__)
#define pmsg_debug(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_DEBUG, __VA_ARGS__)
#define pmsg_trace(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_TRACE, __VA_ARGS__)
#define pmsg_trace2(...) avrdude_message2(__func__, MSG2_PROGNAME|MSG2_FLUSH, MSG_TRACE2, __VA_ARGS__)
#define imsg_ext_error(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT1|MSG2_FLUSH, MSG_EXT_ERROR, __VA_ARGS__)
#define imsg_error(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT1|MSG2_FLUSH, MSG_ERROR, __VA_ARGS__)
#define imsg_warning(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT1|MSG2_FLUSH, MSG_WARNING, __VA_ARGS__)
#define imsg_info(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT2|MSG2_FLUSH, MSG_INFO, __VA_ARGS__)
#define imsg_notice(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT2|MSG2_FLUSH, MSG_NOTICE, __VA_ARGS__)
#define imsg_notice2(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT2|MSG2_FLUSH, MSG_NOTICE2, __VA_ARGS__)
#define imsg_debug(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT2|MSG2_FLUSH, MSG_DEBUG, __VA_ARGS__)
#define imsg_trace(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT2|MSG2_FLUSH, MSG_TRACE, __VA_ARGS__)
#define imsg_trace2(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, MSG2_INDENT2|MSG2_FLUSH, MSG_TRACE2, __VA_ARGS__)

#define imsg_ext_error(...) avrdude_message2(__func__, MSG2_INDENT1|MSG2_FLUSH, MSG_EXT_ERROR, __VA_ARGS__)
#define imsg_error(...) avrdude_message2(__func__, MSG2_INDENT1|MSG2_FLUSH, MSG_ERROR, __VA_ARGS__)
#define imsg_warning(...) avrdude_message2(__func__, MSG2_INDENT1|MSG2_FLUSH, MSG_WARNING, __VA_ARGS__)
#define imsg_info(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_INFO, __VA_ARGS__)
#define imsg_notice(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_NOTICE, __VA_ARGS__)
#define imsg_notice2(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_NOTICE2, __VA_ARGS__)
#define imsg_debug(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_DEBUG, __VA_ARGS__)
#define imsg_trace(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_TRACE, __VA_ARGS__)
#define imsg_trace2(...) avrdude_message2(__func__, MSG2_INDENT2|MSG2_FLUSH, MSG_TRACE2, __VA_ARGS__)
#define term_out(...) avrdude_message2(stdout, __LINE__, __FILE__, __func__, MSG2_FLUSH, MSG_INFO, __VA_ARGS__)
#define fmsg_out(fp, ...) avrdude_message2(fp, __LINE__, __FILE__, __func__, MSG2_FLUSH, MSG_INFO, __VA_ARGS__)

#endif
11 changes: 2 additions & 9 deletions src/avrpart.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,22 +498,15 @@ void avr_mem_display(const char *prefix, FILE *f, const AVRMEM *m,
int i, j;
char * optr;

if (m == NULL) {
if (m == NULL || verbose > 2) {
fprintf(f,
"%s Block Poll Page Polled\n"
"%sMemory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack\n"
"%s----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------\n",
prefix, prefix, prefix);
}
else {
if (verbose > 2) {
fprintf(f,
"%s Block Poll Page Polled\n"
"%sMemory Type Alias Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack\n"
"%s----------- -------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------\n",
prefix, prefix, prefix);
}

if (m != NULL) {
// Only print memory section if the previous section printed isn't identical
if(prev_mem_offset != m->offset || prev_mem_size != m->size || (strcmp(p->family_id, "") == 0)) {
prev_mem_offset = m->offset;
Expand Down
4 changes: 2 additions & 2 deletions src/flip2.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ enum flip2_mem_unit {
FLIP2_MEM_UNIT_EXT_MEM_DF = 0x10
};

#ifdef HAVE_LIBUSB

/* EXPORTED PROGRAMMER FUNCTION PROTOTYPES */

static int flip2_open(PROGRAMMER *pgm, const char *port_spec);
Expand All @@ -146,8 +148,6 @@ static void flip2_setup(PROGRAMMER * pgm);
static void flip2_teardown(PROGRAMMER * pgm);

/* INTERNAL PROGRAMMER FUNCTION PROTOTYPES */
#ifdef HAVE_LIBUSB
// The internal ones are made conditional, as they're not defined further down #ifndef HAVE_LIBUSB

static void flip2_show_info(struct flip2 *flip2);

Expand Down
Loading

0 comments on commit 5b008a0

Please sign in to comment.