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

Přesnost synchronizace interní časové základny analogových přijímačů DCF77 firmy Meinberg vůči UTC činí cca 100 us. 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ší. I ty nejjednodušší přijímače 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.
Přijímače GPS mají přesnost interní časové základny cca mikrosekundu proti UTC (za běžných provozních podmínek spíš na úrovni 100 ns). 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 některých 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-MQ 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 3 řá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 vteřin až jednotky minut.

Prakticky shodnou přesnost, jako interní 10MHz krystalový oscilátor přijímače, má vnější výstup PPS (obdélník, hrana jednou za vteřinu, délka pulzu 200 ms) a další 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. Případně "v průmyslu" přes pulzní signály, IRIG nebo třeba generovaný signál DCF77.

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 10 us (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, Meinbergové se o Windows vyjadřují poměrně skepticky.
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ý.
Přes LAN pod Windows je přesnost opět omezena granularitou časových značek, která je pod NT/2k/XP dána granularitou plánovače (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 (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é před pár lety povstal Precision Time Protocol (PTP). Vyžaduje speciální hardware na klientu i serveru (= neběhá po standardních síťovkách), pro optimální přesnost (desítky/stovky ns) i speciální switche. Ale 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í kartu, která funguje jako "PTP přijímač" (a poskytne podobné časoměrné služby, jako GPS přijímač v podobě PCI karty).

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.

V Linuxu se dají časové značky zjišťovat nejsnáz asi voláním GetTimeOfDay. Jádro vrací datový typ "struct timeval", který obsahuje dva membery: vteřiny od "počátku" (Epoch) a zlomek vteřiny v mikrosekundách. Časovou základnu si kernel vede sice softwarově, ale v okamžiku volání tohoto syscallu 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.

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