On 23 Mar 2021 at 10:05, Miroslav Lichvar wrote:
>
> That issue with oscillations around resolution of the clock, I think
> you could try smaller PI constants, or you could switch to the nullf
> servo, which is intended for cases like this.
>
Yes I've tried fiddling with the P and I contributions and some other
coefficients that I've found in that area, also with the parameters
of the linear regression servo - to not much avail, if memory serves.
I haven't tried the nullf servo - will give it a try when I have
another opportunity (time and all the boxes together in the test
rig).
I did suspect some rounding error in the servo feedback stats/math,
and I'm aware that there are conversions from the native data type /
resolution coming out of the i210 HW registers (integer / fixed
point), to the floating-point data types being used by the LinuxPTP
servo library - but my relatively superficial conclusion was, that
those anomalous "outliers" indeed come from the i210 hardware
(timestamping registers). The offset reported is essentially the raw
i210 TS register sample taken that particular second, maybe just
type-converted from s32 to float - but no averaging / smearing /
filtering on that. Obviously I cannot see what's happening in the
silicon - those details under the i210's hood are a bit of a mystery
to me, and that's probably the way Intel would like them to remain
:-)
I'm actually a little surprised that the servo typically is able to
converge to a clean 0 and stay that way, with no random glitches, no
flapping around the 8ns lsb boundary. I understand that the i210 HW
does support fractional (below 1ppb) frequency adjustments - so it
wouldn't be all that surprising to see scenaria where the frequency
adjustment (which is some weighted average product of past offsets)
would remain non-zero (fraction of a ppb) for a couple seconds and
then the cumulative phase offset would exceed 8 ns, the servo would
get a kick from the TS register and "fractionally creep" the other
way. This doesn't seem to be the case...
I have implemented the following trigger in my own code of cmp.c and
cmp2.c
if ((offset == 0) && (abs(ppb) < 0.01))
phcs[i]->aligned_periods++;
else
phcs[i]->aligned_periods = 0;
if (phcs[i]->aligned_periods > 4) {
// switch to measurement stage
phcs[i]->initial_sync_stage = 0;
...etc
I.e. after 4 servo periods where the ppb offset was within +/- 10^-6,
I'd call the servo settled forever.
This is my heuristic based on practical observation that, while not
entirely settled, there would be some fraction on the order of 10^-1
or 10^-2 fluttering in the ppb, which would result in an occasional
non-zero phase offset - but eventually I'd get the ppb float residues
way below 10^-6 and they'd stay that way forever. Servo converged.
Which is where I'd start to take my measurements.
I was certainly hoping for this to happen while I was building my
25MHz synth :-)
Then afterwards, when I distilled that "anomaly of not settling",
I also tried just nailing ppb to 0 the moment when phase offset
becomes 0 - this is still present in a commented section at line 625
in my i210_ext_pps.c .
And, it didn't work. In the anomalous state, despite the ppb being
bolted to a clean 0 and written to the PHC, the phase offset (TS
register output) would run at 0 for a couple samples, then give a
shot of 8 ns, then probably return to zero...
Actually, I've spotted a similar behavior on part of the linreg
servo, possibly as an inherent effect of the algorithm. After a
couple dozen samples with phase offset = 0 (and ppb fluttering on the
order of 0.1 to 0.01), the ppb value suddenly drops to a pure 0.
(This doesn't happen with the PI, where I can always see some debris
reported below 10^-14 ppb if I count the zeroes correctly.)
While looking for a possible explanation, in the new v3.1 I've found
SERVO_LOCKED_STABLE and servo_offset_threshold /
servo_num_offset_values (config parameters). This logic is absent in
v1.8, and likely not related to the behavior of the linreg servo
(converging to pure zero ppb).
And I'm wondering if I should add SERVO_LOCKED_STABLE to the switch
case that does clockadj_set_freq() in my proggies :-) So far I only
check for SERVO_LOCKED . == I'll have to return to that, even though
SERVO_LOCKED_STATE is possibly quite a corner case, with the
servo_offset_threshold configured for 0 by default.
I hope to check that stuff again in a few weeks.
Frank
___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel