我在写一个CAN记录器程序。记录数据的方式类似于candump-tool在调用candump (如candump any:https://github.com/linux-can/can-utils/blob/master/candump.c )时所做的事情。
candump any使candump绑定到任何设备,即addr.can_ifindex = 0;然后使用recvmsg获取CAN帧,然后获取附加的时间戳,将其写入日志文件或屏幕上。
我的问题是,内核是否确保以下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驱动程序中的源代码位置也会有帮助。
发布于 2020-10-23 18:14:14
简短的回答是肯定的,除非你的司机做了很奇怪的事情。可以使用与其他网络设备相同的netif子系统。SKB有几种获得时间戳的方法。
HW时间戳:
如果您的驱动程序使用硬件时间戳,则时间戳基于硬件提供的任何内容。
SW时间戳:
如果启用了预队列,那么在驱动程序将skb提交给netif_receive_skb之后不久就会有时间戳。
https://elixir.bootlin.com/linux/v4.14.202/source/net/core/dev.c#L4554
如果未启用预队列,则时间戳将在经过更多处理后应用,但仍位于相同的NAPI接收线程中。
https://elixir.bootlin.com/linux/v4.14.202/source/net/core/dev.c#L4352
这里是模糊部分:
有一些特殊的模式(RSP/RFP)允许内核使用SMP负载平衡skb处理。内核不处理napi接收线程中的skb,而是将skb放在每个cpu队列中。现在,如果没有启用预队列,则会在某个时间后从每个cpu队列中添加时间戳。然而,文档称接收订单没有被修改,所以时间戳也应该保持有序。
发布于 2020-11-03 14:22:24
我希望在@user14508498的回答中添加一些内容。
我终于做了一些测量。如果我将中断插入到不同的CPU(例如CAN0到CPU0,CAN1到CPU1),那么candump确实会收到一些非时间顺序的可以帧,也就是说,在这种特定情况下,上面的断言并不总是正确的。至少在我的系统上,数量级在1-2微秒左右.当两个中断被固定在同一个处理器上时,我无法观察到相同的情况。
https://stackoverflow.com/questions/63266390
复制相似问题