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;
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;
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)