Tradiční poučka praví, že přesnost synchronizace interní časové základny
analogových přijímačů DCF77 firmy Meinberg (analogový AM demodulátor)
vůči UTC činí cca 1 ms (milisekunda).
Digitální přijímače PCI511 a PZF (oboje software radio běžící na DSP)
jsou ještě o něco přesnější - tradičně se uvádělo 100 us (mikrosekund),
přestože neformálně vývojáři tvrdí, že když to jednou zkoušeli měřit,
tak jim výstup korelačního fázového demodulátoru u nich v Bad Pyrmontu
v průběhu asi týdne švidral v rozmezí pár desítek nanosekund,
což je číslo dost neuvěřitelné (srovnatelné s kvalitním příjmem GPS).
Výše zmíněných cca 100 us řádově odpovídá rozdílu (na našem území)
ve zpoždění na vrub šíření rádiových vln buď pozemní cestou
vs. odrazem od ionosféry, které v přijímači nelze rozlišit/oddělit.
DCF77 je bohužel technologie radioamatérsky dobrodružná,
kterýžto aspekt nabývá na významu s rostoucí vzdáleností
od vysílače (Mainflingen ve Frankfurtu) - každopádně toto povídání
nemá být soustředěno na zábavné aspekty DCF77, pro zájemce je zde
samostatná WWW stránka.
I ty nejjednodušší přijímače DCF77 AM obsahují lokální oscilátor s krystalem
a MCU (maličký procesor), který se stará o jemné dolaďování krystalového oscilátoru
podle demodulovaných, dekódovaných, zkontrolovaných a post-kompenzovaných dat.
MCU dále obsluhuje vnější rozhraní RS232 (nebo USB).
Tolik pro srovnání s případnou levnou konkurencí, kde demodulovaný signál je
buď softwarově dekódován na hostitelském počítači, nebo snad ještě hardwarově
načten do posuvného registru a dále softwarově zpracováván hostitelským CPU.
Levné přijímače DCF77 se také chytí pouze jednou denně v noci, Meinberg
přijímá signál trvale.
Přijímače GPS mají přesnost interní časové základny řádově pod mikrosekundu proti
UTC - za běžných provozních podmínek běžně na úrovni 100 ns, s ideálně umístěnou
anténou a kvalitním oscilátorem v nízkých desítkách ns. Mezi generacemi
Meinberg GPS170 a GPS180 series došlo k mírnému zlepšení. Přijímače Meinberg
ve srovnání s běžnými spotřebními GPSkami nevynikají mobilitou nebo počtem
kanálů, zato mají nekompromisně ošetřeny "průmyslové" aspekty - příjem na
vzdálenou venkovní anténu, nepřetržitý bezvýpadkový příjem rádiového signálu,
maximální přesnost lokální časové základny, sadu vnějších rozhraní pro časovou
synchronizaci PC i pro synchronizaci času v průmyslu, nemilosrdné hlášení
výpadků (navigační GPSky se leckdy tváří spokojeně i ve chvíli, kdy už si
polohu reálně "cucají z prstu".)
Pokud se týče jitteru/wanderu, u většiny GPS přijímačů Meinberg je na výběr
několik různě kvalitních lokálních oscilátorů - tabulka na webu firmy
Meinberg rozebírá jejich stabilitu dokonce v několika ohledech
V dokumentaci firmy Meinberg schází jedno sladké tajemství, klíčově důležité
pro naše zákazníky, kteří používají synchronizaci signálem 10 MHz (např.
vysílací technika DVB/DAB). Výstup 10 MHz u GPS přijímačů Meinberg je
"fázově synchronní" s PPS výstupem a s GPS časem pouze u oscilátorů od
OCXO-SQ výše (frekvence oscilátoru je nepatrně spojitě dolaďována servosmyčkou).
Přijímač s oscilátorem TCXO (u Meinbergů základ/standard) dorovnává
vandrování lokálního oscilátoru vkládáním/ubíráním půl-tiků signálu
10 MHz oproti výstupu PPS - tzn. hrana PPS při každém takovém dorovnání
"poskočí" o 50 ns (což je minimálně o 2 řády pod rozlišením NTP, a řádově
srovnatelné s rozlišením PTP na 100Mb Ethernetu). Prakticky jsme v konkrétním
případě pozorovali "dorovnávací skok" jednou za pár desítek sekund až jednotky
minut. Tato informace platila pro přijímače GPS170 series, modernější GPS180
vybavené nejlevnějším TCXO už "skáčou" po cca 12 ns. Každopádně toto je
patrně jeden z důvodů, proč je v rodně IMS základem OCXO-SQ.
Pokud jde o "plně zavěšené" oscilátory (OCXO-SQ a výš): zmíněná reziduální nepřesnost v zavěšeném stavu, v desítkách ns, nemá podobu nějakého rychlého chaosu, jitteru. Jedná se o velmi pozvolné vandrování, které projde dolní propustí filtru v dolaďovací servosmyčce. Reálně ho lze pozorovat na osciloskopu, nejlépe s velmi dlouhým digitálním dosvitem (v desítkách minut).
Prakticky shodnou přesnost, jako interní 10MHz krystalový oscilátor přijímače, mají vnější výstupy PPS (obdélník, hrana jednou za sekundu, délka pulzu 200 ms) a další frekvenční a pulzní výstupy, odvozené hardwarovými děličkami od krystalu.
Existuje několik různě přesných způsobů, jak časovací informaci dostat do počítače
(resp. obecně do synchronizovaného zařízení).
Na hardwarové úrovni to jde přes PCI sběrnici, přes USB, přes RS232 nebo přes LAN,
kde je dost rozdíl mezi NTP a PTP.
Případně "v průmyslu" přes diskrétní pulzní signály, IRIG nebo třeba generovaný signál DCF77.
V oblasti PDH/SDH lze použít frekvenční výstupy 2048 kHz nebo framed E1
na elektrickém rozhraní G.703 twist nebo koax - přesnost je prakticky shodná jako
u interního krystalového oscilátoru v GPS přijímači.
S přesností asi nejhůř je na tom RS232 bez PPS, použito jako vstup do PC s běžícím
NTPd (cca do 10 ms), RS232+PPS je někde na úrovni nízkých jednotek mikrosekund
(dáno rychlostí reakce obsluhy na IRQ na PC, navázané na PPS).
Na PC je dále problém, jak tu přesnost udržet ve Windows čistě softwarově
mezi dvěma tiky PPS - až po Windows XP včetně bývala granularita časových značek
GetSystemTime() a GetSystemTimeAsFileTime() asi 15 ms (perioda plánovače procesů),
v modernějších Windows už je to 1 milisekunda.
I v Linuxu může být maličko netriviální dostat PPS signál dovnitř přes sériový nebo
paralelní port - jedna věc je zprovoznit v kernelu PPS API (už nějakou dobu je
přítomno ve vanilce), jiná věc je zvládnout to hardwarově: jednak pinout,
druhak TTL výstup hodin Meinberg nemusí odpovídat napěťovým úrovním RS232 portu
a LPT port se dnes již příliš nevyskytuje.
Samotný RS232 výstup z GPS přijímače může být i poměrně přesný. V tomto ohledu stojí za zmínku přijímač GPS164, který má náběžnou hranu prvního znaku v řetězci na sériovém portu (vysílán jednou za sekundu) synchronní s hranou PPS na úrovni jednotek mikrosekund. Je to údajně umožněno použitým mikrokontrolérem (konkrétní model od firmy Infineon), který umí spouštět DMA přenos hranou externího signálu - a Meinbergové toto použili ke krmení výstupního UARTu daty (řetězcem).
Hardwarová karta instalovaná uvnitř počítače skýtá možnost snímat časové značky přímo z jejího oscilátoru. Maximální dosažitelná přesnost je dána rychlostí transakce na PCI sběrnici (+rychlostí obvodů na kartě), což je odhadem mikrosekunda nebo lepší (možná i o řád).
Podobně je tomu s USB - ale není úplně jisté, jak rychle se odpověď dostane do user space, protože nejde o přímou neblokující I/O instrukci, ale posílají se v zásadě zprávy (URBy) přes USB. Odpověď je doručována se signalizací pomocí IRQ, ovšem skrz celý "Windows USB stack".
Přes LAN a NTP na Linuxu lze dosáhnout vzájemnou přesnost dvou instancí
NTPd na úrovni 100-500 us, možná i lepší - pokud předpokládáme gigabitovou
LAN bez nějakého zásadního zatížení, nebo alespoň vyhrazený 100Mb Ethernet.
Není třeba se bát běžného provozu na gigabitové síti, algoritmus rozkladu
round-trip zpoždění v NTPd na jednotlivé složky (systematické a náhodné)
je docela chytrý. Pravda je, že standardní ntpd už v oblasti pod milisekundu
"netlačí tolik na pilu" a druhak není NTP imunní vůči asymetrickému
zpoždění na přenosových trasách (pokud ostatní provoz teče převážně
jedním směrem) protože round-trip se pro potřeby postkompenzace
prostě vydělí dvěma... NTP zejm. v referenční implementaci ntpd
také poměrně zvolna konverguje po startu. V tomto a jiných ohledech
se konkurenční software Chrony chová jinak, napohled možná lépe.
Přes LAN pod Windows je přesnost opět omezena granularitou časových značek,
dnes již 1 ms (spíš než dřívějších 15 ms) - týká se běhu open-source NTPd
na Windows (instalátor zkompilované binární podoby ntpd
pro Windows lze stáhnout od Meinbergů).
Meinbergové mají na svých NTP serverech Linux a open-source NTPd, mírně
vyladěné pro optimální vzájemnou spolupráci a pro použitý hardware.
Libovolný NTP server firmy Meinberg, ač má papírově poměrně "slabý" procesor,
zvládne obsloužit tisíce současně běžících instancí NTPd v roli klientů
(díky kvalitní kompenzaci přenosových a jiných zpoždění v NTPd).
Čili z hlediska přesnosti optimálním způsobem, jak poskytovat přesný čas
počítačům v lokální síti přes NTP, je pořídit k nim Meinberg LanTime
a spustit na nich NTPd nebo Chrony (zde v roli NTP klientů).
Také se tímto způsobem dá snadno vyřešit redundance.
Z oblasti "průmyslového řízení a regulace" (výrobní linky, pohony apod.)
přišla inspirace, ze které začátkem tisíciletí povstal Precision Time Protocol (PTP).
Vyžaduje speciální hardware na klientu i serveru = na standardních síťovkách
není lepší než NTP. Pro optimální přesnost (jednotky až stovky nanosekund)
vyžaduje i speciální switche, se zhoršenou přesností běhá i přes normální
kancelářské switche. Samotný framing je kompatibilní se standardním Ethernetem.
Na výkonných carrier-grade switchích (které o PTP nemají potuchy)
není výjimkou dosažení přesnosti v "nízkých mikrosekundách".
Pokud chceme pomocí PTP synchronizovat počítač, potřebujeme speciální síťovou
kartu, která funguje jako "PTP přijímač" a poskytne systému své
hardwarové hodiny pro potřeby pořizování přesných časových značek
s teoretickým rozlišením v nanosekundách.
Dobrá zpráva je, že moderní gigabitové síťové karty značek např. Intel a Broadcom
již obsahují HW podporu pro PTP (timestamping engine, PHC) a zejména novější
generace (i210, i350 a mladší) jsou zřejmě schopny se standardním krystalem
dosahovat přesnosti na úrovni 10 nanosekund při periodě doladění
"jednou za sekundu". Tato úroveň přesnosti je zřejmě omezena pouze
nekvalitním 25MHz krystalem, který síťový čip taktuje - pokud síťovka
dostane přesné hodiny = lepší krystal, nebo její hodiny zavěsíte
v laboratorních podmínkách alternativní cestou na oscilátor PTP
grandmasteru, zmizí reziduální vandrování servosmyčky zcela
- chyba v nanosekundách hlášená ptp4l je trvale 0.
Mluvíme-li o přesnosti časování, následuje další otázka: jak v daném OS zjišťovat časovou značku. V zásadě můžete buď použít standardní prostředky operačního systému a dalšího softwaru (NTPd), nebo můžete pomocí Meinbergovic API (user-space DLL) sáhnout přímo na hardware přijímačové karty, kterou v počítači případně máte zabudovanou.
Pod Windows existují dvě základní knihovní funkce standardního Windows API:
GetSystemTime() a GetSystemTimeAsFileTime().
První vrací datový typ s rozlišením 1 ms, druhá vrací datový typ s rozlišením 100 ns.
Vrácená hodnota je přímo kalendářní datum a čas ve zmíněném rozlišení.
Potíž je, že na NT/2k/XP mají obě reálnou granularitu odvozenou od periody plánovače,
běžně 15.6 ms. Budu citovat vývojáře od Meinbergů:
"
Under Windows Vista / 7 / Server 2008 the timer tick interval may be
reduced to 1 ms, if the multimedia timer has been set to highest
resolution. Anyway, the basic behaviour is unchanged.
"
Dále se pod Windows dá zavolat QueryPerformanceCounter(), což vrátí okamžitou hodnotu
nějakého hardwarového časovače (záleží na čipsetu), který tiká obvykle rychlostí 3.5 MHz
(jsou možné i jiné frekvence), tj. granularita i přesnost cca 300 ns. Pak je ale na
progrmátorovi aplikace, aby si tuhle hodnotu nějak přepočetl na reálný čas - který
musí napřed nepřesně "ukotvit" pomocí GetSystemTimeAsFileTime()...
Meinbergové mají utilitku,
pomocí které lze přesnost těchto tří funkcí pod Windows změřit.
Taky se dá zavolat instrukce rdtsc (ovšem nikoli v user space, je privilegovaná)
- tenhle 64b čítač sice tiká frekvencí jádra procesoru, takže má vysoké rozlišení, ale taky
s tím souvisí další nectnosti: TSC čítače mívají různou hodnotu na různých jádrech ve
vícejádrových procesorech nebo SMP serverech (dá se řešit nastavením afinity procesu
na konkrétní CPU jádro), hodinová základna není příliš stabilní, na některých procesorech
je frekvence TSC proměnlivá (mění se s taktem jádra, který je ovládán power managementem,
u Intelu např. SpeedStep a TurboBoost). Kromě toho se opět jedná o prostý čítač,
bez přímé vazby na hodiny reálného času.
Momentálně (2019) se nezdá, že by Microsoft Windows měly nějakou
systémovou podporu pro IEEE1588 PTP, nebo pro síťové čipy
s odpovídajícím hardwarovým PHC.
V Linuxu existuje pro časování a snímání časových značek přehršel
"rozhraní" / knihovních a systémových funkcí. Pokud se přidržíme
časových značek, stojí za to zmínit starší syscall gettimeofday(),
které vrací zlomkovou část v mikrosekundách (struct timeval),
a modernější syscall clock_gettime(), který vrací zlomkovou část
v nanosekundách (struct timespec). Aby nanosekundové rozlišení
reálně fungovalo, musí mít jádro povolenu podporu high-resolution
timers, což je dnes v distribucích už obecně zapnuto.
V moderním PC hardwaru se obvykle také nějaký vhodný timer najde.
Časovou základnu si kernel vede sice softwarově, ale v okamžiku volání
výše uvedených syscallů provede přesnou interpolaci podle HPET, TSC, "ACPI timer",
Local APIC timer (per-CPU) nebo nějakého dalšího hardwarového časovače,
který si při bootu vyhodnotil jako nejkvalitnější. Dnešní PCčka obsahují
několik různých hardwarových čítačů/časovačů nad rámec klasického PC XT
časovače i8254 nebo-li "PIT", a linuxový kernel ty standardní zná a při
bootu se rozhodne pro jeden z nich podle jakýchsi kritérií - přesněji řečeno,
vybírá si dokonce přinejmenším dva, jeden pro periodický tik časové základny
plánovače a systémových hodin, druhý pro snímání/interpolaci přesných značek mezi tiky.
V souvislosti s příchodem podpory PTP v síťovkách dostalo linuxové jádro také
jednotnou abstrakci pro PHC "device", podporuje dokonce více instancí
PHC zařízení, u kterých si umí držet přehled o vztazích mezi PHC a jeho
souvisejícím síťovým rozhraním. Na PHC lze zavěsit systémovou časovou základnu,
nebo (simultánně) lze PHC využít k hardwarovému značkování paketů při
sniffování wiresharkem/tcpdumpem apod.
Tzn. rozlišení časových značek v dnešním Linuxu je v nanosekundách,
reálná přesnost může být velmi snadno pod 1 mikrosekundou i bez
speciálního hardwaru (nad rámec dnes běžných PC čipsetů),
s vymazlenou časovou základnou PHC zavěšenou na PTP klidně
v jednotkách ns, pokud víte, jak se konkrétního PHC zeptat.
Pokud se týče Meinbergovic proprietárního SDK/API, to je k dispozici pod Windows i v Linuxu.
K využití tohoto API je třeba upravit aplikaci, aby volala Meinbergovic
proprietární funkce namísto standardních systémových = je třeba držet v ruce zdrojáky aplikace.
Aplikace loadne DLL knihovnu (resp. .so knihovnu v Linuxu), která umí pracovat s Meinbergovic
kernel-space ovladačem, a prostřednitvím těchto dvou součástek si nejrychlejším možným
způsobem vezme čas z hardwarové časové základny karty, což jsou v podstatě vysoce
přesné hodiny reálného času. Funguje to pochopitelně nejlíp u vestavbových karet do PCI.
Přesněji řečeno: u klasických modelů PCI32 se komunikace s RTC na kartě provádí
prostřednictvím nějakého MCU (malý procesor), kterému se pošle příkaz a on odpoví.
U nových modelů na sběrnici PCI-e jsou registry RTC přímo mapovány (read-only)
do PCI IOMEM okna, takže zjištění časové značky znamená skutečně minimální časovou
prodlevu. Je pravda, že oproti CPU je PCI-e sběrnice pořád relativně pomalá, takže
volající CPU jádro je po dobu provádění této instrukce zablokováno - s tím se vcelku
nedá nic dělat.
API také nabízí funkce, které vracejí čas interpolovaný pomocí CPU TSC,
synchronizovaný každou sekundu proti hardwaru GPS karty - ty mají mnohem
rychlejší odezvu / větší průchodnost.
Chcete-li vědět víc, tady je k dispozici Meinberg SDK (API):
http://www.meinberg.de/english/sw/sdk.htm
V ZIPovém archivu je EXE instalátor. Pokud Vás zajímá pouze dokumentace,
tak software ani nemusíte instalovat, stačí když z EXE balíku 7zipem vybalíte
jenom .CHM help file. V něm je Meinberg API popsané. Asi nejzajímavější je popis těchto "modulů":
Getting high resolution time stamps
Getting extrapolated high resolution time stamps
Dokumentace je generovaná Doxygenem a trochu neučesaná, ale zároveň
poměrně rozsáhlá a podrobná.
Pokud se týče dolaďování lokální časové základny operačního systému, ať už v Linuxu
(NTPd) nebo pod Windows (NTPd nebo Meinbergovic driver+service): dolaďování časové
základny je v každém případě spojité, zejména nedochází ke skokům dozadu
(běh časové základny je monotónní), ale ani dopředu.
Za normálních okolností se odchylky dorovnávají tak, že softwarová regulační smyčka
na základě statistik rozdílů oproti dostupným zdrojům času jemně dolaďuje nikoli okamžitý
čas, ale *rychlost běhu* časové základny (nějaký dělící poměr). Takže nějaké anomálie
v monotonicitě a spojitosti běhu času se nekonají.
Přechody zimní/letní čas jsou záležitost uživatelského rozhraní, interní hodiny ve Windows
i v UNIXu běží v UTC, a v UTC jsou také zpracovávány časové značky.
Ke skokové změně času dojde přinejhorším při bootu, když má počítač v hardwarovém RTC
úplně nesmyslný čas - dojde k ní ve chvíli, kdy se rozběhne software
zajišťující synchronizaci proti vnějšímu zdroji. Od té chvíle je běh času monotónní.
V některém obslužném softwaru jde nastavit práh pro skokové vs. spojité doladění.
Ke skokovému doladění může dojít v zásadě v jedné ze dvou situací: