Skip to content

Commit 9fa5f62

Browse files
committed
net: gptp: adjust only frequency for continuous synchronization
Current clock synchronization was always stepping clock. This was causing large offset, and discontiguous ptp hardware clock time. For TSN hardware, discontiguous ptp hardware clock time was not able to be used for other TSN protocols. This patch is to convert to frequency adjustment with a basic PI control algorithm. Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
1 parent bfd3781 commit 9fa5f62

File tree

4 files changed

+54
-19
lines changed

4 files changed

+54
-19
lines changed

subsys/net/l2/ethernet/gptp/Kconfig

+6
Original file line numberDiff line numberDiff line change
@@ -211,4 +211,10 @@ config NET_GPTP_STATISTICS
211211
Enable this if you need to collect gPTP statistics. The statistics
212212
can be seen in net-shell if needed.
213213

214+
config NET_GPTP_MONITOR_SYNC_STATUS
215+
bool "Monitor real-time synchronization status"
216+
help
217+
Monitor real-time synchronization status, like synchronization offset,
218+
frequency offset and so on. This will print continuous messages.
219+
214220
endif # NET_GPTP

subsys/net/l2/ethernet/gptp/gptp.c

+16
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ K_FIFO_DEFINE(gptp_rx_queue);
3535
static k_tid_t tid;
3636
static struct k_thread gptp_thread_data;
3737
struct gptp_domain gptp_domain;
38+
struct gptp_clock_data gptp_clock;
3839

3940
int gptp_get_port_number(struct net_if *iface)
4041
{
@@ -911,6 +912,18 @@ int gptp_get_port_data(struct gptp_domain *domain,
911912
return 0;
912913
}
913914

915+
double gptp_servo_pi(int64_t nanosecond_diff)
916+
{
917+
double kp = 0.7;
918+
double ki = 0.3;
919+
double ppb;
920+
921+
gptp_clock.pi_drift += ki * nanosecond_diff;
922+
ppb = kp * nanosecond_diff + gptp_clock.pi_drift;
923+
924+
return ppb;
925+
}
926+
914927
static void init_ports(void)
915928
{
916929
net_if_foreach(gptp_add_port, &gptp_domain.default_ds.nb_ports);
@@ -929,5 +942,8 @@ void net_gptp_init(void)
929942
{
930943
gptp_domain.default_ds.nb_ports = 0U;
931944

945+
gptp_clock.domain = &gptp_domain;
946+
gptp_clock.pi_drift = 0.0;
947+
932948
init_ports();
933949
}

subsys/net/l2/ethernet/gptp/gptp_mi.c

+11-19
Original file line numberDiff line numberDiff line change
@@ -786,14 +786,12 @@ static void gptp_update_local_port_clock(void)
786786
nanosecond_diff = -(int64_t)NSEC_PER_SEC + nanosecond_diff;
787787
}
788788

789-
ptp_clock_rate_adjust(clk, port_ds->neighbor_rate_ratio);
790-
791789
/* If time difference is too high, set the clock value.
792790
* Otherwise, adjust it.
793791
*/
794792
if (second_diff || (second_diff == 0 &&
795-
(nanosecond_diff < -5000 ||
796-
nanosecond_diff > 5000))) {
793+
(nanosecond_diff < -50000000 ||
794+
nanosecond_diff > 50000000))) {
797795
bool underflow = false;
798796

799797
key = irq_lock();
@@ -822,28 +820,22 @@ static void gptp_update_local_port_clock(void)
822820
tm.second++;
823821
tm.nanosecond -= NSEC_PER_SEC;
824822
}
825-
826-
/* This prints too much data normally but can be enabled to see
827-
* what time we are setting to the local clock.
828-
*/
829-
if (0) {
830-
NET_INFO("Set local clock %lu.%lu",
831-
(unsigned long int)tm.second,
832-
(unsigned long int)tm.nanosecond);
823+
if (IS_ENABLED(CONFIG_NET_GPTP_MONITOR_SYNC_STATUS)) {
824+
NET_INFO("Set local clock %"PRIu64".%09u", tm.second, tm.nanosecond);
833825
}
834-
835826
ptp_clock_set(clk, &tm);
836827

837828
skip_clock_set:
838829
irq_unlock(key);
839830
} else {
840-
if (nanosecond_diff < -200) {
841-
nanosecond_diff = -200;
842-
} else if (nanosecond_diff > 200) {
843-
nanosecond_diff = 200;
844-
}
831+
double ppb = gptp_servo_pi(nanosecond_diff);
832+
833+
ptp_clock_rate_adjust(clk, 1.0 + (ppb / 1000000000.0));
845834

846-
ptp_clock_adjust(clk, nanosecond_diff);
835+
if (IS_ENABLED(CONFIG_NET_GPTP_MONITOR_SYNC_STATUS)) {
836+
NET_INFO("sync offset %9"PRId64" ns, freq offset %f ppb",
837+
nanosecond_diff, ppb);
838+
}
847839
}
848840
}
849841
#endif /* CONFIG_NET_GPTP_USE_DEFAULT_CLOCK_UPDATE */

subsys/net/l2/ethernet/gptp/gptp_private.h

+21
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ extern "C" {
3030
#define GPTP_STATS_INC(port, var)
3131
#endif
3232

33+
/**
34+
* @brief gPTP clock data.
35+
*/
36+
struct gptp_clock_data {
37+
/** gptp_domain pointer */
38+
struct gptp_domain *domain;
39+
/** pi control drift value */
40+
double pi_drift;
41+
};
42+
43+
extern struct gptp_clock_data gptp_clock;
44+
3345
/**
3446
* @brief Is a slave acting as a slave.
3547
*
@@ -117,6 +129,15 @@ static inline uint64_t gptp_timestamp_to_nsec(struct net_ptp_time *ts)
117129
return (ts->second * NSEC_PER_SEC) + ts->nanosecond;
118130
}
119131

132+
/**
133+
* @brief gPTP PI servo.
134+
*
135+
* @param nanosecond_diff nanosecond offset.
136+
*
137+
* @return ppb value to adjust.
138+
*/
139+
double gptp_servo_pi(int64_t nanosecond_diff);
140+
120141
/**
121142
* @brief Change the port state
122143
*

0 commit comments

Comments
 (0)