# Implementation of Precise Time Synchronization between two Xaviers over WLAN

**URL:** <https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980>\
**Category:** Jetson AGX Xavier\
**Created:** [February 28, 2019, 9:49am UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980 "2019-02-28T09:49:22Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Andrey1984](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/andrey1984/32/14130_2.png) [@Andrey1984](https://forums.developer.nvidia.com/u/Andrey1984)\
**Post date:** [February 28, 2019, 9:49am UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/1 "2019-02-28T09:49:22Z")

</div>

There is a paper from Texas Instruments [TI] that defines implementation of a solution for their hardware.  
I am just wondering if that can be in a simple way implemented between two Xavier devices.  
Reference: [http://www.ti.com/lit/an/swaa162a/swaa162a.pdf](http://www.ti.com/lit/an/swaa162a/swaa162a.pdf)  
Update: seems a sort of a solution found: [Ubuntu Manpage: ptpd - Precision Time Protocol daemon (1588-2008)](http://manpages.ubuntu.com/manpages/bionic/man8/ptpd.8.html)

```auto
sudo apt install ptpd
 sudo ptpd -M -V -i wlan0
2019-02-28 10:09:27.344150 ptpd2[17401].startup (info) (___) Configuration OK
2019-02-28 10:09:27.344979 ptpd2[17401].startup (info) (___) Successfully acquired lock on /var/run/ptpd2.lock
2019-02-28 10:09:27.345228 ptpd2[17401].startup (notice) (___) PTPDv2 started successfully on wlan0 using "masteronly" preset (PID 17401)
2019-02-28 10:09:27.345276 ptpd2[17401].startup (info) (___) TimingService.PTP0: PTP service init
# Timestamp, State, Clock ID, One Way Delay, Offset From Master, Slave to Master, Master to Slave, Observed Drift, Last packet Received, One Way Delay Mean, One Way Delay Std Dev, Offset From Master Mean, Offset From Master Std Dev, Observed Drift Mean, Observed Drift Std Dev, raw delayMS, raw delaySM
2019-02-28 10:09:27.345324, init, 
2019-02-28 10:09:27.446728 ptpd2[17401].wlan0 (notice) (lstn_init) Now in state: PTP_LISTENING
2019-02-28 10:09:27.446993, lstn_init, 1

```

another device

```auto
sudo ptpd -s -V -i wlan0
[sudo] password for nvidia: 
2019-02-28 10:32:52.194791 ptpd2[9812].startup (info) (___) Configuration OK
2019-02-28 10:32:52.196482 ptpd2[9812].startup (info) (___) Successfully acquired lock on /var/run/ptpd2.lock
2019-02-28 10:32:52.197157 ptpd2[9812].startup (notice) (___) PTPDv2 started successfully on wlan0 using "slaveonly" preset (PID 9812)
2019-02-28 10:32:52.197311 ptpd2[9812].startup (info) (___) TimingService.PTP0: PTP service init
# Timestamp, State, Clock ID, One Way Delay, Offset From Master, Slave to Master, Master to Slave, Observed Drift, Last packet Received, One Way Delay Mean, One Way Delay Std Dev, Offset From Master Mean, Offset From Master Std Dev, Observed Drift Mean, Observed Drift Std Dev, raw delayMS, raw delaySM
2019-02-28 10:32:52.197407, init, 
2019-02-28 10:32:52.198968 ptpd2[9812].wlan0 (info) (init) Observed_drift loaded from kernel: -7030 ppb
2019-02-28 10:32:52.299384 ptpd2[9812].wlan0 (notice) (lstn_init) Now in state: PTP_LISTENING
2019-02-28 10:32:52.299602, lstn_init, 1 
2019-02-28 10:32:53.543388 ptpd2[9812].wlan0 (info) (lstn_init) New best master selected: 00e18cfffea0c36e(unknown)/1
2019-02-28 10:32:53.543757 ptpd2[9812].wlan0 (notice) (slv) Now in state: PTP_SLAVE, Best master: 00e18cfffea0c36e(unknown)/1 (IPv4:192.168.1.2)
2019-02-28 10:32:53.543937, slv, 00e18cfffea0c36e(unknown)/1, 0.000000000, 0.000000000, 0.000000000, 0.000000000, -7029.617309570, I, 0.000000000, 0, 0.000000000, 0, 0, 0, 0.000000000, 0.000000000
2019-02-28 10:32:53.544100 ptpd2[9812].wlan0 (notice) (slv) Received first Sync from Master
2019-02-28 10:32:53.544201, slv, 00e18cfffea0c36e(unknown)/1, 0.000000000, 0.047955897, 0.000000000, 0.095911794, -7029.617309570, S, 0.000000000, 0, 0.000000000, 0, 0, 0, 0.095911794, 0.000000000
2019-02-28 10:32:54.465615, slv, 00e18cfffea0c36e(unknown)/1, 0.000000000, 0.057057355, 0.000000000, 0.018202916, -7029.617309570, S, 0.000000000, 0, 0.000000000, 0, 0, 0, 0.018202916, 0.000000000
2019-02-28 10:32:54.547512, slv, 00e18cfffea0c36e(unknown)/1, 0.006653023, 0.057057355, 0.008409175, 0.018202916, 50027.737690430, D, 0.000000000, 0, 0.000000000, 0, 0, 0, 0.018202916, 0.008409175
2019-02-28 10:32:54.547758 ptpd2[9812].wlan0 (notice) (slv) Received first Delay Response from Master
2019-02-28 10:32:55.492999, slv, 00e18cfffea0c36e(unknown)/1, 0.006653023, 0.028695407, 0.008409175, 0.045840921, 50027.737690430, S, 0.000000000, 0, 0.000000000, 0, 0, 0, 0.045840921, 0.008409175
2019-02-28 10:32:55.591088, slv, 00e18cfffea0c36e(unknown)/1, 0.014482247, 0.028695407, 0.016792874, 0.045840921, 78723.144690430, D, 0.000000000, 0, 0.000000000, 0, 0, 0, 0.045840921, 0.016792874
2019-02-28 10:32:56.517412, slv, 00e18cfffea0c36e(unknown)/1, 0.014482247, 0.047172271, 0.016792874, 0.069638892, 78723.144690430, S, 0.000000000, 0, 0.000000000, 0, 0, 0, 0.069638892, 0.016792874

```

seems working!

---

<div class="post-metadata">

**Author:** ![Andrey1984](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/andrey1984/32/14130_2.png) [@Andrey1984](https://forums.developer.nvidia.com/u/Andrey1984)\
**Post date:** [March 1, 2019, 1:31am UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/2 "2019-03-01T01:31:41Z")

</div>

next step seems to sync Master via gps to sattelite.  
Any walkthrough?  
mapping the post to [https://devtalk.nvidia.com/default/topic/1046186/jetson-agx-xavier/connecting-gps-with-pps-to-xavier/](https://devtalk.nvidia.com/default/topic/1046186/jetson-agx-xavier/connecting-gps-with-pps-to-xavier/)

---

<div class="post-metadata">

**Author:** ![Andrey1984](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/andrey1984/32/14130_2.png) [@Andrey1984](https://forums.developer.nvidia.com/u/Andrey1984)\
**Post date:** [March 3, 2019, 2:04pm UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/3 "2019-03-03T14:04:39Z")

</div>

I added the daemon to autostart with parameter wlan0, but it appears that it can not recognize the interface unless I restart the daemon after the system boot.

```auto
systemctl status ptpd
● ptpd.service - LSB: start and stop ptpd
   Loaded: loaded (/etc/init.d/ptpd; generated)
   Active: active (exited) since Sun 2019-03-03 13:46:52 UTC; 5min ago
     Docs: man:systemd-sysv-generator(8)
  Process: 5241 ExecStart=/etc/init.d/ptpd start (code=exited, status=0/SUCCESS)

Mar 03 13:46:52 jetson-0423018055033 ptpd2[5653]: Loading configuration file: /e
Mar 03 13:46:52 jetson-0423018055033 ptpd2[5653]: Checking configuration
Mar 03 13:46:52 jetson-0423018055033 ptpd2[5653]: Configuration OK
Mar 03 13:46:52 jetson-0423018055033 ptpd2[5653]: Interface wlan0 does not exist
Mar 03 13:46:52 jetson-0423018055033 ptpd[5241]: Interface wlan0 does not exist.
Mar 03 13:46:52 jetson-0423018055033 ptpd[5241]: Error: Cannot use wlan0 interfa
Mar 03 13:46:52 jetson-0423018055033 ptpd[5241]: PTPDv2 startup failed
Mar 03 13:46:52 jetson-0423018055033 ptpd2[5653]: Error: Cannot use wlan0 interf
Mar 03 13:46:52 jetson-0423018055033 ptpd2[5653]: PTPDv2 startup failed
Mar 03 13:46:52 jetson-0423018055033 systemd[1]: Started LSB: start and stop ptp

```

However, it wharts working after manual execution of:

```auto
sudo systemctl restart ptpd

```

```auto
systemctl status ptpd
● ptpd.service - LSB: start and stop ptpd
   Loaded: loaded (/etc/init.d/ptpd; generated)
   Active: active (running) since Sun 2019-03-03 13:53:53 UTC; 5s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 9206 ExecStop=/etc/init.d/ptpd stop (code=exited, status=0/SUCCESS)
  Process: 9240 ExecStart=/etc/init.d/ptpd start (code=exited, status=0/SUCCESS)
    Tasks: 1 (limit: 4915)
   CGroup: /system.slice/ptpd.service
           └─9278 /usr/sbin/ptpd -c /etc/ptpd.conf

Mar 03 13:53:53 jetson-0423018055033 systemd[1]: Starting LSB: start and stop ptpd...
Mar 03 13:53:53 jetson-0423018055033 ptpd2[9274]: PTPDv2 version 2.3.1 starting
Mar 03 13:53:53 jetson-0423018055033 ptpd2[9274]: Starting ptpd2 daemon with parameters: /usr/sbin/ptpd -c /etc/ptpd
Mar 03 13:53:53 jetson-0423018055033 ptpd2[9274]: Loading configuration file: /etc/ptpd.conf
Mar 03 13:53:53 jetson-0423018055033 ptpd2[9274]: Checking configuration
Mar 03 13:53:53 jetson-0423018055033 ptpd2[9274]: Configuration OK
Mar 03 13:53:53 jetson-0423018055033 ptpd2[9274]: Successfully acquired lock on /var/run/ptpd2.lock
Mar 03 13:53:53 jetson-0423018055033 systemd[1]: Started LSB: start and stop ptpd.
...skipping...
● ptpd.service - LSB: start and stop ptpd
   Loaded: loaded (/etc/init.d/ptpd; generated)
   Active: active (running) since Sun 2019-03-03 13:53:53 UTC; 5s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 9206 ExecStop=/etc/init.d/ptpd stop (code=exited, status=0/SUCCESS)
  Process: 9240 ExecStart=/etc/init.d/ptpd start (code=exited, status=0/SUCCESS)
    Tasks: 1 (limit: 4915)
   CGroup: /system.slice/ptpd.service
           └─9278 /usr/sbin/ptpd -c /etc/ptpd.conf

Mar 03 13:53:53 jetson-0423018055033 systemd[1]: Starting LSB: start and stop ptpd...
Mar 03 13:53:53 jetson-0423018055033 ptpd2[9274]: PTPDv2 version 2.3.1 starting
Mar 03 13:53:53 jetson-0423018055033 ptpd2[9274]: Starting ptpd2 daemon with parameters: /usr/sbin/ptpd -c /etc/ptpd
Mar 03 13:53:53 jetson-0423018055033 ptpd2[9274]: Loading configuration file: /etc/ptpd.conf
Mar 03 13:53:53 jetson-0423018055033 ptpd2[9274]: Checking configuration
Mar 03 13:53:53 jetson-0423018055033 ptpd2[9274]: Configuration OK
Mar 03 13:53:53 jetson-0423018055033 ptpd2[9274]: Successfully acquired lock on /var/run/ptpd2.lock
Mar 03 13:53:53 jetson-0423018055033 systemd[1]: Started LSB: start and stop ptpd.

```

I created configuration file /etc/ptpd.conf

```auto
cat /etc/ptpd.conf
ptpengine:interface=wlan0
ptpengine:preset=masteronly
ptpengine:use_libpcap=y
ptpengine:panic_mode=y
ptpengine:panic_mode_duration=10
clock:drift_handling=file
global:log_file=/var/log/ptpd2.log
global:log_file_max_size=5000
; rotate logs up to 5 files
global:log_file_max_files=5
global:log_status=y
global:statistics_file=/var/log/ptpd2.stats

```

and referenced it at:

```auto
" cat /etc/default/ptpd
# /etc/default/ptpd

# Set to "yes" to actually start ptpd automatically
START_DAEMON=yes

# Add command line options for ptpd
PTPD_OPTS="-c /etc/ptpd.conf"

```

It seems processed fine on the boot, but for the missed slan0 interface.  
Any idea, how to get it autostart?

---

<div class="post-metadata">

**Author:** ![linuxdev](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/linuxdev/32/10243_2.png) [@linuxdev](https://forums.developer.nvidia.com/u/linuxdev)\
**Post date:** [March 3, 2019, 9:44pm UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/4 "2019-03-03T21:44:56Z")

</div>

This isn’t something I’ve done before, but what starts the slan0 interface? NetworkManager? A static script? Systemd?

I really hate NetworkManager, but it can be useful for falling back from one connection type to another and not blocking during boot. However, in theory systemd would be the way to make this part of the system in a reliable way. You might explore “/etc/systemd/system/” and explore maybe creating a custom version of something there (without editing pre-existing files, but instead making a copy and adding a symbolic link to the new version). Sorry, I haven’t done what you are doing, so all I have is a methodology and not an end answer.

---

<div class="post-metadata">

**Author:** ![Andrey1984](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/andrey1984/32/14130_2.png) [@Andrey1984](https://forums.developer.nvidia.com/u/Andrey1984)\
**Post date:** [March 4, 2019, 4:08am UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/5 "2019-03-04T04:08:28Z")

</div>

slan0?  
with wlan0 starts wifi card intel 8265 ngw.  
I’ll try asking at [intel forum](https://forums.intel.com/s/question/0D50P00004FkijRSAR/8265ngw-for-precise-time-synchronization-between-two-devices) as well.  
I’ll try playing with systemd/system thx, may be I will add some delay like

```auto
sleep 120

```

or something

---

<div class="post-metadata">

**Author:** ![Andrey1984](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/andrey1984/32/14130_2.png) [@Andrey1984](https://forums.developer.nvidia.com/u/Andrey1984)\
**Post date:** [May 12, 2019, 3:30pm UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/6 "2019-05-12T15:30:44Z")

</div>

Is there a chance to implement something like [url][https://devtalk.nvidia.com/default/topic/1031778/faq/drive-px2-time-sync-guide/post/5249342/#5249342[/url]](https://devtalk.nvidia.com/default/topic/1031778/faq/drive-px2-time-sync-guide/post/5249342/#5249342%5B/url%5D)  
at AGX Xavier? Any support of Time Sensitive Networking with deterministic communication support?

---

<div class="post-metadata">

**Author:** ![Andrey1984](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/andrey1984/32/14130_2.png) [@Andrey1984](https://forums.developer.nvidia.com/u/Andrey1984)\
**Post date:** [May 12, 2019, 6:03pm UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/7 "2019-05-12T18:03:49Z")

</div>

after wiring gps to serial of host pc and executing

```auto
sudo ldattach PPS /dev/ttyS0

```

and installing ntp and gpsd it seems to read NEMA sequences continuously , but in a corrupted way:

```auto
sudo cat /dev/ttyS0
���f��~��f���`�~�f`~�������x�x

```

upd: sorted out further with help of the instruction from [Synchronizing ntpd to a Garmin GPS 18 LVC via gpsd](http://www.rjsystems.nl/en/2100-ntpd-garmin-gps-18-lvc-gpsd.php)

```auto
ntpq -ccv -p -crv -ckern -csysinfo
associd=0 status=0011 1 event, clk_no_reply,
device="SHM/Shared memory interface",
timecode="2019-05-12T20:17:51.000000000Z", poll=4, noreply=1,
badformat=0, baddata=0, stratum=0, refid=PPS, flags=0
     remote refid st t when poll reach delay offset jitter
==============================================================================
-SHM(0) .NMEA. 0 l 3 16 7 0.000 -3.950 6.015
*SHM(1) .PPS. 0 l 2 16 7 0.000 357.648 0.153

```

[External Media](https://devtalk.nvidia.com/cmd/default/download-comment-attachment/79011/ "Media hosted on another site. Click to open in a new tab.")

 ![asusboard.png](https://global.discourse-cdn.com/nvidia/original/2X/5/5f11cac2d63391eeecc532968669f3636fd175c1.png)

---

<div class="post-metadata">

**Author:** ![Andrey1984](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/andrey1984/32/14130_2.png) [@Andrey1984](https://forums.developer.nvidia.com/u/Andrey1984)\
**Post date:** [May 22, 2019, 2:24pm UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/8 "2019-05-22T14:24:09Z")

</div>

and is there any solution for synchronization CSI cameras across multiple devices? [xaviers/nano]

---

<div class="post-metadata">

**Author:** ![Andrey1984](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/andrey1984/32/14130_2.png) [@Andrey1984](https://forums.developer.nvidia.com/u/Andrey1984)\
**Post date:** [May 23, 2019, 12:55am UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/9 "2019-05-23T00:55:07Z")

</div>

Can any of these synchronization methods be utilized at AXG XAvier ?  
DriveWorks relies on the system time source of Tegra, in particular the CLOCK\_MONOTONIC time source. This time source adjusted to the UNIX epoch time is used internally to timestamp all sensors and events. Timestamps within the same context are guaranteed to be in sync. One thing to note is that this time source is relative to UNIX epoch time on Unix based platforms. Any NTP/PTP time corrections will influence this clock.  
DriveWorks computes timestamps for each sensor when data arrives to Tegra, so sensor data returned always has a timestamp associated with it. In particular:  
• GMSL Cameras: timestamping is done by the kernel driver triggered by the HW when full frame has been written into memory.  
• SocketCAN: timestamping occurs by the kernel driver when the full message is captured from the HW by the driver. When HW timestamping is used, timestamping is performed at the HW level, by the TegraCAN hardware. The HW counters are synced to the SW clock.  
• AurixCAN: messages through this interface are timestamped by the Aurix safety OS. gPTP must be running and Aurix+Tegra clock must be synced to make CAN messages timestamped by Aurix be in sync with DriveWorks timestamps.  
• Serial port sensors (GPS): timestamping occurs when packets arrive to DriveWorks, at the SW level.  
• Xsens IMU/GPS proprietary mode: clock of the Xsens devices are synchronized to DriveWorks clock, making timestamps to be in sync with DriveWorks timestamps.

source:  
[https://devtalk.nvidia.com/default/topic/1022173/drive-linux/whats-the-sync-strategy-of-the-sensors-inputs-/post/5210765/#5210765](https://devtalk.nvidia.com/default/topic/1022173/drive-linux/whats-the-sync-strategy-of-the-sensors-inputs-/post/5210765/#5210765)

---

<div class="post-metadata">

**Author:** ![JerryChang](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/jerrychang/32/14043_2.png) [@JerryChang](https://forums.developer.nvidia.com/u/JerryChang)\
**Post date:** [May 23, 2019, 9:27am UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/10 "2019-05-23T09:27:59Z")

</div>

hello Andrey1984,

FYI, you may refer to below for the timestamp of CSI frames,  
thanks

```auto
<i>$TOP/kernel_src/kernel/nvidia/drivers/media/platform/tegra/camera/vi/vi5_fops.c</i>

static void vi5_capture_dequeue(struct tegra_channel *chan,
	struct tegra_channel_buffer *buf)
{
...
	/* Read SOF from capture descriptor */
	ts = ns_to_timespec((s64)descr->status.<b>sof_timestamp</b>);

```

---

<div class="post-metadata">

**Author:** ![Andrey1984](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/andrey1984/32/14130_2.png) [@Andrey1984](https://forums.developer.nvidia.com/u/Andrey1984)\
**Post date:** [May 23, 2019, 10:08am UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/11 "2019-05-23T10:08:19Z")

</div>

Thank you for pointing out!  
I am trying to sort out how and in what manner it could be used to synchronize cameras across multiple jetsons and with synchronization with ptpd + gps/ ntp somehow: seems a long way to go.

---

<div class="post-metadata">

**Author:** ![Andrey1984](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/andrey1984/32/14130_2.png) [@Andrey1984](https://forums.developer.nvidia.com/u/Andrey1984)\
**Post date:** [May 26, 2019, 4:43pm UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/12 "2019-05-26T16:43:17Z")

</div>

How to timestamp CSI camera frames at nano/xavier?

> [@JerryChang](#):
>
> hello Andrey1984,
> 
> FYI, you may refer to below for the timestamp of CSI frames,  
> thanks
> 
> ```auto
> <i>$TOP/kernel_src/kernel/nvidia/drivers/media/platform/tegra/camera/vi/vi5_fops.c</i>
> 
> static void vi5_capture_dequeue(struct tegra_channel *chan,
> struct tegra_channel_buffer *buf)
> {
> ...
> /* Read SOF from capture descriptor */
> ts = ns_to_timespec((s64)descr->status.<b>sof_timestamp</b>);
> 
> ```

---

<div class="post-metadata">

**Author:** ![JerryChang](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/jerrychang/32/14043_2.png) [@JerryChang](https://forums.developer.nvidia.com/u/JerryChang)\
**Post date:** [May 28, 2019, 3:07am UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/13 "2019-05-28T03:07:32Z")

</div>

hello Andrey1984,

> > > How to timestamp CSI camera frames at nano/xavier?

please note that there’re different VI driver versions for different platforms.  
for example,  
$TOP/kernel\_src/kernel/nvidia/drivers/media/platform/tegra/camera/vi/  
vi2\_fops: Jetson-TX1 / Jetson-Nano;  
vi4\_fops: Jetson-TX2 / Jetson-TX2i;  
vi5\_fops: Jetson-Xavier.

all of them sharing same mechanism to waiting for SOF/EOF from sensor streaming to acquire a frame.  
VI driver also feed the timestamp to the vb2 buffer before sending the frame to user-space.  
thanks

---

<div class="post-metadata">

**Author:** ![Andrey1984](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/andrey1984/32/14130_2.png) [@Andrey1984](https://forums.developer.nvidia.com/u/Andrey1984)\
**Post date:** [May 28, 2019, 7:48am UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/14 "2019-05-28T07:48:06Z")

</div>

@JerryChang, Thank you for your response.

Does it need to rewrite argus camera sample code to enable the feature? Or may be gstreamer could be used to do the enablement of the feature?

Finding1:  
“virtual uint64\_t Argus::ICaptureMetadata::getSensorTimestamp ( ) const  
pure virtual  
Returns the start timestamp for the sensor (in nanoseconds).  
​  
This is the time that the first data from this capture arrives from the sensor.”

Finding2: [GstBuffer](https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstBuffer.html#GST-BUFFER-PTS:CAPS)

Finding3:  
[https://devtalk.nvidia.com/default/topic/1010111/jetson-tx1/nvmm-memory/post/5158652/#5158652](https://devtalk.nvidia.com/default/topic/1010111/jetson-tx1/nvmm-memory/post/5158652/#5158652)

References:  
[https://docs.nvidia.com/jetson/archives/l4t-multimedia-archived/l4t-multimedia-282/classArgus\_1\_1ICaptureMetadata.html#ae4ff79489b0aef6766742a61d1a17cfc](https://docs.nvidia.com/jetson/archives/l4t-multimedia-archived/l4t-multimedia-282/classArgus_1_1ICaptureMetadata.html#ae4ff79489b0aef6766742a61d1a17cfc)  
[https://devtalk.nvidia.com/default/topic/1045966/jetson-tx2/nvcamerasrc-timestamps-precision-lack/post/5307813/#5307813](https://devtalk.nvidia.com/default/topic/1045966/jetson-tx2/nvcamerasrc-timestamps-precision-lack/post/5307813/#5307813)

---

<div class="post-metadata">

**Author:** ![JerryChang](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/jerrychang/32/14043_2.png) [@JerryChang](https://forums.developer.nvidia.com/u/JerryChang)\
**Post date:** [May 29, 2019, 7:14am UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/15 "2019-05-29T07:14:41Z")

</div>

hello Andrey1984,

you could use the Argus APIs to get the sensor timestamp,  
there’s slightly difference of capture timestamp between VI-mode and VI-bypass mode.  
VI-bypass mode:  
it records the timestamp while sending the CSI capture event, and using the monotonic time in microseconds.  
VI-mode:  
As I mentioned in [comment #10](https://devtalk.nvidia.com/default/topic/1047944/jetson-agx-xavier/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/post/5342272/#5342272), it save the Start-of-Frame timestamp by TSC.  
this TSC is in the unit of nanosecond, and there is offsets between TSC and monotonic time.  
you may also check [Topic 1038131](https://devtalk.nvidia.com/default/topic/1038131/) for reference,  
thanks

---

<div class="post-metadata">

**Author:** ![Andrey1984](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/andrey1984/32/14130_2.png) [@Andrey1984](https://forums.developer.nvidia.com/u/Andrey1984)\
**Post date:** [May 29, 2019, 8:01am UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/16 "2019-05-29T08:01:24Z")

</div>

Hi JerryChang,  
Thank you for your response.  
It appears that I shall investigate and approach implementation of two methods: I & II.

I.)  
Shall I with a purpose to enable the timestamp at Xavier in VI-mode do the following:

1.open the file below and make it to have the form as attached below:  
$TOP/kernel\_src/kernel/nvidia/drivers/media/platform/tegra/camera/vi/vi5\_fops.c

```auto
static void vi5_capture_dequeue(struct tegra_channel *chan,
	struct tegra_channel_buffer *buf)
{
...
	/* Read SOF from capture descriptor */
	ts = ns_to_timespec((s64)descr->status.sof_timestamp);

```

1. build the kernel
2. run somewhat recording sequence? for example?

II.)  
Shall I with a purpose to use the VI-bypass mode do the following:

1. Modify the video driver to a form below:

```auto
static bool vi_notify_wait(...)
{
..
    *ts = ns_to_timespec((s64)status.sof_ts);

```

1. build the kernel somehow and get it installed to Jetson?

2. run e.g

```auto
./yavta -c10 -n4 -F/tmp/test.raw /dev/video0

```

to test with?

---

<div class="post-metadata">

**Author:** ![Andrey1984](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/andrey1984/32/14130_2.png) [@Andrey1984](https://forums.developer.nvidia.com/u/Andrey1984)\
**Post date:** [May 29, 2019, 8:25am UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/17 "2019-05-29T08:25:01Z")

</div>

Attempt 1. Progress report I. Method I “VI-mode”.  
Step 1. Downloading SDK Manager to Host PC.  
After completion of the download the file vi5\_fops.c has not been located.  
Attempting downloading the package [https://developer.nvidia.com/embedded/dlc/l4t-jetson-driver-package-32-1-JAX-TX2](https://developer.nvidia.com/embedded/dlc/l4t-jetson-driver-package-32-1-JAX-TX2) instead to locate the file.  
The file vi5\_fops.c is not detected within the archive.  
Looking for other ways.  
At Xavier device I do not have such a location or a file and neither at host pc or within the driver package.  
Xavier:

```auto
/usr/src/linux-headers-4.9.140-tegra-ubuntu18.04_aarch64/kernel-4.9/drivers/media/platform$ ls
Kconfig am437x blackfin davinci exynos4-is mtk-vcodec omap rcar-vin s5p-g2d s5p-mfc sti vivid xilinx
Makefile atmel coda exynos-gsc marvell-ccic mtk-vpu omap3isp s3c-camif s5p-jpeg soc_camera ti-vpe vsp1

```

Archive located: [https://developer.nvidia.com/embedded/dlc/l4t-sources-32-1-JAX-TX2](https://developer.nvidia.com/embedded/dlc/l4t-sources-32-1-JAX-TX2)  
file located: JAX-TX2-public\_sources.tbz2  
Is there a way to build the kernel at XAvier directly with native environment or it necessarily needs to be build at x86\_64 device?  
What file of the list below is it?

```auto
tar -xvf JAX-TX2-public_sources.tbz2 
public_sources/
public_sources/dtc-1.4.0.tar.bz2.sha1sum
public_sources/nvsample_cudaprocess_src.tbz2.sha1sum
public_sources/gstjpeg_src.tbz2.sha1sum
public_sources/libgstnvvideosinks_src.tbz2.sha1sum
public_sources/gstomx1_src.tbz2.sha1sum
public_sources/public_sources_sha.txt
public_sources/libgstnvvideosinks_src.tbz2
public_sources/FreeRTOSV8.1.2_src.tbz2
public_sources/kernel_src.tbz2
public_sources/nvgstapps_src.tbz2
public_sources/gstegl_src.tbz2
public_sources/gstomx1_src.tbz2
public_sources/gst-nvvideo4linux2_src.tbz2
public_sources/gstjpeg_src.tbz2
public_sources/kernel_src.tbz2.sha1sum
public_sources/v4l2_libs_src.tbz2
public_sources/FreeRTOSV8.1.2_src.tbz2.sha1sum
public_sources/gst-nvvideo4linux2_src.tbz2.sha1sum
public_sources/gstegl_src.tbz2.sha1sum
public_sources/u-boot_src.tbz2.sha1sum
public_sources/nvgstapps_src.tbz2.sha1sum
public_sources/u-boot_src.tbz2
public_sources/nvsample_cudaprocess_src.tbz2
public_sources/v4l2_libs_src.tbz2.sha1sum
public_sources/dtc-1.4.0.tar.bz2

```

It should be the **kernel\_src.tbz2**

changing the values from

```auto
/* Read SOF from capture descriptor */
	ts = ns_to_timespec((s64)descr->status.sof_timestamp);
	trace_tegra_channel_capture_frame("sof", ts);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0)
	/* update time stamp of the buffer */
	vb->timestamp.tv_sec = ts.tv_sec;
	vb->timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
#else
	vb->vb2_buf.timestamp = descr->status.sof_timestamp;
#endif

```

Well, it doesn’t need to be changed, does it?  
It seems already to have the value as:

```auto
ts = ns_to_timespec((s64)descr->status.sof_timestamp);

```

Step 2. will edit the file.  
Step 3. will sort out updating kernel with edited file - probably via flashing OS with sdkmanager  
Step 4. figuring out how to do testing if the update will work.  
Step 5. will test if I can record and retrieve the timestamp.

Fr step 2 I will add the content to the file vi5\_fops.c  
For step 3 I see that I edit the file and then use sdkmanager to flash Jetson Xavier with it. Right?

---

<div class="post-metadata">

**Author:** ![JerryChang](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/jerrychang/32/14043_2.png) [@JerryChang](https://forums.developer.nvidia.com/u/JerryChang)\
**Post date:** [May 29, 2019, 8:44am UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/18 "2019-05-29T08:44:18Z")

</div>

hello Andrey1984,

1. your proposal of Method-II is wrong,  
please check the [Camera Architecture Stack](https://docs.nvidia.com/jetson/archives/l4t-archived/l4t-321/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Fjetson_xavier_camera_soft_archi.html%23wwpID0E0OC0HA), VI-bypass mode handle the camera buffer processing in the [Camera Core], which is not public release source. hence you should have implementation through gstreamer and using the Argus APIs to get the sensor timestamp, (for example, Argus::ICaptureMetadata::getSensorTimestamp)

2. below two sample commands shows methods to access camera sensor with VI-mode and VI-bypass mode.  
VI-mode

```auto
$ v4l2-ctl -d /dev/video0 --set-fmt-video=width=2592,height=1944,pixelformat=RG10 --set-ctrl bypass_mode=0 --stream-mmap --stream-count=1

```

VI-bypass mode

```auto
$ gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! 'video/x-raw(memory:NVMM),width=1920, height=1080, framerate=30/1, format=NV12' ! nvoverlaysink -ev

```

1. you may also check the [Kernel Customization](https://docs.nvidia.com/jetson/archives/l4t-archived/l4t-321/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Fkernel_custom.html%23) to compile the kernel image, and there’s [Flashing a Specific Partition](https://docs.nvidia.com/jetson/archives/l4t-archived/l4t-321/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Fflashing.html%23wwpID0E0LB0HA) session to update specific partition.  
for example,

```auto
$ sudo ./flash.sh -r -k kernel jetson-xavier mmcblk0p1

```

---

<div class="post-metadata">

**Author:** ![Andrey1984](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/andrey1984/32/14130_2.png) [@Andrey1984](https://forums.developer.nvidia.com/u/Andrey1984)\
**Post date:** [May 29, 2019, 9:17am UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/19 "2019-05-29T09:17:34Z")

</div>

thank you for the update.  
the command below sets a mode for the v4l2 device as /dev/video0 as bypass\_mode=0  
VI Mode

```auto
v4l2-ctl -d /dev/video0 --set-fmt-video=width=2592,height=1944,pixelformat=RG10 --set-ctrl bypass_mode=0 --stream-mmap --stream-count=1

```

And the command below starts gstreamer on it.

```auto
$ gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! 'video/x-raw(memory:NVMM),width=1920, height=1080, framerate=30/1, format=NV12' ! nvoverlaysink -ev

```

As in the former sequence the command adjusted controls to set bypass\_mode=0.  
0 means that it is opposite to bypass mode, right?  
And the latter command will play gstreamer in mode that has been set with the previous command, Right?  
And when playing - does it use the "monotonic time in microseconds? How it can be seen? Or that would still have required use of argus api separately somehow with some specific code modification?  
Thanks

---

<div class="post-metadata">

**Author:** ![Andrey1984](https://sea2.discourse-cdn.com/nvidia/user_avatar/forums.developer.nvidia.com/andrey1984/32/14130_2.png) [@Andrey1984](https://forums.developer.nvidia.com/u/Andrey1984)\
**Post date:** [May 29, 2019, 9:24am UTC](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980/20 "2019-05-29T09:24:57Z")

</div>

Attempting to get an image with it  
what shows image is

```auto
gst-launch-1.0 nvarguscamerasrc ! 'video/x-raw(memory:NVMM),width=1024, height=768, framerate=120/1, format=NV12' ! nvvidconv flip-method=0 ! nvegltransform ! nveglglessink -e

```

what doesn’t:

```auto
gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! 'video/x-raw(memory:NVMM),width=1920, height=1080, framerate=30/1, format=NV12' ! nvoverlaysink -ev

```

```auto
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
/GstPipeline:pipeline0/GstNvArgusCameraSrc:nvarguscamerasrc0.GstPad:src: caps = video/x-raw(memory:NVMM), width=(int)1920, height=(int)1080, format=(string)NV12, framerate=(fraction)30/1
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:src: caps = video/x-raw(memory:NVMM), width=(int)1920, height=(int)1080, format=(string)NV12, framerate=(fraction)30/1
/GstPipeline:pipeline0/GstNvOverlaySink-nvoverlaysink:nvoverlaysink-nvoverlaysink0.GstPad:sink: caps = video/x-raw(memory:NVMM), width=(int)1920, height=(int)1080, format=(string)NV12, framerate=(fraction)30/1
/GstPipeline:pipeline0/GstCapsFilter:capsfilter0.GstPad:sink: caps = video/x-raw(memory:NVMM), width=(int)1920, height=(int)1080, format=(string)NV12, framerate=(fraction)30/1
GST_ARGUS: Creating output stream
CONSUMER: Waiting until producer is connected...
GST_ARGUS: Available Sensor modes :
GST_ARGUS: 2592 x 1944 FR = 29.999999 fps Duration = 33333334 ; Analog Gain range min 1.000000, max 16.000000; Exposure Range min 34000, max 550385000;

GST_ARGUS: 2592 x 1458 FR = 29.999999 fps Duration = 33333334 ; Analog Gain range min 1.000000, max 16.000000; Exposure Range min 34000, max 550385000;

GST_ARGUS: 1280 x 720 FR = 120.000005 fps Duration = 8333333 ; Analog Gain range min 1.000000, max 16.000000; Exposure Range min 22000, max 358733000;

GST_ARGUS: Running with following settings:
   Camera index = 0 
   Camera mode = 1 
   Output Stream W = 2592 H = 1458 
   seconds to Run = 0 
   Frame Rate = 29.999999 
GST_ARGUS: PowerService: requested_clock_Hz=27216000
GST_ARGUS: Setup Complete, Starting captures for 0 seconds
GST_ARGUS: Starting repeat capture requests.
CONSUMER: Producer has connected; continuing.

```

```auto
./yavta -c10 -n4 -F/home/test.raw /dev/video0
Device /dev/video0 opened.
Device `vi-output, ov5693 2-0036' on `platform:15c10000.vi:2' (driver 'tegra-video') is a video capture (without mplanes) device.
Video format: SBGGR10 (30314742) 2592x1458 (stride 5184) field none buffer size 7558272
4 buffers requested.
length: 7558272 offset: 0 timestamp type/source: mono/EoF
Buffer 0/0 mapped at address 0x7f7b774000.
length: 7558272 offset: 7561216 timestamp type/source: mono/EoF
Buffer 1/0 mapped at address 0x7f7b03e000.
length: 7558272 offset: 15122432 timestamp type/source: mono/EoF
Buffer 2/0 mapped at address 0x7f7a908000.
length: 7558272 offset: 22683648 timestamp type/source: mono/EoF
Buffer 3/0 mapped at address 0x7f7a1d2000.

```

```auto
v4l2-ctl -d /dev/video0 --set-fmt-video=width=2592,height=1944,pixelformat=RG10 --set-ctrl bypass_mode=0 --stream-mmap --stream-count=1
<
nvidia@nvidia-desktop:~/yavta$ ./yavta -c10 -n4 -F/home/test.raw /dev/video0
Device /dev/video0 opened.
Device `vi-output, ov5693 2-0036' on `platform:15c10000.vi:2' (driver 'tegra-video') is a video capture (without mplanes) device.
Video format: SRGGB10 (30314752) 2592x1944 (stride 5184) field none buffer size 10077696
4 buffers requested.
length: 10077696 offset: 0 timestamp type/source: mono/EoF
Buffer 0/0 mapped at address 0x7f7ade4000.
length: 10077696 offset: 10080256 timestamp type/source: mono/EoF
Buffer 1/0 mapped at address 0x7f7a447000.
length: 10077696 offset: 20160512 timestamp type/source: mono/EoF
Buffer 2/0 mapped at address 0x7f79aaa000.
length: 10077696 offset: 30240768 timestamp type/source: mono/EoF
Buffer 3/0 mapped at address 0x7f7910d000.
0 (0) [-] none 0 10077696 B 167047.273698 167049.276832 -0.515 fps ts mono/EoF
1 (1) [-] none 1 10077696 B 167047.307029 167049.310128 30.002 fps ts mono/EoF
2 (2) [-] none 2 10077696 B 167047.340361 167049.343515 30.001 fps ts mono/EoF
3 (3) [-] none 3 10077696 B 167047.373692 167049.376837 30.002 fps ts mono/EoF
4 (0) [-] none 4 10077696 B 167047.407023 167049.410113 30.002 fps ts mono/EoF
5 (1) [-] none 5 10077696 B 167047.440354 167049.443450 30.002 fps ts mono/EoF
6 (2) [-] none 6 10077696 B 167047.473685 167049.476783 30.002 fps ts mono/EoF
7 (3) [-] none 7 10077696 B 167047.507017 167049.510139 30.001 fps ts mono/EoF
8 (0) [-] none 8 10077696 B 167047.540348 167049.543494 30.002 fps ts mono/EoF
9 (1) [-] none 9 10077696 B 167047.573679 167049.576806 30.002 fps ts mono/EoF
Captured 10 frames in 0.362655 seconds (27.574343 fps, 277885849.288754 B/s).

```

The latter doesn’t appear to use SoF, does it?  
Does it mean that SoF in not included into the default kernel implementation regardless the fact that the default sources of the kernel has it?  
Does the default kernel require modification to get the SoF added or it is presented by default? How to check that?

[Next page](https://forums.developer.nvidia.com/t/implementation-of-precise-time-synchronization-between-two-xaviers-over-wlan/70980.md?page=2)
