From 1ff268ab13dd299c4cdc1e379df5397bd6a394e3 Mon Sep 17 00:00:00 2001 From: Alex AUVOLAT Date: Fri, 3 Jan 2014 19:05:10 +0100 Subject: Added simulator monitor tool. --- monitor/Makefile | 5 +++ monitor/disp.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ monitor/main.c | 61 ++++++++++++++++++++++++++++++++++++ monitor/mon | Bin 0 -> 14209 bytes monitor/mon.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++ monitor/mon.h | 54 ++++++++++++++++++++++++++++++++ 6 files changed, 298 insertions(+) create mode 100644 monitor/Makefile create mode 100644 monitor/disp.c create mode 100644 monitor/main.c create mode 100755 monitor/mon create mode 100644 monitor/mon.c create mode 100644 monitor/mon.h (limited to 'monitor') diff --git a/monitor/Makefile b/monitor/Makefile new file mode 100644 index 0000000..15dadc4 --- /dev/null +++ b/monitor/Makefile @@ -0,0 +1,5 @@ +CF=main.c disp.c mon.c +HF=mon.h + +mon: $(CF) $(HF) + gcc -o $@ $(CF) -lcurses -O2 diff --git a/monitor/disp.c b/monitor/disp.c new file mode 100644 index 0000000..d25c04d --- /dev/null +++ b/monitor/disp.c @@ -0,0 +1,92 @@ +#include +#include "mon.h" + +/* Screen disposition : + + program | program + status | output + window | interp. + ---------------------- + command line +*/ + +#define STATUS_WIN_WIDTH 60 + +static void disp_cmdline(); + +static char command[100]; +static int cmd_pos = 0; + +static WINDOW *wpstatus, *wpoutput, *wcmdline; + +void disp_init() { + initscr(); + cbreak(); + noecho(); + nonl(); + + wpstatus = newwin(LINES - 4, STATUS_WIN_WIDTH, 1, 1); + wpoutput = newwin(LINES - 4, COLS - STATUS_WIN_WIDTH - 3, 1, STATUS_WIN_WIDTH + 2); + wcmdline = newwin(1, COLS - 2, LINES - 2, 1); + + intrflush(wcmdline, FALSE); + keypad(wcmdline, TRUE); + nodelay(wcmdline, TRUE); + + cmd_pos = 0; + command[0] = 0; + disp_cmdline(); +} + +void disp_finish() { + endwin(); +} + +void handle_kbd(t_mon *mon) { + int x; + while ((x = wgetch(wcmdline)) != ERR) { + if (x == '\r') { + mon_handle_command(mon, command); + cmd_pos = 0; + } else if (x == KEY_BACKSPACE) { + if (cmd_pos > 0) cmd_pos--; + } else if (x >= 32 && x <= 127) { + if (cmd_pos < 99) + command[cmd_pos++] = x; + } + command[cmd_pos] = 0; + disp_cmdline(); + } +} + +// DISPLAY + +void disp_cmdline() { + werase(wcmdline); + wprintw(wcmdline, "> %s", command); + wrefresh(wcmdline); +} + +void disp_display(t_mon *mon) { + int i; + + werase(wpstatus); + + wprintw(wpstatus, "Step:\t\t%d\n", mon->step); + wprintw(wpstatus, "\nInputs:\n"); + for (i = 0; i < mon->n_inputs; i++) { + wprintw(wpstatus, "\t%s (%d)\t%s\n", mon->inputs[i].name, mon->inputs[i].size, mon->inputs[i].value); + } + if (mon->n_inputs == 0) wprintw(wpstatus, "\t(none)\n"); + wprintw(wpstatus, "\nOutputs:\n"); + for (i = 0; i < mon->n_outputs; i++) { + wprintw(wpstatus, "\t%s\t%s\t%ld\n", mon->outputs[i].name, mon->outputs[i].v_bin, mon->outputs[i].v_int); + } + if (mon->n_outputs == 0) wprintw(wpstatus, "\t(none)\n"); + + wmove(wcmdline, 0, cmd_pos + 2); + wrefresh(wpstatus); +} + + + diff --git a/monitor/main.c b/monitor/main.c new file mode 100644 index 0000000..27fc1e0 --- /dev/null +++ b/monitor/main.c @@ -0,0 +1,61 @@ +#include +#include + +#include "mon.h" + +#define MON2SIM "/tmp/mon2sim" +#define SIM2MON "/tmp/sim2mon" + +void usage(char* p) { + fprintf(stderr, "Usage:\n"); + fprintf(stderr, " %s [...]\n"); + fprintf(stderr, "\n"); +} + +int main(int argc, char *argv[]) { + int err; + + if (argc < 2) { + usage(argv[0]); + return 1; + } + + // Launch simulator + mkfifo(MON2SIM, 0600); + mkfifo(SIM2MON, 0600); + int sim_pid = fork(); + if (sim_pid == 0) { + // child : launch simulator + freopen(MON2SIM, "r", stdin); + freopen(SIM2MON, "w", stdout); + execv(argv[1], argv + 1); + } + + t_mon mon; + mon.to_sim = fopen(MON2SIM, "w"); + mon.from_sim = fopen(SIM2MON, "r"); + if (err = mon_read_prologue(&mon)) { + fprintf(stderr, "\nError while launching simulator (%d).\n", err); + goto finish; + } + + // Setup display + disp_init(); + + // RUN !!! + mon_loop(&mon); + + // clean up + disp_finish(); + +finish: + kill(sim_pid, SIGTERM); + waitpid(sim_pid); + + fclose(mon.to_sim); + fclose(mon.from_sim); + unlink(MON2SIM); + unlink(SIM2MON); + + return 0; +} diff --git a/monitor/mon b/monitor/mon new file mode 100755 index 0000000..9c7d629 Binary files /dev/null and b/monitor/mon differ diff --git a/monitor/mon.c b/monitor/mon.c new file mode 100644 index 0000000..8ff2851 --- /dev/null +++ b/monitor/mon.c @@ -0,0 +1,86 @@ +#include +#include + +#include "mon.h" + +int mon_read_prologue(t_mon *mon) { + int i; + + if (fscanf(mon->from_sim, " %d %d\n", &mon->n_inputs, &mon->n_outputs) == EOF) + return -1; + + mon->inputs = malloc(mon->n_inputs * sizeof(t_input)); + mon->outputs = malloc(mon->n_outputs * sizeof(t_output)); + + // Read input description + for (i = 0; i < mon->n_inputs; i++) { + mon->inputs[i].value[0] = '0'; + mon->inputs[i].value[1] = 0; + if (fscanf(mon->from_sim, "%d %s\n", &mon->inputs[i].size, mon->inputs[i].name) == EOF) + return -(i+2); + } + + // Zeroify output description + for (i = 0; i < mon->n_outputs; i++) { + mon->outputs[i].name[0] = 0; + mon->outputs[i].v_bin[0] = 0; + mon->outputs[i].v_int = 0; + } + + mon->step = 0; + mon->status = MS_RUN; + + mon->clk = time(NULL); + + return 0; +} + +void mon_loop(t_mon *mon) { + disp_display(mon); + while (mon->status != MS_FINISH) { + handle_kbd(mon); + if (mon->status == MS_AUTO) { + mon_step(mon); + } else { + usleep(10000); + } + } +} + +void mon_handle_command(t_mon *mon, char *c) { + if (c[0] == 0) { // empty command : run step + mon_step(mon); + } else if (!strcmp(c, "q")) { + mon->status = MS_FINISH; + } else if (!strcmp(c, "a")) { + mon->status = MS_AUTO; + } else if (!strcmp(c, "m")) { + mon->status = MS_RUN; + } +} + +void mon_step(t_mon *mon) { + int i = 0; + + // Get ticker + time_t new_clk = time(NULL); + int ticker = new_clk - mon->clk; + mon->clk = new_clk; + + // Send inputs to simulator + for (i = 0; i < mon->n_inputs; i++) { + fprintf(mon->to_sim, "%s\n", mon->inputs[i].value); + } + + // Read outputs from simulator + for (i = 0; i < mon->n_outputs; i++) { + fscanf(mon->from_sim, "%s %s %d\n", + mon->outputs[i].name, + mon->outputs[i].v_bin, + &mon->outputs[i].v_int); + } + + // Display + mon->step++; + disp_display(mon); +} diff --git a/monitor/mon.h b/monitor/mon.h new file mode 100644 index 0000000..e08f01c --- /dev/null +++ b/monitor/mon.h @@ -0,0 +1,54 @@ +#ifndef DEF_MON_H +#define DEF_MON_H + +#include +#include +#include + +typedef unsigned long long int t_value; + +typedef struct { + char name[32]; + char v_bin[32]; + t_value v_int; +} t_output; + +typedef struct { + char name[32]; + int size; + char value[32]; +} t_input; + +typedef enum { + MS_FINISH, + MS_RUN, + MS_AUTO +} t_status; + +typedef struct { + FILE *to_sim, *from_sim; + + int n_inputs, n_outputs; + t_input *inputs; + t_output *outputs; + + int step; + + t_status status; + + time_t clk; +} t_mon; + +void disp_init(); +void disp_display(t_mon *mon); +void disp_finish(); + +void handle_kbd(t_mon *mon); + +int mon_read_prologue(t_mon *mon); // nonzero on error +void mon_step(t_mon *mon); +void mon_loop(t_mon *mon); + +void mon_handle_command(t_mon *mon, char *c); + +#endif -- cgit v1.2.3