From: Andy Spencer Date: Sat, 15 Mar 2014 11:41:25 +0000 (+0000) Subject: Make control script more configurable X-Git-Url: http://pileus.org/git/?p=~andy%2Fcsm213a-hw;a=commitdiff_plain;h=f9b0067097963fa87b35d7844de1a30d2c93c005 Make control script more configurable --- diff --git a/hw2/control.c b/hw2/control.c index bae3e98..09694bb 100644 --- a/hw2/control.c +++ b/hw2/control.c @@ -3,9 +3,30 @@ #include #include +#include #include "messages.h" +// Options +char *opt_tty; +int opt_pretend; +int opt_verbose; + +int opt_device; +ntime_t opt_world; +ntime_t opt_start; +ntime_t opt_period; +int opt_relay; +int opt_sync; + +// Helper functions +uint64_t ipow(int i) { + int num = 1; + while (i-- > 0) + num *= 10; + return num; +} + void error(char *msg) { printf("Error: %s\n", msg); @@ -21,22 +42,101 @@ void dump(const char *label, uint8_t *data, int len) printf("\n"); } -int main(int argc, char **argv) +ntime_t gettime(const char *str) { - if (argc < 3) - error("usage: control /dev/ttyACM0 0 sync"); + ntime_t time = {}; + int start, end; + sscanf(str, "%u.%n%u%n", &time.seconds, &start, &time.nanosec, &end); + time.nanosec *= ipow(9-(end-start)); + return time; +} - // Parse args - char *opt_tty = argv[1]; - int opt_device = atoi(argv[2]); - int opt_sync = argv[3] && !strcmp(argv[3], "sync") ? - MSG_CTL_VALID_SYNC : 0; - int opt_relay = opt_device == 2; +void usage(void) +{ + printf("usage: control [OPTIONS] [TTY]\n"); + printf("\n"); + printf("Options:\n"); + printf(" -d,--device=id mbed Device ID\n"); + printf(" -w,--world=time initial world time\n"); + printf(" -s,--start=time emit start time\n"); + printf(" -p,--period=time emit period\n"); + printf(" -r,--relay enable relay mode\n"); + printf(" -y,--sync enable time sync\n"); + printf(" -n,--pretend do not send message\n"); + printf(" -v,--verbose print debug messages\n"); + printf(" -h,--help print this usage\n"); +} - // Lookup current wall-clock time +// Argument parsing +void parse(int argc, char **argv) +{ + // Get timestamp struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); + // Default arguments; + opt_tty = "/dev/ttyACM0"; + opt_device = 1; + opt_world = (ntime_t){ts.tv_sec, ts.tv_nsec}; + opt_start = (ntime_t){0, 0}; + opt_period = (ntime_t){1, 0}; + + // Long options + struct option long_options[] = { + {"device", required_argument }, + {"world", required_argument }, + {"start", required_argument }, + {"period", required_argument }, + {"relay", no_argument }, + {"sync", no_argument }, + {"pretend", no_argument }, + {"verbose", no_argument }, + {"help", no_argument }, + {0, 0 }, + }; + + // Run parser + while (1) { + int opt = getopt_long(argc, argv, "d:w:s:p:rynvh", long_options, 0); + if (opt == -1) + break; + switch (opt) { + case 'd': opt_device = atoi(optarg); break; + case 'w': opt_world = gettime(optarg); break; + case 's': opt_start = gettime(optarg); break; + case 'p': opt_period = gettime(optarg); break; + case 'r': opt_relay = 1; break; + case 'y': opt_sync = 1; break; + case 'n': opt_pretend = 1; break; + case 'v': opt_verbose++; break; + case 'h': usage(); exit(0); break; + default: usage(); exit(1); break; + } + } + if (optind < argc) + opt_tty = argv[optind]; +} + +// Main +int main(int argc, char **argv) +{ + // Lookup current wall-clock time + parse(argc, argv); + + // Debug output + if (opt_verbose) { + printf("options:\n"); + printf(" tty = %s\n", opt_tty); + printf(" device = %d\n", opt_device); + printf(" world = %d.%09u\n", opt_world.seconds, opt_world.nanosec); + printf(" start = %d.%09u\n", opt_start.seconds, opt_start.nanosec); + printf(" period = %d.%09u\n", opt_period.seconds, opt_period.nanosec); + printf(" relay = %s\n", opt_relay ? "true" : "false"); + printf(" sync = %s\n", opt_sync ? "true" : "false"); + printf(" pretend = %s\n", opt_pretend ? "true" : "false"); + printf(" verbose = %s\n", opt_verbose ? "true" : "false"); + } + // Message buffers header_t head = {}; init_msg_t body = {}; @@ -52,32 +152,31 @@ int main(int argc, char **argv) | MSG_CTL_VALID_START | MSG_CTL_VALID_PERIOD | MSG_CTL_VALID_WORLD - | opt_relay - | opt_sync; - - // Set message body - body.device = opt_device; - body.world.seconds = ts.tv_sec; - body.world.nanosec = ts.tv_nsec; - body.start.seconds = ts.tv_sec; - body.start.nanosec = 0; //ts.tv_nsec; - body.period.seconds = 0; - body.period.nanosec = 100000000; - // [s][m][u][n] + | (opt_relay ? MSG_CTL_RELAY_MODE : 0) + | (opt_sync ? MSG_CTL_BEGIN_SYNC : 0); + + body.device = opt_device; + body.world = opt_world; + body.start = opt_start; + body.period = opt_period; // Transmit message FILE *fd = fopen(opt_tty, "a+"); if (!fd) error("opening device"); int len = 0; - len += fwrite(&head, 1, sizeof(head), fd); - len += fwrite(&body, 1, sizeof(body), fd); + if (!opt_pretend) { + len += fwrite(&head, 1, sizeof(head), fd); + len += fwrite(&body, 1, sizeof(body), fd); + } fclose(fd); + if (opt_verbose > 2) + printf("wrote %d bytes\n", len); // Debug output - dump("head", (uint8_t*)&head, sizeof(head)); - dump("body", (uint8_t*)&body, sizeof(body)); - - printf("wrote %d bytes\n", len); + if (opt_verbose > 2) { + dump("head", (uint8_t*)&head, sizeof(head)); + dump("body", (uint8_t*)&body, sizeof(body)); + } return 0; } diff --git a/hw2/install.sh b/hw2/install.sh index 8d16c2e..ee72df9 100755 --- a/hw2/install.sh +++ b/hw2/install.sh @@ -24,8 +24,8 @@ fi if [ "$2" ]; then install "$1" "$2" "$3" & else - install "$1" /dev/sdb /mnt/mbed1 & - install "$1" /dev/sdc /mnt/mbed2 & + install "$1" /dev/sdb1 /mnt/mbed1 & + install "$1" /dev/sdc1 /mnt/mbed2 & fi wait diff --git a/hw2/main_comm.c b/hw2/main_comm.c index 54cdffc..ed864cc 100644 --- a/hw2/main_comm.c +++ b/hw2/main_comm.c @@ -217,7 +217,8 @@ void comm_handle_init(header_t *head, init_msg_t *body) body->control & MSG_CTL_VALID_START ? "START" : "start", body->control & MSG_CTL_VALID_PERIOD ? "PERIOD" : "period", body->control & MSG_CTL_VALID_WORLD ? "WORLD" : "world", - body->control & MSG_CTL_VALID_SYNC ? "SYNC" : "sync"); + body->control & MSG_CTL_RELAY_MODE ? "RELAY" : "relay", + body->control & MSG_CTL_BEGIN_SYNC ? "SYNC" : "sync"); sirq_printf(" dev -- %d\r\n", body->device); time_printf(" start ", comm_read_time(body->start)); time_printf(" period", comm_read_time(body->period)); @@ -241,7 +242,7 @@ void comm_handle_init(header_t *head, init_msg_t *body) else comm_relay_mode = 0; - if (body->control & MSG_CTL_VALID_SYNC) + if (body->control & MSG_CTL_BEGIN_SYNC) comm_sync_due = tdma_time() + comm_sync_delay; } diff --git a/hw2/makefile b/hw2/makefile index fef6181..36f60c8 100644 --- a/hw2/makefile +++ b/hw2/makefile @@ -9,7 +9,7 @@ CPPFLAGS = LDFLAGS = -lm # Common rules -all: mbed.elf tester.elf control +all: mbed.bin tester.bin control terms: test -c $(UART0) && term $(UART0) & @@ -24,9 +24,9 @@ mbed.elf: main.o main_time.o main_emit.o main_comm.o \ mbed-run: mbed.bin control install.sh @./install.sh $< - @./control $(UART0) 1 - @./control $(UART0) 2 - @./control $(UART0) 2 sync + @./control -d1 $(UART0) + @./control -d2 $(UART0) + @./control -d2 -y $(UART0) # Testing mbed (mbed3) tester.elf: tester.o serial_irq.o timer_dma.o messages.o diff --git a/hw2/messages.h b/hw2/messages.h index ef81129..cd94398 100644 --- a/hw2/messages.h +++ b/hw2/messages.h @@ -18,7 +18,7 @@ extern "C" { #define MSG_CTL_VALID_START 0x0004 // start time is valid #define MSG_CTL_VALID_PERIOD 0x0008 // period is valid #define MSG_CTL_RELAY_MODE 0x4000 // relay output messages -#define MSG_CTL_VALID_SYNC 0x8000 // begin time sync +#define MSG_CTL_BEGIN_SYNC 0x8000 // begin time sync #pragma pack(1)