From: Nathael Pajani Date: Thu, 12 Apr 2012 11:43:36 +0000 (+0200) Subject: Working on serial utility functions, working on command line arguments X-Git-Tag: v1.0~53 X-Git-Url: http://git.techno-innov.fr/?a=commitdiff_plain;h=3f2b377efd23d72bfbd26f03b3091e3283315d1e;p=soft%2Ftools%2Flpctools Working on serial utility functions, working on command line arguments --- diff --git a/isp_main.c b/isp_main.c index 5a02f2f..b18c24e 100644 --- a/isp_main.c +++ b/isp_main.c @@ -5,16 +5,16 @@ *********************************************************************/ -#include +#include /* malloc, free */ #include #include -#include /* for open, getopt, close */ +#include /* open, getopt, close, usleep */ #include #include #include -#include +#include /* strncmp */ #include #include @@ -38,30 +38,30 @@ void help(char *prog_name) { fprintf(stderr, "-----------------------------------------------------------------------\n"); fprintf(stderr, "Usage: %s [options] device command [command arguments]\n" \ - "Default baudrate is B115200\n" \ - " is the (host) serial line used to programm the device\n" \ - " is one of:\n" \ - " synchronize \n" \ - " unlock \n" \ - " set-baud-rate \n" \ - " echo \n" \ - " write-to-ram \n" \ - " read-memory \n" \ - " prepare-for-write \n" \ - " copy-ram-to-flash \n" \ - " go \n" \ - " erase \n" \ - " blank-check \n" \ - " read-part-id \n" \ - " read-boot-version \n" \ - " compare \n" \ - " read-uid \n" \ - "Available options:\n" \ - " -s | --synchronize : Perform synchronization before sending command\n" \ - " -b | --baudrate=N : Use this baudrate (does not issue the set-baud-rate command)\n" \ - " -t | --trace : turn on trace output of serial communication\n" \ - " -h | --help : display this help\n" \ - " -v | --version : display version information\n", prog_name); + " Default baudrate is B115200\n" \ + " is the (host) serial line used to programm the device\n" \ + " is one of:\n" \ + " \t synchronize \n" \ + " \t unlock \n" \ + " \t set-baud-rate \n" \ + " \t echo \n" \ + " \t write-to-ram \n" \ + " \t read-memory \n" \ + " \t prepare-for-write \n" \ + " \t copy-ram-to-flash \n" \ + " \t go \n" \ + " \t erase \n" \ + " \t blank-check \n" \ + " \t read-part-id \n" \ + " \t read-boot-version \n" \ + " \t compare \n" \ + " \t read-uid \n" \ + " Available options:\n" \ + " \t -s | --synchronize : Perform synchronization before sending command\n" \ + " \t -b | --baudrate=N : Use this baudrate (does not issue the set-baud-rate command)\n" \ + " \t -t | --trace : turn on trace output of serial communication\n" \ + " \t -h | --help : display this help\n" \ + " \t -v | --version : display version information\n", prog_name); fprintf(stderr, "-----------------------------------------------------------------------\n"); } @@ -72,30 +72,35 @@ void help(char *prog_name) #define SERIAL_BAUD B115200 -char * serial_device = NULL; int serial_fd = -1; int trace_on = 0; -int serial_open(int baudrate) + +/* Open the serial device and set it up. + * Returns 0 on success, negativ value on error. + * Actal setup is done according to LPC11xx user's manual. + * Only baudrate can be changed using command line option. + */ +int serial_open(int baudrate, char* serial_device) { struct termios tio; if (serial_device == NULL) { printf("No serial device given on command line\n"); - exit(-1); + return -2; } /* Open serial port */ serial_fd = open(serial_device, O_RDWR | O_NONBLOCK); if (serial_fd < 0) { perror("Unable to open serial_device"); - printf("Tried to open %s.\n", serial_device); + printf("Tried to open \"%s\".\n", serial_device); return -1; } /* Setup serial port */ memset(&tio, 0, sizeof(tio)); - tio.c_iflag = IXON | IXOFF; /* See section 21.4.4 of LPC11xx user's manual (UM10398) */ - tio.c_cflag = CS8 | CREAD | CLOCAL; /* 8n1, see termios.h for more information */ + tio.c_iflag = IXON | IXOFF; /* See section 21.4.4 of LPC11xx user's manual (UM10398) */ + tio.c_cflag = CS8 | CREAD | CLOCAL; /* 8n1, see termios.h for more information */ tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 5; cfsetospeed(&tio, baudrate); @@ -105,17 +110,18 @@ int serial_open(int baudrate) return 0; } +/* Simple write() wrapper, with trace if enabled */ int serial_write(const char* buf, unsigned int buf_size) { int nb = 0; if (trace_on) { - printf("Sending %d :\n", buf_size); + printf("Sending %d octet(s) :\n", buf_size); isp_dump((unsigned char*)buf, buf_size); } nb = write(serial_fd, buf, buf_size); if (nb <= 0) { - perror("Serial read error"); + perror("Serial write error"); return -1; } return nb; @@ -125,28 +131,48 @@ int isp_ret_code(char* buf) { if (trace_on) { /* FIXME : Find how return code are sent (binary or ASCII) */ - printf("Received code : '0x%02x'\n", *buf); + printf("Received code: '0x%02x'\n", *buf); } return 0; } -int serial_read(char* buf, unsigned int buf_size) +/* Try to read at least "min_read" characters from the serial line. + * Returns -1 on error, 0 on end of file, or read count otherwise. + */ +int serial_read(char* buf, unsigned int buf_size, unsigned int min_read) { int nb = 0; - - nb = read(serial_fd, buf, buf_size); - if (nb < 0) { - perror("Serial read error"); - return -1; - } else if (nb == 0) { - printf("End of file !!!!\n"); - return -1; + unsigned int count = 0; + + if (min_read > buf_size) { + printf("serial_read: buffer too small for min read value.\n"); + return -3; } + + do { + nb = read(serial_fd, &buf[count], (buf_size - count)); + if (nb < 0) { + if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { + usleep( 5000 ); + continue; + } + perror("Serial read error"); + return -1; + } else if (nb == 0) { + printf("serial_read: end of file !!!!\n"); + return 0; + } + if (trace_on == 2) { + isp_dump((unsigned char*)(&buf[count]), nb); + } + count += nb; + } while (count < min_read); + if (trace_on) { - printf("Received : %d octets\n", nb); - isp_dump((unsigned char*)buf, nb); + printf("Received %d octet(s) :\n", count); + isp_dump((unsigned char*)buf, count); } - return nb; + return count; } /* Connect or reconnect to the target */ @@ -159,7 +185,7 @@ int connect() serial_write(SYNCHRO_START, 1); /* Wait for answer */ - serial_read(buf, SERIAL_BUFSIZE); + serial_read(buf, SERIAL_BUFSIZE, strlen(SYNCHRO)); /* Check answer, and acknoledge if OK */ if (strncmp(SYNCHRO, buf, strlen(SYNCHRO)) == 0) { @@ -169,7 +195,7 @@ int connect() return 0; } /* Empty read buffer (echo on ?) */ - serial_read(buf, SERIAL_BUFSIZE); + serial_read(buf, SERIAL_BUFSIZE, 1); /* and turn off echo */ serial_write("A 0\r\n", 1); @@ -181,20 +207,29 @@ int main(int argc, char** argv) { int baudrate = SERIAL_BAUD; int synchronize = 0; + char* serial_device = NULL; + + /* For "command" handling */ + char* command = NULL; + char** cmd_args = NULL; + int nb_cmd_args = 0; + /* parameter parsing */ while(1) { - int option_index = 0, c=0; + int option_index = 0; + int c = 0; struct option long_options[] = { - {"help", no_argument, 0, 'h'}, - {"baudrate", required_argument, 0, 'b'}, {"synchronize", no_argument, 0, 's'}, + {"baudrate", required_argument, 0, 'b'}, + {"trace", no_argument, 0, 't'}, + {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'v'}, {0, 0, 0, 0} }; - c = getopt_long_only(argc, argv, "hb:sv", long_options, &option_index); + c = getopt_long(argc, argv, "sb:thv", long_options, &option_index); /* no more options to parse */ if (c == -1) break; @@ -230,14 +265,40 @@ int main(int argc, char** argv) } } - /* FIXME : get serial device and command (and arguments) */ - /* serial_device = strdup(optarg); */ + /* Parse remaining command line arguments (not options). */ + + /* First one should be serial device */ + if (optind < argc) { + serial_device = argv[optind++]; + if (trace_on) { + printf("Serial device : %s\n", serial_device); + } + } + /* Next one should be "command" */ + if (optind < argc) { + command = argv[optind++]; + if (trace_on) { + printf("Command : %s\n", command); + } + } + /* And then remaining ones (if any) are command arguments */ + if (optind < argc) { + nb_cmd_args = argc - optind; + cmd_args = malloc(nb_cmd_args * sizeof(char *)); + while (optind < argc) { + printf ("%s\n", argv[optind++]); + } + } + if (serial_device == NULL) { + printf("No serial device given, exiting\n"); + help(argv[0]); return 0; } - - - serial_open(baudrate); + if (serial_open(baudrate, serial_device) != 0) { + printf("Serial open failed, unable to initiate serial communication with target.\n"); + return -1; + } /* FIXME : do not sync if command is sync */ if (synchronize) { @@ -247,6 +308,9 @@ int main(int argc, char** argv) /* FIXME : call command handler */ + if (cmd_args != NULL) { + free(cmd_args); + } close(serial_fd); return 0; }