Zdroje času od firmy Meinberg - přesnosti na různých rozhraních / vrstvách / technologiích

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í:


Takže jsme v situaci, kdy GPS, DCF77, NTP a PTP o přestupných sekundách vědí a umí s nimi pracovat, ale lokální časové základny OS přestupnou sekundu neuznávají - a je třeba je doladit buď skokem, nebo "rozmáznutím". Což se projeví chybou v logu a třeba pár desítkami minut nepřesnosti (nebo diskontinuitou v délce 1s).