]> rtime.felk.cvut.cz Git - can-benchmark.git/blobdiff - latester/latester.c
Another bug
[can-benchmark.git] / latester / latester.c
index 1ab978167310d3442abee9fa7fc627c196794962..090676023da5b739e98d9445cafd7d7d1e5cd3c2 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************/
 /* CAN latency tester                                                     */
-/* Copyright (C) 2010, 2011 Michal Sojka, DCE FEE CTU Prague                    */
+/* Copyright (C) 2010, 2011, 2012, 2013 Michal Sojka, DCE FEE CTU Prague  */
 /* License: GPLv2                                                        */
 /**************************************************************************/
 
@@ -197,20 +197,51 @@ crc_t crc_update(crc_t crc, uint32_t data, size_t bit_len)
     return crc;
 }
 
+uint32_t calc_bitmap_crc(uint32_t *bitmap, unsigned start, unsigned end)
+{
+    crc_t crc = 0;
+    crc = crc_update(crc, bitmap[0] << start, 32 - start);
+    crc = crc_update(crc, bitmap[1], 32);
+    crc = crc_update(crc, bitmap[2], end - 64 > 32 ? 32 : end - 64); /* FIXME: This seems to be broken for end < 64 */
+    crc = crc_update(crc, bitmap[3], end > 96 ? end - 96 : 0);
+    return (uint32_t)htons(crc << 17);
+}
+
+void write_crc_to_bitmap(uint32_t crc, uint32_t *bitmap, struct can_frame *frame)
+{
+    unsigned index = frame->can_id & CAN_EFF_FLAG ? 2 : 1;
+    if (frame->can_dlc < 4)
+        bitmap[index] |= crc >> (frame->can_dlc*8);
+    if (frame->can_dlc == 3)
+        bitmap[index + 1] |= crc << 8;
+    if (frame->can_dlc >= 4 && frame->can_dlc < 8)
+    {
+        bitmap[index + 1] |= crc >> (frame->can_dlc*8);
+        if (frame->can_dlc == 7)
+            bitmap[index + 2] = crc << 8;
+    }
+    else if (frame->can_dlc == 8)
+        bitmap[index + 2] = crc;
+}
+
 unsigned calc_stuff_bits(struct can_frame *frame) {
        uint32_t bitmap[4];
        unsigned start = 0, end;
        uint32_t mask, ones = 0, basemask = 0xf8000000;
        unsigned stuffed = 0;
        memset(bitmap, 0, sizeof(bitmap));
-       crc_t crc = 0;
-       uint32_t crcx;
+       uint32_t crc;
 
 /*     char received[64]; */
 /*     sprint_canframe(received, frame, true); */
 /*     printf("Frame: %s\n", received); */
        
        if (frame->can_id & CAN_EFF_FLAG) {
+               // bit 31                              0
+               // [0] |...........................sBBBB| s = SOF, B = Base ID (11 bits)
+               // [1] |BBBBBBBSIEEEEEEEEEEEEEEEEEER10DLC4| S = SRR, I = IDE, E = Extended ID (18 bits), DLC4 = DLC
+               // [2] |00000000111111112222222233333333| Data bytes, MSB first
+               // [3] |44444444555555556666666677777777|
                bitmap[0] =
                        ((frame->can_id & CAN_EFF_MASK) >> 25);
                bitmap[1] =
@@ -220,33 +251,27 @@ unsigned calc_stuff_bits(struct can_frame *frame) {
                        (!!(frame->can_id & CAN_RTR_FLAG)) << 6         |
                        0 << 4                                          |
                        frame->can_dlc & 0xf;
-               bitmap[2] = htonl(((uint32_t*)frame->data)[0]);
-               bitmap[3] = htonl(((uint32_t*)frame->data)[1]);
+               memcpy(&bitmap[2], &frame->data, frame->can_dlc);
                start = 27;
                end = 64 + 8*frame->can_dlc;
-               crc = crc_update(crc, bitmap[0] << start, 32-start);
-               crc = crc_update(crc, bitmap[1], 32);
-               crc = crc_update(crc, bitmap[2], end - 64 > 32 ? 32 : end - 64);
-               crc = crc_update(crc, bitmap[3], end > 96 ? end - 96 : 0);
-               crcx = (uint32_t)htons(crc) << 17;
-               if (frame->can_dlc < 4)
-                       bitmap[2] |= crcx >> (frame->can_dlc*8);
-               if (frame->can_dlc = 3)
-                       bitmap[3] |= crcx << 8;
-               if (frame->can_dlc >= 4)
-                       bitmap[3] |= crcx >> (frame->can_dlc*8);
        } else {
+               // bit 31                              0
+               // [0] |.............sIIIIIIIIIIIRE0DLC4| s = SOF, I = ID (11 bits), R = RTR, E = IDE, DLC4 = DLC
+               // [1] |00000000111111112222222233333333| Data bytes, MSB first
+               // [2] |44444444555555556666666677777777|
                bitmap[0] =
                        (frame->can_id << 7) |
                        (!!(frame->can_id & CAN_RTR_FLAG)) << 6 |
                        0 << 4                                  |
                        frame->can_dlc & 0xf;
-               bitmap[1] = htonl(((uint32_t*)frame->data)[0]);
-               bitmap[2] = htonl(((uint32_t*)frame->data)[1]);
+               memcpy(&bitmap[1], &frame->data, frame->can_dlc);
                start = 13;
                end = 32 + 8*frame->can_dlc;
        }
-       /* TODO: Calc stuff bits in CRC */
+        crc = calc_bitmap_crc(bitmap, start, end);
+        write_crc_to_bitmap(crc, bitmap, frame);
+        end += 15;
+
        while (start < end) {
                mask = basemask >> (start & 0x1f);
                while (1) {
@@ -305,6 +330,9 @@ void msg_info_print(FILE *f, struct msg_info *mi)
        static long num = 0;
        char sent[64], received[64];
 
+       if (!f)
+               return;
+
        sprint_canframe(sent, &mi->sent, true);
        sprint_canframe(received, &mi->received, true);
 
@@ -972,37 +1000,41 @@ int main(int argc, const char *argv[])
 
        histogram_fprint(&histogram, opt.f_hist);
        histogram_fprint(&histogram_gw, opt.f_hist_gw);
-       fclose(opt.f_hist);
-       fclose(opt.f_hist_gw);
-       fclose(opt.f_msgs);
-
-
-       fprintf(opt.f_stat, "cmdline='");
-       for (i=0; i<argc; i++)
-               fprintf(opt.f_stat, "%s%s", argv[i], i < argc-1 ? " " : "");
-       fprintf(opt.f_stat, "'\n");
-
-       timespec_subtract(&diff, &stats.tac, &stats.tic);
-       fprintf(opt.f_stat, "duration=%s # seconds\n", tstamp_str(NULL, &diff));
+       if (opt.f_hist)
+               fclose(opt.f_hist);
+       if (opt.f_hist_gw)
+               fclose(opt.f_hist_gw);
+       if (opt.f_msgs)
+               fclose(opt.f_msgs);
+
+       if (opt.f_stat) {
+               fprintf(opt.f_stat, "cmdline='");
+               for (i=0; i<argc; i++)
+                       fprintf(opt.f_stat, "%s%s", argv[i], i < argc-1 ? " " : "");
+               fprintf(opt.f_stat, "'\n");
+
+               timespec_subtract(&diff, &stats.tac, &stats.tic);
+               fprintf(opt.f_stat, "duration=%s # seconds\n", tstamp_str(NULL, &diff));
        
-       fprintf(opt.f_stat, "sent=%d\n", count);
-       fprintf(opt.f_stat, "overrun=%d\n", stats.overrun);
-       if (stats.overrun && !opt.quiet)
-               printf("overrun=%d\n", stats.overrun);
-       fprintf(opt.f_stat, "enobufs=%d\n", stats.enobufs);
-       if (stats.enobufs && !opt.quiet)
-               printf("enobufs=%d\n", stats.enobufs);
-       fprintf(opt.f_stat, "lost=%d\n", stats.lost);
-       if (stats.lost && !opt.quiet)
-               printf("lost=%d\n", stats.lost);
-       fprintf(opt.f_stat, "timeouts=%d\n", stats.timeouts);
-       if (stats.timeouts && !opt.quiet)
-               printf("timeouts=%d\n", stats.timeouts);
-       fprintf(opt.f_stat, "invalid_frame=%d\n", stats.timeouts);
-       if (stats.timeouts && !opt.quiet)
-               printf("invalid_frame=%d\n", stats.timeouts);
-
-       fclose(opt.f_stat);
+               fprintf(opt.f_stat, "sent=%d\n", count);
+               fprintf(opt.f_stat, "overrun=%d\n", stats.overrun);
+               if (stats.overrun && !opt.quiet)
+                       printf("overrun=%d\n", stats.overrun);
+               fprintf(opt.f_stat, "enobufs=%d\n", stats.enobufs);
+               if (stats.enobufs && !opt.quiet)
+                       printf("enobufs=%d\n", stats.enobufs);
+               fprintf(opt.f_stat, "lost=%d\n", stats.lost);
+               if (stats.lost && !opt.quiet)
+                       printf("lost=%d\n", stats.lost);
+               fprintf(opt.f_stat, "timeouts=%d\n", stats.timeouts);
+               if (stats.timeouts && !opt.quiet)
+                       printf("timeouts=%d\n", stats.timeouts);
+               fprintf(opt.f_stat, "invalid_frame=%d\n", stats.timeouts);
+               if (stats.timeouts && !opt.quiet)
+                       printf("invalid_frame=%d\n", stats.timeouts);
+
+               fclose(opt.f_stat);
+       }
 
        return 0;
 }