[ntp:questions] NTP synchronization using two "external" clocks (here: "Local Clock" and "DS3231-RTC")
unruh at invalid.ca
Tue May 29 17:46:31 UTC 2012
On 2012-05-29, Andreas Baer <synthetic.gods at gmail.com> wrote:
>>> I have some questions about time synchronization using ntpd involving
>>> two external RTCs (local clock / DS3231) on Linux. Maybe some aspects
>> No, the RTC is NOT the local clock. The local clock is the system clock
>> itself (ie using the clock to sync itself. Amazingly it is always
>> perfectly on time!)
> Ah OK, sorry for my misunderstanding so it's even better that I asked
> my questions in the first place. :-)
>>> stated in the following context are trivial or wrong but I want to
>>> have a kind of certainty in that topic so I'm asking it on this list.
>>> I'm in an isolated network where I want to have a single Linux machine
>>> serving as an NTP server. I cannot use the Linux-shipped device driver
>>> for the DS3231 (accessed via I2C) because this RTC is placed on a
>>> custom board connected to the mainboard only via USB.
>>> Right now I can have simple access (read/write) to the clock via
>>> standard time structure (struct tm) using an existing API. Of course I
>>> want to use the accurate DS3231 clock as primary time source for ntpd
>>> in this isolated server case.
>> You need to write an ntp driver for that clock.
>>> Possible Solution 1: "Directly feed ntpd"
>>> What is the best way to feed ntpd with the DS3231 clock data?
>>> I tried to understand the source code of ntpd relating the reference
>>> clock drivers especially 'Type 8 - Generic Reference Driver (PARSE)'
>>> in order to find an easy way to input properly formatted time data
>>> into ntpd but there seems to be no 'simple' solution and I don't have
>>> full understanding of all consequences.
>> You could also use the shm driver. Ie, you set up a little program to
>> read the clock every second or whatever, and place the result into a
>> shared memory segment and have ntp read from that shm (labeled NTP0 to
>> NTP4 I beleive)
> OK, sounds reasonable.
> How about that 128 ms range, is it sufficient to update this 'memory
The 128ms is the time offset that ntpd will correct with a step. Thus,
if your clock really reports the time on the second every second, then
over that second your computer will also have advanced almost exactly a
second and the difference between the expternal clock and your
computer's system clock will by very small ( much less than 128ms).
> segment' once every second or is there any fixed time range that I
> should follow? I understand that you always write both timestamps, the
Nope. ntp like to read the clock with a minimum poll interval of 4 (16
sec) so your procedure can collect the offsets for 16 seconds and
average the offsets to report to the shm.
> external clock time and the system time when that external clock time
> was received, so it shouldn't matter, right? Also if it was not
> possible to update the memory segment at some point in the future or
> this 'little program' crashed for example, it just stops getting any
> input like for an external ntp server that is suddenly not available
> due to a network failure.
>>> Should I write a kernel device driver which emulates a certain device
>>> which access is already implemented as ntpd-driver to easily configure
>>> ntpd for that device? What about that 'Type 33 - Dumb clock'
>>> interface, would that be reasonable or even possible?
No need for a kernel driver, but you can do it. Be guided by programs
like shmpps, or gpsd (or even use them). They will rely on answering the
interupt and timing in userspace so may not be good to the 1us level,
but certainly should be to the 10us level.
>>> Possible Solution 2: "Sync with local-RTC"
>>> Besides directly feeding ntpd with the DS3231 clock data I could
>>> manually trigger the synchronization DS3231 => local-RTC and configure
>>> ntpd for using only the local-RTC (127.127.1.0) as time resource. That
>> You midunderstant device driver 1.0, It does not use the rtc.
> Again thanks for clarification.
>>> would be an easy solution but I maybe found a problem. RTCs have an
>>> accuracy of one second and I would always hard set the local-RTC to a
>>> specific timestamp. This would certainly require a STEP by ntpd to
>>> synchronize the system time to the changed local-RTC because of
>>> crossing the 128ms border almost all the time, right? Of course I want
>>> to prevent steps as much as possible.
>> Nope. You have the rtc interrupt at its one second transition, and then
>> act as if it were a PPS device. But that is not a good way, since
>> many systems no longer have an rtc interrupt, but do polling instead.
>> The way it works is that the PPS is timed by the system clock, and the
>> difference between that time and the seconds transition is the offset
>> which is driven to zero by ntp.
>> But again this is really really a bad way. Setting the rtc is also a
>> real pain because the rtc waits .5 seconds before it sets itself. Thus
>> you have to write to it .5 seconds before the time you are setting it
>> Far better to just use the shm driver to directly write to it. Ie, read
>> the time from you clock, read the system time at the same time. and
>> write those two times to the shm (shared memory) , and ntpd will do the
More information about the questions