Aplikace systému Control Web používá název kanály pro datové elementy (o datových elementech se dočtete v kapitole Datové elementy a výrazy, které mají vztah k reálným snímačům nebo řídicím prvkům. Podle takto definovaného směru (je-li kanál připojen na snímač nebo řídicí prvek) se rozlišují kanály vstupní (určené k měření) a výstupní (určené k zápisu dat do technologie).
Vstupní kanály primárně existují v technologii a aplikace používá jen jejich obraz. Výstupní kanály naopak "vznikají" v aplikaci a technologie, která data z výstupních kanálů používá, pracuje závisle. Aby byla zaručena vzájemná koherence hodnot v technologii a aplikaci, musejí být kanály přenášeny — komunikovány jednou do aplikace a jednou do technologie. Směr, jakým jsou kanály komunikovány, je důležitý pro základní obsluhu komunikace — vstupní kanál je v aplikaci pouhým obrazem a jeho měření proto musí řízeně sledovat, jak a jestli se jej podařilo z technologie přenést; zatímco výstupní kanál je správný v aplikaci a klade na zápis menší nároky — jestli a jak se hodnota dostane do technologie — s určitou nadsázkou — již není věcí aplikace.
Zároveň je však komunikační část aplikace navržena symetricky, a i přes zřetelný významový rozdíl vstupních a výstupních kanálů je možné shodně sledovat jak průběh měření tak průběh zápisu. Aplikace (neboli přístroje) používá pro komunikaci (souhrnný název pro měření i zápis) jednoho mechanizmu a obsluha kanálů obou směrů je (na první pohled) shodná.
Aplikace reálného času při komunikaci pečlivě váží, který kanál bude v konkrétním časovém kroku jádra potřebovat (o časovém kroku jádra a časování vůbec se dočtete v kapitole Časování aplikací reálného času. Rozhodování, který kanál změřit a který ne, provádí jádro ve spolupráci s přístroji, které samy nejlépe vědí, jaké kanály budou při své aktivaci potřebovat. Přístroje s procedurami a časovače navíc dokáží s jádrem komunikovat složitěji a jednotlivé potřebné kanály jsou tak měřeny postupně (odpovídající mechanizmus časování je přerušovaná aktivace přístroje) podle postupně se vyvíjejícího běhu přístroje.
Časový krok jádra je elementární jednotka běhu aplikace, a je proto nutné zaručit, aby během něj pracovaly všechny přístroje se shodnými hodnotami kanálů. V opačném případě by dva grafy shodně časované ukázaly různé hodnoty kanálů, a to je jistě situace nepřípustná. Každý vstupní kanál je proto v jednotlivém časovém kroku jádra měřen pouze jedenkrát, a to i v případě, že je přístroji požadován (kvůli přerušované aktivaci) vícekrát.
Bylo by všechno příliš jednoduché, kdyby neexistovaly výjimky. Vstupní kanály během jednoho kroku jádra mohou nabýt dvou hodnot v případě, že jejich komunikace doběhla zpožděně až během aktivace přístrojů. První hodnota vstupního kanálu je stará (z některého předcházejícího časového kroku), druhá se potom v kanále objeví během přerušení aktivace, byl-li kanál úspěšně doměřen. Dvojí hodnota kanálu se nikdy nevyskytne v časových krocích, které doměří všechna data před vypršením komunikační prodlevy — o prodlevách pojednává následující oddíl této kapitoly.
Odlišným způsobem se pracuje s výstupními kanály. Přístroje během svých aktivací mohou výstupní kanál libovolně nastavovat (a musí tak činit, jinak by aplikace nemohla vůbec nic ovládat), přičemž je přirozené, že v jednom časovém kroku může jeden kanál zapisovat více přístrojů. Jádro všechny požadavky respektuje a hodnota výstupního kanálu se proto během jednoho časového kroku jádra může měnit. Výstupní kanál se v tomto ohledu chová velice podobně, jako proměnná, a může být během jednoho časového kroku několikrát přepsán. Po dokončení aktivací přístrojů je tudíž do technologie zapsána poslední hodnota výstupního kanálu.
Výstupní kanály mohou být během jednoho časového kroku jádra nejen několikrát přístroji zapsány, ale také několikrát komunikovány. Způsobuje to mechanizmus přerušované aktivace přístrojů, který musí během jednotlivých přerušení kromě měření nových vstupních kanálů také zapisovat kanály výstupní, neboť jejich zapsání může ovlivnit bezprostředně následující měření — vše (měření i zápis) se přitom odehraje během jednoho přerušení aktivace.
Výsledkem je důležitý rozdíl mezi vstupními a výstupními kanály: vstupní kanály jsou během jednoho kroku měřeny jen jednou a mohou tak mít jen jednu hodnotu, výstupní kanály jsou během jednoho kroku potenciálně několikrát upravovány a také několikrát komunikovány.
Souhrnný průběh časového kroku z pohledu vstupních kanálů je následující:
Souhrnný průběh časového kroku z pohledu výstupních kanálů je následující:
Všimněte si, že se u výstupních kanálů nikde nehovoří o ukončení vzniku požadavků (jako u vstupů). Tato vlastnost je přímým důsledkem okamžitých reakcí ovládacích prvků na uživatelské zásahy. Stisk tlačítka (nebo jiná podobná akce) může v principu nastat v jakémkoli časovém okamžiku, bez sebemenší vazby na časový krok jádra. Jádro proto zpracovává všechny požadavky na zápis kanálů asynchronně. Pokud se okamžik asynchronního zápisu na kanál vyskytne během nějakého časového kroku jádra, je požadavek přiřazen k normálním — synchronním zápisům (zápisům uskutečněným během aktivací) a je vyřízen spolu s nimi. Požadavek se pouze přidá k existujícím.
Pokud však asynchronní zápis vznikne mimo časový krok jádra, musí jádro provést mimořádný časový krok, ve kterém se uskuteční pouze komunikace asynchronně vzniklých požadavků. Je proto možné navrhnout a zkonstruovat aplikaci, která nebude mít žádné časované přístroje — jádro proto nikdy nebude periodicky spuštěno, aby aktivovalo přístroje — a stále bude možné zcela normálně zapisovat na výstupní kanály. To je další důležitý rozdíl mezi vstupními a výstupními kanály — požadavek na měření vždy vychází z aktivovaného přístroje, a je proto vždy synchronní, zatímco požadavek na zápis může být asynchronní, neboť může vzniknou v důsledku uživatelského zásahu.
Kromě vstupních a výstupních kanálů existují také kanály obousměrné. Obousměrné kanály jsou kombinací vstupního a výstupního kanálu a systém se k nim chová podle situace, v níž jsou použity. Obousměrný kanál použitý jako vstup bude měřen, obousměrný kanál použitý jako výstup bude zapisován. Používají-li se obousměrné kanály v jednom kroku jádra současně jako vstupní i výstupní, může nastat takzvaný překryv komunikace, kdy buď později dokončené měření přepíše předchozí hodnotu připravenou k zápisu nebo kdy zápis do kanálu přepíše aktuálně změřenou hodnotu. Jádro pro obousměrné kanály nedefinuje žádná dodatečná pravidla, a proto vždy "vyhrává poslední", ať to již je dokončené měření nebo požadavek na zápis. Vznikne-li překryv, je možné, že aplikace může pracovat s hodnotou, kterou nezměřila (protože ji překryl zápis hodnoty jiné) nebo že se do technologie zapíše hodnota, která nebyla zapsána (protože ji překryla hodnota z později dokončeného měření). Obousměrné kanály je proto třeba používat obezřetně a pokud není jejich použití skutečně nutné, je vhodnější používat kanály jednosměrné.
Veškerá komunikace kanálů aplikace probíhá pomocí ovladačů. Kanály jsou datové elementy aplikace, ovladače potom samostatné komponenty (malé samostatné programy), které realizují přenášení kanálů z a do technologie. Logika komunikací, tedy kdy a jaký kanál se má měřit nebo zapisovat, je součástí jádra aplikace, ovladač je jen prostředník, který požadavky aplikace vyřizuje a transformuje je do podoby, které rozumí snímač nebo řídicí prvek.
Každý ovladač je spjat s nějakým "svým" zařízením, se kterým dokáže komunikovat. Existují také ovladače, které nepatří "k zařízení" ale "k protokolu", a je proto možné je nasadit ke komunikaci s mnoha různými zařízeními. Obecně vzato, ovladač vždy komunikuje nějakým protokolem — i třeba zápis a čtení dat z měřicí karty zasunuté přímo v počítači je řízen protokolem — i když velmi jednoduchým. Ovladač tedy rozumí svému protokolu a je pomocí něj schopen předávat vstupně/výstupnímu zařízení požadavky aplikace.
Ovladač je obyčejně pomocí souboru s parametry (o souborech hovoří kapitola Soubory systému Control Web) nastaven na určitou množinu dat — vnitřních kanálů — které odpovídají nějakým způsobem datům přímo v techologickém zařízení. Každý vnitřní kanál má své číslo — číslo kanálu v ovladači — které se používá při definici kanálu v aplikaci. Pomocí tohoto čísla tedy dochází k logickému propojení pojmenovaného kanálu — datového elementu s kanálem — částí ovladače. Číslo kanálu v ovladači je základní informace, která se při výměně dat mezi jádrem a ovladačem používá k rozlišení kanálu, a každý požadavek jádra směrovaný k ovladači je proto tímto číslem vybaven.
Výměna dat mezi jádrem a ovladačem je při čtení i zápisu velmi podobná. Protokol těchto výměn je v obou případech shrnut do tří významově shodných kroků, které jsou realizovány pomocí pěti (nebo čtyř) procedur.
Při čtení dat (měření) používá jádro tyto procedury ovladače (všechny procedury kromě InputRequestCompleted zpracovávají jeden kanál a všechny proto mají v jednom svém parametru jeho číslo):
Při zápisu dat (měření) používá jádro tyto procedury ovladače (všechny procedury kromě OutputRequestCompleted zpracovávají jeden kanál a všechny proto mají v jednom svém parametru jeho číslo):
Mechanizmy vstupní i výstupní komunikace jsou pevnou specifikací a ovladač je musí dodržet, jinak systém nemůže zaručit správný běh aplikace. Existuje jedna situace, kdy ovladač i při (formálním) splnění požadavků může pracovat chybně. Chyba ovladače vznikne tehdy, potvrzuje-li ovladač měření i zápisy pomocí procedur InputFinalized a OutputFinalized bez ohledu na stav komunikace. Například, ovladač komunikující s průmyslovým automatem po sériové lince je téměř vždy jádrem donucen vrátit se z procedur s hodnotou false, neboť po sériové lince data okamžitě změřit nelze. Pokud ovladač přesto vrací v této situaci systematicky hodnotu true, tak podvádí.
Popisované chování je chybné, neboť ovladač předstírá, že se komunikace vyřeší ihned — a aplikace v takové situaci nemůže čekat na výsledek komunikace s použitím prodlev a nemá možnost komunikaci řídit. Kvůli ovladači potom aplikace nedokáže správně (předpovídatelně a podle specifikací systému) komunikovat.
V některých speciálních případech je popsané chybné chování žádoucí, jedná se však vždy o nestandardní způsoby komunikace (například určité módy DDE komunikace). Ovladače, které se takto chovají, by měly mít tuto odchylku dobře popsánu ve své dokumentaci, aby se nemohla stát zdrojem nedorozumění.
Průběh komunikace kanálu je velmi přesně signalizován pomocí obsahu atributu status. Atribut je v aplikaci kdykoli k dosažení, takže je možné zjistit momentální stav každého kanálu (o jiných atributech se můžete dočíst v kapitole Datové elementy a výrazy). Typicky (avšak řídce) se stavy kanálů používají při řízené komunikaci, která je popsána v kapitole Časování aplikací reálného času. Stavy kanálu jsou reprezentovány jednotlivými bity atributu status, takže k jejich testování s výhodou použijete bitových funkcí, zejména pak funkci bitget (funkce je popsána v kapitole Datové elementy a výrazy).
Pro oba směry komunikace jsou definovány celkem čtyři stavy kanálů (u jména stavu je vždy v hranatých závorkách číslo bitu, které je třeba použít v parametru funkce bitget):
Povšimněte si, že stavy stWaitACK a stTimeout se vylučují se stavy stError a stACKed a nikdy nemohou být aktivní současně. Stavy stWaitACK a stTimeout mohou být současně aktivní za situace, kdy vznikl nový požadavek na komunikaci a starý ještě nebyl dokončen. Vzhledem k rozdílu chování vstupních a výstupních kanálů je současný výskyt těchto bitů možný pouze u výstupních kanálů, neboť u vstupních kanálů nikdy není zahájena nová komunikace před dokončením komunikace předchozí.
Jádro a ovladač si navzájem vyměňují hodnoty buď pomocí procedury ovladače GetInput (GetInput2) v případě měření a nebo pomocí procedury ovladače OutputRequest (OutputRequest2) v případě zápisu. V obou případech je nutné do ovladače zapisovat (a z něj číst) kanály všech dostupných datových typů, a je proto třeba, aby existoval nějaký univerzální způsob, jak toho dosáhnout.
Systém Control Web definuje pro přenos hodnot (jakýchkoli hodnot, ne pouze kanálů, ale i proměnných a externích dat) pomocnou datovou strukturu s následující definicí (použit je zápis jazyka C):
typedef char typeString255[255]; struct TValue { // Value storage struct { unsigned Type; union { // switch (Type) char ValBoolean; // vtBoolean unsigned char ValShortCard; // vtShortCard unsigned short ValCardinal; // vtCardinal unsigned ValLongCard; // vtLongCard signed char ValShortInt; // vtShortInt signed short ValInteger; // vtInteger signed ValLongInt; // vtLongInt float ValReal; // vtReal double ValLongReal; // vtLongReal typeString255 *ValPString; // vtPString struct { // vtBuffer unsigned char BType; unsigned short BLen256; void *PBuffer; }; }; }; };
Všechny výměny dat v aplikaci probíhají s použitím tohoto typu. Položka Type obsahuje vždy jednu z hodnot vtBoolean..vtBuffer a určuje tak, jaká data záznamu jsou platná (definici použitých konstant, stejně jako definice jiných typů, které se používají při výměně dat s ovladačem obsahuje kapitola Rozhraní ovladačů pro Control Web). Datové typy obsáhnuté typem TValue ekvivalentně odpovídají datovým typům dostupným v aplikaci. Popis těchto typů včetně jejich paměťové náročnosti najdete v kapitole Datové elementy a výrazy.
Pro práci s daty ve formátu TValue platí tři jednoduchá pravidla:
Hovoří se o datových typech kanálů, strukturách pro jejich přenos, ale jak se typ kanálu přiřazuje? Celkem existují tři místa, která s typem kanálu souvisejí:
Kolize typů, popsaná v prvním pravidle o práci s typem TValue proto nastane, neodpovídají-li si navzájem parametrický soubor a definice kanálu (případně soubor '*.dmf', neboť bez souladu definice kanálu a '*.dmf' souboru se aplikaci nepodaří ani přeložit).
Kanály číselných typů jsou uvnitř jádra uloženy v podobě odpovídající jejich typu. V této podobě se také hodnoty všech kanálů dostávají protřednictvím funkcí GetInput a OutputRequest do ovladače. Při předávání hodnot do aplikace (přístrojům) [při ukládání výsledků přístrojů do jádra] dochází ke konverzi hodnot na dlouhé reálné (desetinné) číslo [z reálného čísla na typ kanálu]. Konverze urychluje výpočty v běžící aplikaci, neboť veškeré výpočty výrazů probíhají v reálných číslech. O výpočtech výrazů a číselných datových typech se dočtete také v kapitole Datové elementy a výrazy.
Ovladač můžete navrhnout několika způsoby v závislosti na typu zařízení, se kterým ovladač komunikuje. Zařízení je možné rozdělit na dvě velké skupiny — "blízká" zařízení, se kterými je možno data vyměňovat okamžitě, a "daleká" zařízení, která k poskytnutí a přijetí dat potřebují jistý čas. Těmto dvěma základním skupinám také odpovídají dvě základní strategie návrhu ovladače.
První skupina blízkých a rychlých zařízení (to jsou například měřicí karty zasunuté přímo v počítači) poskytuje hodnoty okamžitě, a ovladač proto může pracovat jen jako prodloužená ruka jádra aplikace. Hodnoty jsou při měření čteny přímo ze zařízení a bezprostředně vraceny jádru, při zápisu ovladač data okamžitě předá zařízení. Taková komunikace neobsahuje žádná zdržení a ovladač proto nemusí mít žádný výkonný kód, který by na pozadí řešil paralelně probíhající komunikaci. Ovladače této třídy jsou velmi jednoduché a je možné je vytvořit ve velice krátké době.
Druhá skupina ovladačů zařízení, s nimiž se musí komunikovat, je složitější. Komplikace způsobuje zpoždění, které nutně vzniká při přenosu dat po jakýchkoli komunikačních linkách (zpoždění vzniká i na 100MBps lokální síti, a i přesto, že je toto zpoždění o několik řádů menší než zpoždění na sériové lince, je stále natolik velké, že počítač brzdí). Ovladač musí jednak reagovat na požadavky aplikace a jednak musí průběžně vyřizovat komunikaci se zařízením. Komunikace se zařízením přitom běží zcela nezávisle na aplikaci a jejím časování, a ovladač proto musí pracovat samostatně bez vazby na systém Control Web. Aby bylo možné takovou činnost realizovat, musí mít ovladač svůj samostatný prováděcí tok (thread), který bude komunikaci na pozadí podle potřeb zajišťovat. Ovladače této třídy jsou obecně složitější, protože musejí jednak umět komunikační protokol svého zařízení (protokoly bývají občas velmi komplikované) a jednak musejí pracovat nezávisle (ve svém toku), což vyžaduje větší programátorskou obezřetnost (o prováděcích tocích se můžete dočíst v kapitole Co to jsou procesy a prováděcí toky).
Oba přístupy k návrhu ovladače je možné shrnout následovně:
V určitých speciálních případech je možné, aby se ovladač choval podle obou vzorů najednou. Komunikace probíhá složitějším způsobem (na pozadí) ale procedury InputFinalized a OutputFinalized vracejí vždy hodnotu true. Pokud není toto chování ovladače zapnuto uživatelem, nebo není jinak dobře zdůvodněno, je považováno za chybné, protože znemožňuje aplikaci řízení komunikace. Programování ovladače s touto chybou je jednodušší, než programování ovladače pracujícího plně podle druhého vzoru — chybný ovladač nemusí obsahovat logiku obsluhování potvrzení komunikace kanálu. K vytvoření chybného ovladače je nutné vynaložit méně práce, což může k takovému řešení svádět. Výsledkem menšího množství práce však bude špatný ovladač.