LIUNXPTP代码学习(时钟同步分析)

这部分主要讲解时钟如何利用偏移量和延时进行时钟同步。

如何实现时钟同步

void process_sync(struct port *p, struct ptp_message *m)
{
   
	enum syfu_event event;
	switch (p->state) {
   
	case PS_INITIALIZING:
	case PS_FAULTY:
	case PS_DISABLED:
	case PS_LISTENING:
	case PS_PRE_MASTER:
	case PS_MASTER:
	case PS_GRAND_MASTER:
	case PS_PASSIVE:
		return;
	case PS_UNCALIBRATED:
	case PS_SLAVE:
		break;
	}

	if (check_source_identity(p, m)) {
   
		return;
	}

	if (!msg_unicast(m) &&
	    m->header.logMessageInterval != p->log_sync_interval) {
   
		p->log_sync_interval = m->header.logMessageInterval;
		clock_sync_interval(p->clock, p->log_sync_interval);
	}

	m->header.correction += p->asymmetry;

	if (one_step(m)) {
   
		port_synchronize(p, m->header.sequenceId,
				 m->hwts.ts, m->ts.pdu,
				 m->header.correction, 0,
				 m->header.logMessageInterval);
		flush_last_sync(p);
		return;
	}

	if (p->syfu == SF_HAVE_FUP &&
	    fup_sync_ok(p->last_syncfup, m) &&
	    p->last_syncfup->header.sequenceId == m->header.sequenceId) {
   
		event = SYNC_MATCH;
	} else {
   
		event = SYNC_MISMATCH;
	}
	port_syfufsm(p, event, m);
}
static void port_synchronize(struct port *p,
			     uint16_t seqid,
			     tmv_t ingress_ts,
			     struct timestamp origin_ts,
			     Integer64 correction1, Integer64 correction2,
			     Integer8 sync_interval)
{
   
	enum servo_state state, last_state;
	tmv_t t1, t1c, t2, c1, c2;

	port_set_sync_rx_tmo(p);

	t1 = timestamp_to_tmv(origin_ts);
	t2 = ingress_ts;
	c1 = correction_to_tmv(correction1);
	c2 = correction_to_tmv(correction2);
	//如果是p2p使用延迟机制,则这里的
	t1c = tmv_add(t1, tmv_add(c1, c2));

	switch (p->state) {
   
	case PS_UNCALIBRATED:
	case PS_SLAVE:
	    //记录t1,t2,还有修正域的和,为了延迟不对称或者有小数ns
		monitor_sync(p->slave_event_monitor,
			     clock_parent_identity(p->clock), seqid,
			     t1, tmv_add(c1, c2), t2);
		break;
	default:
		break;
	}

	last_state = clock_servo_state(p->clock);
	//保持时钟的同步
	state = clock_synchronize(p->clock, t2, t1c);
	switch (state) {
   
	case SERVO_UNLOCKED:
		port_dispatch(p, EV_SYNCHRONIZATION_FAULT, 0);
		if (servo_offset_threshold(clock_servo(p->clock)) != 0 &&
		    sync_interval != p->initialLogSyncInterval) {
   
			p->logPdelayReqInterval = p->logMinPdelayReqInterval;
			p->logSyncInterval = p->initialLogSyncInterval;
			port_tx_interval_request(p, SIGNAL_NO_CHANGE,
						 SIGNAL_SET_INITIAL,
						 SIGNAL_NO_CHANGE);
		}
		break;
	case SERVO_JUMP:
		port_dispatch(p, EV_SYNCHRONIZATION_FAULT, 0);
		flush_delay_req(p);
		if (p->peer_delay_req) {
   
			msg_put(p->peer_delay_req);
			p->peer_delay_req = NULL;
		}
		break;
	case SERVO_LOCKED:
		port_dispatch(p, EV_MASTER_CLOCK_SELECTED, 0);
		break;
	case SERVO_LOCKED_STABLE:
		message_interval_request(p, last_state, sync_interval);
		break;
	}
}
enum servo_state clock_synchronize(struct clock *c, tmv_t ingress, tmv_t origin)
{
   
	enum servo_state state = SERVO_UNLOCKED;
	double adj, weight;
	int64_t offset;

	c->ingress_ts = ingress;

	tsproc_down_ts(c->tsproc, origin, ingress);
	//更新offset,保持时钟同步
	if (tsproc_update_offset(c->tsproc, &c->master_offset, &weight)) {
   
		if (c->free_running) {
   
			return clock_no_adjust
  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值