From: Martin Jerabek Date: Mon, 30 May 2016 16:45:48 +0000 (+0200) Subject: latester: support for determining time offset between can interfaces (on CAN-BENCH... X-Git-Url: http://rtime.felk.cvut.cz/gitweb/can-benchmark.git/commitdiff_plain/95e2144f1cc7525bcae7f202b06f0825ee7d508d latester: support for determining time offset between can interfaces (on CAN-BENCH platform) --- diff --git a/latester/latester.c b/latester/latester.c index a6f1453..b396fd2 100644 --- a/latester/latester.c +++ b/latester/latester.c @@ -94,6 +94,7 @@ int num_interfaces = 0; int count = 0; /* Number of sent messages */ unsigned msg_in_progress = 0; int completion_pipe[2]; +struct timespec can_tsdiff = {0, 0}; /* can_rx2_ts - can_rx1_ts */ struct msg_info { canid_t id; @@ -557,6 +558,62 @@ void process_final_rx(int s) error(1, errno, "completion_pipe write"); } +void determine_can_timing_offset(struct pollfd *pfd, int nifc) +{ + int uiofd; + volatile uint32_t *can_crossbar; + uint32_t oldreg; + struct can_frame frame; + struct timespec ts_rx1, ts_rx2, ts_dummy; + int res; + + if(nifc < 2) + return; + + uiofd = open("/dev/uio0", O_RDWR); + if(uiofd < 0) + { + perror("determine_can_timing_offset: /dev/uio0"); + return; + } + + can_crossbar = (volatile uint32_t *) mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, uiofd, 0); + if(can_crossbar == MAP_FAILED) + { + perror("mmap"); + goto cleanup1; + } + + // Bit: 20 19 18 17 16 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + // STBY E3 E2 E1 E0 I3 I2 I1 I0 C3 C2 C1 C0 + // C*: can* (outer can physical interface) connection line assignment (0-3) + // I*: ifc* (inner can network interface) connection line assignment (0-3) + // E*: can* output enable: 1 = connect to physical interface, 0 = disconnect from physical interface, conenect RX and TX together + // STBY: CAN Transceivers standby mode + oldreg = can_crossbar[0]; + can_crossbar[0] = 0x00000000; // connect all interfaces together, disable output, disable standby + + frame.can_id = 0x00; + frame.can_dlc = 4; + memcpy(frame.data, "SYNC", 4); + res = write(pfd[0].fd, &frame, sizeof(frame)); + if(res != sizeof(frame)) + { + perror("write"); + goto cleanup2; + } + + receive(pfd[1].fd, &frame, &ts_rx1, &ts_dummy); + receive(pfd[2].fd, &frame, &ts_rx2, &ts_dummy); + timespec_subtract(&can_tsdiff, &ts_rx2, &ts_rx1); + +cleanup2: + can_crossbar[0] = oldreg; + munmap((void*)can_crossbar, 4096); +cleanup1: + close(uiofd); +} + void *measure_thread(void *arg) { int s, i, ret; @@ -613,6 +670,9 @@ void *measure_thread(void *arg) pfd[i].events = POLLIN; } + determine_can_timing_offset(pfd, num_interfaces); + + set_sched_policy_and_prio(SCHED_FIFO, 40); #define SEND() send_and_check(pfd[0].fd)