我有两个设备A和B都使用64位计时器。一个滴答等于1ns。我想同步两个定时器的漂移。我知道A和B之间的延迟,通常我会将A的当前时间频繁地发送给B。在B中,我会添加传播延迟并使用这个值作为比较值来同步B。在我的情况下,我只能每100 my发送一次较低的32位定时器。我试着用A部分简单地替换B的下半部分,但是这项工作只有在没有32位溢出的情况下才能完成。是否有检测此溢出的方法?溢出示例(短路计时器):
计时器B: 0x00FF
定时器A: 0x010A
=> 0x0A到B替换导致计时器B0x000A而不是计时器B0x010A。
所以我需要检测A中已经发生的溢出,而在B中没有发生。
底流实例(短路计时器):
计时器B: 0x0205
定时器A: 0x01F6
=> 0xF6 =>计时器B: 0x02F6代替0x01F6
在这种情况下,计时器B比定时器A快。
发布于 2016-04-12 18:39:52
下面是我用来找出timera最接近的可能值的方法,给定timerb,message中的32位timera,以及delay中的预期传播延迟
#include <stdint.h>
int64_t expected_timera(const int64_t timerb,
const uint32_t message,
const uint32_t delay)
{
const int64_t timer1 = (timerb / INT64_C(4294967296)) * INT64_C(4294967296)
+ (int64_t)message + (int64_t)delay;
const int64_t timer0 = timer1 - INT64_C(4294967296);
const int64_t timer2 = timer1 + INT64_C(4294967296);
const uint64_t delta0 = timerb - timer0;
const uint64_t delta1 = (timer1 > timerb) ? timer1 - timerb : timerb - timer1;
const uint64_t delta2 = timer2 - timerb;
if (delta0 < delta1)
return (delta0 < delta2) ? timer0 : timer2;
else
return (delta1 <= delta2) ? timer1 : timer2;
}就我个人而言,我还将使用线性调整从实际计时器B中计算timerb:
static volatile int64_t real_timer_b; /* Actual timer b */
static int64_t timerb_real; /* real_timer_b at last sync time */
static int64_t timerb_offset; /* timera at last sync time */
static int32_t timerb_scale; /* Q30 scale factor (0,2) */
static inline int64_t timerb(void)
{
return ((int64_t)(int32_t)(real_timer_b - timerb_real) * (int64_t)timerb_scale) / INT64_C(1073741824) + timerb_offset;
}timerb_real = 0,timerb_offset = 0,timerb_scale = 1073741824,timerb() == real_timer_b。
当timera > timerb()时,您需要增加timerb_scale。当timera < timerb()时,您需要减少timerb_scale。您不希望每100 to计算一次确切的值,因为传输延迟中的抖动将直接影响timerb();您希望在数(数十)秒内缓慢地调整它。作为一种奖励,您可以保持timerb()的单调性,而不会突然向前或向后跳。
网络时间协议实现做了非常类似的事情,您可能会在那里找到更多的实现帮助。
https://stackoverflow.com/questions/36571471
复制相似问题