DevicesJan Hlavatý
V minulém díle jsme se seznámili s obecnými informacemi o softwarových
zařízeních v systému Amigy devices. V tomto článku si povíme něco bližšího o
dvou z nich - o timer.device, které je schopno měřit čas, a o serial.device,
které ovládá sériový port. Se znalostí těchto dvou zařízení si můžete například
napsat malý prográmek, který inicializuje váš modem. timer.device
Zařízení "timer.device" je určeno k měření časových intervalů. Princip
měření spočívá ve vyplnění délky intervalu v IORequest struktuře a poslání
struktury ke zpracování funkcí DoIO(). Po uplynutí daného intervalu bude
IORequest dokončen a vrácen zpět volajícímu. Zařízení "timer.device" používá
rozšířenou strukturu IO (pozor, ne IOSTD - jen minimální strukturu s položkami
až do IO_ERROR, za kterou následuje speciální struktura TIMEVAL nebo ECLOCKVAL
do které se zapisuje délka časového intervalu v závislosti na použitém způsobu
zadávání) jménem TIMEREQUEST. Struktura TIMEVAL sestává ze dvou longů, první
obsahuje počet sekund (TV_SECS), druhý počet mikrosekund (TV MICRO, rozsah
0-1000!). Struktura ECLOCKVAL je stejně dlouhá jako TIMEVAL, první long (EV_HI)
obsahuje vyšších 32 bitů, druhý (EV_LO) nižších 32 bitů 64-bitové hodnoty. Tato
hodnota vyjadřuje počet tiků interních hardwarových hodin (E-Clock - 709379 Hz u
PAL, 715909 Hz u NTSC verze Amigy). Struktury ECLOCKVAL a TIMEVAL se v
IORequestu překrývají (union, IOTV_TIME). Způsob měření intervalu a interpretace
IOTV_TIME závisí na nastavení UNIT při volání OpenDevice(). Timer.device
obsahuje pět jednotek (UNITS), které měří s různou přesností a jsou vhodné pro
různě dlouhé intervaly:
UNIT_MICROHZ: používá časovače V CIA 8520 které čítají E-Clock. Je vhodný pro
měření krátkých časových intervalů (tak do půl sekundy). Samotný hardware je
poměrně přesný (rozlišení asi 2 mikrosekundy), v hodně zatíženém systému však
přesnost trochu klesá. Tato jednotka používá na IOTV_TIME strukturu TIMEVAL.
UNIT_VBLANK: Používá vblank přerušení. Je vhodný pro měření dlouhých časových
intervalů (přes půl sekundy), rozlišení je asi 1/50 sekundy. Tato unit používá
strukturu TIMEVAL.
UNIT_ECLOCK: Používá stejný hardware a je stejně přesný jako UNIT_MICROHZ, v
IOTV_TIME však používá strukturu ECLOCKVAL.
UNIT_WAITUNTIL: Používá stejný způsob měření jako UNIT_VBLANK, používá strukturu
TIMEREQUEST. Čeká, dokud není systémový čas větší nebo roven hodnotě uvedené v
TIMEVAL.
UNIT_WAITECLOCK: Tato unit funguje podobně jako UVIT_WAITUNTIL, k měření však
používá systémový E-Clock (s přesností a rozlišením jako UNIT_MICROHZ). Současná
hodnota čítače E-Clock je přístupná pomocí speciální "knihovní" funkce
timer.device- viz dále. Knihovní funkce
Kromě normálních příkazů (popsány dále) je u timer.device k dispozici ještě
několik "knihovních" funkcí pro práci s časem a hodnotami TIMEVAL a ECLOCKVAL.
Tyto funkce se volají jako funkce knihoven pomocí offsetů, báze knihovny se
získá po úspěšném volání OpenDevice() z IO_DEVICE.
AddTime(): A0: cílová struktura timeval, A1: zdrojová struktura timeval; tato
funkce přičte k hodnotě uložené v cílové struktuře timeval hodnotu ze zdrojové
struktury timeval. A0 a A1 zůstanou po provedení funkce nezměněny pro další
použití. Lze volat z přerušení. .
CmpTime(): A0: cíl. timeval, A1: zdroj. timeval; Tato funkce porovná dvě hodnoty
timeval a vrací: 0 pokud jsou stejné. -1 pokud je cílová timeval větší než
zdrojová. +1 pokud je cílová timeval menší než zdrojová. A0 a A1 jsou opět
nezměněny, lze volat z přerušení.
GetSysTime(): Tato funkce existuje u OS V36 (2.0) a výše - načte aktuální
systémový čas do struktury TIMEVAL na kterou ukazuje A0. Lze ji volat i z
přerušení.
ReadEClock(): Tato funkce existuje u OS V36 (2.0) a výše - načte aktuální stav
64-bitového čítače E-Clock do struktury ECLOCKVAL na kterou ukazuje A0. Navíc v
D0 vrací frekvenci E-Clock (v Hz). Tímto způsobem lze měřit velmi krátké časové
intervaly, lze ji volat i z přerušení. Tato funkce se používá např. v přerušení
obsluhujícím klávesnici na zajištění minimální délky trvání signálu
potvrzujícího převzetí rawkey kódu od klávesnicového mikroprocesoru. Na začátku
se po převzetí kódu a aktivaci potvrzení načte hodnota E-Clock, přičte se k ní
minimální délka potvrzení a hodnota se schová. Poté se zpracuje došlý kód a
nakonec se zjišťuje, jestli je hodnota E-Clock už vyšší nebo rovna vypočtené.
Nakonec se deaktivuje potvrzení. Při tomto způsobu není potřeba žádný IORequest,
je však vhodný jen pro VELMI krátké intervaly (v popsaném případě něco kolem 700
tiků EClock).
SubTime(): A0: cíl. timeval, A1: zdroj. timeval; Od hodnoty cílového timeval
odečte zdroj. timeval - jinak vše viz AddTime().
U verze OS 1.3 je použití UNIT_MICROHZ nespolehlivé pro velmi krátké intervaly,
pozor na to!
Timer.device má jen tři normální příkazy:
TR_ADDREQUEST: Toto je příkaz používaný pro všechny IORequesty určené pro měření
intervalů. Počká daný časový interval, pak vrátí IORequest. Čekání lze přerušit
pomocí dvojice AbortIO()/WaitIO(). IORequest MUSÍ mít inicializovaný
MN_REPLYPORT (quick-mód je v tomto případě nesmyslný). TR_TIME obsahuje
patřičnou hodnotu dle UNIT.
TR_GETSYSTIME: Tento příkaz načte aktuální systémový čas do timeval struktury v
TR_TIME iorequestu. MN_REPLYPORT iorequestu musí být nastaven. Je zaručeno
neustálé zvyšování syst. času a načtená hodnota je unikátní (nikdy nenačtete
dvakrát za sebou stejný čas - samozřejmě kromě případu nastavení systémového
času zpět) - toho lze využít pro jednoznačnou identifikaci - jak to dělá např.
DOS při formátování disket.
TR_SETSYSTIME: Nastaví systémový čas na hodnotu udanou v TIMEVAL struktuře v
TR_TIME. MN_REPLYPORT iorequestu musí být nastaven. Mimochodem, systémový čas je
tentýž čas který lze nastavovat příkazem "date" nebo v "Time" preferencích. serial.device
Toto softwarové zařízení je určeno k ovládání interního sériového portu
Amigy, prakticky však definuje standard pro ovladače jakýchkoliv sériových portů
připojených k Amize. Jediný rozdíl pak bude ve jménu zařízení a číslu unit.
Zařízení poskytuje systému základní služby spojené se sériovým portem samotný
přenos dat z a do počítače přes sériový port, hardwarový (RTS/CTS) nebo
softwarový (xON/xOFF) handshaking a nastavování základních parametrů hardware
portu jako je například přenosová rychlost. Princip ovládání zařízení je úplně
stejný jako u ostatních devices. Zařízení používá rozšířenou IOSTD strukturu
jménem IOEXTSER, definovanou v include souboru "devices/serial.i": STRUCTURE IOEXTSER, IOSTD_SIZE
ULONG IO_CTLCHAR
ULONG IO_RBUFLEN
ULONG IO_EXTFLAGS
ULONG IO_BAUD
ULONG IO_BRKTIME
STRUCT IO_TERMARRAY,TERMARRAY_SIZE
UBYTE IO_READLEN
UBYTE IO_WRITELEN
UBYTE IO_STOPBITS
UBYTE IO_SERFLAGS
UWORD IO_STATUS
LABEL IO_EXTSER_SIZE Tato struktura by měla být vynulovánu před voláním OpenDevice(). Význam
rozšiřujících položek je následující:
IO_CTLCHAR: Toto jsou v podstatě 4 byte, z nichž první dva obsahují kódy které
se mají používat jako xON a xOFF. To jsou vyhrazené kódy, které se používají pro
softwarový handshaking - umožňují poslat zařízení které vysílá data která
přijímáme požadavek na pozastavení vysílání (například když. nestíháme
zpracovávat). xOFF znamená pozastavit, xON opět obnovit přenos dat. Normální
hodnota xON je 17 a xOFF 19. Pokud používáte xON a xOFF pro handshaking, nesmí
se tyto kódy samozřejmě vyskytovat v přenášených datech.
IO_RBUFLEN: Požadovaná velikost interního bufferu serial.device. Musí být
násobkem 64 byte a minimálně 64. Serial.device zachycuje přicházející data do
svého vlastního bufferu, ze kterého pak data kopíruje do datových bufferů
iorequestů požadujících čtení. Tím se zamezuje případně ztrátě dat, pokud v
daném okamžiku není aktivní žádný požadavek na čtení. Nastavením tohoto
parametru můžete určit velikost tohoto interního bufferu. Naproti tomu při
vysílání dat se přenášená data čtou přímo z datových bufferů iorequestů
požadujících zápis.
IO_EXTFLAGS: Rozšířené příznaky: bit 1: MSPON - aktivace mark-space parity bit
0: MARK - pokud je mark-space parita zapnutu, použít mark
IO_BAUD: Přenosová rychlost přímo v Bd. Platný rozsah je 112-292000, prakticky
použitelná maximální hodnota je něco kolem 38400.
IO_BRKTIME: Délka BREAK signálu v mikrosekundách (viz SDCMD_BREAK)
IO_TERMARRAY: Serial.device umožňuje používat speciální mód čtení dat EOFMODE.
Tento mód umožňuje načítat bloky dat ukončené nějakým speciálním znakem.
Například by bylo možné použít tento mód na načítání řádků textu ukončených
znakem <LF>. V těchto osmi bajtech jsou uloženy všechny kódy, který mají tento
"ukončovací" účinek (EOF kódy). Kódy musí být setříděny od největšího po
nejmenší, všech 8 byte musí být platných - pokud je kódů míň, musí být zbývající
místa vyplněna posledním (nejmenším) kódem. Tyto kódy se používají jen v EOFMODE
módu.
IO_READLEN: Délka znaku pro čtení v bitech (7 nebo 8, obvykle 8)
IO_WRITELEN: Délka znaku pro vysílání v bitech (7 nebo 8, obvykle 8)
IO_STOPBITS: Počet stop-bitů pro čtení (1 nebo 2, obvykle 1)
IO_SERFLAGS: Příznaky:
bit 7: XDISABLED: Zákaz použití xON/xOFF handshakingu
bit 6: EOFMODE: Aktivace EOFMODE - požadavky na čtení jsou ukončovány některým z
EOF kódů
bit 5: SHARED: Umožnění vícenásobného otevření serial.device a jeho sdílení.
Tento flag musí být nastaven již PŘED voláním OpenDevice()!
bit 4: RAD_BOOGIE: Vysokorychlostní mód - vyšší rychlosti je dosaženo vynecháním
testů parity, kontroly BREAK-signálu a zpracování xON/xOFF. Délka znaku musí být
8 bitů a nelze použít interní softwarový handshaking.
bit 3: QUEUEDBRK: Je-li tento flag nastaven, BREAK signál se vyšle až po vyslání
všech dat předaných k vyslání před iorequestem požadujícím vyslání BREAK
signálu. V opačném případě, je BREAK generován okamžitě a po jeho skončení se
pokračuje ve vysílání.
bit 2: 7WIRE: Aktivuje sedmidrátové propojení RS232 (RxD, TxD, RTS, CTS. DTR,
DSR, GND) - tento flag aktivuje používání hardwarového handshakingu. Tento flag
musí být nastaven PŘED voláním OpenDevice()! Navíc, aby byl tento mód aktivován,
MUSÍ být v okamžiku otevření serial.device aktivní signál DSR. V opačném případě
se tento mód neaktivuje! Z tohoto důvodu je třeba např. nastavit modem tak, aby
udržoval DSR stále aktivní. V opačném případě nebude fungovat RTS/CTS hardwarový
handshaking!
bil 1 : PARTY_ODD: Parita - 0 = sudá, 1 = lichá
bit 0: PARTY_ON: Aktivace parity
IO_STATUS: Sem jsou vyplňovány stavové informace příkazem SDCMD_QUERY. Jedná se
zejména o čtení stavu signálů RS-232 a o detekci některých stavů (např. BREAK
nebo hardwarové přetočení) Význam bitů je následující:
bit 0: rezervován
bit 1: rezervován
bit 2: RI (ring indicator) - aktivní v 1
bit 3: DSR - aktivní v 0
bit 4: CTS - aktivní v 0
bit 5: CD (carrier detect) - aktivní v 0
bit 6: RTS - aktivní v 0
bit 7: DTR - aktivní v 0
bit 8: 1 = detekováno hardwarové přetočení bitů
bit 9: 1 = byl vyslán BREAK signál
bit 10: l = byl přijat BREAK signál
bit 11: vysílání pozastaveno (xOFF)
bit 12: příjem pozastaven (xOFF)
bit 13-15: rezervováno Při otevření serial.device musí být již vyplněny bity SHARED a 7WIRE v
IO_SERFLAGS. Parametry jako je rychlost přenosu nebo počet stop-bitů jsou při
otevření vyplněny implicitními hodnotami - v případě serial.device jsou to
hodnoty nastavené v serial preferencích. Po otevření device lze všechny tyto
parametry změnit speciálním příkazem.
Serial.device podporuje následující příkazy
CMD_CLEAR: Vymaže všechny dosud přijaté znaky z interního bufferu.
CMD_FLUSH: Odstraní všechny čekající iorequesty ze serial.device. Právě
probíhající iorequesty nejsou ovlivněny.
CMD_READ: Načte počet znaků specifikovaný v IO_LENGTH z interního bufferu do
bufferu jehož adresa je v IO_DATA. Pokud je k dispozici dostatečný počet znaků,
iorequest může být okamžitě dokončen v QUICK módu. V případě chyby obsahuje
IO_ACTUAL počet znaků načtených než se chyba vyskytla.
CMD_RESET: Přeruší všechny iorequesty a inicializuje hardware sériového portu,
nastaví implicitní hodnoty u všech parametrů.
CMD_START: Obnoví přenos pozastavený pomocí xOFF vysláním xON.
CMD_STOP: Pozastaví přenos vysláním xOFF.
CMD_WRITE: Vyšle data z bufferu na nějž ukazuje IO_DATA na sériový port. Délka
dat je předávána v IO_LENGTH. Pokud je délka nastavena na -1, konec dat je
označen nulovým bajtem (0) podobně jako u C-řetězců.
SDCMD_BREAK: Vyšle signál BREAK. Toho je dosaženo aktivováním datové linky na
delší časový úsek (asi 2.5 sekundy).
SDCMD_QUERY: Umožňuje zjištění stavových informací - vyplní stavově bity v
IO_STATUS a do IO_ACTUAL - uloží aktuální počet znaků v přijímacím bufferu
serial.device.
SDCMD_SETPARAMS: Umožňuje nastavit parametry - nastavení serial.device je
změněno podle hodnot dodaných v iorequestu. Flagy EOFMODE a QUEUEDBREAK nemusí
být měněny tímto příkazem - stačí je nastavit v odpovídajícím iorequestu.
Většinu parametrů nelze měnit je-li zrovna aktivní nějaký iorequest.
Doporučený postup při čtení dat ze sériového portu je následující:
1. Pomocí SDCMD_QUERY zjistit počet znaků v bufferu.
2. Pokud jsou v bufferu nějaké znaky, načíst je pomocí DoIO( ) a CMD_READ a
pokračovat bodem 1.
3. Pokud v bufferu znaky nejsou, pomocí BeginIO() aktivovat asynchronní
požadavek na čtení jednoho znaku. Poté co znak dostanete, pokračovat bodem 1.
Před uzavřením serial.device pomocí CloseDevice() je nezbytné přerušit všechny
aktivní iorequesty pomocí AbortIO()/WaitIO()! Vytlačiť článok
Pozn.: články boli naskenované ako text a preto obsahujú aj zopár chýb. Taktiež neručíme za zdrojové kódy (Asm, C, Arexx, AmigaGuide, Html) a odkazy na web. Dúfame, že napriek tomu vám táto databáza dobre poslúži.
Žiadna časť nesmie byť reprodukovaná alebo inak šírená bez písomného povolenia vydavatela © ATLANTIDA Publishing
none
|