]> rtime.felk.cvut.cz Git - can-benchmark.git/blobdiff - latester/latester.c
Allow messages with zero id
[can-benchmark.git] / latester / latester.c
index 63d96e5381d5f549bac39dc823a3b9fe618f0083..cb578a11ed716ad591198df47fe7b1acb27199fb 100644 (file)
@@ -59,13 +59,14 @@ struct options {
        unsigned oneattime;
        FILE *file;
        FILE *histogram;
+       int length;
 };
 
 struct options opt = {
        .id = 10,
        .period_us = 0,
        .timeout_ms = 1000,
-
+       .length = 2,
 };
 
 int num_interfaces = 0;
@@ -78,6 +79,7 @@ struct msg_info {
        struct timespec ts_sent, ts_sent_kern;
        struct timespec ts_rx_onwire, ts_rx_onwire_kern;
        struct timespec ts_rx_final, ts_rx_final_kern;
+       struct can_frame sent, received;
 };
 
 #define MAX_INFOS 10000
@@ -85,15 +87,45 @@ struct msg_info msg_infos[MAX_INFOS];
 
 struct histogram histogram;
 
+void sprint_canframe(char *buf , struct can_frame *cf, int sep) {
+       /* documentation see lib.h */
+
+       int i,offset;
+       int dlc = (cf->can_dlc > 8)? 8 : cf->can_dlc;
+
+       if (cf->can_id & CAN_ERR_FLAG) {
+               sprintf(buf, "%08X#", cf->can_id & (CAN_ERR_MASK|CAN_ERR_FLAG));
+               offset = 9;
+       } else if (cf->can_id & CAN_EFF_FLAG) {
+               sprintf(buf, "%08X#", cf->can_id & CAN_EFF_MASK);
+               offset = 9;
+       } else {
+               sprintf(buf, "%03X#", cf->can_id & CAN_SFF_MASK);
+               offset = 4;
+       }
+
+       if (cf->can_id & CAN_RTR_FLAG) /* there are no ERR frames with RTR */
+               sprintf(buf+offset, "R");
+       else
+               for (i = 0; i < dlc; i++) {
+                       sprintf(buf+offset, "%02X", cf->data[i]);
+                       offset += 2;
+                       if (sep && (i+1 < dlc))
+                               sprintf(buf+offset++, ".");
+               }
+}
+
 static inline struct msg_info *frame2info(struct can_frame *frame)
 {
        uint16_t idx;
-       if (frame->can_dlc == 2) {
+       if (frame->can_dlc >= 2) {
                memcpy(&idx, frame->data, sizeof(idx));
                if (idx >= MAX_INFOS)
                        error(1, 0, "%s idx too high", __FUNCTION__);
-       } else
+       } else {
+               
                error(1, 0, "%s error", __FUNCTION__);
+       }
        return &msg_infos[idx];
 }
 
@@ -103,30 +135,36 @@ static inline char *tstamp_str(const void *ctx, struct timespec *tstamp)
                               tstamp->tv_sec, tstamp->tv_nsec/1000);
 }
 
-void print_msg_info(struct msg_info *mi)
+void msg_info_print(FILE *f, struct msg_info *mi)
 {
        struct timespec diff;
        void *local = talloc_new (NULL);
+       static long num = 0;
+       char sent[64], received[64];
+
+       sprint_canframe(sent, &mi->sent, true);
+       sprint_canframe(received, &mi->received, true);
 
 #define S(ts) tstamp_str(local, &ts)
 #define DIFF(a, b) (timespec_subtract(&diff, &b, &a), S(diff))
 
        if (num_interfaces == 2)
-               printf("%s -> %s (%s) = %s (%s)\n",
-                      S(mi->ts_sent), S(mi->ts_rx_final_kern), S(mi->ts_rx_final),
+               fprintf(f, "%ld: %s %s -> %s (%s) %s = %s (%s)\n",
+                       num, S(mi->ts_sent), sent, S(mi->ts_rx_final_kern), S(mi->ts_rx_final), received,
                       DIFF(mi->ts_sent, mi->ts_rx_final_kern),
                       DIFF(mi->ts_sent, mi->ts_rx_final));
        else
-               printf("%s -> %s (%s) -> %s (%s) = %s (%s), %s (%s)\n",
-                      S(mi->ts_sent),
-                      S(mi->ts_rx_onwire_kern), S(mi->ts_rx_onwire),
-                      S(mi->ts_rx_final_kern), S(mi->ts_rx_final),
-                      DIFF(mi->ts_sent, mi->ts_rx_onwire_kern),
-                      DIFF(mi->ts_sent, mi->ts_rx_onwire),
-                      DIFF(mi->ts_rx_onwire_kern, mi->ts_rx_final_kern),
-                      DIFF(mi->ts_rx_onwire, mi->ts_rx_final));
+               fprintf(f, "%ld: %s %s -> %s (%s) -> %s (%s) %s = %s (%s), %s (%s)\n",
+                       num, S(mi->ts_sent), sent,
+                       S(mi->ts_rx_onwire_kern), S(mi->ts_rx_onwire),
+                       S(mi->ts_rx_final_kern), S(mi->ts_rx_final), received,
+                       DIFF(mi->ts_sent, mi->ts_rx_onwire_kern),
+                       DIFF(mi->ts_sent, mi->ts_rx_onwire),
+                       DIFF(mi->ts_rx_onwire_kern, mi->ts_rx_final_kern),
+                       DIFF(mi->ts_rx_onwire, mi->ts_rx_final));
 #undef S
 #undef DIFF
+       num++;
        talloc_free (local);
 }
 
@@ -134,17 +172,18 @@ int msg_info_store(FILE *f, struct msg_info *mi)
 {
        struct timespec diff;
        void *local = talloc_new (NULL);
+       static long num = 0;
 
 #define S(ts) tstamp_str(local, &ts)
 #define DIFF(a, b) (timespec_subtract(&diff, &b, &a), S(diff))
 
        if (num_interfaces == 2)
-               fprintf(f, "%d %d %s\n",
-                       mi->id, mi->length,
+               fprintf(f, "%ld %d %d %s\n",
+                       num, mi->id, mi->length,
                        DIFF(mi->ts_sent, mi->ts_rx_final_kern));
        else
-               fprintf(f, "%d %d %s\n",
-                       mi->id, mi->length,
+               fprintf(f, "%ld %d %d %s\n",
+                       num, mi->id, mi->length,
                        DIFF(mi->ts_rx_onwire_kern, mi->ts_rx_final_kern));
 #undef S
 #undef DIFF
@@ -229,7 +268,7 @@ static inline int sock_get_if_index(int s, const char *if_name)
 
 static inline get_tstamp(struct timespec *ts)
 {
-       clock_gettime(CLOCK_REALTIME, ts);
+       clock_gettime(CLOCK_MONOTONIC, ts);
 }
 
 int send_frame(int socket)
@@ -240,9 +279,10 @@ int send_frame(int socket)
        static int curr_msg = -1;
        int i;
        uint16_t idx;
-       
+
+       MEMSET_ZERO(frame);
        i = curr_msg+1;
-       while (msg_infos[i].id != 0 && i != curr_msg) {
+       while (msg_infos[i].id != -1 && i != curr_msg) {
                i++;
                if (i >= MAX_INFOS)
                        i = 0;
@@ -253,7 +293,9 @@ int send_frame(int socket)
                curr_msg = i;
 
        frame.can_id = opt.id;
-       frame.can_dlc = 2;
+       if (opt.length < 2)
+               error(1, 0, "Length < 2 is not yet supported");
+       frame.can_dlc = opt.length;
        idx = curr_msg;
        memcpy(frame.data, &idx, sizeof(idx));
        mi = frame2info(&frame);
@@ -261,13 +303,14 @@ int send_frame(int socket)
        mi->id = frame.can_id;
        mi->length = frame.can_dlc;
        get_tstamp(&mi->ts_sent);
+       mi->sent = frame;
        ret = write(socket, &frame, sizeof(frame));
        return ret;
 }
 
 void msg_info_free(struct msg_info *mi)
 {
-       mi->id = 0;
+       mi->id = -1;
 }
 
 static inline void get_next_timeout(struct timespec *timeout)
@@ -364,6 +407,7 @@ void process_final_rx(int s)
        mi = frame2info(&frame);
        mi->ts_rx_final_kern = ts_kern;
        mi->ts_rx_final = ts_user;
+       mi->received = frame;
 
        if (opt.histogram)
                histogram_add(&histogram, get_msg_latency_us(mi));
@@ -501,6 +545,7 @@ struct poptOption optionsTable[] = {
        { "verbose",'v', POPT_ARG_NONE,                           NULL, 'v',         "Send the next message only when the previous was finally received"},
        { "file",   'f', POPT_ARG_STRING,                         NULL, 'f',         "File where to store results", "filename"},
        { "histogram", 'h', POPT_ARG_STRING,                      NULL, 'h',         "Store histogram in file", "filename"},
+       { "length", 'l', POPT_ARG_INT|POPT_ARGFLAG_SHOW_DEFAULT,  &opt.length, 0,    "The length of generated messages", "bytes"},
        POPT_AUTOHELP
        { NULL, 0, 0, NULL, 0 }
 };
@@ -552,7 +597,7 @@ int main(int argc, const char *argv[])
 {
        pthread_t thread;
        sigset_t set;
-       int ret;
+       int ret, i;
 
        parse_options(argc, argv);
 
@@ -561,8 +606,11 @@ int main(int argc, const char *argv[])
        signal(SIGINT, term_handler);
        signal(SIGTERM, term_handler);
 
+       for (i=0; i<MAX_INFOS; i++)
+               msg_infos[i].id = -1;
+
        if (opt.histogram) {
-               histogram_init(&histogram, 1000000, 1);
+               histogram_init(&histogram, 5000000, 1);
        }
 
        ret = pipe(completion_pipe);
@@ -576,7 +624,8 @@ int main(int argc, const char *argv[])
 
        struct timespec next, now, diff;
        clock_gettime(CLOCK_MONOTONIC, &next);
-       while (!finish_flag && (opt.count == 0 || count < opt.count)) {
+       int completed = 0;
+       while (!finish_flag && (opt.count == 0 || completed < opt.count)) {
                struct pollfd pfd[1];
                pfd[0].fd = completion_pipe[0];
                pfd[0].events = POLLIN;
@@ -585,10 +634,14 @@ int main(int argc, const char *argv[])
                        error(1, errno, "poll main");
                if (ret > 0 && (pfd[0].revents & POLLIN)) {
                        struct msg_info *mi;
-                       read(completion_pipe[0], &mi, sizeof(mi));
+                       int ret;
+                       ret = read(completion_pipe[0], &mi, sizeof(mi));
+                       if (ret < sizeof(mi))
+                               error(1, errno, "read completion returned %d", ret);
                        if (opt.file)
-                               msg_info_store(opt.file, mi);
+                               msg_info_print(opt.file, mi);
                        msg_info_free(mi);
+                       completed++;
                }
 
                clock_gettime(CLOCK_MONOTONIC, &now);