Delay in receiving Socket can messages

799 views Asked by At

I implement linux application which receives CAN messages and calculates period(using socketcan on raspberry pi4). The problem is that sometimes (about 0.5%) socketcan receives messages with delay. When I send 10ms messages with baudrate 500Kbps from my laptop(using vector tool), normally I can get reasonable period(9ms ~ 11ms) from raspberry pi. But sometimes it comes with 15ms ~ 16ms(then, next message comes after 4ms ~ 5ms). Even if I send 1 message only, same phenomenon occurs, so that the bus load could not be the reason. How can I resolve this issue?

Here is my source code as below.

wiringPiSetupSys();

if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
{
    perror("Socket");
    return 1;
}

strcpy(ifr.ifr_name, "can0");
ioctl(s, SIOCGIFINDEX, &ifr);

memset(&addr, 0, sizeof(addr));
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;

if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
    perror("Bind");
    return 1;
}

while (1)
{
    nbytes = read(s, &frame, sizeof(struct can_frame));
    period = micros() - last_timer;
    last_timer = micros();
}
2

There are 2 answers

0
fantasista On

I think that for the correct frame reception time, you need to get the frame timestamp, not the system value. you can get the exact timestamp with ioctl call after reading the message from the socket.

struct timeval tv;
ioctl (s, SIOCGSTAMP, & tv);
0
avra On

Your CAN messages are received into SocketCAN buffer, and they are not processed immediately because Linux is a multitasking operating system, and SocketCAN is just waiting for its time slice to process the buffer and distribute messages to all CAN application(s). While you can not avoid this delay (which depends on current system load and number of processes), you can ask SocketCAN to deliver timestamps (as @fantasista has answered) so you can determine arrival time of each CAN message.