How to get the clock source offset_ns on Jetpack 6

Hi all,

I am looking for the value of the offset of the RT Clock used by the camera subsystem to assign the SoF and EoF timestamps. In Jetpack <= 5, it was in /sys/devices/system/clocksource/clocksources0/offset_n but in Jetpack 6, it is not longer there.

How can I get it again in JP 6?

Cheers and thanks in advance

The offset_ns can be calculated with below API for rel36 , please try it:

uint64_t readOffsetNs()
    {
        unsigned long raw_nsec, tsc_ns;
        unsigned long cycles, frq;
        struct timespec tp;

        asm volatile("mrs %0, cntfrq_el0" : "=r"(frq));
        asm volatile("mrs %0, cntvct_el0" : "=r"(cycles));

        clock_gettime(CLOCK_MONOTONIC_RAW, &tp);

        tsc_ns = (cycles / frq) * 1000000000;
        raw_nsec = tp.tv_sec * 1000000000 + tp.tv_nsec;

        uint64_t offset_ns = llabs(tsc_ns-raw_nsec);

        return offset_ns;
    }
1 Like

Hi @ShaneCCC

Unfortunately, the results don’t seem to be correct.

  1. Everytime I invoke the function, the offset changes. I am not sure if this is an expected behaviour.

Here are some results:

Offset (ns): 20579335328
Offset (ns): 20561566304
Offset (ns): 20440638752
  1. Another reason is that subtracting the SoF by the offset_ns is greater than the CLOCK_MONOTONIC_RAW of the system.

I am getting the SoF from consumerFrameInfo->frameSoFTime in the consumer_thread in gstnvarguscamerasrc.cpp. I am getting the CLOCK_MONOTONIC_RAW using clock_gettime (CLOCK_MONOTONIC_RAW, &vs_time);

To the best of my knowledge, to get the SoF relative to CLOCK_MONOTONIC_RAW, we need to apply the following equation:

SoF = sof_tsc - offset_ns

Is it possible I am misinterpreting something?

Thanks for your kindness and I appreciate your support.

For JP5 , the offset_ns in sysnode is calculated during system boot , After calculation, it is a fixed value. you can check the code in kernel-5.10/kernel/time/timekeeping.c
For JP6 , The API provided in last comment is calculated dynamically.
I have tested that the dynamic range is not very large:

    uint64_t readOffsetNs()
 {
        unsigned long raw_nsec, tsc_ns;
        unsigned long cycles, frq;
        struct timespec tp;

        asm volatile("mrs %0, cntfrq_el0" : "=r"(frq));
        asm volatile("mrs %0, cntvct_el0" : "=r"(cycles));

        clock_gettime(CLOCK_MONOTONIC_RAW, &tp);

        tsc_ns = (cycles * 100 / (frq / 10000)) * 1000;
        raw_nsec = tp.tv_sec * 1000000000 + tp.tv_nsec;

        printf("offset_ns:%lld\n", llabs(tsc_ns-raw_nsec));

        return 0;
}

int main(void )
{
   for(int i=0 ; i< 100; i++)
   {
          sleep(1);
           readOffsetNs();
   }
}
   nvidia@nvidia-desktop:~$ ./timetest

offset_ns:25189339576
offset_ns:25189362048
offset_ns:25189362104
offset_ns:25189361360
offset_ns:25189362216
offset_ns:25189361376
offset_ns:25189360680

nvidia@nvidia-desktop:~$ cat /sys/devices/system/clocksource/clocksource0/offset_ns
25189364448

      If you need a fixed value, you can calculate it once and use it as a global value.

Thanks

Thanks!

We have tested the latest code, and we have integrated it into nvargus, and everything worked.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.