diff options
| author | James Miller <jamesmiller@chromium.org> | 2012-09-28 14:28:00 +0000 | 
|---|---|---|
| committer | Tom Rini <trini@ti.com> | 2012-12-19 15:51:23 -0700 | 
| commit | a683c288d46336410ddfa2f5c70046dd1d4a5d1e (patch) | |
| tree | 5dbf38d6a47020846aa97fb2e3eb9a2219027623 /common/cmd_sf.c | |
| parent | 095728803eedfce850a2f85828f79500cb09979e (diff) | |
| download | olio-uboot-2014.01-a683c288d46336410ddfa2f5c70046dd1d4a5d1e.tar.xz olio-uboot-2014.01-a683c288d46336410ddfa2f5c70046dd1d4a5d1e.zip | |
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 <sjg@chromium.org>
Signed-off-by: James Miller <jamesmiller@chromium.org>
Signed-off-by: Taylor Hutt <thutt@chromium.org>
[trini: Drop 'const' from bytes_per_second()]
Signed-off-by: Tom Rini <trini@ti.com>
Diffstat (limited to 'common/cmd_sf.c')
| -rw-r--r-- | common/cmd_sf.c | 41 | 
1 files changed, 39 insertions, 2 deletions
| diff --git a/common/cmd_sf.c b/common/cmd_sf.c index 5ac1d0c4c..83e2785e0 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;  } |