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.
- 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
- 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.