【问题标题】:CAN socket read with frames lateCAN 套接字读取延迟帧
【发布时间】:2020-02-07 14:56:26
【问题描述】:

我正在使用如下创建的 CAN linux 套接字:

    ...
    sockaddr_can addr;
    struct ifreq ifr;

    _sock_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);

    if (_sock_fd < 0) {
        throw(std::bad_exception());
    }

    strcpy(ifr.ifr_name, "can0");
    if (0 != ioctl(_sock_fd, SIOCGIFINDEX, &ifr)) {
        throw(std::bad_exception());
    }
    addr.can_family = AF_CAN;
    addr.can_ifindex = ifr.ifr_ifindex;

    fcntl(_sock_fd, F_SETFL, O_NONBLOCK);

    if (0 != bind(_sock_fd, (struct sockaddr*)&addr, sizeof(addr))) {
        throw(std::bad_exception());
    }
    ...

接下来我使用通常的read 函数来读取来自 CAN 网络的帧:

int CANSocket::CANRead(canid_t &id, vector<uint8_t> &data) {

    size_t size = 0;

    while (size < sizeof(struct can_frame)) {
        size += read(_sock_fd, &_msg, sizeof(struct can_frame));
    }

    id = _msg.can_id;

    data.clear();
    for (int i = 0; i < _msg.can_dlc; ++i) {
        data.push_back(_msg.data[i]);
    }

    return data.size();
}

我的问题是,当我调用 CANRead 函数时,它返回的帧比 candump 实用程序获得的实际帧早了大约 100 帧。

我在读取帧之间使用 5 毫秒睡眠,服务器以每秒 25 帧的速度发送帧。

例如:当我通过candump 实用程序列出读取帧时,我得到例如帧

101
102
103
104
...
200

但我的程序同时运行会返回类似的帧

1
1
1
2
2
2
...
99

我在帧读取和套接字配置中出了什么问题,所以它读取了带有重复的延迟帧?

【问题讨论】:

  • Linux 不是 RTOS。你为什么sleep?每个sleep 可能花费的时间远远超过 5 毫秒,因为您的进程将产生它的时间片并且您会获得上下文切换。您的进程再次执行需要多长时间取决于您在后台运行了多少东西。
  • @Lundin,是的,它不是 RTOS,但我希望它可以按原样从套接字读取数据而没有这种延迟? candump 成功了,所以我认为问题在于我的代码而不是 Linux。
  • while (size &lt; sizeof(struct can_frame)) { size += read(_sock_fd, &amp;_msg, sizeof(struct can_frame)); } 如果您在第一个 read 上获得部分读取 - 读取 struct can_frame 的一部分,那么while (size &lt; sizeof(struct can_frame)) { size += read(_sock_fd, &amp;_msg, sizeof(struct can_frame)); } 将会搞砸事情,然后用框架的其余部分覆盖它,并且可能下一个read() 上的下一个帧的一部分。那么你的直播就完全关闭了。

标签: c++ linux sockets unix can-bus


【解决方案1】:

问题是由套接字读取缓冲引起的。将缓冲区大小设置为小已解决问题:

    ...
    int bufsize = 128;
    if (0 != setsockopt(_sock_fd, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize))) {
        throw(std::bad_exception());
    }
    ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多