Problems with PTP Server in lib_tsn

Sub forums for various specialist XMOS applications. e.g. USB audio, motor control and robotics.
Post Reply
User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

Problems with PTP Server in lib_tsn

Post by gerrykurz »

The ptp server does not seem to be reporting accurate timestamps.

I am running the following code:

Code: Select all

                        
ptp_get_time_info(ptp_server, ptp_time_information);

printf("PTP Time: %u %u.%u Local Time: %u \n", ptp_time_information.ptp_ts.seconds[1], ptp_time_information.ptp_ts.seconds[0], ptp_time_information.ptp_ts.nanoseconds, ptp_time_information.local_ts);

ptp_get_time_info_mod64(ptp_server, ptp_time_information_mod64);

printf("PTP Time: %u %u Local Time: %u \n", ptp_time_information_mod64.ptp_ts_hi, ptp_time_information_mod64.ptp_ts_lo, ptp_time_information_mod64.local_ts);

ptp_get_time_info(ptp_server, ptp_time_information);

printf("PTP Time: %u %u.%u Local Time: %u \n", ptp_time_information.ptp_ts.seconds[1], ptp_time_information.ptp_ts.seconds[0], ptp_time_information.ptp_ts.nanoseconds, ptp_time_information.local_ts);

ptp_get_time_info_mod64(ptp_server, ptp_time_information_mod64);

printf("PTP Time: %u %u Local Time: %u \n", ptp_time_information_mod64.ptp_ts_hi, ptp_time_information_mod64.ptp_ts_lo, ptp_time_information_mod64.local_ts);
and here are the results:
PTP Time: 0 1436858884.793158864 Local Time: 1342369710
PTP Time: 334544778 4235578576 Local Time: 1342369650
PTP Time: 0 1436858884.793158864 Local Time: 1342369709
PTP Time: 334544778 4235578576 Local Time: 1342369650
It seems to me that the both the ptp time and the local time should be increasing not remaining the same or decreasing.

Can someone at xmos explain this please.


User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

Post by gerrykurz »

So I am doing something wrong or is this a bug?

More code:

Code: Select all

ptp_get_time_info(ptp_server, ptp_time_information);

printf("PTP Time: %u %u.%u Local Time: %u \n",   ptp_time_information.ptp_ts.seconds[1],
                                                                         ptp_time_information.ptp_ts.seconds[0],
                                                                         ptp_time_information.ptp_ts.nanoseconds,
                                                                         ptp_time_information.local_ts);

ptp_get_time_info_mod64(ptp_server, ptp_time_information_mod64);

printf("PTP Time: %u %u Local Time: %u \n",  ptp_time_information_mod64.ptp_ts_hi,
                                                                        ptp_time_information_mod64.ptp_ts_lo,
                                                                        ptp_time_information_mod64.local_ts);

ptp_get_time_info(ptp_server, ptp_time_information);

printf("PTP Time: %u %u.%u Local Time: %u \n",   ptp_time_information.ptp_ts.seconds[1],
                                                                         ptp_time_information.ptp_ts.seconds[0],
                                                                         ptp_time_information.ptp_ts.nanoseconds,
                                                                         ptp_time_information.local_ts);

ptp_get_time_info_mod64(ptp_server, ptp_time_information_mod64);

printf("PTP Time: %u %u Local Time: %u \n",  ptp_time_information_mod64.ptp_ts_hi,
                                                                        ptp_time_information_mod64.ptp_ts_lo,
                                                                        ptp_time_information_mod64.local_ts);

delay_milliseconds(100);

ptp_get_time_info(ptp_server, ptp_time_information);

printf("PTP Time: %u %u.%u Local Time: %u \n",   ptp_time_information.ptp_ts.seconds[1],
                                                                         ptp_time_information.ptp_ts.seconds[0],
                                                                         ptp_time_information.ptp_ts.nanoseconds,
                                                                         ptp_time_information.local_ts);

ptp_get_time_info_mod64(ptp_server, ptp_time_information_mod64);

printf("PTP Time: %u %u Local Time: %u \n",  ptp_time_information_mod64.ptp_ts_hi,
                                                                        ptp_time_information_mod64.ptp_ts_lo,
                                                                        ptp_time_information_mod64.local_ts);
Results:
PTP Time: 0 1436863006.48868117 Local Time: 1331146835
PTP Time: 334545738 2322683669 Local Time: 1331146773
PTP Time: 0 1436863006.48868117 Local Time: 1331146834
PTP Time: 334545738 2322683669 Local Time: 1331146774
PTP Time: 0 1436863006.48868117 Local Time: 1331146834
PTP Time: 334545738 2322683669 Local Time: 1331146772
?????????
User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

Post by gerrykurz »

I have come up with a number of issues in the ptp code.

First is the tile timer offset calculation:

In the gptp.xc source file is an initialization routine "ptp_init" in which the following code is found:

Code: Select all

  unsigned server_tile_id;
  unsigned other_tile_now;
  unsigned this_tile_now;

  i_eth_cfg.get_tile_id_and_timer_value(server_tile_id, other_tile_now);
  this_tile_now = get_local_time();

  if (server_tile_id != get_tile_id_from_chanend(c))
  {
    tile_timer_offset = other_tile_now-this_tile_now-3; // 3 is an estimate of the channel + instruction latency
  }
  else
  {
    tile_timer_offset = 0;
  }
So I ran a modified version of this code on a single tile to check the instruction latency

Code: Select all

    unsigned int other_tile_now;
    unsigned int this_tile_now;
    signed int timer_offset_instruction_latency = 0;

   for(int index = 0; index < 10; index = index + 1)
    {
        linkport1_cfg_if.get_tile_id_and_timer_value(tile_id, other_tile_now);
        tile2_timer :> this_tile_now;
        timer_offset_instruction_latency = timer_offset_instruction_latency + (other_tile_now - this_tile_now);
    }
    timer_offset_instruction_latency = timer_offset_instruction_latency / 10;
The linkport1_cfg_if is running on the same tile that this routine is running on so other_tile_now and this_tile_now are read from the same tile timer.

The average latency over 10 iterations is 11 timer counts.

This is quite a bit more than the estimated value of 3 in the ptp code above.

As I see it, the latency could only be worse when reading a remote tile timer through a link.

Second is the "ptp_get_requested_time_info" routine in the gptp_client.xc source file.

Code: Select all

void ptp_get_requested_time_info(chanend c,
                                 ptp_time_info &info)
{
  timer tmr;
  signed thiscore_now,othercore_now;
  unsigned server_tile_id;
  slave {
    tmr :> thiscore_now;
    c :> othercore_now;
    c :> info.local_ts;
    c :> info.ptp_ts;
    c :> info.ptp_adjust;
    c :> info.inv_ptp_adjust;
    c :> server_tile_id;
  }
  if (server_tile_id != get_local_tile_id())
  {
    info.local_ts = info.local_ts - (othercore_now-thiscore_now-3);
  }
}
This routine is supposed to return the synchronized ptp timerstamp and local timestamp however the offset calculation is different from the previous ptp code.

thiscore_now is read before othercore_now in this case so not only is the arbitrary correction factor of 3 wrong in value, it is also wrong in sign.

Comments anyone.....
User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

Post by gerrykurz »

Ok so I think I am getting this figured out somewhat.

The get_ptp_time_info returns a structure which correlates local time to ptp time.

This correlation gets updated periodically in the ptp server (looks like it is every 100 us)

So to get a current ptp timestamp from a current local time, the following steps are done:

1)Get a current ptp time info structure. (current to within 100us????)

2)Read the local time.

3)Call the local_timestamp_to_ptp function to convert the local time to ptp time.

Is this correct?

However, I still think there is an error in the "ptp_get_requested_time_info" function
in the conversion of the reference local timestamp from the ptp server to a reference local timestamp of the requesting caller (when they are on different tiles).
User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

Post by gerrykurz »

Here is another experiment:

Code: Select all

                        ptp_get_time_info(ptp_server, ptp_time_information);
                        ptp_get_time_info_mod64(ptp_server, ptp_time_information_mod64);
                        tile2_timer :> test_timestamp1;
                        local_timestamp_to_ptp(current_ptp_time1, test_timestamp1, ptp_time_information);

                        printf("PTP Time Info: %u %u.%u Local Time: %u \n", ptp_time_information.ptp_ts.seconds[1],
                                                                            ptp_time_information.ptp_ts.seconds[0],
                                                                            ptp_time_information.ptp_ts.nanoseconds,
                                                                            ptp_time_information.local_ts);

                        printf("PTP Time Info Mod64: %u %u Local Time: %u \n",      ptp_time_information_mod64.ptp_ts_hi,
                                                                                    ptp_time_information_mod64.ptp_ts_lo,
                                                                                    ptp_time_information_mod64.local_ts);

                        printf("Tile 2 Current Time = %u\n",            test_timestamp1);

                        printf("Tile 2 Current PTP Time = %u %u.%u\n",  current_ptp_time1.seconds[1],
                                                                        current_ptp_time1.seconds[0],
                                                                        current_ptp_time1.nanoseconds);

                        delay_milliseconds(100);

                        ptp_get_time_info_mod64(ptp_server, ptp_time_information_mod64);
                        ptp_get_time_info(ptp_server, ptp_time_information);
                        tile2_timer :> test_timestamp2;
                        local_timestamp_to_ptp(current_ptp_time2, test_timestamp2, ptp_time_information);

                        int delay_time = (test_timestamp2 - test_timestamp1) * 10;

                        printf("\nDelay Time from Local Time = %u ns \n", delay_time);

                        delay_time = current_ptp_time2.seconds[0] - current_ptp_time1.seconds[0];
                        delay_time = delay_time + (current_ptp_time2.nanoseconds - current_ptp_time1.nanoseconds);

                        printf("\nDelay Time from PTP Time = %u ns \n\n", delay_time);

                        printf("PTP Time Info: %u %u.%u Local Time: %u \n", ptp_time_information.ptp_ts.seconds[1],
                                                                            ptp_time_information.ptp_ts.seconds[0],
                                                                            ptp_time_information.ptp_ts.nanoseconds,
                                                                            ptp_time_information.local_ts);

                        printf("PTP Time Info Mod64: %u %u Local Time: %u \n",      ptp_time_information_mod64.ptp_ts_hi,
                                                                                    ptp_time_information_mod64.ptp_ts_lo,
                                                                                    ptp_time_information_mod64.local_ts);

                        printf("Tile 2 Current Time = %u\n",            test_timestamp2);

                        printf("Tile 2 Current PTP Time = %u %u.%u\n",  current_ptp_time2.seconds[1],
                                                                        current_ptp_time2.seconds[0],
                                                                        current_ptp_time2.nanoseconds);
Here are the results:
PTP Time Info: 0 1436915026.484011712 Local Time: 1328872318
PTP Time Info Mod64: 334557850 2113938112 Local Time: 1328872257
Tile 2 Current Time = 1328943184
Tile 2 Current PTP Time = 0 1436915026.484720374

Delay Time from Local Time = 100221230 ns
Delay Time from PTP Time = 100221620 ns

PTP Time Info: 0 1436915026.484011712 Local Time: 1328872318
PTP Time Info Mod64: 334557850 2113938112 Local Time: 1328872257
Tile 2 Current Time = 1338965307
Tile 2 Current PTP Time = 0 1436915026.584941994
Observations:
1)Reference local time from TimeInfo and TimeInfoMod64 is consistently about 600 ns different when they should be the same.
2) After a 100 ms delay, the time info structure has not changed.
3) The delay time calculated from the local time and from the ptp time conversion using the local time is about 400 ns different.

Are these bugs? Or is this the expected tolerance?
User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

Post by gerrykurz »

More results after changing delay to 1 sec:
PTP Time Info: 0 1436916355.86526906 Local Time: 1328752441
PTP Time Info Mod64: 334558159 3571558842 Local Time: 1328752381
Tile 2 Current Time = 1328827366
Tile 2 Current PTP Time = 0 1436916355.87276159

Delay Time from Local Time = 1000218390 ns
Delay Time from PTP Time = 1000222350 ns

PTP Time Info: 0 1436916355.969233625 Local Time: 1417022764
PTP Time Info Mod64: 334558160 159298265 Local Time: 1417022704
Tile 2 Current Time = 1428849205
Tile 2 Current PTP Time = 0 1436916356.87498509
Observations:
1)Again the difference between the local timestamps in the info structures is 600 ns.
2)The difference in delay time calculations this time is 3.96 us
3)The info structures updated after 890 ms.

Are these expected results?
User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

Post by gerrykurz »

Could someone from XMOS kindly respond to this?
srinie
XCore Addict
Posts: 158
Joined: Thu Mar 20, 2014 8:04 am

Post by srinie »

gerrykurz wrote: It seems to me that the both the ptp time and the local time should be increasing not remaining the same or decreasing.

Can someone at xmos explain this please.
gerrykurz wrote:So I am doing something wrong or is this a bug?


?????????

Hi, this is the way the gPTP ts logic works:
  • if the client task (which is subscribed to ptp server in the end-point) requests a gptp time, server sends its timestamp value;
  • but the server updates its time stamp info based on the config value of
    #define UPDATE_REFERENCE_TIMESTAMP_PERIOD (500000000)
  • hence if he client asks ptp server before this period, it returns the same value!


Hope this clarifies why you are getting the same time stamps in a repeated requests.


Regards,
/srinie
User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

Post by gerrykurz »

Yes, I think I get that now.

As I see it, the reference timestamps in the ptp info structure get updated periodically as you point out along with some offset or correction factors which are used to convert a current timestamp to current ptp time and vice versa as needed by the application.

If this understanding is correct, then that is fine.

However, there are still some issues which are perplexing to me.

Shouldn't the reference timestamps in the ptp info structure and the ptp mod 64 info structure be the same when read between update cycles? It appears to me from looking at the code, that they both use the same underlying reference time variables when the structures are updated. Or are these two structure completely independent of one another and therefore cannot be used interchangeably?

And when I measured a one second time delay using local timer timestamps and using those timestamps converted to ptp time, there was close to a 4 us difference. It is my understanding that ptp time should be accurate to at least several hundred ns if not better.
User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

Post by gerrykurz »

This issue has been filed as a support ticket and there is no resolution yet.
Post Reply