【发布时间】:2020-08-05 13:35:23
【问题描述】:
我正在编写一个 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 帧,然后它获取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 驱动程序中的源代码位置提示也会很有帮助。
【问题讨论】:
-
不要在时间戳之间使用
<和>。要正确处理翻转,您必须减去两个时间戳(使用无符号算术),然后您可以将差值与阈值进行比较。 -
我不明白这样比较时间戳会出现什么问题?
-
<认为 2038 年 1 月 20 日早于 2038 年 1 月 18 日。 -
你知道,我们说的是微秒吗? Linux 在 CAN 中断中采用 Unix 时间戳,精度为 µs。
-
在微秒内,溢出发生的频率是一百万次。您不必等到 2038 年才能体验该错误。不要将时间戳视为绝对值,将它们视为相对值。