Where does the question come from?
When doing Linux periodic tasks, we usually avoid CLOCK_REALTIMEuse CLOCK_MONOTONIC. The reason is also very straightforward. The system time may be modified, and the monotonic clock will not suddenly go backwards with a manual time adjustment. It is more appropriate to use it to calculate timeouts and schedule cycles.
butUsing a monotonic clock and absolute time waiting, will the periodic frame transmission be stable?
In an EtherCAT synchronization investigation based on Xenomai, the application was scheduled by the Cobalt real-time core, but the phase still shifted first and then gradually returned. We find out the time base it relies on from the synchronization algorithm, and then locate the impact path through clock measurement and source code analysis. This article follows this idea and explains the relationship between the host clock and cycle synchronization. To facilitate discussion, equipment A, master station M0 and master station M1 are uniformly used.
1 Running environment and synchronization goals
Device A is an ARM64 embedded device running Linux 6.1.141, Dovetail and Xenomai 3.3 series. Real-time applications execute periodic tasks via the Cobalt POSIX interface and interact with the EtherCAT master via the RTDM interface.
The period for this discussion is 500µs, which is 2000 cycles per second. We choose the DC clock of the EtherCAT reference slave station as the synchronization base.The application adjusts its period to follow the reference DC. on the host systemd-timesyncd Keeps running and is responsible for synchronizing the host system time with an external time source.
There are actually two different sync targets here:
- Host system time wishFollow network time source。
- EtherCAT Application Cycle HopesFollow reference slave DC。
This investigation focuses on the second goal: whether the application’s periodic frame transmission can stably follow the reference DC.
2 Looking at the periodic frame timing from the phase waveform
When troubleshooting, we observe two quantities in the continuous oscilloscope of the drive debugging software: the period of the SYNC signal, and SYNC − IRQ phase difference. The IRQ here is SM2 interrupt of ESCunder this configuration, it is triggered when the PDO frame passes through ESC. Therefore, the IRQ provides us with a position on the slave side to observe the arrival moment of the PDO frame.
The screenshot below shows the phenomenon seen at that time:

The red curve in the figure is the SYNC signal period, and the cyan curve is SYNC time minus IRQ time. The horizontal axis covers approximately one minute, and the cursor interval is approximately 59.924 seconds; both channels display the amount of time in µs. In the statistics column, the SYNC period is about 500µs, the minimum value of the phase difference is 449µs, the maximum value is 480µs, and the variation range is about 31µs.
The cyan curve first dropped sharply, then gradually rose back to near the original level, and then similar changes occurred again.. Under the same cycle pairing relationship,SYNC − IRQ decrease means that IRQ moves later relative to SYNC, that is, the time when the PDO frame arrives at ESC becomes later than SYNC.; The rebound in the difference means that it is gradually moving forward again.
Under the condition that the transmission path delay is stable, the change of IRQ relative to SYNC reflects the change of the master station’s periodic frame sending time.About 31µs is the phase change amplitude, which cannot be directly understood as a certain application period suddenly extended by 31µs.
The application is already adjusting the cycle through the DC synchronization algorithm, so first check whether the phase calculation and cycle correction are correct, and whether the actual frame transmission is affected by the lateness of the thread or the delay in sending and receiving.
The screenshot does not have matching event-by-event parameters and timestamp records. This article uses it to illustrate the phenomenon; the subsequent software phase and clock samples come from another set of records and cannot correspond point by point.
The synchronization algorithm takes a while to recognize and compensate for the frequency difference, so it is also necessary to determine whether the offset and rebound in the waveform are related to its response process.
Check the algorithm, including checking the time base it depends on. The cycle correction will eventually be implemented on the next waiting target; if the clock used to generate the target changes the travel time rate, the actual cycle and frame sending time will also be affected.
In addition to the synchronization algorithm itself, we also need to check:Has the Cobalt MONOTONIC’s travel rate changed? If so, what changed it?Next, we will establish a method to compare clock rates, and then conduct controlled experiments to examine possible influencing factors.
2. Measuring the travel time rate of Cobalt MONOTONIC
To determine whether a clock is changing speed, you need to choose a comparison base. Linux is used here CLOCK_MONOTONIC_RAWhereinafter referred to as RAW; itWithout NTP rate correctionsuitable for observing changes in software time scale relative to the original monotonic time. It is not an external standard clock, and this comparison is not used to judge absolute time accuracy.
Measuring attentionHow much each clock has advanced during the same period of timerather than whether a certain reading is equal.
1 Let’s first distinguish what we are observing
In the period synchronization problem, there are at least three quantities:
相位误差:应用同步位置与参考时钟目标位置之间的偏差
频率误差:两个时钟单位时间内推进速度的差异
执行迟到:线程执行到某个检查点时,已经超过计划目标多少时间
These three quantities may influence each other, but they are not the same indicator. We only see that the phase is offset by tens of microseconds, and we cannot immediately determine whether the thread woke up late, the message was sent late, or the rate relationship between the two clocks changed.
2 Take down the clock together
We record Cobalt MONOTONIC, Linux MONOTONIC, Linux RAW and calendar time REALTIME together, and retain DC phase, period correction amount, deadline, reference sample and real-time thread MSW count. When verifying the time correction factor later, combine it with adjtimex Parametric analysis.
When comparing different time domains, two sequential reads cannot be regarded as the same time. One available sampling method is:
Cobalt MONOTONIC before
Linux MONOTONIC
Linux RAW
Linux REALTIME
Cobalt MONOTONIC after
Use the midpoint of the two Cobalt readings to approximate the intermediate moment, and then record the entire bracket width. When the brackets are too wide, the pairing error of the sample becomes larger and should be marked separately or excluded from the fine rate analysis.
Here’s the Linux side sampling and adjtimex The query is completed by a separate diagnostic path and is not put into the hard real-time cycle thread. When a single process uses both Linux and Cobalt entries, the calling paths need to be explicitly distinguished.
3 Do not compare the starting point, compare the increment
The starting points of different time domains may differ significantly. Count directly at a certain time MONOTONIC - RAWwhat is obtained is a value mixed with the starting point difference and the accumulated frequency difference, which cannot directly explain the current rate.
We take two valid paired samples and calculate:
relative_ppm = (ΔMONOTONIC / ΔRAW - 1) × 1,000,000
By doing the same calculation for Cobalt MONOTONIC, you can compare whether the relative RAW rates of the two change together. Here ppm means one part per million, and a positive value means it goes faster than RAW.
4 List host school time as a candidate factor
With methods of comparing rates, possible influencing factors can be examined. Timesyncd on the host has been running: it is used for frequency adjustment of time adjustment, will it also be transmitted to Cobalt? We selected this factor for a controlled experiment.
Linux Passed adjtimex() Wait for the interface maintenance time to correct the parameters.struct timex in freq Instead of expressing directly in ppm, use scaled units:
freq_ppm = timex.freq / 65536.0
For example, in this actual test freq=2574371after conversion it is approximately 39.281784ppm。offset units must also be combined STA_NANO Status bit judgment cannot always be regarded as microseconds. Linux adjtimex manual
freq It is just one of the correction parameters and cannot directly replace the actual measured rate in the window.so the set values and measured values are listed separately in the table.
5 one controlled frequency modulation
In order to test whether the host frequency modulation will affect Cobalt, we retain timesyncd, use the correction value at that time as the baseline, first subtract 60ppm, recover after about 30 seconds, then increase 60ppm, recover again after about 30 seconds, and compare the clock advancement rate of each stage.
Below are the setpoints recorded and the average rate within the window. All “relative RAW” means relative to native RAW, not relative to an external standard clock:
| stage | adjtimex.freq conversion value ppm | Linux MONOTONIC relative to RAW ppm | Cobalt MONOTONIC relative to RAW ppm |
|---|---|---|---|
| initial baseline | 39.282 | 42.765 | 42.839 |
| Baseline minus 60ppm | -20.718 | -17.195 | -17.195 |
| first recovery | 39.282 | 42.620 | 42.620 |
| Baseline plus 60ppm | 99.282 | 102.418 | 102.423 |
| Second recovery | 39.282 | 42.255 | 42.255 |

Each point in the figure represents the average value of the corresponding window, and the connecting line only represents the test sequence, not the writing instant or the continuous trajectory between windows.
The measured speed and freq If the parameters differ by a few ppm, the phase convergence of the core and the bracket sampling error also need to be considered. You cannot judge whether the write is successful based on this difference alone.
The most noteworthy thing in the table is the two columns of measured rates:Linux MONOTONIC and Cobalt MONOTONIC change speed relative to RAW together, and the amount of change is consistent with the injection direction and amplitude.. The Cobalt MONOTONIC on this device does take over the host frequency modulation.
See the appendix “Experimental Sampling and Statistical Methods” for the sampling range and screening methods of each window.
The experiment has given the relationship between the clocks, but has not yet individually explained why the initial waveform shows a “sudden drop and then a rise.” Next, answer the basic question: The hardware counter runs as usual, why can the software clock change speed?
Why can the three-monotonic clock change speed?
1 Reading time and triggering wake-up are two different things
clocksource Provides a continuously running hardware count, which the kernel converts to the current time;clockevent It is responsible for triggering an interrupt at a specified time. The time when it is read and when the thread actually starts executing need to be analyzed separately. Linux clock sources and clock events documentation
2 How does the hardware count become nanoseconds?
To avoid doing complex operations on the high-frequency path, Linux usually uses multiplication and shifting to complete the count conversion. Ignoring details such as wrapping, the reading process can be simplified to:
delta_cycles = 当前硬件计数 - 上次记录的硬件计数
delta_ns = delta_cycles × mult / 2^shift
当前时间 = 时间基值 + delta_ns
Hardware counters are low-level inputs,mult、shift and time base values are software conversion parameters. Even if the hardware counter is always running normally, the software canBy adjusting the conversion relationship, make “one software second” slightly faster or slightly slower than the original count.。
NTP timing correction usually does not require changing the hardware oscillator, let alone changing the CPU frequency. The “frequency modulation” discussed in this article,Mainly frequency correction of system time scale。
3 Calendar time can jump or be corrected gradually
CLOCK_REALTIME Represents the calendar time corresponding to the Unix Epoch. Directly setting it to a new position is called step; adjusting the travel time rate to gradually eliminate the error is called slew. Which method is used depends on the time synchronization program, configuration and current errors.
Therefore, the time-consuming calculation by subtracting two REALTIME timestamps may also include the time correction operation. This is why MONOTONIC is usually chosen for periodic tasks. Linux clock_gettime manual
4 CLOCK_MONOTONIC
CLOCK_MONOTONIC Does not provide a calendar date and does not allow applications to directly set it to any value. For the normal user mode clock interface, it guarantees that the time will not go backwards, but two consecutive reads can be the same and do not guarantee strict increment each time.
when REALTIME When set by a forward or backward jump, the kernel will process the offset relationship between the two to avoid passing this calendar time jump directly to MONOTONIC. but,NTP’s progressive correction of the system’s travel rate will still affect it.
in other words,MONOTONIC Addresses the chronological issue without committing to a “fixed ratio to uncorrected hardware counts”. The Linux manual explains respectively “not affected by discontinuous timing” and “affected by progressive frequency adjustment”. Linux clock_gettime manual
5 CLOCK_MONOTONIC_RAW
CLOCK_MONOTONIC_RAW supplyRaw monotonic time without NTP rate correction. Linux timekeeper is maintained separately tkr_mono and tkr_raw Reading base, NTP correction will act on the conversion and accumulation process of the former, RAW retains the time scale without such correction.
As can be seen from the implementation of Linux 6.1, the frequency adjustment will be updated tkr_mono.multand compensate the base value to maintain time continuity; this is two different things from “suddenly adding an offset to the current time”. Linux 6.1 timekeeping.c
What is drawn here is a simplified relationship during normal operation, and processing such as sleep and leap seconds is not carried out. RAW also needs to convert the count into time, rather than returning it directly to the hardware register; it is still affected by the frequency error of the hardware itself and cannot be understood as a naturally accurate standard time. Linux timekeeping interface description
6 The difference is only 30ns per cycle, why should we pay attention?
Back to the previous 60ppm FM experiment. Compared with RAW, if a clock is 60ppm faster, then after one second of RAW, the clock will take approximately 60µs longer.
1 秒 × 60 / 1,000,000 = 60µs
Assuming that the frequency difference between the two remains fixed during this period, the RAW duration corresponding to the MONOTONIC interval of 500µs is:
T_raw = 500000ns / (1 + 60 × 10^-6)
≈ 499970ns
The difference is only about 30ns per cycle.Timing for ordinary services may be small, but for cycle synchronization that needs to follow another hardware clock, this is a persistent frequency difference input.
If no other corrections are made at all, it can accumulate to about 60µs after one second. Actual DC servos will attempt to compensate, so this simple calculation cannot directly predict the phase peak value of a closed-loop system; it illustrates how errors enter the system. How often the synchronizer updates the frequency correction will affect how this frequency difference accumulates into phase changes; Section 5 will estimate the magnitude based on specific parameters.
4. Why does Cobalt also undertake Linux schooling?
The variable speed mechanism of Linux MONOTONIC explains a column of data in the experiment. Another column from Cobalt: why does it change almost simultaneously? This depends on continuing along the path of the actual calls made by the application.
1 The same function name may take different paths
In the Xenomai application, see clock_gettime() It cannot be immediately concluded that it is calling a normal libc service. pass xeno-config Provided compilation and linkage parameters, POSIX interfaces can be wrapped into Cobalt implementations.
sleep interface clock_nanosleep() The final symbol binding also needs to be checked to determine the service actually used by the cycle wait. Xenomai POSIX application porting instructions
2 This Dovetail path
Device A uses Dovetail. After viewing the corresponding implementation, the key relationship is very direct:
/* Dovetail 路径中的两个返回表达式。 */
return ktime_get_mono_fast_ns();
return ktime_get_real_fast_ns();
The first one comes from pipeline_read_cycle_counter()the second one comes from pipeline_read_wallclock(). Although the previous function here carries cycle_counter The name returns the nanosecond value of the Linux monotonic time; it cannot be regarded as an uncorrected hardware count based on the name alone. Xenomai 3.3.3 Dovetail clock adaptation
therefore,The Cobalt core monotonic time on this path will take over the Linux rate correctionthe core calendar time reads the Linux REALTIME time scale. The real-time core is still responsible for real-time task scheduling and timer processing, but the time scale is not isolated from Linux timing.
It should be noted that these fast accessors have specific kernel context semantics; they are only used here to confirm the time source, and the full properties of ordinary POSIX clocks are not deduced from them.
3 Why old I-pipe experience cannot be directly applied
In the old legacy TSC path, Cobalt reads the hardware high-resolution count and then uses its own scaling relationship to obtain the monotonic time. in this path MONOTONIC and MONOTONIC_RAW You can achieve the same thing.
REALTIME Then superimpose Cobalt’s wall time offset on this timeline. Historically also provided CLOCK_HOST_REALTIMEused to get the calendar time seen by Linux. This explains why in early Xenomai experience, it was often said that “Cobalt’s MONOTONIC is not affected by Linux NTP FM”.
But this understanding has its background. The user library source code of Xenomai 3.2.4 contains both legacy TSC and vDSO paths.Actual behavior cannot be judged solely based on the “3.x” version number. Xenomai 3.2.4 user mode clock source code
4 User mode reading requires another layer of consideration
Back to this experiment, the sampling comes from user mode, and it is not enough to confirm the source of the core clock.
The user library for Xenomai 3.3.3 uses Linux vDSO for common clocks:MONOTONIC and RAW Pass their respective clock IDs to vDSO;REALTIME and HOST_REALTIME Then read the vDSO’s REALTIME. Xenomai 3.3.3 User mode clock implementation
vDSO is user-mode code mapped to the process. It reads the time data and hardware counts released by the kernel, usually without falling into a system call.. The user mode reads the time directly, which does not mean that this time has nothing to do with Linux timekeeper.NTP has updated the conversion data, and subsequent vDSO reads will still use the updated data.
Figure shows supported fast read paths, with capabilities dependent on architecture and clock source. Linux vDSO Manual
This path explains the source of Cobalt MONOTONIC and RAW data in the experiment. However, successfully reading the time value is not enough to prove that there is no backup path or domain switching; before using it in a real-time loop, you still need to confirm the actual architecture, clocksource, library version and running status.
It is easy to understand the reading relationships involved this time:
| read path | MONOTONIC | REALTIME | RAW |
|---|---|---|---|
| Ordinary Linux user mode | Does not follow the calendar time step and is affected by NTP rate correction | Calendar time, can be step or progressive correction | Without NTP rate correction |
| Old Cobalt legacy TSC user mode path | Independent counting conversion | Monotone Time Superposition Cobalt Wall Offset | Equivalent to the MONOTONIC of this path |
| This Cobalt user mode vDSO path | Linux MONOTONIC time scale | Linux REALTIME time scale | Linux RAW time scale |
The last row in the table refers to user mode reading. Kernel system calls, RTDM clock interfaces and sleep interfaces need to be confirmed along their respective source codes, especiallyRAW reading results cannot be directly extended to sleep implementation。
For example, this version of the kernel __cobalt_clock_gettime() MONOTONIC and RAW will be merged into the core monotonic time read branch. This is different from the path where the user library directly hands the RAW ID to the Linux vDSO. Therefore, when analyzing the sampling results, the actual calling path must be confirmed, and user-mode vDSO reading cannot be regarded as equivalent to directly calling the Cobalt kernel interface. Cobalt kernel clock reading implementation
How to enter the DC synchronization loop with five frequency differences
The clock experiment and source code show that the host frequency modulation can reach Cobalt MONOTONIC. Next, we need to see how the periodic algorithm uses this timeline and how to respond when frequency differences occur.
1 Application time, reference samples and waiting targets
application time It is the time coordinate handed over to the master station by the application, which is used to establish the time relationship such as DC initialization; in this example of the user mode synchronizer, it also provides a phase comparison reference that advances according to the nominal cycle. It advances separately from the actual waiting target. Without limiting which clock domain the waiting target uses, the relationship between the two can be written as:
名义应用时间 A[k+1] = A[k] + 500000ns
实际等待目标 W[k+1] = W[k] + 500000ns + a[k]
in a[k] is the period correction of the synchronizer output. When preparing the reference message, the elapsed time of the current moment relative to the waiting target of this cycle is added to the nominal application time, and this application time is saved; when the reference response is returned, the saved value is compared with the corresponding reference time. This avoids comparing the application time of the current cycle to the reference response of the previous cycle. The reference DC time obtained by the interface has deducted the transmission delay according to the agreement of the master station, and is not the “DC current value” at the moment when the host reads the interface.
Phase calculation can be summarized as:
d[k] = low32(A_sample[k]) - D_ref32[k] // 按 32 位模数相减
e[k] = wrap_T(d[k]) // 按周期 T 归一相位
The source code will first process the 32-bit wraparound according to the signed difference, and then use the adjacent effective difference to advance the phase. You cannot simply take the unsigned large number directly modulo the period. At a 500µs period, the phase interval is [-250µs, 250µs)。这里定义的正方向是应用时间相位领先参考 DC,与开头调试通道的正方向不能直接画等号。
例如,应用相位比参考 DC 领先 100ns,给下一周期增加 1ns 等待时间,应用的名义时间仍只增加 500000ns,而参考 DC 在实际多等待的 1ns 内继续前进,正误差便向减小的方向变化。负误差则通过缩短等待间隔来修正。这就是本例“应用跟随 DC”的方向。
修正落在应用的下一次等待目标上,不把参考 DC 反向拉向主机 NTP 时间。运行期间,参考 DC 同步报文读取参考时钟并将其传播给其他从站;它与把主机时间写入参考时钟的操作不同。初始化时建立 DC 偏移、配置 SYNC 起点,也应与运行期间的周期跟踪分开理解。
当等待目标使用 MONOTONIC 时,主机调频会改变 500000ns + a[k] Corresponding actual durationand then change the reference sampling time, adding a frequency difference input to the synchronization loop. This is the connection between the clock speed and cycle synchronization measured earlier.
2 How a change of about 30µs might occur
As calculated earlier, 60ppm only makes a difference of about 30ns in a single 500µs period. To understand how this accumulates to tens of microseconds, one needs to consider the time window used by the synchronizer to update frequency estimates.
The following is the default configuration of the checked synchronizer——1024 valid samples,as well as 60ppm frequency variationMake an estimate. The complete configuration and step-by-step frequency modulation boundaries of the original screenshot are not all preserved, so this calculation is used to illustrate possible mechanisms and magnitudes and cannot be regarded as a point-by-point restoration of the screenshot.
Calculated based on obtaining one valid reference sample per cycle, the window length is:
T_window = 1024 × 500µs = 0.512s
lib/dc_sync_user.c The control in has two parts:Each active period is fine-tuned based on the current phase output;The frequency correction is updated at the end of the window using the average change of adjacent phase differences.. Omitting rounding, limiting and abnormal sample processing, it can be written as:
每满 1024 个有效样本:
频率修正 += 窗口内差值增量的平均值
+ sign(窗口平均相位) × 1ns
每个有效周期:
周期修正 = 频率修正 + sign(当前相位) × 1ns
The unit of “frequency correction” here is the number of nanoseconds added or subtracted per cycle.It needs to use data over a period of time to estimate the frequency difference, and cannot complete all compensation at the same moment when the frequency parameters change.. After a sudden change in the host time scale, the remaining frequency difference will continue to accumulate into a phase offset before the new frequency correction gradually takes effect.
To estimate the magnitude,Ignoring the feedback compensation within the window for the time being, it is assumed that the newly added 60ppm frequency difference lasts for a complete window:
每周期的时间差 ≈ 500000ns × 60 × 10^-6 = 30ns
一个滤波窗口内的相位累积量
≈ 30ns × 1024
= 30720ns
= 30.72µs
Under the above assumptions, the difference of about 30ns in a single cycle can be accumulated to about 30µs after about half a second, which is of the same order as the change in the screenshot.. This provides a way to understand fast phase shifts: software time does not have to jump, and persistent frequency differences can create visible shifts in a short period of time. However, just because the magnitudes are similar, it cannot be confirmed that the sudden drop in the screenshot is this process.
Subsequently, the window update causes the frequency correction to gradually offset the new frequency difference, and the phase no longer continues to accumulate in the same direction, but the phase offset that has been formed has to be pulled back. Just look at each cycle sign(phase) × 1ns The correction capability of this direct phase term at 2kHz is approximately:
1ns/周期 × 2000 周期/秒 = 2µs/秒
30µs ÷ 2µs/秒 ≈ 15秒
This provides “Depart quickly first, then return slowly“A possible mechanism. The frequency term of the complete controller also contains the sign correction of the window average phase, soDo not regard 15 seconds as a fixed recovery time;The actual slope is also affected by the step position within the window, integer rounding, original frequency difference and sampling continuity.
The filter length is configurable, and discontinuities in valid samples will also extend the window, so the above values are not a fixed response. What is revealed here is an influence path: the time scale change of the host will add frequency difference input to the periodic synchronization loop, and the response speed of the synchronizer determines how the phase changes accordingly.
Six Conclusions
The most likely place for people to go astray in this investigation isUnderstand “monotonic” as “fixed travel speed”and directly brought the experience established on I-pipe in the past to the Dovetail system.
For device A, the source code and controlled measurements correspond to each other: the Linux NTP correction changes the MONOTONIC relative to RAW rate, and the MONOTONIC used by Cobalt changes accordingly.Who schedules the cycle and who measures the cycle time are two things that need to be confirmed separately.。
This article confirms that host frequency modulation can enter the path of cycle time reference. Window estimation of synchronizers provides a possible mechanism for understanding phase changes in tens of microseconds, butMatching the magnitudes does not mean confirming the specific cause of the original image.. The corresponding relationship between the inflection points in the screenshots and FM events still needs to be recorded more completely.
When the application also follows an external DC, PHC, or other independent clock, the relationship between the time domains is part of the synchronization algorithm. When reading time, calculating remaining time, arranging sleep, and judging lateness, you all need to know which timeline you are on. In this way, if you see phase mutations or deadline misses, you can continue to locate based on specific evidence.
Appendix: How to check your own system
If you encounter similar problems, you can start with the following read-only checks to confirm the time source and frequency difference, and then decide whether a controlled experiment is needed.
1 Confirm the actual version and clock source
uname -a
xeno-config --version
cat /sys/devices/system/clocksource/clocksource0/current_clocksource
cat /proc/xenomai/clock/coreclk
Document the kernel, Xenomai user libraries, and I-pipe or Dovetail paths. The same version string may also contain different patches. You should still check the actual build source code when analyzing key behaviors.
2 First make a read-only frequency difference measurement
The following Python paragraph is only used for ordinary Linux diagnosis. It compares native MONOTONIC and RAW. It does not adjust any clock and is not a real-time cycle program:
import time
def sample():
before = time.clock_gettime_ns(time.CLOCK_MONOTONIC)
raw = time.clock_gettime_ns(time.CLOCK_MONOTONIC_RAW)
after = time.clock_gettime_ns(time.CLOCK_MONOTONIC)
return (before + after) // 2, raw, after - before
m0, r0, width0 = sample()
time.sleep(10)
m1, r1, width1 = sample()
ppm = ((m1 - m0) / (r1 - r0) - 1) * 1_000_000
print(f"MONOTONIC relative to RAW: {ppm:.6f} ppm")
print(f"sampling bracket: {width0} ns, {width1} ns")
The actual RAW increment is used here, so it is not required sleep(10) Lasts exactly ten seconds. A single measurement is also insufficient to describe the dynamic frequency modulation process and should be continuously recorded and analyzed in conjunction with the sampling bracket width.
Next, obtain the corresponding timestamp from the Cobalt program. You cannot use Python’s Linux MONOTONIC results to directly replace Cobalt’s actual path verification.
3 Read-only query adjtimex
In the normal Linux diagnostic process, you can modes Set zero to query the current status:
#include
#include
int main(void)
{
struct timex tx = {0};
int state = adjtimex(&tx);
if (state < 0) {
perror("adjtimex");
return 1;
}
printf("state=%d freq=%.9fppm offset=%ld status=0x%x\n",
state, tx.freq / 65536.0, tx.offset,
(unsigned int)tx.status);
return 0;
}
This query does not write time parameters. To conduct a controlled frequency modulation experiment, you should use an independent test environment to save the baseline, clarify the boundaries of each write and recovery results, and identify whether the time synchronization service made other writes during the experiment. There is no need to stop the NTP service first during the read-only troubleshooting phase.
Appendix: Experimental Sampling and Statistical Methods
This set of data collection is divided into windows according to the readback time after writing, and is recorded as follows:
| stage | Start and end time | The number of valid paired samples used for rate calculations | RAW span s of first and last valid samples | Effective sample maximum bracket width µs |
|---|---|---|---|---|
| initial baseline | 03:23:40.684—03:23:45.685 | 40 | 3.905 | 9.334 |
| Baseline minus 60ppm | 03:23:45.685—03:24:15.689 | 286 | 28.941 | 19.250 |
| first recovery | 03:24:15.689—03:24:45.693 | 285 | 28.734 | 10.792 |
| Baseline plus 60ppm | 03:24:45.693—03:25:15.697 | 289 | 28.943 | 16.919 |
| Second recovery | 03:25:15.697—03:25:45.701 | 289 | 28.937 | 10.501 |
During statistics, the clock is sampled at about 10Hz, and the midpoint of the Cobalt readings is used to select the window; 0.5 seconds are removed from the beginning and end of each window, and samples with a bracket width exceeding 20µs are eliminated. Finally, the window average rate is calculated based on the increment of the first and last valid samples, and the results are consistent with the above table.The number of effective samples does not mean taking the arithmetic average of the ppm of all adjacent samples.
In the experiment, both recovery times read back to the original baseline, and no additional frequency parameter changes were observed within each measurement window. The core’s original phase progression correction may still continue, so freq The set value and the measured rate do not have to be exactly the same.