Commit e3b97f36 authored by Jeroen Vreeken's avatar Jeroen Vreeken
Browse files

Merge ../dt_ctrl-pand into beaglebone

parents db128019 6475d0a9
......@@ -26,12 +26,15 @@
#include <string.h>
#include <math.h>
#include <time.h>
#include <err.h>
#include <trace/trace.h>
time_t starttime;
#define VAL_BUFLEN (60 * 5)
int val_buflen;
//#define VAL_BUFLEN (60 * 5)
FILE *fdplot = NULL;
int doplot = 0;
......@@ -39,19 +42,30 @@ struct trace_view {
struct trace *trace;
char *tmpfilename;
FILE *fdtmp;
struct trace_value value[VAL_BUFLEN];
struct trace_value *value;
int bufpos;
};
struct trace_view *traces;
float samp_min, samp_max;
static void add_to_range(float val)
{
if (val < samp_min)
samp_min = val;
if (val > samp_max)
samp_max = val;
}
void plot_values(struct trace_view *traces, int nr_traces)
{
int i;
int bufpos = (traces[0].bufpos+VAL_BUFLEN-1) % VAL_BUFLEN;
int bufpos = (traces[0].bufpos + val_buflen - 1) % val_buflen;
long long now = traces[0].value[bufpos].t.tv_sec;
long nown = traces[0].value[bufpos].t.tv_nsec;
float range, range_low, range_high;
fprintf(fdplot, "plot ");
......@@ -65,6 +79,19 @@ void plot_values(struct trace_view *traces, int nr_traces)
"");
}
fprintf(fdplot, "\n");
// Calculate an y range that will fit all samples, plus a tiny bit
// more so the lowest/highest values are still visible at the edges of
// the plot.
//printf("sample range: %f, %f\n", samp_min, samp_max);
range = samp_max - samp_min;
if (range == 0.0)
range = 0.1;
range_low = samp_min - range * 0.02;
range_high = samp_max + range * 0.02;
fprintf(fdplot, "set yrange [%e:%e]\n", range_low, range_high);
fflush(NULL);
return;
......@@ -77,34 +104,42 @@ static void print_value(FILE *fd,
case TRACE_VALUE_TYPE_FLOAT:
fprintf(fd, "%ld.%09ld %e\n",
value->t.tv_sec, value->t.tv_nsec, value->value.f);
add_to_range(value->value.f);
break;
case TRACE_VALUE_TYPE_BOOL:
fprintf(fd, "%ld.%09ld %d\n",
value->t.tv_sec, value->t.tv_nsec, value->value.b);
add_to_range(value->value.b);
break;
case TRACE_VALUE_TYPE_UINT8:
fprintf(fd, "%ld.%09ld %u\n",
value->t.tv_sec, value->t.tv_nsec, value->value.u8);
add_to_range(value->value.u8);
break;
case TRACE_VALUE_TYPE_UINT16:
fprintf(fd, "%ld.%09ld %u\n",
value->t.tv_sec, value->t.tv_nsec, value->value.u16);
add_to_range(value->value.u16);
break;
case TRACE_VALUE_TYPE_UINT32:
fprintf(fd, "%ld.%09ld %u\n",
value->t.tv_sec, value->t.tv_nsec, value->value.u32);
add_to_range(value->value.u32);
break;
case TRACE_VALUE_TYPE_SINT8:
fprintf(fd, "%ld.%09ld %d\n",
value->t.tv_sec, value->t.tv_nsec, value->value.s8);
add_to_range(value->value.s8);
break;
case TRACE_VALUE_TYPE_SINT16:
fprintf(fd, "%ld.%09ld %d\n",
value->t.tv_sec, value->t.tv_nsec, value->value.s16);
add_to_range(value->value.s16);
break;
case TRACE_VALUE_TYPE_SINT32:
fprintf(fd, "%ld.%09ld %d\n",
value->t.tv_sec, value->t.tv_nsec, value->value.s32);
add_to_range(value->value.s32);
break;
}
}
......@@ -120,8 +155,9 @@ static void handler_value(struct trace *trace,
view->value[view->bufpos] = *value;
freopen(NULL, "w", view->fdtmp);
for (i = view->bufpos + 1; i < VAL_BUFLEN; i++) {
if (!view->value[i].t.tv_sec)
for (i = view->bufpos + 1; i < val_buflen; i++) {
if ((!view->value[i].t.tv_sec) ||
(view->value[i].t.tv_sec == 1))
continue;
print_value(view->fdtmp, trace, &view->value[i]);
......@@ -136,55 +172,159 @@ static void handler_value(struct trace *trace,
view->bufpos++;
view->bufpos %= VAL_BUFLEN;
view->bufpos %= val_buflen;
doplot++;
}
static void usage(char *progname)
{
fprintf(stderr, "usage: %s [options] [one or more trace names]\n"
"available options:\n"
" --host [hostname] set the name of the host to connect to\n"
" --port [port#] set the remote port number to connect "
"to\n"
" --interval [seconds] set the sample interval\n",
" --history [seconds] set the length of the plot\n",
progname);
exit(1);
}
int main(int argc, char **argv)
{
int i, ret = 0;
struct timespec t_int;
struct trace_view *t;
double interval, history;
char *host;
int trace_nr, i, port, ret = 0;
starttime = time(NULL);
host = "localhost";
port = 10000;
if (argc < 2)
usage(argv[0]);
history = 60.0;
interval = 0.2;
traces = calloc(sizeof(struct trace_view), argc - 1);
trace_nr = 0;
for (i = 0; i < argc - 1; i++) {
char *tracename = argv[i+1];
struct trace_pkt *pkt;
struct timespec t_int;
int fdmkstemp;
printf("%s\n", tracename);
traces[i].trace = trace_open("localhost", 10000);
if (!traces[i].trace) {
printf("open trace failed\n");
if (strcmp(tracename, "--host") == 0) {
if (i >= argc - 2)
errx(1, "missing hostname");
i++;
host = argv[i + 1];
fprintf(stderr, "Setting remote host to '%s'\n",
host);
continue;
}
if (strcmp(tracename, "--port") == 0) {
if (i >= argc - 2)
errx(1, "missing port number");
i++;
port = atoi(argv[i + 1]);
fprintf(stderr, "Setting remote port to %d\n", port);
continue;
}
if (strcmp(tracename, "--interval") == 0) {
if (i >= argc - 2)
errx(1, "missing interval argument");
i++;
interval = atof(argv[i + 1]);
fprintf(stderr, "Setting sample interval %fs\n",
interval);
continue;
}
if (strcmp(tracename, "--history") == 0) {
if (i >= argc - 2)
errx(1, "missing history argument");
i++;
history = atof(argv[i + 1]);
fprintf(stderr, "Setting history to %fs\n", history);
continue;
}
fprintf(stderr, "Adding trace '%s'\n", tracename);
t = &traces[trace_nr];
t->trace = trace_open(host, port);
if (!t->trace) {
fprintf(stderr, "opening trace on %s:%d failed\n",
host, port);
return 1;
}
traces[i].trace->private = &traces[i];
trace_name_set(traces[i].trace, tracename);
t->trace->private = &traces[trace_nr];
trace_name_set(t->trace, tracename);
traces[i].tmpfilename = malloc(100);
sprintf(traces[i].tmpfilename, "/tmp/trace_view_XXXXXX");
fdmkstemp = mkstemp(traces[i].tmpfilename);
t->tmpfilename = malloc(100);
sprintf(t->tmpfilename,
"/tmp/trace_view_XXXXXX");
fdmkstemp = mkstemp(t->tmpfilename);
printf("Going to use %s temp file for '%s' data\n",
traces[i].tmpfilename, tracename);
traces[i].fdtmp = fdopen(fdmkstemp, "w");
if (traces[i].fdtmp == NULL) {
t->tmpfilename, tracename);
t->fdtmp = fdopen(fdmkstemp, "w");
if (t->fdtmp == NULL) {
perror("fopen() failed");
return 1;
}
t_int.tv_sec = 0;
t_int.tv_nsec = 200*1000*1000;
t->trace->handler_value = handler_value;
trace_nr++;
}
if (trace_nr == 0) {
// Only options, but no trace names..
fprintf(stderr, "Error: Need at least one trace name.\n\n");
usage(argv[0]);
}
// calculate buffer length & sample interval
if (interval <= 0.0)
errx(1, "invalid interval!");
if (history <= 0.0)
errx(1, "invalid history length!");
if (history < interval)
errx(1, "history length must be >= interval!");
t_int.tv_sec = floor(interval);
t_int.tv_nsec = (interval - t_int.tv_sec) * 1.0e9;
//t_int.tv_sec = 0;
//t_int.tv_nsec = 200 * 1000;
// set interval on all trace connections
for (i = 0; i < trace_nr; i++) {
struct trace_pkt *pkt;
t = &traces[i];
pkt = trace_packet_new();
trace_packet_interval_set(pkt,
&t_int, TRACE_INTERVAL_TYPE_INTERVAL);
trace_packet_write(traces[i].trace, pkt);
trace_packet_write(t->trace, pkt);
trace_packet_put(pkt);
}
traces[i].trace->handler_value = handler_value;
// allocate memory for enough samples
val_buflen = ceil(history / interval);
//printf("buflen=%d samples\n", val_buflen);
//printf("interval= %d.%09d\n", t_int.tv_sec, t_int.tv_nsec);
for (i = 0; i < trace_nr; i++) {
traces[i].value = calloc(val_buflen,
sizeof(struct trace_value));
if (traces[i].value == NULL)
errx(1, "out of memory!");
}
fdplot = popen("gnuplot -noraise", "w");
......@@ -195,24 +335,32 @@ int main(int argc, char **argv)
fprintf(fdplot, "set grid\n");
samp_min = +INFINITY;
samp_max = -INFINITY;
do {
fd_set fdrx;
int high = 0;
FD_ZERO(&fdrx);
for (i = 0; i < argc - 1; i++)
for (i = 0; i < trace_nr; i++) {
trace_fd_set(traces[i].trace, &fdrx, &high);
}
select(high+1, &fdrx, NULL, NULL, NULL);
for (i = 0; i < argc - 1; i++)
for (i = 0; i < trace_nr; i++) {
trace_handle(traces[i].trace, &fdrx);
}
if (doplot >= argc - 1) {
plot_values(traces, argc - 1);
if (doplot >= trace_nr) {
plot_values(traces, trace_nr);
doplot = 0;
samp_min = +INFINITY;
samp_max = -INFINITY;
}
} while (ret == 0);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment