[time-nuts] looking for good description/generalized model for time adjustments
Hal Murray
hmurray at megapathdsl.net
Wed Jul 29 18:44:43 UTC 2009
> I'm looking for a good (short) description and/or a generalized model
> for relating a local time counter to some external reference. Here's
> the scenario.. A computer has a local clock that is a counter being
> driven by a local oscillator. Periodically, we get "time updates" from
> some outside source that give an "absolute time" and a sync.
What sort of accuracy do you want? seconds? milliseconds? microseconds?
What sort of computer? A big one where you can run lots of software or a
tiny one where every instruction counts? How stable is the environment
(temperature)?
The trick is to think of frequency rather than time.
The usual problem with clock drift is that the local oscillator is off
slightly, typically a few 10s of ppm. You can fix most of that if you can
fudge the frequency of the clock. Say your system is updating the time from
an interrupt that goes off every ms and you are keeping time in ms.
The old code would look something like:
ms = ms + 1
if ms == 1000 { sec = sec + 1; ms = 0}
The first step is to change that to:
ns = ns + 1000000
if ns == 1000000 {ms = ms + 1; ns = 0}
if ms == 1000 { sec = sec + 1; ms = 0}
The trick is you want to change that first 1000000 to match what the osc is
actually delivering. So the code looks like:
initialize: nspertick = 1000000 + ppmfudge
run time:
ns = ns + nspertick
while ns >= 1000000 {ms = ms + 1; ns = ns - 1000000}
if ms == 1000 { sec = sec + 1; ms = 0}
if ppmfudge is negative, you will skip occasional updates to ms (drop ticks).
if ppmfudge is positive, you will occasionally jump by 2 ms.
I picked ms and ns for this example since the numbers work out conveniently
for an integer fudge factor in ppm. You will need more bits for finer
control.
1 ppm is 0.08 seconds per day or 1/2 second per week.
With that sort of setup, and a stable clock (temperature?) you can get within
a few seconds per week by hand.
If you want to get the human out of the loop, you can implement a PLL. That
gets complicated with filtering and stability and such.
Have you looked into ntp? The fudge factor is usually called drift. It's
usually stored in /etc/ntp/drift or /var/lib/ntp/drift or something like
that. With a good local clock (gps, pps), you can easily track temperature.
(I'll say more if anybody wants.)
Historical trivia:
I first learned about this back in 1976 or early 1977. Shortly after I got
to Xerox, Ed Taft fixed a bug in the Alto OS by adding that code. The
machine was designed with a 170 ns cycle time. Everybody knew that,
including the guys who wrote the timekeeping code.
You can't buy 170ns crystals. They come in MHz. So they got 5.88 MHz. If I
did the math right, that's off by 340 pm or 29 seconds per day. (That feels
about right. 30 seconds per day is horrible for a mature system, but close
enough that many other things will be more important during the early
days/years of a project.)
More trivia: The early 3 megabit Ethernet was actually 5.88 / 2.
--
These are my opinions, not necessarily my employer's. I hate spam.
More information about the time-nuts
mailing list