【问题标题】:Linux SocketCAN behaviour of recvmsgrecvmsg 的 Linux SocketCAN 行为
【发布时间】:2020-08-05 13:35:23
【问题描述】:

我正在编写一个 CAN 记录器程序。我记录数据的方式类似于candump-tool 在调用candump 时的方式,例如candump anyhttps://github.com/linux-can/can-utils/blob/master/candump.c

candump any 使candump 绑定到任何设备,即addr.can_ifindex = 0; 然后它使用recvmsg 获取CAN 帧,然后它获取struct msghdr msg; 附加的时间戳以将其写入日志文件或到屏幕上。

我的问题是,内核是否确保以下assert 始终有效?

struct msghdr msg;
// init stuff
// ...
s[0] = _skt_1; // can0
s[1] = _skt_2; // can1
// configure and bind sockets
// ...
select(s[1]+1, &rdfs, NULL, NULL, NULL));
recvmsg(s[0], &msg, 0); // https://linux.die.net/man/2/recvmsg
timestamp_1 = getTimestamp(msg);
recvmsg(s[1], &msg, 0); // https://linux.die.net/man/2/recvmsg
timestamp_2 = getTimestamp(msg);
// Always valid?
assert(timestamp_1 < timestamp_2);

在 SocketCAN 驱动程序中的源代码位置提示也会很有帮助。

【问题讨论】:

  • 不要在时间戳之间使用&lt;&gt;。要正确处理翻转,您必须减去两个时间戳(使用无符号算术),然后您可以将差值与阈值进行比较。
  • 我不明白这样比较时间戳会出现什么问题?
  • &lt; 认为 2038 年 1 月 20 日早于 2038 年 1 月 18 日。
  • 你知道,我们说的是微秒吗? Linux 在 CAN 中断中采用 Unix 时间戳,精度为 µs。
  • 在微秒内,溢出发生的频率是一百万次。您不必等到 2038 年才能体验该错误。不要将时间戳视为绝对值,将它们视为相对值。

标签: c linux kernel socketcan


【解决方案1】:

简短的回答是肯定的,除非你的司机做了一些很奇怪的事情。 CAN 使用与其他网络设备相同的 netif 子系统。 SKB 获取时间戳的方式有多种。

硬件时间戳:

如果您的驱动程序使用硬件时间戳,则时间戳基于硬件提供的任何内容。

SW 时间戳:

如果启用了netdev_tstamp_prequeue,那么在您的驱动程序将 skb 提交到 netif_receive_skb 后不久就会有一个时间戳

https://elixir.bootlin.com/linux/v4.14.202/source/net/core/dev.c#L4554

如果netdev_tstamp_prequeue 未启用,则在处理更多处理后应用时间戳,但仍在同一个 NAPI 接收线程中。

https://elixir.bootlin.com/linux/v4.14.202/source/net/core/dev.c#L4352

这里是模糊部分:

有一些特殊模式 (RSP/RFP) 允许内核使用 SMP 对 skb 处理进行负载平衡。内核不是在 napi 接收线程中处理 skb,而是将 skb 放入每个 cpu 队列中。现在,如果netdev_tstamp_prequeue 未启用,则时间戳会在一段时间后从每个 CPU 队列中退出时添加。但是,文档说接收顺序没有被修改,所以时间戳也应该保持顺序。

【讨论】:

  • 太棒了,谢谢各位。但还有一件事我还不能理解:当中断由不同的 CPU 处理时(例如,can0 固定到 CPU0 并且 can1 固定到CPU1)? “内核将skb放入每个cpu队列中” imo。意味着,将中断固定到不同的 CPU 可能会导致(由于抢占)从这 2 个堆栈中拉出帧时的错误顺序?所以我想我最好的选择是将两个中断都固定在同一个 CPU 上?我想,最后我还是要测试一下……
【解决方案2】:

我想在@user14508498 的答案中添加一些内容。

我终于做了一些测量。如果我将中断固定到不同的 CPU(例如 CAN0 到 CPU0 和 CAN1 到 CPU1),candump 确实会以非时间顺序接收一些 CAN 帧,即上述断言在这种特定情况下并不总是正确的。至少在我的系统上的数量级约为 1-2 微秒。当两个中断都固定在同一个处理器上时,我无法观察到相同的情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-07
    • 1970-01-01
    • 2020-12-13
    • 1970-01-01
    • 1970-01-01
    • 2014-11-23
    • 1970-01-01
    • 2019-03-07
    相关资源
    最近更新 更多