【问题标题】:Delay in receiving Socket can messages接收 Socket can 消息的延迟
【发布时间】:2020-11-28 06:22:32
【问题描述】:

我实现了接收 CAN 消息并计算周期的 linux 应用程序(在树莓派 pi4 上使用 socketcan)。问题是有时(大约 0.5%)socket 可以延迟接收消息。当我从笔记本电脑(使用矢量工具)发送波特率为 500Kbps 的 10ms 消息时,通常我可以从树莓派获得合理的周期(9ms ~ 11ms)。但有时它会出现 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();
}

【问题讨论】:

    标签: linux sockets raspberry-pi delay socketcan


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-07
        • 1970-01-01
        • 1970-01-01
        • 2022-10-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-03
        • 2021-12-23
        相关资源
        最近更新 更多