Revamp terminal output: progress bar, callback and stdout/stderr (#1132)

* 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
This commit is contained in:
Stefan Rueger 2022-10-23 21:56:45 +01:00 committed by GitHub
parent 34fa2faba5
commit 5b008a04cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 421 additions and 355 deletions

View File

@ -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
;;

View File

@ -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;
}

View File

@ -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
@ -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) {
@ -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);
@ -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) {
@ -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) {
@ -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)
@ -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)

View File

@ -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"
@ -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
@ -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(__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 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 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 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 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

View File

@ -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;

View File

@ -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);
@ -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);

View File

@ -103,7 +103,7 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM
static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem,
unsigned long addr, unsigned char data);
static int jtag3_set_sck_period(const PROGRAMMER *pgm, double v);
void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p);
void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp);
static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes);
@ -1077,7 +1077,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) {
if (PDATA(pgm)->set_sck(pgm, parm) < 0)
return -1;
}
jtag3_print_parms1(pgm, progbuf);
jtag3_print_parms1(pgm, progbuf, stderr);
if (conn == PARM3_CONN_JTAG)
{
pmsg_notice2("jtag3_initialize(): "
@ -2333,12 +2333,12 @@ static void jtag3_display(const PROGRAMMER *pgm, const char *p) {
}
void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) {
void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) {
unsigned char buf[3];
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VTARGET, buf, 2) < 0)
return;
msg_info("%sVtarget %s: %.2f V\n", p,
fmsg_out(fp, "%sVtarget %s: %.2f V\n", p,
verbose? "": " ", b2_to_u16(buf)/1000.0);
// Print features unique to the Power Debugger
@ -2350,7 +2350,7 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) {
if (jtag3_getparm(pgm, SCOPE_GENERAL, 1, PARM3_VADJUST, buf, 2) < 0)
return;
analog_raw_data = b2_to_u16(buf);
msg_info("%sVout set %s: %.2f V\n", p,
fmsg_out(fp, "%sVout set %s: %.2f V\n", p,
verbose? "": " ", analog_raw_data / 1000.0);
// Read measured generator voltage value (VOUT)
@ -2362,7 +2362,7 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) {
else {
if (analog_raw_data & 0x0800)
analog_raw_data |= 0xF000;
msg_info("%sVout measured %s: %.02f V\n", p,
fmsg_out(fp, "%sVout measured %s: %.02f V\n", p,
verbose? "": " ", ((float) analog_raw_data / -200.0));
}
@ -2375,7 +2375,7 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) {
else {
if (analog_raw_data & 0x0800)
analog_raw_data |= 0xF000;
msg_info("%sCh A voltage %s: %.03f V\n", p,
fmsg_out(fp, "%sCh A voltage %s: %.03f V\n", p,
verbose? "": " ", ((float) analog_raw_data / -200.0));
}
@ -2386,7 +2386,7 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) {
if (buf[0] != 0x90)
pmsg_error("invalid PARM3_ANALOG_A_CURRENT data packet format\n");
else
msg_info("%sCh A current %s: %.3f mA\n", p,
fmsg_out(fp, "%sCh A current %s: %.3f mA\n", p,
verbose? "": " ", (float) analog_raw_data * 0.003472);
// Read channel B voltage
@ -2398,7 +2398,7 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) {
else {
if (analog_raw_data & 0x0800)
analog_raw_data |= 0xF000;
msg_info("%sCh B voltage %s: %.03f V\n", p,
fmsg_out(fp, "%sCh B voltage %s: %.03f V\n", p,
verbose? "": " ", (float) analog_raw_data / -200.0);
}
@ -2411,7 +2411,7 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) {
else {
if (analog_raw_data & 0x0800)
analog_raw_data |= 0xF000;
msg_info("%sCh B current %s: %.3f mA\n", p,
fmsg_out(fp, "%sCh B current %s: %.3f mA\n", p,
verbose? "": " ", (float) analog_raw_data * 0.555556);
}
break;
@ -2422,33 +2422,33 @@ void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p) {
return;
if (b2_to_u16(buf) > 0) {
msg_info("%sJTAG clock megaAVR/program : %u kHz\n", p, b2_to_u16(buf));
fmsg_out(fp, "%sJTAG clock megaAVR/program : %u kHz\n", p, b2_to_u16(buf));
}
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_MEGA_DEBUG, buf, 2) < 0)
return;
if (b2_to_u16(buf) > 0) {
msg_info("%sJTAG clock megaAVR/debug : %u kHz\n", p, b2_to_u16(buf));
fmsg_out(fp, "%sJTAG clock megaAVR/debug : %u kHz\n", p, b2_to_u16(buf));
}
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_JTAG, buf, 2) < 0)
return;
if (b2_to_u16(buf) > 0) {
msg_info("%sJTAG clock Xmega : %u kHz\n", p, b2_to_u16(buf));
fmsg_out(fp, "%sJTAG clock Xmega : %u kHz\n", p, b2_to_u16(buf));
}
if (jtag3_getparm(pgm, SCOPE_AVR, 1, PARM3_CLK_XMEGA_PDI, buf, 2) < 0)
return;
if (b2_to_u16(buf) > 0) {
msg_info("%sPDI/UPDI clock Xmega/megaAVR : %u kHz\n", p, b2_to_u16(buf));
fmsg_out(fp, "%sPDI/UPDI clock Xmega/megaAVR : %u kHz\n", p, b2_to_u16(buf));
}
}
static void jtag3_print_parms(const PROGRAMMER *pgm) {
jtag3_print_parms1(pgm, "");
static void jtag3_print_parms(const PROGRAMMER *pgm, FILE *fp) {
jtag3_print_parms1(pgm, "", fp);
}
static unsigned char jtag3_memtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr) {

View File

@ -38,7 +38,7 @@ int jtag3_setparm(const PROGRAMMER *pgm, unsigned char scope,
unsigned char *value, unsigned char length);
int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
unsigned char **resp, const char *descr);
void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p);
void jtag3_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp);
int jtag3_set_vtarget(const PROGRAMMER *pgm, double voltage);
extern const char jtag3_desc[];
extern const char jtag3_dw_desc[];

View File

@ -104,7 +104,7 @@ static int jtagmkI_getparm(const PROGRAMMER *pgm, unsigned char parm,
unsigned char * value);
static int jtagmkI_setparm(const PROGRAMMER *pgm, unsigned char parm,
unsigned char value);
static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p);
static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp);
static int jtagmkI_resync(const PROGRAMMER *pgm, int maxtries, int signon);
@ -1170,13 +1170,13 @@ static void jtagmkI_display(const PROGRAMMER *pgm, const char *p) {
msg_info("%sICE HW version: 0x%02x\n", p, hw);
msg_info("%sICE FW version: 0x%02x\n", p, fw);
jtagmkI_print_parms1(pgm, p);
jtagmkI_print_parms1(pgm, p, stderr);
return;
}
static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p) {
static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) {
unsigned char vtarget, jtag_clock;
const char *clkstr;
double clk;
@ -1211,15 +1211,15 @@ static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p) {
clk = 1e6;
}
msg_info("%sVtarget : %.1f V\n", p, 6.25 * (unsigned)vtarget / 255.0);
msg_info("%sJTAG clock : %s (%.1f us)\n", p, clkstr, 1.0e6 / clk);
fmsg_out(fp, "%sVtarget : %.1f V\n", p, 6.25 * (unsigned)vtarget / 255.0);
fmsg_out(fp, "%sJTAG clock : %s (%.1f us)\n", p, clkstr, 1.0e6 / clk);
return;
}
static void jtagmkI_print_parms(const PROGRAMMER *pgm) {
jtagmkI_print_parms1(pgm, "");
static void jtagmkI_print_parms(const PROGRAMMER *pgm, FILE *fp) {
jtagmkI_print_parms1(pgm, "", fp);
}
const char jtagmkI_desc[] = "Atmel JTAG ICE mkI";

View File

@ -144,7 +144,7 @@ static int jtagmkII_reset(const PROGRAMMER *pgm, unsigned char flags);
static int jtagmkII_set_sck_period(const PROGRAMMER *pgm, double v);
static int jtagmkII_setparm(const PROGRAMMER *pgm, unsigned char parm,
unsigned char * value);
static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p);
static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp);
static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes);
@ -2508,13 +2508,13 @@ static void jtagmkII_display(const PROGRAMMER *pgm, const char *p) {
PDATA(pgm)->serno[0], PDATA(pgm)->serno[1], PDATA(pgm)->serno[2],
PDATA(pgm)->serno[3], PDATA(pgm)->serno[4], PDATA(pgm)->serno[5]);
jtagmkII_print_parms1(pgm, p);
jtagmkII_print_parms1(pgm, p, stderr);
return;
}
static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p) {
static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) {
unsigned char vtarget[4], jtag_clock[4];
char clkbuf[20];
double clk;
@ -2522,7 +2522,7 @@ static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p) {
if (jtagmkII_getparm(pgm, PAR_OCD_VTARGET, vtarget) < 0)
return;
msg_info("%sVtarget : %.1f V\n", p, b2_to_u16(vtarget) / 1000.0);
fmsg_out(fp, "%sVtarget : %.1f V\n", p, b2_to_u16(vtarget) / 1000.0);
if ((pgm->flag & PGM_FL_IS_JTAG)) {
if (jtagmkII_getparm(pgm, PAR_OCD_JTAG_CLK, jtag_clock) < 0)
@ -2541,15 +2541,15 @@ static void jtagmkII_print_parms1(const PROGRAMMER *pgm, const char *p) {
sprintf(clkbuf, "%.1f kHz", 5.35e3 / (double)jtag_clock[0]);
clk = 5.35e6 / (double)jtag_clock[0];
msg_info("%sJTAG clock : %s (%.1f us)\n", p, clkbuf, 1.0e6 / clk);
fmsg_out(fp, "%sJTAG clock : %s (%.1f us)\n", p, clkbuf, 1.0e6 / clk);
}
}
return;
}
static void jtagmkII_print_parms(const PROGRAMMER *pgm) {
jtagmkII_print_parms1(pgm, "");
static void jtagmkII_print_parms(const PROGRAMMER *pgm, FILE *fp) {
jtagmkII_print_parms1(pgm, "", fp);
}
static unsigned char jtagmkII_memtype(const PROGRAMMER *pgm, const AVRPART *p, unsigned long addr) {

View File

@ -783,7 +783,8 @@ typedef struct programmer_t {
unsigned long addr, unsigned char *value);
int (*read_sig_bytes) (const struct programmer_t *pgm, const AVRPART *p, const AVRMEM *m);
int (*read_sib) (const struct programmer_t *pgm, const AVRPART *p, char *sib);
void (*print_parms) (const struct programmer_t *pgm);
int (*term_keep_alive)(const struct programmer_t *pgm, const AVRPART *p);
void (*print_parms) (const struct programmer_t *pgm, FILE *fp);
int (*set_vtarget) (const struct programmer_t *pgm, double v);
int (*set_varef) (const struct programmer_t *pgm, unsigned int chan, double v);
int (*set_fosc) (const struct programmer_t *pgm, double v);

View File

@ -87,36 +87,48 @@ static const char *avrdude_message_type(int msglvl) {
}
}
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, ...) {
int rc = 0;
va_list ap;
if(msglvl <= MSG_ERROR) // Serious error? Freee 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
if ((quell_progress < 2? verbose: verbose+1-quell_progress) >= msglvl) {
// 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_PROGNAME) {
fprintf(stderr, "%s", progname);
fprintf(fp, "%s", progname);
if(verbose >= MSG_NOTICE && (msgmode & MSG2_FUNCTION))
fprintf(stderr, " %s()", fname);
fprintf(fp, " %s()", func);
if(verbose >= MSG_DEBUG && (msgmode & MSG2_FILELINE)) {
const char *pr = strrchr(file, '/'); // only print basename
#if defined (WIN32)
if(!pr)
pr = strrchr(file, '\\');
#endif
pr = pr? pr+1: file;
fprintf(fp, " [%s:%d]", pr, lno);
}
if(msgmode & MSG2_TYPE)
fprintf(stderr, " %s", avrdude_message_type(msglvl));
fprintf(stderr, ": ");
fprintf(fp, " %s", avrdude_message_type(msglvl));
fprintf(fp, ": ");
} else if(msgmode & MSG2_INDENT1) {
fprintf(stderr, "%*s", (int) strlen(progname)+1, "");
fprintf(fp, "%*s", (int) strlen(progname)+1, "");
} else if(msgmode & MSG2_INDENT2) {
fprintf(stderr, "%*s", (int) strlen(progname)+2, "");
fprintf(fp, "%*s", (int) strlen(progname)+2, "");
}
va_start(ap, format);
rc = vfprintf(stderr, format, ap);
rc = vfprintf(fp, format, ap);
va_end(ap);
}
if(msgmode & MSG2_FLUSH)
fflush(stderr);
fflush(fp);
return rc;
}

View File

@ -140,6 +140,7 @@ PROGRAMMER *pgm_new(void) {
pgm->write_setup = NULL;
pgm->read_sig_bytes = NULL;
pgm->read_sib = NULL;
pgm->term_keep_alive= NULL;
pgm->print_parms = NULL;
pgm->set_vtarget = NULL;
pgm->set_varef = NULL;

View File

@ -47,7 +47,7 @@
static int stk500_getparm(const PROGRAMMER *pgm, unsigned parm, unsigned *value);
static int stk500_setparm(const PROGRAMMER *pgm, unsigned parm, unsigned value);
static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p);
static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp);
static int stk500_send(const PROGRAMMER *pgm, unsigned char *buf, size_t len) {
@ -1160,13 +1160,13 @@ static void stk500_display(const PROGRAMMER *pgm, const char *p) {
msg_info("%sTopcard : %s\n", p, n);
}
if(strcmp(pgm->type, "Arduino") != 0)
stk500_print_parms1(pgm, p);
stk500_print_parms1(pgm, p, stderr);
return;
}
static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p) {
static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) {
unsigned vtarget, vadjust, osc_pscale, osc_cmatch, sck_duration;
stk500_getparm(pgm, Parm_STK_VTARGET, &vtarget);
@ -1175,11 +1175,11 @@ static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p) {
stk500_getparm(pgm, Parm_STK_OSC_CMATCH, &osc_cmatch);
stk500_getparm(pgm, Parm_STK_SCK_DURATION, &sck_duration);
msg_info("%sVtarget : %.1f V\n", p, vtarget / 10.0);
msg_info("%sVaref : %.1f V\n", p, vadjust / 10.0);
msg_info("%sOscillator : ", p);
fmsg_out(fp, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
fmsg_out(fp, "%sVaref : %.1f V\n", p, vadjust / 10.0);
fmsg_out(fp, "%sOscillator : ", p);
if (osc_pscale == 0)
msg_info("Off\n");
fmsg_out(fp, "Off\n");
else {
int prescale = 1;
double f = STK500_XTAL / 2;
@ -1203,16 +1203,16 @@ static void stk500_print_parms1(const PROGRAMMER *pgm, const char *p) {
unit = "kHz";
} else
unit = "Hz";
msg_info("%.3f %s\n", f, unit);
fmsg_out(fp, "%.3f %s\n", f, unit);
}
msg_info("%sSCK period : %.1f us\n", p, sck_duration * 8.0e6 / STK500_XTAL + 0.05);
fmsg_out(fp, "%sSCK period : %.1f us\n", p, sck_duration * 8.0e6 / STK500_XTAL + 0.05);
return;
}
static void stk500_print_parms(const PROGRAMMER *pgm) {
stk500_print_parms1(pgm, "");
static void stk500_print_parms(const PROGRAMMER *pgm, FILE *fp) {
stk500_print_parms1(pgm, "", fp);
}
static void stk500_setup(PROGRAMMER * pgm)

View File

@ -262,7 +262,7 @@ static int stk500v2_setparm(const PROGRAMMER *pgm, unsigned char parm, unsigned
static int stk500v2_getparm2(const PROGRAMMER *pgm, unsigned char parm, unsigned int *value);
static int stk500v2_setparm2(const PROGRAMMER *pgm, unsigned char parm, unsigned int value);
static int stk500v2_setparm_real(const PROGRAMMER *pgm, unsigned char parm, unsigned char value);
static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p);
static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp);
static int stk500v2_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m,
unsigned int page_size,
unsigned int addr, unsigned int n_bytes);
@ -3075,7 +3075,7 @@ static void stk500v2_display(const PROGRAMMER *pgm, const char *p) {
stk500v2_getparm2(pgm, PARAM2_EC_ID_TABLE_REV, &rev);
msg_info("%sEC_ID table rev : %d\n", p, rev);
}
stk500v2_print_parms1(pgm, p);
stk500v2_print_parms1(pgm, p, stderr);
return;
}
@ -3095,7 +3095,7 @@ f_to_kHz_MHz(double f, const char **unit)
return f;
}
static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) {
static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) {
unsigned char vtarget = 0, vadjust = 0, osc_pscale = 0, osc_cmatch = 0, sck_duration =0; //XXX 0 is not correct, check caller
unsigned int sck_stk600, clock_conf, dac, oct, varef;
unsigned char vtarget_jtag[4];
@ -3110,8 +3110,7 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) {
pgmcp->cookie = PDATA(pgm)->chained_pdata;
jtagmkII_getparm(pgmcp, PAR_OCD_VTARGET, vtarget_jtag);
pgm_free(pgmcp);
msg_info("%sVtarget : %.1f V\n", p,
b2_to_u16(vtarget_jtag) / 1000.0);
fmsg_out(fp, "%sVtarget : %.1f V\n", p, b2_to_u16(vtarget_jtag) / 1000.0);
} else if (PDATA(pgm)->pgmtype == PGMTYPE_JTAGICE3) {
PROGRAMMER *pgmcp = pgm_dup(pgm);
pgmcp->cookie = PDATA(pgm)->chained_pdata;
@ -3119,11 +3118,11 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) {
// Copy pgm->id contents over to pgmcp->id
for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln))
ladd(pgmcp->id, cfg_strdup("stk500v2_print_parms1()", ldata(ln)));
jtag3_print_parms1(pgmcp, p);
jtag3_print_parms1(pgmcp, p, fp);
pgm_free(pgmcp);
} else {
stk500v2_getparm(pgm, PARAM_VTARGET, &vtarget);
msg_info("%sVtarget : %.1f V\n", p, vtarget / 10.0);
fmsg_out(fp, "%sVtarget : %.1f V\n", p, vtarget / 10.0);
}
switch (PDATA(pgm)->pgmtype) {
@ -3132,12 +3131,12 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) {
stk500v2_getparm(pgm, PARAM_VADJUST, &vadjust);
stk500v2_getparm(pgm, PARAM_OSC_PSCALE, &osc_pscale);
stk500v2_getparm(pgm, PARAM_OSC_CMATCH, &osc_cmatch);
msg_info("%sSCK period : %.1f us\n", p,
fmsg_out(fp, "%sSCK period : %.1f us\n", p,
stk500v2_sck_to_us(pgm, sck_duration));
msg_info("%sVaref : %.1f V\n", p, vadjust / 10.0);
msg_info("%sOscillator : ", p);
fmsg_out(fp, "%sVaref : %.1f V\n", p, vadjust / 10.0);
fmsg_out(fp, "%sOscillator : ", p);
if (osc_pscale == 0)
msg_info("Off\n");
fmsg_out(fp, "Off\n");
else {
prescale = 1;
f = STK500V2_XTAL / 2;
@ -3153,14 +3152,14 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) {
f /= prescale;
f /= (osc_cmatch + 1);
f = f_to_kHz_MHz(f, &unit);
msg_info("%.3f %s\n", f, unit);
fmsg_out(fp, "%.3f %s\n", f, unit);
}
break;
case PGMTYPE_AVRISP_MKII:
case PGMTYPE_JTAGICE_MKII:
stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration);
msg_info("%sSCK period : %.2f us\n", p,
fmsg_out(fp, "%sSCK period : %.2f us\n", p,
(float) 1000000 / avrispmkIIfreqs[sck_duration]);
break;
@ -3172,7 +3171,7 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) {
if (stk500v2_jtag3_send(pgm, cmd, 1) >= 0 &&
stk500v2_jtag3_recv(pgm, cmd, 4) >= 2) {
unsigned int sck = cmd[1] | (cmd[2] << 8);
msg_info("%sSCK period : %.2f us\n", p,
fmsg_out(fp, "%sSCK period : %.2f us\n", p,
(float)(1E6 / (1000.0 * sck)));
}
}
@ -3180,23 +3179,23 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) {
case PGMTYPE_STK600:
stk500v2_getparm2(pgm, PARAM2_AREF0, &varef);
msg_info("%sVaref 0 : %.2f V\n", p, varef / 100.0);
fmsg_out(fp, "%sVaref 0 : %.2f V\n", p, varef / 100.0);
stk500v2_getparm2(pgm, PARAM2_AREF1, &varef);
msg_info("%sVaref 1 : %.2f V\n", p, varef / 100.0);
fmsg_out(fp, "%sVaref 1 : %.2f V\n", p, varef / 100.0);
stk500v2_getparm2(pgm, PARAM2_SCK_DURATION, &sck_stk600);
msg_info("%sSCK period : %.2f us\n", p,
fmsg_out(fp, "%sSCK period : %.2f us\n", p,
(float) (sck_stk600 + 1) / 8.0);
stk500v2_getparm2(pgm, PARAM2_CLOCK_CONF, &clock_conf);
oct = (clock_conf & 0xf000) >> 12u;
dac = (clock_conf & 0x0ffc) >> 2u;
f = pow(2, (double)oct) * 2078.0 / (2 - (double)dac / 1024.0);
f = f_to_kHz_MHz(f, &unit);
msg_info("%sOscillator : %.3f %s\n",
fmsg_out(fp, "%sOscillator : %.3f %s\n",
p, f, unit);
break;
default:
msg_info("%sSCK period : %.1f us\n", p,
fmsg_out(fp, "%sSCK period : %.1f us\n", p,
sck_duration * 8.0e6 / STK500V2_XTAL + 0.05);
break;
}
@ -3205,8 +3204,8 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p) {
}
static void stk500v2_print_parms(const PROGRAMMER *pgm) {
stk500v2_print_parms1(pgm, "");
static void stk500v2_print_parms(const PROGRAMMER *pgm, FILE *fp) {
stk500v2_print_parms1(pgm, "", fp);
}
static int stk500v2_perform_osccal(const PROGRAMMER *pgm) {

View File

@ -33,10 +33,21 @@
#include <errno.h>
#if defined(HAVE_LIBREADLINE)
# include <readline/readline.h>
# include <readline/history.h>
#include <readline/readline.h>
#include <readline/history.h>
#ifdef _MSC_VER
#include "msvc/unistd.h"
#else
#include <unistd.h>
#endif
#ifdef WIN32
#include <windows.h>
#endif
#endif
#include "avrdude.h"
#include "term.h"
@ -114,7 +125,7 @@ static int nexttok(char *buf, char **tok, char **next) {
n = q;
uint8_t quotes = 0;
while (*n && (!isspace(*n) || quotes)) {
// poor man's quote and escape processing
// Poor man's quote and escape processing
if (*n == '"' || *n == '\'')
quotes++;
else if(*n == '\\' && n[1])
@ -173,7 +184,7 @@ static int chardump_line(char *buffer, unsigned char *p, int n, int pad) {
int i;
unsigned char b[128];
// sanity check
// Sanity check
n = n < 1? 1: n > sizeof b? sizeof b: n;
memcpy(b, p, n);
@ -202,7 +213,7 @@ static int hexdump_buf(FILE *f, int startaddr, unsigned char *buf, int len) {
n = len;
hexdump_line(dst1, p, n, 48);
chardump_line(dst2, p, n, 16);
fprintf(f, "%04x %s |%s|\n", addr, dst1, dst2);
term_out("%04x %s |%s|\n", addr, dst1, dst2);
len -= n;
addr += n;
p += n;
@ -214,7 +225,7 @@ static int hexdump_buf(FILE *f, int startaddr, unsigned char *buf, int len) {
static int cmd_dump(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
if (argc < 2 || argc > 4) {
terminal_message(MSG_INFO,
msg_error(
"Usage: %s <memory> <addr> <len>\n"
" %s <memory> <addr> ...\n"
" %s <memory> <addr>\n"
@ -229,8 +240,7 @@ static int cmd_dump(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
char *memtype = argv[1];
AVRMEM *mem = avr_locate_mem(p, memtype);
if (mem == NULL) {
terminal_message(MSG_INFO, "%s (dump): %s memory type not defined for part %s\n",
progname, memtype, p->desc);
pmsg_error("(dump) %s memory type not defined for part %s\n", memtype, p->desc);
return -1;
}
int maxsize = mem->size;
@ -242,12 +252,10 @@ static int cmd_dump(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
if (argc >= 3 && strcmp(argv[2], "...") != 0) {
addr = strtoul(argv[2], &end_ptr, 0);
if (*end_ptr || (end_ptr == argv[2])) {
terminal_message(MSG_INFO, "%s (dump): can't parse address %s\n",
progname, argv[2]);
pmsg_error("(dump) cannot parse address %s\n", argv[2]);
return -1;
} else if (addr < 0 || addr >= maxsize) {
terminal_message(MSG_INFO, "%s (dump): %s address 0x%05x is out of range [0, 0x%05x]\n",
progname, mem->desc, addr, maxsize-1);
pmsg_error("(dump) %s address 0x%05x is out of range [0, 0x%05x]\n", mem->desc, addr, maxsize-1);
return -1;
}
}
@ -263,8 +271,7 @@ static int cmd_dump(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
} else if (argc == 4) {
len = strtol(argv[3], &end_ptr, 0);
if (*end_ptr || (end_ptr == argv[3])) {
terminal_message(MSG_INFO, "%s (dump): can't parse length %s\n",
progname, argv[3]);
pmsg_error("(dump) cannot parse length %s\n", argv[3]);
return -1;
}
} else {
@ -288,7 +295,7 @@ static int cmd_dump(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
uint8_t *buf = malloc(len);
if (buf == NULL) {
terminal_message(MSG_INFO, "%s (dump): out of memory\n", progname);
pmsg_error("(dump) out of memory\n");
return -1;
}
@ -297,11 +304,9 @@ static int cmd_dump(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
int rc = pgm->read_byte_cached(pgm, p, mem, addr + i, &buf[i]);
if (rc != 0) {
report_progress(1, -1, NULL);
terminal_message(MSG_INFO, "%s (dump): error reading %s address 0x%05lx of part %s\n",
progname, mem->desc, (long) addr + i, p->desc);
pmsg_error("(dump) error reading %s address 0x%05lx of part %s\n", mem->desc, (long) addr + i, p->desc);
if (rc == -1)
terminal_message(MSG_INFO, "%*sread operation not supported on memory type %s\n",
(int) strlen(progname)+9, "", mem->desc);
imsg_error("%*sread operation not supported on memory type %s\n", 7, "", mem->desc);
return -1;
}
report_progress(i, len, NULL);
@ -309,7 +314,7 @@ static int cmd_dump(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
report_progress(1, 1, NULL);
hexdump_buf(stdout, addr, buf, len);
fprintf(stdout, "\n");
term_out("\n");
free(buf);
@ -365,7 +370,7 @@ static int is_mantissa_only(char *p) {
static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
if (argc < 4) {
terminal_message(MSG_INFO,
msg_error(
"Usage: write <memory> <addr> <data>[,] {<data>[,]}\n"
" write <memory> <addr> <len> <data>[,] {<data>[,]} ...\n"
"\n"
@ -399,14 +404,13 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
}
int i;
uint8_t write_mode; // Operation mode, "standard" or "fill"
uint8_t start_offset; // Which argc argument
int len; // Number of bytes to write to memory
char *memtype = argv[1]; // Memory name string
uint8_t write_mode; // Operation mode, "standard" or "fill"
uint8_t start_offset; // Which argc argument
int len; // Number of bytes to write to memory
char *memtype = argv[1]; // Memory name string
AVRMEM *mem = avr_locate_mem(p, memtype);
if (mem == NULL) {
terminal_message(MSG_INFO, "%s (write): %s memory type not defined for part %s\n",
progname, memtype, p->desc);
pmsg_error("(write) %s memory type not defined for part %s\n", memtype, p->desc);
return -1;
}
int maxsize = mem->size;
@ -414,21 +418,19 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
char *end_ptr;
int addr = strtoul(argv[2], &end_ptr, 0);
if (*end_ptr || (end_ptr == argv[2])) {
terminal_message(MSG_INFO, "%s (write): can't parse address %s\n",
progname, argv[2]);
pmsg_error("(write) cannot parse address %s\n", argv[2]);
return -1;
}
if (addr < 0 || addr >= maxsize) {
terminal_message(MSG_INFO, "%s (write): %s address 0x%05x is out of range [0, 0x%05x]\n",
progname, mem->desc, addr, maxsize-1);
pmsg_error("(write) %s address 0x%05x is out of range [0, 0x%05x]\n", mem->desc, addr, maxsize-1);
return -1;
}
// Allocate a buffer guaranteed to be large enough
uint8_t *buf = calloc(mem->size + 8 + maxstrlen(argc-3, argv+3)+1, sizeof(uint8_t));
if (buf == NULL) {
terminal_message(MSG_INFO, "%s (write): out of memory\n", progname);
pmsg_error("(write) out of memory\n");
return -1;
}
@ -438,8 +440,7 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
start_offset = 4;
len = strtoul(argv[3], &end_ptr, 0);
if (*end_ptr || (end_ptr == argv[3])) {
terminal_message(MSG_INFO, "%s (write ...): can't parse length %s\n",
progname, argv[3]);
pmsg_error("(write ...) cannot parse length %s\n", argv[3]);
free(buf);
return -1;
}
@ -471,8 +472,8 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
};
if(sizeof(long long) != sizeof(int64_t) || (data.a[0]^data.a[7]) != 1)
terminal_message(MSG_INFO, "%s (write): assumption on data types not met? "
"Check source and recompile\n", progname);
pmsg_error("(write) assumption on data types not met? "
"Check source and recompile\n");
bool is_big_endian = data.a[7];
for (i = start_offset; i < len + start_offset; i++) {
@ -518,7 +519,7 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
bool is_out_of_range = 0;
int nhexdigs = p-argi-2;
if(is_signed) { // Is input in range for int64_t?
if(is_signed) { // Is input in range for int64_t?
errno = 0; (void) strtoll(argi, NULL, 0);
is_outside_int64_t = errno == ERANGE;
}
@ -566,9 +567,8 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
}
if(is_outside_int64_t || is_out_of_range)
terminal_message(MSG_INFO, "%s (write): %s out of int%d_t range, "
"interpreted as %d-byte %lld; consider 'U' suffix\n",
progname, argi, data.size*8, data.size, data.ll);
pmsg_error("(write) %s out of int%d_t range, "
"interpreted as %d-byte %lld; consider 'U' suffix\n", argi, data.size*8, data.size, (long long int) data.ll);
}
}
}
@ -583,8 +583,8 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
data.f = strtof(argi, &end_ptr);
if (end_ptr != argi && toupper(*end_ptr) == 'F' && end_ptr[1] == 0)
data.size = 4;
if (end_ptr != argi && *end_ptr == 0) // no suffix defaults to float but ...
// ... do not accept valid mantissa-only floats that are integer rejects (eg, 078 or ULL overflows)
if (end_ptr != argi && *end_ptr == 0) // No suffix defaults to float but ...
// ... do not accept valid mantissa-only floats that are integer rejects (eg, 078 or ULL overflows)
if (!is_mantissa_only(argi))
data.size = 4;
}
@ -593,29 +593,27 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
if ((*argi == '\'' && argi[arglen-1] == '\'') || (*argi == '\"' && argi[arglen-1] == '\"')) {
char *s = calloc(arglen-1, 1);
if (s == NULL) {
terminal_message(MSG_INFO, "%s (write str): out of memory\n", progname);
pmsg_error("(write str) out of memory\n");
free(buf);
return -1;
}
// Strip start and end quotes, and unescape C string
strncpy(s, argi+1, arglen-2);
cfg_unescape(s, s);
if (*argi == '\'') { // Single C-style character
if (*argi == '\'') { // Single C-style character
if(*s && s[1])
terminal_message(MSG_INFO, "%s (write): only using first character of %s\n",
progname, argi);
pmsg_error("(write) only using first character of %s\n", argi);
data.ll = *s;
data.size = 1;
free(s);
} else { // C-style string
} else { // C-style string
data.str_ptr = s;
}
}
}
if(!data.size && !data.str_ptr) {
terminal_message(MSG_INFO, "%s (write): can't parse data %s\n",
progname, argi);
pmsg_error("(write) cannot parse data %s\n", argi);
free(buf);
return -1;
}
@ -644,8 +642,8 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
data.bytes_grown = 0;
if ((addr + len + data.bytes_grown) > maxsize) {
terminal_message(MSG_INFO, "%s (write): selected address and # bytes exceed "
"range for %s memory\n", progname, memtype);
pmsg_error("(write) selected address and # bytes exceed "
"range for %s memory\n", memtype);
free(buf);
return -1;
}
@ -653,11 +651,11 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
if(data.str_ptr)
free(data.str_ptr);
terminal_message(MSG_NOTICE, "Info: writing %d bytes starting from address 0x%02lx",
pmsg_notice2("(write) writing %d bytes starting from address 0x%02lx",
len + data.bytes_grown, (long) addr);
if (write_mode == WRITE_MODE_FILL)
terminal_message(MSG_NOTICE, "; remaining space filled with %s", argv[argc - 2]);
terminal_message(MSG_NOTICE, "\n");
msg_notice2("; remaining space filled with %s", argv[argc - 2]);
msg_notice2("\n");
pgm->err_led(pgm, OFF);
bool werror = false;
@ -665,19 +663,16 @@ static int cmd_write(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
for (i = 0; i < len + data.bytes_grown; i++) {
int rc = pgm->write_byte_cached(pgm, p, mem, addr+i, buf[i]);
if (rc) {
terminal_message(MSG_INFO, "%s (write): error writing 0x%02x at 0x%05lx, rc=%d\n",
progname, buf[i], (long) addr+i, (int) rc);
pmsg_error("(write) error writing 0x%02x at 0x%05lx, rc=%d\n", buf[i], (long) addr+i, (int) rc);
if (rc == -1)
terminal_message(MSG_INFO, "%*swrite operation not supported on memory type %s\n",
(int) strlen(progname)+10, "", mem->desc);
imsg_error("%*swrite operation not supported on memory type %s\n", 8, "", mem->desc);
werror = true;
}
uint8_t b;
rc = pgm->read_byte_cached(pgm, p, mem, addr+i, &b);
if (b != buf[i]) {
terminal_message(MSG_INFO, "%s (write): error writing 0x%02x at 0x%05lx cell=0x%02x\n",
progname, buf[i], (long) addr+i, b);
pmsg_error("(write) error writing 0x%02x at 0x%05lx cell=0x%02x\n", buf[i], (long) addr+i, b);
werror = true;
}
@ -713,14 +708,13 @@ static int cmd_send(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
int len;
if (spi_mode && (pgm->spi == NULL)) {
terminal_message(MSG_INFO, "%s (send): the %s programmer does not support direct SPI transfers\n",
progname, pgm->type);
pmsg_error("(send) the %s programmer does not support direct SPI transfers\n", pgm->type);
return -1;
}
if ((argc > 5) || ((argc < 5) && (!spi_mode))) {
terminal_message(MSG_INFO, spi_mode?
msg_error(spi_mode?
"Usage: send <byte1> [<byte2> [<byte3> [<byte4>]]]\n":
"Usage: send <byte1> <byte2> <byte3> <byte4>\n");
return -1;
@ -733,8 +727,7 @@ static int cmd_send(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
for (i=1; i<argc; i++) {
cmd[i-1] = strtoul(argv[i], &e, 0);
if (*e || (e == argv[i])) {
terminal_message(MSG_INFO, "%s (send): can't parse byte %s\n",
progname, argv[i]);
pmsg_error("(send) cannot parse byte %s\n", argv[i]);
return -1;
}
}
@ -749,19 +742,17 @@ static int cmd_send(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
/*
* display results
*/
terminal_message(MSG_INFO, "results:");
term_out("results:");
for (i=0; i<len; i++)
terminal_message(MSG_INFO, " %02x", res[i]);
terminal_message(MSG_INFO, "\n");
fprintf(stdout, "\n");
term_out(" %02x", res[i]);
term_out("\n\n");
return 0;
}
static int cmd_erase(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
terminal_message(MSG_INFO, "%s: erasing chip\n", progname);
term_out("erasing chip ...\n");
// Erase chip and clear cache
pgm->chip_erase_cached(pgm, p);
@ -771,20 +762,18 @@ static int cmd_erase(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
static int cmd_pgerase(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
if(argc < 3) {
terminal_message(MSG_INFO, "Usage: pgerase <memory> <addr>\n");
msg_error("Usage: pgerase <memory> <addr>\n");
return -1;
}
char *memtype = argv[1];
AVRMEM *mem = avr_locate_mem(p, memtype);
if(!mem) {
terminal_message(MSG_INFO, "%s (pgerase): %s memory type not defined for part %s\n",
progname, memtype, p->desc);
pmsg_error("(pgerase) %s memory type not defined for part %s\n", memtype, p->desc);
return -1;
}
if(!avr_has_paged_access(pgm, mem)) {
terminal_message(MSG_INFO, "%s (pgerase): %s memory cannot be paged addressed by %s\n",
progname, memtype, ldata(lfirst(pgm->id)));
pmsg_error("(pgerase) %s memory cannot be paged addressed by %s\n", memtype, (char *) ldata(lfirst(pgm->id)));
return -1;
}
@ -793,21 +782,17 @@ static int cmd_pgerase(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
char *end_ptr;
int addr = strtoul(argv[2], &end_ptr, 0);
if(*end_ptr || (end_ptr == argv[2])) {
terminal_message(MSG_INFO, "%s (pgerase): can't parse address %s\n",
progname, argv[2]);
pmsg_error("(pgerase) cannot parse address %s\n", argv[2]);
return -1;
}
if (addr < 0 || addr >= maxsize) {
terminal_message(MSG_INFO, "%s (pgerase): %s address 0x%05x is out of range [0, 0x%05x]\n",
progname, mem->desc, addr, maxsize-1);
pmsg_error("(pgerase) %s address 0x%05x is out of range [0, 0x%05x]\n", mem->desc, addr, maxsize-1);
return -1;
}
// terminal_message(MSG_INFO, "%s: %s page erase 0x%05x\n", progname, mem->desc, addr & ~(mem->page_size-1));
if(pgm->page_erase_cached(pgm, p, mem, (unsigned int) addr) < 0) {
terminal_message(MSG_INFO, "%s (pgerase): unable to erase %s page at 0x%05x\n",
progname, mem->desc, addr);
pmsg_error("(pgerase) unable to erase %s page at 0x%05x\n", mem->desc, addr);
return -1;
}
@ -816,9 +801,9 @@ static int cmd_pgerase(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
static int cmd_part(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
fprintf(stdout, "\n");
term_out("\n");
avr_display(stdout, p, "", 0);
fprintf(stdout, "\n");
term_out("\n");
return 0;
}
@ -831,20 +816,18 @@ static int cmd_sig(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
rc = avr_signature(pgm, p);
if (rc != 0) {
terminal_message(MSG_INFO, "%s (sig): error reading signature data, rc=%d\n",
progname, rc);
pmsg_error("(sig) error reading signature data, rc=%d\n", rc);
}
m = avr_locate_mem(p, "signature");
if (m == NULL) {
terminal_message(MSG_INFO, "%s (sig): signature data not defined for device %s\n",
progname, p->desc);
pmsg_error("(sig) signature data not defined for device %s\n", p->desc);
}
else {
fprintf(stdout, "Device signature = 0x");
term_out("Device signature = 0x");
for (i=0; i<m->size; i++)
fprintf(stdout, "%02x", m->buf[i]);
fprintf(stdout, "\n\n");
term_out("%02x", m->buf[i]);
term_out("\n\n");
}
return 0;
@ -861,8 +844,8 @@ static int cmd_quit(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
static int cmd_parms(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
pgm->print_parms(pgm);
terminal_message(MSG_INFO, "\n");
pgm->print_parms(pgm, stdout);
term_out("\n");
return 0;
}
@ -873,18 +856,16 @@ static int cmd_vtarg(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
char *endp;
if (argc != 2) {
terminal_message(MSG_INFO, "Usage: vtarg <value>\n");
msg_error("Usage: vtarg <value>\n");
return -1;
}
v = strtod(argv[1], &endp);
if (endp == argv[1]) {
terminal_message(MSG_INFO, "%s (vtarg): can't parse voltage %s\n",
progname, argv[1]);
pmsg_error("(vtarg) cannot parse voltage %s\n", argv[1]);
return -1;
}
if ((rc = pgm->set_vtarget(pgm, v)) != 0) {
terminal_message(MSG_INFO, "%s (vtarg): unable to set V[target] (rc = %d)\n",
progname, rc);
pmsg_error("(vtarg) unable to set V[target] (rc = %d)\n", rc);
return -3;
}
return 0;
@ -897,7 +878,7 @@ static int cmd_fosc(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
char *endp;
if (argc != 2) {
terminal_message(MSG_INFO, "Usage: fosc <value>[M|k] | off\n");
msg_error("Usage: fosc <value>[M|k] | off\n");
return -1;
}
v = strtod(argv[1], &endp);
@ -905,8 +886,7 @@ static int cmd_fosc(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
if (strcmp(argv[1], "off") == 0)
v = 0.0;
else {
terminal_message(MSG_INFO, "%s (fosc): can't parse frequency %s\n",
progname, argv[1]);
pmsg_error("(fosc) cannot parse frequency %s\n", argv[1]);
return -1;
}
}
@ -915,8 +895,7 @@ static int cmd_fosc(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
else if (*endp == 'k' || *endp == 'K')
v *= 1e3;
if ((rc = pgm->set_fosc(pgm, v)) != 0) {
terminal_message(MSG_INFO, "%s (fosc): unable to set oscillator frequency (rc = %d)\n",
progname, rc);
pmsg_error("(fosc) unable to set oscillator frequency (rc = %d)\n", rc);
return -3;
}
return 0;
@ -929,19 +908,17 @@ static int cmd_sck(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
char *endp;
if (argc != 2) {
terminal_message(MSG_INFO, "Usage: sck <value>\n");
msg_error("Usage: sck <value>\n");
return -1;
}
v = strtod(argv[1], &endp);
if (endp == argv[1]) {
terminal_message(MSG_INFO, "%s (sck): can't parse period %s\n",
progname, argv[1]);
pmsg_error("(sck) cannot parse period %s\n", argv[1]);
return -1;
}
v *= 1e-6; /* Convert from microseconds to seconds. */
v *= 1e-6; // Convert from microseconds to seconds
if ((rc = pgm->set_sck_period(pgm, v)) != 0) {
terminal_message(MSG_INFO, "%s (sck): unable to set SCK period (rc = %d)\n",
progname, rc);
pmsg_error("(sck) unable to set SCK period (rc = %d)\n", rc);
return -3;
}
return 0;
@ -955,34 +932,30 @@ static int cmd_varef(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
char *endp;
if (argc != 2 && argc != 3) {
terminal_message(MSG_INFO, "Usage: varef [channel] <value>\n");
msg_error("Usage: varef [channel] <value>\n");
return -1;
}
if (argc == 2) {
chan = 0;
v = strtod(argv[1], &endp);
if (endp == argv[1]) {
terminal_message(MSG_INFO, "%s (varef): can't parse voltage %s\n",
progname, argv[1]);
pmsg_error("(varef) cannot parse voltage %s\n", argv[1]);
return -1;
}
} else {
chan = strtoul(argv[1], &endp, 10);
if (endp == argv[1]) {
terminal_message(MSG_INFO, "%s (varef): can't parse channel %s\n",
progname, argv[1]);
pmsg_error("(varef) cannot parse channel %s\n", argv[1]);
return -1;
}
v = strtod(argv[2], &endp);
if (endp == argv[2]) {
terminal_message(MSG_INFO, "%s (varef): can't parse voltage %s\n",
progname, argv[2]);
pmsg_error("(varef) cannot parse voltage %s\n", argv[2]);
return -1;
}
}
if ((rc = pgm->set_varef(pgm, chan, v)) != 0) {
terminal_message(MSG_INFO, "%s (varef): unable to set V[aref] (rc = %d)\n",
progname, rc);
pmsg_error("(varef) unable to set V[aref] (rc = %d)\n", rc);
return -3;
}
return 0;
@ -992,19 +965,19 @@ static int cmd_varef(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
static int cmd_help(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
int i;
fprintf(stdout, "Valid commands:\n");
term_out("Valid commands:\n");
for (i=0; i<NCMDS; i++) {
if(!*(void (**)(void)) ((char *) pgm + cmd[i].fnoff))
continue;
fprintf(stdout, " %-7s : ", cmd[i].name);
fprintf(stdout, cmd[i].desc, cmd[i].name);
fprintf(stdout, "\n");
term_out(" %-7s : ", cmd[i].name);
term_out(cmd[i].desc, cmd[i].name);
term_out("\n");
}
fprintf(stdout, "\n"
term_out("\n"
"Note that not all programmer derivatives support all commands. Flash and\n"
"EEPROM type memories are normally read and written using a cache via paged\n"
"read and write access; the cache is synchronised on quit. Use the part\n"
"command to display valid memory types for use with dump and write.\n\n");
"read and write access; the cache is synchronised on quit or flush commands.\n"
"The part command displays valid memory types for use with dump and write.\n\n");
return 0;
}
@ -1026,26 +999,24 @@ static int cmd_verbose(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
char *endp;
if (argc != 1 && argc != 2) {
terminal_message(MSG_INFO, "Usage: verbose [<value>]\n");
msg_error("Usage: verbose [<value>]\n");
return -1;
}
if (argc == 1) {
terminal_message(MSG_INFO, "Verbosity level: %d\n", verbose);
msg_error("Verbosity level: %d\n", verbose);
return 0;
}
nverb = strtol(argv[1], &endp, 0);
if (endp == argv[1] || *endp) {
terminal_message(MSG_INFO, "%s (verbose): can't parse verbosity level %s\n",
progname, argv[1]);
pmsg_error("(verbose) cannot parse verbosity level %s\n", argv[1]);
return -1;
}
if (nverb < 0) {
terminal_message(MSG_INFO, "%s: verbosity level must not be negative: %d\n",
progname, nverb);
pmsg_error("(verbose) level must not be negative: %d\n", nverb);
return -1;
}
verbose = nverb;
terminal_message(MSG_INFO, "New verbosity level: %d\n", verbose);
term_out("New verbosity level: %d\n", verbose);
return 0;
}
@ -1055,26 +1026,24 @@ static int cmd_quell(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
char *endp;
if (argc != 1 && argc != 2) {
terminal_message(MSG_INFO, "Usage: quell [<value>]\n");
msg_error("Usage: quell [<value>]\n");
return -1;
}
if (argc == 1) {
terminal_message(MSG_INFO, "Quell level: %d\n", quell_progress);
msg_error("Quell level: %d\n", quell_progress);
return 0;
}
nquell = strtol(argv[1], &endp, 0);
if (endp == argv[1] || *endp) {
terminal_message(MSG_INFO, "%s (quell): can't parse quell level %s\n",
progname, argv[1]);
pmsg_error("(quell) cannot parse quell level %s\n", argv[1]);
return -1;
}
if (nquell < 0) {
terminal_message(MSG_INFO, "%s: quell level must not be negative: %d\n",
progname, nquell);
pmsg_error("(quell) level must not be negative: %d\n", nquell);
return -1;
}
quell_progress = nquell;
terminal_message(MSG_INFO, "New quell level: %d\n", quell_progress);
term_out("New quell level: %d\n", quell_progress);
if(quell_progress > 0)
update_progress = NULL;
@ -1195,8 +1164,7 @@ static int do_cmd(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
return cmd[i].func(pgm, p, argc, argv);
if (len && strncasecmp(argv[0], cmd[i].name, len)==0) {
if (hold != -1) {
terminal_message(MSG_INFO, "%s (cmd): command %s is ambiguous\n",
progname, argv[0]);
pmsg_error("(cmd) command %s is ambiguous\n", argv[0]);
return -1;
}
hold = i;
@ -1206,104 +1174,177 @@ static int do_cmd(PROGRAMMER *pgm, AVRPART *p, int argc, char *argv[]) {
if (hold != -1)
return cmd[hold].func(pgm, p, argc, argv);
terminal_message(MSG_INFO, "%s (cmd): invalid command %s\n",
progname, argv[0]);
pmsg_error("(cmd) invalid command %s\n", argv[0]);
return -1;
}
char *terminal_get_input(const char *prompt) {
#if defined(HAVE_LIBREADLINE) && !defined(WIN32)
char *input;
input = readline(prompt);
if ((input != NULL) && (strlen(input) >= 1))
add_history(input);
return input;
#else
char input[256];
fprintf(stdout, "%s", prompt);
if (fgets(input, sizeof(input), stdin))
{
/* FIXME: readline strips the '\n', should this too? */
return strdup(input);
term_out("%s", prompt);
if(fgets(input, sizeof(input), stdin)) {
int len = strlen(input);
if(len > 0 && input[len-1] == '\n')
input[len-1] = 0;
return cfg_strdup(__func__, input);
}
else
return NULL;
#endif
return NULL;
}
int terminal_mode(PROGRAMMER *pgm, AVRPART *p) {
char *cmdbuf;
char *q;
int rc;
int argc;
char **argv;
static int process_line(char *cmdbuf, PROGRAMMER *pgm, struct avrpart *p) {
int argc, rc;
char **argv = NULL, *q;
rc = 0;
while ((cmdbuf = terminal_get_input("avrdude> ")) != NULL) {
/*
* find the start of the command, skipping any white space
*/
q = cmdbuf;
while (*q && isspace((unsigned char) *q))
q++;
// Find the start of the command, skipping any white space
q = cmdbuf;
while(*q && isspace((unsigned char) *q))
q++;
/* skip blank lines and comments */
if (!*q || (*q == '#'))
continue;
// Skip blank lines and comments
if (!*q || (*q == '#'))
return 0;
/* tokenize command line */
argc = tokenize(q, &argv);
if (argc < 0) {
free(cmdbuf);
return argc;
}
// Tokenize command line
argc = tokenize(q, &argv);
if(!argv)
return -1;
#if !defined(HAVE_LIBREADLINE) || defined(WIN32) || defined(__APPLE__)
fprintf(stdout, ">>> ");
term_out(">>> ");
for (int i=0; i<argc; i++)
fprintf(stdout, "%s ", argv[i]);
fprintf(stdout, "\n");
term_out("%s ", argv[i]);
term_out("\n");
#endif
/* run the command */
rc = do_cmd(pgm, p, argc, argv);
free(argv);
if (rc > 0) {
rc = 0;
break;
// Run the command
rc = do_cmd(pgm, p, argc, argv);
free(argv);
return rc;
}
#if defined(HAVE_LIBREADLINE)
static PROGRAMMER *term_pgm;
static struct avrpart *term_p;
static int term_running;
// Any character in standard input available (without sleeping)?
static int readytoread() {
#ifdef WIN32
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
while(1) {
INPUT_RECORD input[1] = { 0 };
DWORD dwNumberOfEventsRead = 0;
if(!PeekConsoleInputA(hStdin, input, ARRAYSIZE(input), &dwNumberOfEventsRead)) {
DWORD dwError = GetLastError();
// Stdin redirected from a pipe or file (FIXME: reading from a pipe may sleep)
if(dwError == ERROR_INVALID_HANDLE)
return 1;
pmsg_warning("PeekConsoleInputA() failed with error code %u\n", (unsigned int) dwError);
return -1;
}
if(dwNumberOfEventsRead <= 0) // Nothing in the input buffer
return 0;
// Filter out all the events that readline does not handle ...
if((input[0].EventType & KEY_EVENT) != 0 && input[0].Event.KeyEvent.bKeyDown)
return 1;
// Drain other events not handled by readline
if(!ReadConsoleInputA(hStdin, input, ARRAYSIZE(input), &dwNumberOfEventsRead)) {
pmsg_warning("ReadConsoleInputA() failed with error code %u\n", (unsigned int) GetLastError());
return -1;
}
free(cmdbuf);
}
#else
struct timeval tv = { 0L, 0L };
fd_set fds;
FD_ZERO(&fds);
FD_SET(0, &fds);
pgm->flush_cache(pgm, p);
return select(1, &fds, NULL, NULL, &tv) > 0;
#endif
}
return rc;
// Callback processes commands whenever readline() has finished
void term_gotline(char *cmdstr) {
if(cmdstr) {
if(*cmdstr) {
add_history(cmdstr);
// only quit/abort returns a value > 0
if(process_line(cmdstr, term_pgm, term_p) > 0)
term_running = 0;
}
free(cmdstr);
} else {
// call quit at end of file or terminal ^D
term_out("\n");
cmd_quit(term_pgm, term_p, 0, NULL);
term_running = 0;
}
}
int terminal_message(const int msglvl, const char *format, ...) {
int terminal_mode(PROGRAMMER *pgm, struct avrpart *p) {
term_pgm = pgm; // For callback routine
term_p = p;
rl_callback_handler_install("avrdude> ", term_gotline);
term_running = 1;
for(int n=1; term_running; n++) {
if(n%16 == 0) { // Every 100 ms (16*6.25 us) reset bootloader watchdog timer
if(pgm->term_keep_alive)
pgm->term_keep_alive(pgm, NULL);
}
usleep(6250);
if(readytoread() > 0 && term_running)
rl_callback_read_char();
}
rl_callback_handler_remove();
return pgm->flush_cache(pgm, p);
}
#else
int terminal_mode(PROGRAMMER *pgm, struct avrpart *p) {
char *cmdbuf;
int rc = 0;
va_list ap;
fflush(stdout); fflush(stderr);
if (verbose >= msglvl) {
va_start(ap, format);
rc = vfprintf(stderr, format, ap);
va_end(ap);
while((cmdbuf = terminal_get_input("avrdude> "))) {
int rc = process_line(cmdbuf, pgm, p);
free(cmdbuf);
if(rc > 0)
break;
}
fflush(stderr);
return rc;
if(rc <= 0)
cmd_quit(pgm, p, 0, NULL);
return pgm->flush_cache(pgm, p);
}
#endif
static void update_progress_tty(int percent, double etime, const char *hdr, int finish) {
static char *header;
static int last, done;
static int last, done = 1;
int i;
setvbuf(stderr, (char *) NULL, _IONBF, 0);
@ -1330,7 +1371,7 @@ static void update_progress_tty(int percent, double etime, const char *hdr, int
hashes[i/2] = '#';
hashes[50] = 0;
msg_info("\r%s | %s | %d%% %0.2fs", header, hashes, showperc, etime);
msg_info("\r%s | %s | %d%% %0.2f s ", header, hashes, showperc, etime);
if(percent == 100) {
if(finish)
msg_info("\n\n");
@ -1343,7 +1384,7 @@ static void update_progress_tty(int percent, double etime, const char *hdr, int
}
static void update_progress_no_tty(int percent, double etime, const char *hdr, int finish) {
static int last, done;
static int last, done = 1;
setvbuf(stderr, (char *) NULL, _IONBF, 0);

View File

@ -35,7 +35,6 @@ typedef enum {
int terminal_mode(PROGRAMMER * pgm, struct avrpart * p);
char * terminal_get_input(const char *prompt);
void terminal_setup_update_progress();
int terminal_message(const int msglvl, const char *format, ...);
#ifdef __cplusplus
}

View File

@ -335,11 +335,11 @@ int update_is_readable(const char *fn) {
static void ioerror(const char *iotype, UPDATE *upd) {
int errnocp = errno;
pmsg_ext_error("file %s is not %s", update_outname(upd->filename), iotype);
pmsg_ext_error("file %s is not %s: ", update_outname(upd->filename), iotype);
if(errnocp)
msg_ext_error("memstats(): %s", strerror(errnocp));
msg_ext_error("%s", strerror(errnocp));
else if(upd->filename && *upd->filename)
msg_ext_error(" (not a regular or character file?)");
msg_ext_error("(not a regular or character file?)");
msg_ext_error("\n");
}
@ -456,7 +456,8 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
}
pmsg_info("reading %s%s memory ...\n", mem->desc, alias_mem_desc);
report_progress(0, 1, "Reading");
if(mem->size > 32 || verbose > 1)
report_progress(0, 1, "Reading");
rc = avr_read(pgm, p, upd->memtype, 0);
report_progress(1, 1, NULL);
@ -511,7 +512,8 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
update_plural(fs.nbytes), mem->desc, alias_mem_desc);
if (!(flags & UF_NOWRITE)) {
report_progress(0, 1, "Writing");
if(mem->size > 32 || verbose > 1)
report_progress(0, 1, "Writing");
rc = avr_write(pgm, p, upd->memtype, size, (flags & UF_AUTO_ERASE) != 0);
report_progress(1, 1, NULL);
} else {
@ -569,7 +571,8 @@ int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags f
pmsg_notice2("reading on-chip %s%s data ...\n", mem->desc, alias_mem_desc);
}
report_progress (0,1,"Reading");
if(mem->size > 32 || verbose > 1)
report_progress (0,1,"Reading");
rc = avr_read(pgm, p, upd->memtype, v);
report_progress (1,1,NULL);
if (rc < 0) {