From a683c288d46336410ddfa2f5c70046dd1d4a5d1e Mon Sep 17 00:00:00 2001 From: James Miller Date: Fri, 28 Sep 2012 14:28:00 +0000 Subject: [PATCH] spi: Add progress percentage and write speed to `sf update` Output a progress update only at most 10 times per second, to avoid saturating (and waiting on) the console. Make the summary line to fit on a single line. Make sure that cursor sits at the end of each update line instead of the beginning. Sample output: SF: Detected W25Q32 with page size 4 KiB, total 4 MiB Update SPI 1331200 bytes written, 2863104 bytes skipped in 21.912s, speed 199728 B/s time: 21.919 seconds, 21919 ticks Skipping verify Signed-off-by: Simon Glass Signed-off-by: James Miller Signed-off-by: Taylor Hutt [trini: Drop 'const' from bytes_per_second()] Signed-off-by: Tom Rini --- common/cmd_sf.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/common/cmd_sf.c b/common/cmd_sf.c index 5ac1d0c4c1..83e2785e00 100644 --- a/common/cmd_sf.c +++ b/common/cmd_sf.c @@ -67,6 +67,23 @@ static int sf_parse_len_arg(char *arg, ulong *len) return 1; } +/** + * This function takes a byte length and a delta unit of time to compute the + * approximate bytes per second + * + * @param len amount of bytes currently processed + * @param start_ms start time of processing in ms + * @return bytes per second if OK, 0 on error + */ +static ulong bytes_per_second(unsigned int len, ulong start_ms) +{ + /* less accurate but avoids overflow */ + if (len >= ((unsigned int) -1) / 1024) + return len / (max(get_timer(start_ms) / 1024, 1)); + else + return 1024 * len / max(get_timer(start_ms), 1); +} + static int do_spi_flash_probe(int argc, char * const argv[]) { unsigned int bus = CONFIG_SF_DEFAULT_BUS; @@ -167,11 +184,26 @@ static int spi_flash_update(struct spi_flash *flash, u32 offset, const char *end = buf + len; size_t todo; /* number of bytes to do in this pass */ size_t skipped = 0; /* statistics */ + const ulong start_time = get_timer(0); + size_t scale = 1; + const char *start_buf = buf; + ulong delta; + if (end - buf >= 200) + scale = (end - buf) / 100; cmp_buf = malloc(flash->sector_size); if (cmp_buf) { + ulong last_update = get_timer(0); + for (; buf < end && !err_oper; buf += todo, offset += todo) { todo = min(end - buf, flash->sector_size); + if (get_timer(last_update) > 100) { + printf(" \rUpdating, %zu%% %lu B/s", + 100 - (end - buf) / scale, + bytes_per_second(buf - start_buf, + start_time)); + last_update = get_timer(0); + } err_oper = spi_flash_update_block(flash, offset, todo, buf, cmp_buf, &skipped); } @@ -179,12 +211,17 @@ static int spi_flash_update(struct spi_flash *flash, u32 offset, err_oper = "malloc"; } free(cmp_buf); + putc('\r'); if (err_oper) { printf("SPI flash failed in %s step\n", err_oper); return 1; } - printf("%zu bytes written, %zu bytes skipped\n", len - skipped, - skipped); + + delta = get_timer(start_time); + printf("%zu bytes written, %zu bytes skipped", len - skipped, + skipped); + printf(" in %ld.%lds, speed %ld B/s\n", + delta / 1000, delta % 1000, bytes_per_second(len, start_time)); return 0; } -- 2.39.5