mdcart
diff src/main.c @ 0:e6d499a8eb1d
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 12 Mar 2017 06:20:22 +0200 |
parents | |
children | c8d3d23ccd1f |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/main.c Sun Mar 12 06:20:22 2017 +0200 1.3 @@ -0,0 +1,228 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <string.h> 1.7 +#include <stdint.h> 1.8 +#include <errno.h> 1.9 +#include <assert.h> 1.10 +#include <unistd.h> 1.11 +#include <fcntl.h> 1.12 +#include <termios.h> 1.13 + 1.14 +enum { 1.15 + OP_NONE, 1.16 + OP_WRITE, 1.17 + OP_READ, 1.18 + OP_RESET 1.19 +}; 1.20 + 1.21 +int op_write(FILE *dev, FILE *fp); 1.22 +int op_read(FILE *dev, FILE *fp); 1.23 +int op_reset(FILE *dev); 1.24 +int parse_args(int argc, char **argv); 1.25 + 1.26 +int op, verify = 0; 1.27 +const char *devname = "/dev/ttyUSB0"; 1.28 +char *fname = 0; 1.29 +uint32_t start_addr; 1.30 +int read_size = 128 * 1024; 1.31 + 1.32 +int main(int argc, char **argv) 1.33 +{ 1.34 + FILE *fp, *devfp; 1.35 + int dev; 1.36 + struct termios term; 1.37 + 1.38 + if(parse_args(argc, argv) == -1) { 1.39 + return 1; 1.40 + } 1.41 + 1.42 + if((dev = open(devname, O_RDWR)) == -1) { 1.43 + fprintf(stderr, "failed to open device %s: %s\n", devname, strerror(errno)); 1.44 + return 1; 1.45 + } 1.46 + if(tcgetattr(dev, &term) == -1) { 1.47 + fprintf(stderr, "failed to get terminal attributes for %s: %s\n", devname, strerror(errno)); 1.48 + return 1; 1.49 + } 1.50 + term.c_cflag = CS8 | CLOCAL; 1.51 + term.c_iflag &= ~(IXON | IXOFF); 1.52 + term.c_lflag = 0; 1.53 + 1.54 + cfsetispeed(&term, B38400); 1.55 + cfsetospeed(&term, B38400); 1.56 + 1.57 + if(tcsetattr(dev, TCSANOW, &term) == -1) { 1.58 + fprintf(stderr, "failed to set terminal attributes for %s: %s\n", devname, strerror(errno)); 1.59 + return 1; 1.60 + } 1.61 + 1.62 + if(!(devfp = fdopen(dev, "r+"))) { 1.63 + perror("failed to attach I/O stream to the device file\n"); 1.64 + return 1; 1.65 + } 1.66 + setvbuf(devfp, 0, _IONBF, 0); 1.67 + 1.68 + if(fname && !(fp = fopen(fname, op == OP_READ ? "w" : "r"))) { 1.69 + fprintf(stderr, "failed to open %s: %s\n", fname, strerror(errno)); 1.70 + return 1; 1.71 + } 1.72 + 1.73 + switch(op) { 1.74 + case OP_WRITE: 1.75 + if(op_write(devfp, fp) == -1) { 1.76 + fprintf(stderr, "write failed\n"); 1.77 + return 1; 1.78 + } 1.79 + break; 1.80 + 1.81 + case OP_READ: 1.82 + if(op_read(devfp, fp) == -1) { 1.83 + fprintf(stderr, "read failed\n"); 1.84 + return 1; 1.85 + } 1.86 + break; 1.87 + 1.88 + case OP_RESET: 1.89 + if(op_reset(devfp) == -1) { 1.90 + fprintf(stderr, "reset failed\n"); 1.91 + return 1; 1.92 + } 1.93 + break; 1.94 + 1.95 + default: 1.96 + break; 1.97 + } 1.98 + 1.99 + fclose(devfp); 1.100 + close(dev); 1.101 + if(fp) { 1.102 + fclose(fp); 1.103 + } 1.104 + return 0; 1.105 +} 1.106 + 1.107 +#define RET_IF_FAIL(x) \ 1.108 + if(!fgets(buf, sizeof buf, dev) || buf[0] != 'O') return x 1.109 + 1.110 +int op_write(FILE *dev, FILE *fp) 1.111 +{ 1.112 + char buf[128]; 1.113 + int c; 1.114 + 1.115 + fprintf(dev, "p\n"); 1.116 + RET_IF_FAIL(-1); 1.117 + fprintf(dev, "a%d\n", start_addr); 1.118 + RET_IF_FAIL(-1); 1.119 + 1.120 + while((c = fgetc(fp)) != -1) { 1.121 + fprintf(dev, "w%d\n", c); 1.122 + RET_IF_FAIL(-1); 1.123 + } 1.124 + 1.125 + fprintf(dev, "b\n"); 1.126 + RET_IF_FAIL(-1); 1.127 + return 0; 1.128 +} 1.129 + 1.130 +int op_read(FILE *dev, FILE *fp) 1.131 +{ 1.132 + char buf[128]; 1.133 + int i, val; 1.134 + 1.135 + fprintf(dev, "p\n"); 1.136 + RET_IF_FAIL(-1); 1.137 + fprintf(dev, "a%d\n", start_addr); 1.138 + RET_IF_FAIL(-1); 1.139 + 1.140 + for(i=0; i<read_size; i++) { 1.141 + fprintf(dev, "r\n"); 1.142 + if(!fgets(buf, sizeof buf, dev) || buf[0] != 'O') { 1.143 + fprintf(stderr, "read error after %d bytes\n", i); 1.144 + break; 1.145 + } 1.146 + val = atoi(buf + 3); /* skip 'O', 'K', ' ' */ 1.147 + fputc(val, fp); 1.148 + } 1.149 + 1.150 + fprintf(dev, "b\n"); 1.151 + RET_IF_FAIL(-1); 1.152 + return 0; 1.153 +} 1.154 + 1.155 +int op_reset(FILE *dev) 1.156 +{ 1.157 + char buf[128]; 1.158 + fprintf(dev, "p\n"); 1.159 + RET_IF_FAIL(-1); 1.160 + fprintf(dev, "b\n"); 1.161 + RET_IF_FAIL(-1); 1.162 + return 0; 1.163 +} 1.164 + 1.165 +int parse_args(int argc, char **argv) 1.166 +{ 1.167 + int i; 1.168 + 1.169 + for(i=1; i<argc; i++) { 1.170 + if(strcmp(argv[i], "-w") == 0 || strcmp(argv[i], "-write") == 0) { 1.171 + op = OP_WRITE; 1.172 + if(!(fname = argv[++i])) { 1.173 + fprintf(stderr, "%s must be followed by a filename\n", argv[i - 1]); 1.174 + return -1; 1.175 + } 1.176 + 1.177 + } else if(strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "-read") == 0) { 1.178 + op = OP_READ; 1.179 + if(!(fname = argv[++i])) { 1.180 + fprintf(stderr, "%s must be followed by a filename\n", argv[i - 1]); 1.181 + return -1; 1.182 + } 1.183 + 1.184 + } else if(strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "-addr") == 0) { 1.185 + char *endp; 1.186 + if(!argv[++i] || ((start_addr = strtol(argv[i], &endp, 0)), endp == argv[i])) { 1.187 + fprintf(stderr, "%s must be followed by an address\n", argv[i - 1]); 1.188 + return -1; 1.189 + } 1.190 + 1.191 + } else if(strcmp(argv[i], "-R") == 0 || strcmp(argv[i], "-reset") == 0) { 1.192 + op = OP_RESET; 1.193 + 1.194 + } else if(strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "-size") == 0) { 1.195 + char *endp; 1.196 + if(!argv[++i] || ((read_size = strtol(argv[i], &endp, 0)), endp == argv[i])) { 1.197 + fprintf(stderr, "%s must be followed by a size in bytes\n", argv[i - 1]); 1.198 + return -1; 1.199 + } 1.200 + 1.201 + } else if(strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "-verify") == 0) { 1.202 + verify = 1; 1.203 + 1.204 + } else if(strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "-device") == 0) { 1.205 + devname = argv[++i]; 1.206 + 1.207 + } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0) { 1.208 + printf("Usage: %s [options]\n", argv[0]); 1.209 + printf("Options:\n"); 1.210 + printf(" -w|-write <filename>\n"); 1.211 + printf(" -r|-read <filename>\n"); 1.212 + printf(" -a|-addr <address>: start address for read/write operations\n"); 1.213 + printf(" -R|-reset: reboot machine\n"); 1.214 + printf(" -v|-verify: do verification after writing\n"); 1.215 + printf(" -s|-size: read size in bytes\n"); 1.216 + printf(" -d|-device <device file>: serial device (eg /dev/ttyUSB0)\n"); 1.217 + printf(" -h|-help: print usage and exit\n"); 1.218 + return 0; 1.219 + 1.220 + } else { 1.221 + fprintf(stderr, "invalid argument: %s\n", argv[i]); 1.222 + return -1; 1.223 + } 1.224 + } 1.225 + 1.226 + if(!op) { 1.227 + fprintf(stderr, "you must specify an operation\n"); 1.228 + return -1; 1.229 + } 1.230 + return 0; 1.231 +}