接收Socket can消息延迟



我实现了linux应用程序,它接收CAN消息并计算周期(在树莓pi4上使用socketcan(。问题是有时(约0.5%(socketcan会延迟接收消息。当我从笔记本电脑(使用矢量工具(发送10毫秒的信息时,我可以从树莓派获得合理的周期(9毫秒~11毫秒(。但有时会出现15ms~16ms(然后,下一条消息会在4ms~5ms之后出现(。即使我只发送1条消息,也会出现同样的现象,所以总线负载可能不是原因。如何解决此问题?

下面是我的源代码。

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

我认为要获得正确的帧接收时间,需要获得帧时间戳,而不是系统值。从套接字中读取消息后,可以使用ioctl调用获得确切的时间戳。

struct timeval tv;
ioctl (s, SIOCGSTAMP, & tv);

您的CAN消息被接收到SocketCAN缓冲区,并且不会立即处理,因为Linux是一个多任务操作系统,SocketCAN只是在等待其时间片来处理缓冲区并将消息分发给所有CAN应用程序。虽然您无法避免这种延迟(这取决于当前系统负载和进程数量(,但您可以要求SocketCAN提供时间戳(正如@fantasta所回答的那样(,这样您就可以确定每条can消息的到达时间。

最新更新