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;
        tsc_ns =(uint64_t)(((__uint128_t)cycles * 1000000000ull) / frq)
        raw_nsec = tp.tv_sec * 1000000000 + tp.tv_nsec;

        uint64_t offset_ns = llabs(tsc_ns-raw_nsec);

        return offset_ns;
    }

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.