X-Git-Url: http://rtime.felk.cvut.cz/gitweb/can-benchmark.git/blobdiff_plain/b0d0a09235093cf11fbe83ce502d7079bc255f7e..3492126b73da32b9d496f494c9d4c9abe3ea77bf:/latester/latester.c diff --git a/latester/latester.c b/latester/latester.c index 30e62f1..6f4aefd 100644 --- a/latester/latester.c +++ b/latester/latester.c @@ -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 */ /**************************************************************************/ @@ -67,6 +67,7 @@ struct options { /* Temporary variables */ FILE *f_msgs; FILE *f_hist; + FILE *f_hist_gw; FILE *f_stat; }; @@ -98,12 +99,13 @@ struct msg_info { struct timespec ts_rx_onwire, ts_rx_onwire_kern; struct timespec ts_rx_final, ts_rx_final_kern; struct can_frame sent, received; + unsigned lat_measured_us, tx_time_us; }; #define MAX_INFOS 10000 struct msg_info msg_infos[MAX_INFOS]; -struct histogram histogram; +struct histogram histogram, histogram_gw; void sprint_canframe(char *buf , struct can_frame *cf, int sep) { /* documentation see lib.h */ @@ -195,16 +197,34 @@ 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 crc << 17; +} + 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] = @@ -214,33 +234,28 @@ 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); + uint32_t crc_be = htons(crc << 17); + memcpy((char*)bitmap + end/8, &crc_be, 2); /* end is guaranteed to be divisible by 8 */ + end += 15; + while (start < end) { mask = basemask >> (start & 0x1f); while (1) { @@ -269,9 +284,10 @@ unsigned calc_stuff_bits(struct can_frame *frame) { ones = !ones; } //printf ("STUFFED %d BITS\n", stuffed); + return stuffed; } -unsigned calc_frame_txtime(struct can_frame *frame) { +unsigned calc_frame_txtime_us(struct can_frame *frame) { return calc_stuff_bits(frame) + 1 + /* SOF */ 11 + /* ID A */ @@ -298,6 +314,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); @@ -310,7 +329,7 @@ void msg_info_print(FILE *f, struct msg_info *mi) 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), - calc_frame_txtime(&mi->received)); + mi->tx_time_us); break; case 3: fprintf(f, "%ld: %s %s -> %s (%s) -> %s (%s) %s = %s (%s), %s (%s) %d\n", @@ -321,7 +340,7 @@ void msg_info_print(FILE *f, struct msg_info *mi) 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), - calc_frame_txtime(&mi->received)); + mi->tx_time_us); break; } #undef S @@ -363,7 +382,7 @@ void dbg_print_timespec(char *msg, struct timespec *tv) printf("%s sec=%ld nsec=%ld\n", msg, tv->tv_sec, tv->tv_nsec); } -static inline unsigned get_msg_latency_us(struct msg_info *mi) +static inline void calc_msg_latencies(struct msg_info *mi) { struct timespec diff; switch (num_interfaces) { @@ -380,9 +399,10 @@ static inline unsigned get_msg_latency_us(struct msg_info *mi) timespec_subtract(&diff, &mi->ts_rx_final_kern, &mi->ts_sent); break; default: - return 0; + return; } - return diff.tv_sec * 1000000 + diff.tv_nsec/1000; + mi->lat_measured_us = diff.tv_sec * 1000000 + diff.tv_nsec/1000; + mi->tx_time_us = calc_frame_txtime_us(&mi->received); } void set_sched_policy_and_prio(int policy, int rtprio) @@ -646,7 +666,10 @@ void process_final_rx(int s) mi->ts_rx_final = ts_user; mi->received = frame; - histogram_add(&histogram, get_msg_latency_us(mi)); + calc_msg_latencies(mi); + + histogram_add(&histogram, mi->lat_measured_us); + histogram_add(&histogram_gw, mi->lat_measured_us - mi->tx_time_us); ret = write(completion_pipe[1], &mi, sizeof(mi)); if (ret == -1) @@ -829,12 +852,19 @@ int parse_options(int argc, const char *argv[]) } if (opt.name) { - char *f = talloc_asprintf(local, "%s-hist.txt", opt.name); + char *f = talloc_asprintf(local, "%s-hist-raw.txt", opt.name); opt.f_hist = fopen(f, "w"); if (!opt.f_hist) error(1, errno, "fopen: %s", f); } + if (opt.name) { + char *f = talloc_asprintf(local, "%s-hist.txt", opt.name); + opt.f_hist_gw = fopen(f, "w"); + if (!opt.f_hist_gw) + error(1, errno, "fopen: %s", f); + } + if (opt.name) { char *f = talloc_asprintf(local, "%s-stat.txt", opt.name); opt.f_stat = fopen(f, "w"); @@ -875,6 +905,7 @@ int main(int argc, const char *argv[]) msg_infos[i].id = -1; histogram_init(&histogram, 5000000, 1); + histogram_init(&histogram_gw, 5000000, 1); ret = pipe(completion_pipe); if (ret == -1) @@ -952,36 +983,42 @@ int main(int argc, const char *argv[]) close(completion_pipe[1]); histogram_fprint(&histogram, opt.f_hist); - fclose(opt.f_hist); - fclose(opt.f_msgs); - - - fprintf(opt.f_stat, "cmdline='"); - for (i=0; i