在二次开发ntp和ptp模块的时候,会有将系统时间转换为ptp时间或者ntp时间,一般初学者会比较迷糊,现将其总结如下
获取linux系统时间一般有两个函数,获取us级的时间函数和获取ns级的时间函数。一般linux系统时间整数秒从1900年0时0分0秒开始计时,在ptp中启示也是这个值,但是在ntp整数秒计数起时是1970年0时0分0秒,所以在将系统时间转换为ntp时间整数秒的时候,会补偿1970到1900时间差0x83aa7e80,细节见下ntp讲解。
函数gettimeofday(struct timeval *tv, struct timezone *tz)
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
函数int clock_gettime(clockid_t clk_id, struct timespec *tp);
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
ptp时间分为整数秒和小数秒,整数秒为32位数据,小数秒为32位数据,但在PTP时间填充syn,delay等数据包的时候,是Timestamp数据结构,整数秒的最高位多出16为,一般填写0,
typedef struct {
uint16_t msb;
uint32_t lsb;
} UInteger48;
typedef struct {
Integer32 seconds;
Integer32 nanoseconds;
}TimeInternal;
typedef struct {
UInteger48 secondsField;
UInteger32 nanosecondsField;
}Timestamp;
从linux获取时间,可以直接将整数秒和小数秒赋值给ptp时间结构变量,不需要任何转换
Ø MeanDelay ( (t4-t3)+ (t2-t1) - syncorrection -delayrespcorrection) /2
Ø TimeOffset T2-T1 - delaymeanPath - synCorrection
Ø MeanDelay ( t6-t3 - pdelayrespCorrection) /2
Ø TimeOffset T2-T1 - delaymeanPath – synCorrection
typedef struct {
union {
u_int32 Xl_ui;
int32 Xl_i;
} Ul_i;
union {
u_int32 Xl_uf;
int32 Xl_f;
} Ul_f;
} l_fp;
#define l_ui Ul_i.Xl_ui /* unsigned integral part */
#define l_i Ul_i.Xl_i /* signed integral part */
#define l_uf Ul_f.Xl_uf /* unsigned fractional part */
#define l_f Ul_f.Xl_f /* signed fractional part */
Ntp时间结构体的定义比较特殊,官方定义采用两个联合体定义方式,但其实原理是一样的,整数秒为32位数,小数秒也是32位数,只是该结构体定义方式多了有符号和无符号的方式。
Linux系统时间转换为ntp时间的时候,整数秒需要补偿1900-1970年的整数秒,小数秒需要一定的转换。转换方式见下:小数秒需要先乘以1e-9,赋值给double数据,然后乘以“FRAC”,得到小数秒;
#define JAN_1970 0x83aa7e80 /* 2208988800 1970 - 1900 in seconds */
#define FRAC 4294967296. /* 2^32 as a double */
MeanDelay di = ( (t2 - t1)-(t3 - t4) )
Timeoffset ci= ((t2 - t1) + (t3 - t4))/2
Over!!
Thanks!
Author: Felix