mdcart

diff src/main.c @ 1:c8d3d23ccd1f

works
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 12 Mar 2017 23:43:21 +0200
parents e6d499a8eb1d
children
line diff
     1.1 --- a/src/main.c	Sun Mar 12 06:20:22 2017 +0200
     1.2 +++ b/src/main.c	Sun Mar 12 23:43:21 2017 +0200
     1.3 @@ -7,6 +7,7 @@
     1.4  #include <unistd.h>
     1.5  #include <fcntl.h>
     1.6  #include <termios.h>
     1.7 +#include <sys/stat.h>
     1.8  
     1.9  enum {
    1.10  	OP_NONE,
    1.11 @@ -19,12 +20,14 @@
    1.12  int op_read(FILE *dev, FILE *fp);
    1.13  int op_reset(FILE *dev);
    1.14  int parse_args(int argc, char **argv);
    1.15 +void print_progress(int p);
    1.16  
    1.17  int op, verify = 0;
    1.18  const char *devname = "/dev/ttyUSB0";
    1.19  char *fname = 0;
    1.20  uint32_t start_addr;
    1.21  int read_size = 128 * 1024;
    1.22 +int quiet;
    1.23  
    1.24  int main(int argc, char **argv)
    1.25  {
    1.26 @@ -48,8 +51,8 @@
    1.27  	term.c_iflag &= ~(IXON | IXOFF);
    1.28  	term.c_lflag = 0;
    1.29  
    1.30 -	cfsetispeed(&term, B38400);
    1.31 -	cfsetospeed(&term, B38400);
    1.32 +	cfsetispeed(&term, B115200);
    1.33 +	cfsetospeed(&term, B115200);
    1.34  
    1.35  	if(tcsetattr(dev, TCSANOW, &term) == -1) {
    1.36  		fprintf(stderr, "failed to set terminal attributes for %s: %s\n", devname, strerror(errno));
    1.37 @@ -101,22 +104,86 @@
    1.38  	return 0;
    1.39  }
    1.40  
    1.41 -#define RET_IF_FAIL(x)	\
    1.42 -	if(!fgets(buf, sizeof buf, dev) || buf[0] != 'O') return x
    1.43 +#define RET_IF_FAIL(x) if(!fgets(buf, sizeof buf, dev) || buf[0] != 'O') return x
    1.44 +/*#define RET_IF_FAIL(x)	\
    1.45 +	do { \
    1.46 +		if(!fgets(buf, sizeof buf, dev)) return x; \
    1.47 +		printf("--> %s", buf); \
    1.48 +		if(buf[0] != 'O') return x; \
    1.49 +	} while(0)
    1.50 +	*/
    1.51  
    1.52  int op_write(FILE *dev, FILE *fp)
    1.53  {
    1.54  	char buf[128];
    1.55 -	int c;
    1.56 +	int c, prev_progr = -1, written = 0;
    1.57 +	struct stat st;
    1.58 +
    1.59 +	fstat(fileno(fp), &st);
    1.60  
    1.61  	fprintf(dev, "p\n");
    1.62  	RET_IF_FAIL(-1);
    1.63  	fprintf(dev, "a%d\n", start_addr);
    1.64  	RET_IF_FAIL(-1);
    1.65  
    1.66 +	if(!quiet) {
    1.67 +		printf("writing %d bytes starting from %xh\n", (int)st.st_size, start_addr);
    1.68 +	}
    1.69 +
    1.70  	while((c = fgetc(fp)) != -1) {
    1.71 +		int p;
    1.72  		fprintf(dev, "w%d\n", c);
    1.73  		RET_IF_FAIL(-1);
    1.74 +
    1.75 +		if(!quiet) {
    1.76 +			p = 100 * ++written / st.st_size;
    1.77 +			if(p != prev_progr) {
    1.78 +				prev_progr = p;
    1.79 +				print_progress(p);
    1.80 +			}
    1.81 +		}
    1.82 +	}
    1.83 +	if(!quiet) {
    1.84 +		putchar('\n');
    1.85 +	}
    1.86 +
    1.87 +	if(verify) {
    1.88 +		int verified = 0;
    1.89 +
    1.90 +		rewind(fp);
    1.91 +		fprintf(dev, "a%d\n", start_addr);
    1.92 +		RET_IF_FAIL(-1);
    1.93 +
    1.94 +		if(!quiet) {
    1.95 +			printf("verifying %d bytes starting from %xh\n", (int)st.st_size, start_addr);
    1.96 +		}
    1.97 +
    1.98 +		while((c = fgetc(fp)) != -1) {
    1.99 +			int p, val;
   1.100 +			fprintf(dev, "r\n");
   1.101 +
   1.102 +			if(!fgets(buf, sizeof buf, dev) || buf[0] != 'O') {
   1.103 +				fprintf(stderr, "\rread error after %d bytes\n", verified);
   1.104 +				break;
   1.105 +			}
   1.106 +
   1.107 +			if((val = atoi(buf + 3)) != c) {	/* skip 'O', 'K', ' ' */
   1.108 +				fprintf(stderr, "\rverification error at byte %d\n", verified);
   1.109 +				fprintf(stderr, "expected %d (%xh), got %d (%xh)\n", c, c, val, val);
   1.110 +				break;
   1.111 +			}
   1.112 +
   1.113 +			if(!quiet) {
   1.114 +				p = 100 * ++verified / st.st_size;
   1.115 +				if(p != prev_progr) {
   1.116 +					prev_progr = p;
   1.117 +					print_progress(p);
   1.118 +				}
   1.119 +			}
   1.120 +		}
   1.121 +		if(!quiet) {
   1.122 +			putchar('\n');
   1.123 +		}
   1.124  	}
   1.125  
   1.126  	fprintf(dev, "b\n");
   1.127 @@ -127,21 +194,38 @@
   1.128  int op_read(FILE *dev, FILE *fp)
   1.129  {
   1.130  	char buf[128];
   1.131 -	int i, val;
   1.132 +	int i, val, prev_progr = -1;
   1.133  
   1.134  	fprintf(dev, "p\n");
   1.135  	RET_IF_FAIL(-1);
   1.136  	fprintf(dev, "a%d\n", start_addr);
   1.137  	RET_IF_FAIL(-1);
   1.138  
   1.139 +	if(!quiet) {
   1.140 +		printf("reading %d bytes starting from %xh\n", read_size, start_addr);
   1.141 +	}
   1.142 +
   1.143  	for(i=0; i<read_size; i++) {
   1.144 +		int p;
   1.145  		fprintf(dev, "r\n");
   1.146  		if(!fgets(buf, sizeof buf, dev) || buf[0] != 'O') {
   1.147  			fprintf(stderr, "read error after %d bytes\n", i);
   1.148  			break;
   1.149  		}
   1.150 +
   1.151  		val = atoi(buf + 3);	/* skip 'O', 'K', ' ' */
   1.152  		fputc(val, fp);
   1.153 +
   1.154 +		if(!quiet) {
   1.155 +			p = 100 * i / read_size;
   1.156 +			if(p != prev_progr) {
   1.157 +				prev_progr = p;
   1.158 +				print_progress(p);
   1.159 +			}
   1.160 +		}
   1.161 +	}
   1.162 +	if(!quiet) {
   1.163 +		putchar('\n');
   1.164  	}
   1.165  
   1.166  	fprintf(dev, "b\n");
   1.167 @@ -201,6 +285,9 @@
   1.168  		} else if(strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "-device") == 0) {
   1.169  			devname = argv[++i];
   1.170  
   1.171 +		} else if(strcmp(argv[i], "-q") == 0 || strcmp(argv[i], "-quiet") == 0) {
   1.172 +			quiet = 1;
   1.173 +
   1.174  		} else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0) {
   1.175  			printf("Usage: %s [options]\n", argv[0]);
   1.176  			printf("Options:\n");
   1.177 @@ -210,6 +297,7 @@
   1.178  			printf(" -R|-reset: reboot machine\n");
   1.179  			printf(" -v|-verify: do verification after writing\n");
   1.180  			printf(" -s|-size: read size in bytes\n");
   1.181 +			printf(" -q|-quiet: don't print anything to stdout\n");
   1.182  			printf(" -d|-device <device file>: serial device (eg /dev/ttyUSB0)\n");
   1.183  			printf(" -h|-help: print usage and exit\n");
   1.184  			return 0;
   1.185 @@ -226,3 +314,18 @@
   1.186  	}
   1.187  	return 0;
   1.188  }
   1.189 +
   1.190 +void print_progress(int p)
   1.191 +{
   1.192 +	int i, num = p / 2;
   1.193 +	printf("\rprogress: [");
   1.194 +	for(i=0; i<50; i++) {
   1.195 +		if(i == num) {
   1.196 +			putchar('>');
   1.197 +		} else {
   1.198 +			putchar(i < num ? '=' : ' ');
   1.199 +		}
   1.200 +	}
   1.201 +	printf("] %3d%%", p);
   1.202 +	fflush(stdout);
   1.203 +}