# Questions about the Time Synchronization in Specification

**URL:** <https://forum.opencyphal.org/t/questions-about-the-time-synchronization-in-specification/1562>\
**Category:** Specification\
**Created:** [January 5, 2022, 8:13pm UTC](https://forum.opencyphal.org/t/questions-about-the-time-synchronization-in-specification/1562 "2022-01-05T20:13:44Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![xbron](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/xbron/32/985_2.png) [@xbron](https://forum.opencyphal.org/u/xbron)\
**Post date:** [January 5, 2022, 8:13pm UTC](https://forum.opencyphal.org/t/questions-about-the-time-synchronization-in-specification/1562/1 "2022-01-05T20:13:44Z")

</div>

Hello Pavel, I try to understand how to implement the time synchronization in my application and I think that detailed explanation in `uavcan.time.Synchronization` data type description in Specification is useful, but I little bit confused about this 🙄:

1. In a pseudocode of `function update(message)` one can find this comment:

```auto
 // A message is assumed to have two timestamps:
 // Real - sampled from the clock that is being synchronized
 // Monotonic - clock that never leaps and never changes rate

```

But the message of type `uavcan.time.Synchronization` has only one field:  
`truncated uint56 previous_transmission_timestamp_microsecond`  
Or in this case this is a message of another type?

1. In a pseudocode of `function adjust(message)` there is this line:

```auto
local_time_phase_error := previous_rx_real_timestamp - msg.previous_transmission_timestamp_microsecond;

```

Will the `local_time_phase_error` always be less than zero? In `handleReceivedTimeSyncMessage(message)` the state of the slave is changing from STATE\_ADJUST to STATE\_UPDATE and vice versa. The `previous_rx_real_timestamp` gets the previous message timestamp which will be always one time step behind new arrived message. Is it right?

I also have read the original paper which you referenced, but there is no description of synchronization slave logic.

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [January 6, 2022, 9:07pm UTC](https://forum.opencyphal.org/t/questions-about-the-time-synchronization-in-specification/1562/2 "2022-01-06T21:07:46Z")

</div>

> [@xbron](#):
>
> But the message of type `uavcan.time.Synchronization` has only one field:  
> `truncated uint56 previous_transmission_timestamp_microsecond`  
> Or in this case this is a message of another type?

The text you referenced speaks about message _ **metadata** _, not about its fields. The UAVCAN stack is expected to provide the application with two timestamps, plus the one contained in the message, overall three values:

1. Real timestamp, aka wall time, supplied by the local UAVCAN stack. On a POSIX system this may be obtained using `clock_gettime()` with `CLOCK_REALTIME`.

2. Monotonic timestamp supplied by the local UAVCAN stack. On a POSIX system, this may be obtained using `clock_gettime()` with `CLOCK_MONOTONIC`. On a typical embedded system, this would be the time since power-on.

3. The time that you receive from the network in the time synchronization message — [`previous_transmission_timestamp_microsecond`](https://nunaweb.uavcan.org/api/storage/docs/docs/uavcan/index.html#uavcan_time_Synchronization_1_0).

> [@xbron](#):
>
> Will the `local_time_phase_error` always be less than zero? In `handleReceivedTimeSyncMessage(message)` the state of the slave is changing from STATE\_ADJUST to STATE\_UPDATE and vice versa. The `previous_rx_real_timestamp` gets the previous message timestamp which will be always one time step behind new arrived message. Is it right?

No. The data you receive in the message – `previous_transmission_timestamp_microsecond` – is already one time step behind. Therefore, when you do the subtraction, you obtain the time error observed when the previous message was received. You might see now that the observations provided by this algorithm are always delayed.

This is somewhat similar to [IEEE 1588 synchronization](https://en.wikipedia.org/wiki/Precision_Time_Protocol#Synchronization) with the critical difference being that there is only one type of exchange defined.

---

<div class="post-metadata">

**Author:** ![xbron](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/xbron/32/985_2.png) [@xbron](https://forum.opencyphal.org/u/xbron)\
**Post date:** [January 7, 2022, 11:28am UTC](https://forum.opencyphal.org/t/questions-about-the-time-synchronization-in-specification/1562/3 "2022-01-07T11:28:43Z")

</div>

Thank you very much, Pavel 🙂. Do you think that it will be more clear if the text in Specification would explicitly mention the message _metadata_?  
Ok, in case of **Libcanard** how exactly one should get these metadata timestamps (in case of stm32)?

1. I can get the monotonic timestamp using a general hardware timer with microsecond resolution. In case of bxCAN I think that optimal solution is to timestamp the appropriate CAN frame directly in CAN IRQ handler.
2. Is the real timestamp a `CanardMicrosecond timestamp_usec` in `struct CanardRxTransfer`? But comment to this field says that it is

> The timestamp of the first received CAN frame of this transfer

So is this timestamp equal to timestamp that I get using hardware timer in CAN IRQ handler (when synchronization frame is received)? If it’s true what’s the difference between monotonic and real timestamps in case of microcontroller? I understand that the real clock we must adjust and it will leap back and forth but the main question is how to yield it from Canard message?

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [January 7, 2022, 3:04pm UTC](https://forum.opencyphal.org/t/questions-about-the-time-synchronization-in-specification/1562/4 "2022-01-07T15:04:19Z")

</div>

> [@xbron](#):
>
> Do you think that it will be more clear if the text in Specification would explicitly mention the message _metadata_?

Certainly. Looking at the text now, I see that it could be improved in more than one way, so by all means, feel free to send a pull request, it will be reviewed promptly.

> [@xbron](#):
>
> Ok, in case of **Libcanard** how exactly one should get these metadata timestamps (in case of stm32)?

Generally, the clock that you use with libcanard’s `timestamp_usec` et al should be monotonic because it is used for measuring time intervals. Any clock that is synchronized with an external source (e.g., your wall clock) is not monotonic by definition because in order to keep synchronization it has to occasionally change rate or make leaps; hence it cannot be used for precise measurement of small time intervals.

If you adhere to the above, then libcanard is not really aware of any non-monotonic clock, since it is designed to deal with lower levels of the protocol.

> [@xbron](#):
>
> So is this timestamp equal to timestamp that I get using hardware timer in CAN IRQ handler (when synchronization frame is received)?

Normally, yes, this is how it is intended to be. Observe that libcanard does not timestamp anything on its own, it simply doesn’t have access to platform clocks/timers. It merely ferries the timestamps that you provide around. Say, when you receive a new frame, you timestamp it using whatever means are available (e.g., sampling some hardware timer as you wrote), then you pass that timestamp to `canardRxAccept()`, then it becomes the transfer timestamp or just discarded:

> <https://github.com/OpenCyphal/libcanard/blob/224adff8eb191426dc3ae39f265ea72aa7d1e559/libcanard/canard.c#L758-L761>

> [@xbron](#):
>
> If it’s true what’s the difference between monotonic and real timestamps in case of microcontroller? I understand that the real clock we must adjust and it will leap back and forth but the main question is how to yield it from Canard message?

There are several solutions.

Perhaps the cleanest is to define your wall time as a linear function of monotonic time and two coefficients:

t\_\text{wall} = (t\_\text{monotonic} + D) R

Where R is the rate multiplier (R \approx 1) and D is the offset. If the wall clock needs to leap, you adjust D; to adjust its speed, you change R. In this case you will be able to obtain the wall clock as it was observed back when the message was received if you have its monotonic timestamp.

Alternatively, if you don’t want to or can’t define the wall clock as a function of monotonic, you could simply store the wall timestamp in some state that is external to libcanard. If you want to go full caveman you could just use a global variable that is updated whenever a synchronization frame is received (you will have to detect such frames in your CAN driver below libcanard), or you could store it somewhere in the user state attached to the synchronization subject subscription:

> <https://github.com/OpenCyphal/libcanard/blob/224adff8eb191426dc3ae39f265ea72aa7d1e559/libcanard/canard.h#L309-L311>

Another approach is to add a new timestamp field to libcanard but you see how that might be a little more involved.

---

<div class="post-metadata">

**Author:** ![xbron](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/xbron/32/985_2.png) [@xbron](https://forum.opencyphal.org/u/xbron)\
**Post date:** [January 7, 2022, 3:55pm UTC](https://forum.opencyphal.org/t/questions-about-the-time-synchronization-in-specification/1562/5 "2022-01-07T15:55:30Z")

</div>

Thanks again, Pavel, this is a very detailed answer (it’s even more comprehensive than I expected!). I think that I will make a pull request (but after little experiments with my application) 🤔
