Also add "--noprogress" option to turn progress display off again (for subsequent commands).
Signed-off-by: Bernhard Nortmann <[email protected]> --- fel.c | 5 +++++ progress.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- progress.h | 3 +++ 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/fel.c b/fel.c index 9b9a622..0afc160 100644 --- a/fel.c +++ b/fel.c @@ -1123,6 +1123,7 @@ int main(int argc, char **argv) printf("Usage: %s [options] command arguments... [command...]\n" " -v, --verbose Verbose logging\n" " -p, --progress Show progress bar on larger transfers\n" + " -np, --noprogress No (more) progress display after this\n" "\n" " spl file Load and execute U-Boot SPL\n" " If file additionally contains a main U-Boot binary\n" @@ -1182,6 +1183,9 @@ int main(int argc, char **argv) } else if (strcmp(argv[1], "--progress") == 0 || strcmp(argv[1], "-p") == 0) { set_progress_callback(progress_bar); + } else if (strcmp(argv[1], "--noprogress") == 0 || + strcmp(argv[1], "-np") == 0) { + set_progress_callback(NULL); } else if (strncmp(argv[1], "hex", 3) == 0 && argc > 3) { aw_fel_hexdump(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0)); skip = 3; @@ -1199,6 +1203,7 @@ int main(int argc, char **argv) size_t size; void *buf = load_file(argv[3], &size); uint32_t offset = strtoul(argv[2], NULL, 0); + progress_start(); double elapsed = aw_write_buffer(handle, buf, offset, size, true); if (elapsed > 0) pr_info("%.1f kB written in %.1f sec (speed: %.1f kB/s)\n", diff --git a/progress.c b/progress.c index f8d7854..047d079 100644 --- a/progress.c +++ b/progress.c @@ -30,14 +30,45 @@ inline double gettime(void) return tv.tv_sec + (double)tv.tv_usec / 1000000.; } +/* Calculate transfer rate (in bytes per second) */ +inline double rate(size_t transferred, double elapsed) +{ + if (elapsed > 0) + return (double)transferred / elapsed; + return 0.; +} + +/* Estimate remaining time ("ETA") for given transfer rate */ +inline double estimate(size_t remaining, double rate) +{ + if (rate > 0) + return (double)remaining / rate; + return 0.; +} + +/* Return ETA (in seconds) as string, formatted to minutes and seconds */ +const char *format_ETA(double remaining) +{ + static char result[6] = ""; + + int seconds = remaining + 0.5; /* simplistic round() */ + if (seconds >= 0 && seconds < 6000) { + snprintf(result, sizeof(result), + "%02d:%02d", seconds / 60, seconds % 60); + return result; + } + return "--:--"; +} + /* Private progress state variable(s) */ typedef struct { progress_cb_t callback; + double start; /* start point (timestamp) for rate and ETA calculation */ } progress_private_t; static progress_private_t progress = { - .callback = NULL + .callback = NULL, .start = 0. }; /* Exposed functions to manipulate private variables */ @@ -47,6 +78,11 @@ void set_progress_callback(progress_cb_t callback) progress.callback = callback; } +void progress_start(void) +{ + progress.start = gettime(); /* reset start time */ +} + /* * Update progress status, passing information to the callback function. * "quick" is an opaque flag that can indicate "small", frequent or @@ -60,20 +96,30 @@ void progress_update(size_t total, size_t done, bool quick) progress.callback(total, done, quick); } +/* Return relative / "elapsed" time, since progress_start() */ +static inline double progress_elapsed(void) +{ + if (progress.start != 0.) + return gettime() - progress.start; + return 0.; +} + /* Callback function implementing a simple progress bar written to stdout */ void progress_bar(size_t total, size_t done, bool quick) { - static const int WIDTH = 60; /* # of characters to use for progress bar */ + static const int WIDTH = 48; /* # of characters to use for progress bar */ if (quick) return; /* ignore small transfers completing "instantly" */ float ratio = total > 0 ? (float)done / total : 0; int i, pos = WIDTH * ratio; + double speed = rate(done, progress_elapsed()); + double eta = estimate(total - done, speed); printf("\r%3.0f%% [", ratio * 100); /* current percentage */ for (i = 0; i < pos; i++) putchar('='); for (i = pos; i < WIDTH; i++) putchar(' '); - printf("] "); + printf("]%6.1f kB/s, ETA %s ", kilo(speed), format_ETA(eta)); if (done >= total) putchar('\n'); /* output newline when complete */ fflush(stdout); diff --git a/progress.h b/progress.h index 8718a02..3254201 100644 --- a/progress.h +++ b/progress.h @@ -28,8 +28,11 @@ typedef void (*progress_cb_t)(size_t total, size_t done, bool quick); #define kibi(value) ((double)value / 1024.) /* binary prefix "Ki", "K" */ double gettime(void); +double rate(size_t transferred, double elapsed); +double estimate(size_t remaining, double rate); void set_progress_callback(progress_cb_t callback); +void progress_start(void); void progress_update(size_t total, size_t done, bool quick); /* progress callback implementations for various display styles */ -- 2.4.6 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
