summaryrefslogtreecommitdiff
path: root/monitor
diff options
context:
space:
mode:
authorAlex AUVOLAT <alex.auvolat@ens.fr>2014-01-03 19:05:10 +0100
committerAlex AUVOLAT <alex.auvolat@ens.fr>2014-01-03 19:05:10 +0100
commit1ff268ab13dd299c4cdc1e379df5397bd6a394e3 (patch)
tree014db93062f26cdfe2d2639fd833afd554e94a66 /monitor
parentc46fe12e47c405fbb03f0c93121402d873bc470e (diff)
downloadSystDigit-Projet-1ff268ab13dd299c4cdc1e379df5397bd6a394e3.tar.gz
SystDigit-Projet-1ff268ab13dd299c4cdc1e379df5397bd6a394e3.zip
Added simulator monitor tool.
Diffstat (limited to 'monitor')
-rw-r--r--monitor/Makefile5
-rw-r--r--monitor/disp.c92
-rw-r--r--monitor/main.c61
-rwxr-xr-xmonitor/monbin0 -> 14209 bytes
-rw-r--r--monitor/mon.c86
-rw-r--r--monitor/mon.h54
6 files changed, 298 insertions, 0 deletions
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 <curses.h>
+#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 <curses.h>
+#include <signal.h>
+
+#include "mon.h"
+
+#define MON2SIM "/tmp/mon2sim"
+#define SIM2MON "/tmp/sim2mon"
+
+void usage(char* p) {
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, " %s <simulator> [<simulator arguments>...]\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
--- /dev/null
+++ b/monitor/mon
Binary files 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 <stdlib.h>
+#include <unistd.h>
+
+#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 <time.h>
+#include <stdio.h>
+#include <curses.h>
+
+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