diff --git a/src/avr.c b/src/avr.c index 370f09fb..732b284a 100644 --- a/src/avr.c +++ b/src/avr.c @@ -529,6 +529,38 @@ int avr_write_page(const PROGRAMMER *pgm, const AVRPART *p_unused, const AVRMEM } +// Return us since program start, rolls over after ca 1h 12min +unsigned long avr_ustimestamp() { + struct timeval tv; + + memset(&tv, 0, sizeof tv); + if(gettimeofday(&tv, NULL) == 0) { + static unsigned long long epoch; + static int init; + unsigned long long now; + + now = tv.tv_sec*1000000ULL + tv.tv_usec; + if(!init) { + epoch = now; + init = 1; + } + return now - epoch; + } + + return 0; +} + +// Return ms since program start, rolls over after ca 49d 17h +unsigned long avr_mstimestamp() { + return avr_ustimestamp()/1000; +} + +// Return s since program start as double +double avr_timestamp() { + return avr_ustimestamp()/1e6; +} + + int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data) { @@ -544,7 +576,6 @@ int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM OPCODE * writeop; int rc; int readok=0; - struct timeval tv; if (pgm->cmd == NULL) { pmsg_error("%s programmer uses avr_write_byte_default() but does not\n", pgm->type); @@ -706,8 +737,7 @@ int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM } } else { - gettimeofday (&tv, NULL); - start_time = (tv.tv_sec * 1000000) + tv.tv_usec; + start_time = avr_ustimestamp(); do { // Do polling, but timeout after max_write_delay rc = pgm->read_byte(pgm, p, mem, addr, &r); @@ -716,8 +746,7 @@ int avr_write_byte_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM pgm->err_led(pgm, ON); return -4; } - gettimeofday (&tv, NULL); - prog_time = (tv.tv_sec * 1000000) + tv.tv_usec; + prog_time = avr_ustimestamp(); } while (r != data && mem->max_write_delay >= 0 && prog_time - start_time < (unsigned long) mem->max_write_delay); } @@ -1399,7 +1428,6 @@ void report_progress(int completed, int total, const char *hdr) { static int last; static double start_time; int percent; - struct timeval tv; double t; if (update_progress == NULL) @@ -1410,8 +1438,7 @@ void report_progress(int completed, int total, const char *hdr) { completed < 0? 0: completed < INT_MAX/100? 100*completed/total: completed/(total/100); - gettimeofday(&tv, NULL); - t = tv.tv_sec + ((double)tv.tv_usec)/1000000; + t = avr_timestamp(); if(hdr || !start_time) start_time = t; diff --git a/src/jtagmkII.c b/src/jtagmkII.c index 6cc5e01f..1a157afa 100644 --- a/src/jtagmkII.c +++ b/src/jtagmkII.c @@ -481,14 +481,12 @@ static int jtagmkII_recv_frame(const PROGRAMMER *pgm, unsigned char **msg, unsigned char c, *buf = NULL, header[8]; unsigned short r_seqno = 0; - struct timeval tv; double timeoutval = 100; /* seconds */ double tstart, tnow; pmsg_trace("jtagmkII_recv():\n"); - gettimeofday(&tv, NULL); - tstart = tv.tv_sec; + tstart = avr_timestamp(); while ( (state != sDONE ) && (!timeout) ) { if (state == sDATA) { @@ -583,8 +581,7 @@ static int jtagmkII_recv_frame(const PROGRAMMER *pgm, unsigned char **msg, return -5; } - gettimeofday(&tv, NULL); - tnow = tv.tv_sec; + tnow = avr_timestamp(); if (tnow - tstart > timeoutval) { pmsg_error("timeout\n"); free(buf); diff --git a/src/libavrdude.h b/src/libavrdude.h index cb01f7a8..e86407c3 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -886,6 +886,12 @@ int avr_read(const PROGRAMMER * pgm, const AVRPART *p, const char *memtype, cons int avr_write_page(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr); +unsigned long avr_ustimestamp(); + +unsigned long avr_mstimestamp(); + +double avr_timestamp(); + int avr_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, unsigned long addr, unsigned char data); diff --git a/src/main.c b/src/main.c index 86291013..691369cf 100644 --- a/src/main.c +++ b/src/main.c @@ -499,6 +499,8 @@ int main(int argc, char * argv []) char * logfile; /* Use logfile rather than stderr for diagnostics */ enum updateflags uflags = UF_AUTO_ERASE | UF_VERIFY; /* Flags for do_op() */ + (void) avr_ustimestamp(); + #ifdef _MSC_VER _set_printf_count_output(1); #endif diff --git a/src/serialupdi.c b/src/serialupdi.c index cdff0a0a..5d221f88 100644 --- a/src/serialupdi.c +++ b/src/serialupdi.c @@ -207,18 +207,15 @@ static int serialupdi_wait_for_unlock(const PROGRAMMER *pgm, unsigned int ms) { */ unsigned long start_time; unsigned long current_time; - struct timeval tv; uint8_t status; - gettimeofday (&tv, NULL); - start_time = (tv.tv_sec * 1000000) + tv.tv_usec; + start_time = avr_ustimestamp(); do { if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &status) >= 0) { if (!(status & (1 << UPDI_ASI_SYS_STATUS_LOCKSTATUS))) { return 0; } } - gettimeofday (&tv, NULL); - current_time = (tv.tv_sec * 1000000) + tv.tv_usec; + current_time = avr_ustimestamp(); } while ((current_time - start_time) < (ms * 1000)); pmsg_error("timeout waiting for device to unlock\n"); @@ -256,10 +253,8 @@ static int serialupdi_wait_for_urow(const PROGRAMMER *pgm, unsigned int ms, urow */ unsigned long start_time; unsigned long current_time; - struct timeval tv; uint8_t status; - gettimeofday (&tv, NULL); - start_time = (tv.tv_sec * 1000000) + tv.tv_usec; + start_time = avr_ustimestamp(); do { if (updi_read_cs(pgm, UPDI_ASI_SYS_STATUS, &status) >= 0) { if (mode == WAIT_FOR_UROW_HIGH) { @@ -272,8 +267,7 @@ static int serialupdi_wait_for_urow(const PROGRAMMER *pgm, unsigned int ms, urow } } } - gettimeofday (&tv, NULL); - current_time = (tv.tv_sec * 1000000) + tv.tv_usec; + current_time = avr_ustimestamp(); } while ((current_time - start_time) < (ms * 1000)); pmsg_error("timeout waiting for device to complete UROW WRITE\n"); diff --git a/src/stk500v2.c b/src/stk500v2.c index 6a6085a1..bb086c10 100644 --- a/src/stk500v2.c +++ b/src/stk500v2.c @@ -603,7 +603,6 @@ static int stk500v2_recv(const PROGRAMMER *pgm, unsigned char *msg, size_t maxsi * https://savannah.nongnu.org/bugs/index.php?43626 */ long timeoutval = SERIAL_TIMEOUT; // seconds - struct timeval tv; double tstart, tnow; if (PDATA(pgm)->pgmtype == PGMTYPE_AVRISP_MKII || @@ -616,8 +615,7 @@ static int stk500v2_recv(const PROGRAMMER *pgm, unsigned char *msg, size_t maxsi DEBUG("STK500V2: stk500v2_recv(): "); - gettimeofday(&tv, NULL); - tstart = tv.tv_sec; + tstart = avr_timestamp(); while ( (state != sDONE ) && (!timeout) ) { if (serial_recv(&pgm->fd, &c, 1) < 0) @@ -690,9 +688,8 @@ static int stk500v2_recv(const PROGRAMMER *pgm, unsigned char *msg, size_t maxsi return -5; } /* switch */ - gettimeofday(&tv, NULL); - tnow = tv.tv_sec; - if (tnow-tstart > timeoutval) { // wuff - signed/unsigned/overflow + tnow = avr_timestamp(); + if (tnow-tstart > timeoutval) { timedout: pmsg_error("timeout\n"); return -1; diff --git a/src/updi_nvm.c b/src/updi_nvm.c index 93118437..a853b6c2 100644 --- a/src/updi_nvm.c +++ b/src/updi_nvm.c @@ -1201,10 +1201,8 @@ int updi_nvm_wait_ready(const PROGRAMMER *pgm, const AVRPART *p) { */ unsigned long start_time; unsigned long current_time; - struct timeval tv; uint8_t status; - gettimeofday (&tv, NULL); - start_time = (tv.tv_sec * 1000000) + tv.tv_usec; + start_time = avr_ustimestamp(); do { if (updi_read_byte(pgm, p->nvm_base + UPDI_NVMCTRL_STATUS, &status) >= 0) { if (status & (1 << UPDI_NVM_STATUS_WRITE_ERROR)) { @@ -1216,8 +1214,7 @@ int updi_nvm_wait_ready(const PROGRAMMER *pgm, const AVRPART *p) { return 0; } } - gettimeofday (&tv, NULL); - current_time = (tv.tv_sec * 1000000) + tv.tv_usec; + current_time = avr_ustimestamp(); } while ((current_time - start_time) < 10000000); pmsg_error("wait NVM ready timed out\n");