Otvaranje novih portova za Javu s javax.comm

Upoznao sam se s paketom klasa javax.comm kad sam otkrio da se koriste u razvojnom kompletu za Java Ring. (Za detalje o javax.comm, pogledajte stupac Java Developer Rinalda Di Giorgia u svibanjskom izdanju JavaWorlda: "Java dobiva serijsku podršku s novim paketom javax.comm.") Tijekom lude navale na JavaOne za uvođenjem programa u svoj prsten, naišao sam na niz problema, od kojih je najmanje važan bio komuniciranje s prstenom. Preuzeo sam distribuciju s Java Developer Connection-a i neuspješno je pokušao koristiti za razgovor s Java Ringom. Kasnije sam otkrio problem s prstenom: nisam imao ispravno instalirane naslijeđene API-je Dallas Semiconductora. Dok je prsten radio, u osnovi sam zaboravio na komunikacijski paket. Odnosno do jednog vikenda prije otprilike mjesec dana, što je polazna točka za ovu priču.

Iz mnogo različitih razloga (uglavnom povezanih s visoko interaktivnim simuliranim okruženjima - na primjer, igrama), primarno računalo u mom "laboratoriju" pokreće Windows 95. Međutim, ovog određenog vikenda više sam se bavio drugim računalom koje je, na mnogo načina, bio otprilike moćan kao Java Ring: Digital Equipment Corporation PDP-8 / e.

PDP-8 je vjerojatno prvo istinsko osobno računalo. Dizajniran krajem 1960-ih i proizveden u relativno visokim količinama 70-ih, PDP-8 mogao je podići jedan pojedinac, napajao se linijskom strujom od 120 volti i koštao je manje od 0,000. Većina tih računala isporučuje se s jednom perifernom opremom: Teletype Model ASR-33 terminal - originalni "TTY" u računalnom žargonu.

Teletype ASR-33 bio je terminal za ispis koji se isporučio s čitačem papirnate vrpce i bušilicom. Da, upravo je papirnata traka, papir širine 1 inča s rupama probušenim u sebi, bio primarni medij za pohranu programa na PDP-8.

PDP-8 je bilo prvo računalo koje sam ikad programirao i zato ima posebno mjesto u mom srcu. Nadalje, uslijed nekih slučajnih okolnosti, bio sam na pravom mjestu u pravo vrijeme i uspio sam spasiti PDP-8 koji će biti odbačen kao smeće. Fotografija moje nagrade prikazana je u nastavku.

Ovog posebnog vikenda, ne tako davno, odlučio sam vratiti PDP-8 u život, makar samo da bih proživio ta dragocjena rana sjećanja i pokazao svojoj kćeri koliko je dobra sa svojim "ospicama starim 133-MHz Pentiumom. "

Oživljavanje jednog klasika simuliranjem drugog

Da bih započeo svoj napor oživljavanja, morao sam unijeti program u PDP-8. Na PDP-8 to se postiže slijedeći postupak u tri koraka:

  1. Pomoću prekidača na prednjoj ploči korisnik "ukucava" kratki program u memoriju magnetske jezgre. Ovaj se program naziva RIM Loader, a svrha mu je učitati drugi program s papirnate trake koji je u formatu Read-in-Mode (RIM).

  2. RIM Loader učitava papirnu traku u RIM formatu. Ova traka sadrži program nazvan BIN Loader, koji može učitati programe s papirnate trake u binarnom (BIN) formatu.

  3. Na kraju pokrenete BIN Loader da biste učitali program koji stvarno želite, a to je na papirnatoj traci u BIN formatu. Joj!

Nakon prolaska kroz ova tri koraka, program koji želite pokrenuti sprema se u memoriju jezgre. Sve što korisnik treba učiniti je postaviti početnu adresu i reći uređaju da "krene".

U mom naporu da oživim stroj, korak 1 nije predstavljao problem, ali korak 2 uključivao je upotrebu čitača papirnate vrpce u Teletypeu - a ja nisam imao Teletype. Naravno, imao sam svoje stolno računalo, pa je logičan korak bio simulirati čitač papirnate vrpce na svom radnom stolu.

S logičkog i programskog stajališta simuliranje čitača papirnate vrpce je trivijalno. Jednostavno čitate datoteku koja sadrži podatke s "vrpce", šaljete je na serijski priključak brzinom od 110 baud (da, samo 10 znakova u sekundi), sve dok datoteku ne iscrpite. Za oko 10 minuta mogao bih napisati program na jeziku C na svom Solaris sustavu ili FreeBSD sustavu koji bi to mogao učiniti - ali, sjetite se, bio sam u sustavu Windows 95, a ne u Unixu.

Od lošeg do ružnog i opet natrag

Znao sam da ovaj program mogu lako napisati na jeziku C, tako da je to moj odabrani jezik. Loš izbor. Doneo sam svoju kopiju Visual C ++ 5.0 i izbacio jednostavni program koji se zove sendtape.c koji je pozivao open()na komunikacijski port. Pokušao sam ga postaviti u RAW način (način u Unixu u kojem operativni sustav ništa ne pokušava protumačiti na serijskom priključku kao korisnički unos), a zatim sam ga pokušao sastaviti. Ups, nema ioctl()funkcije ili ttyfunkcija - nada, zip, zilch!

Nema problema, pomislio sam u sebi: "Na CD-u sam sa svojim C kompajlerom dobio cijelu mrežnu knjižnicu Microsoftovog programera softvera; brzo ću pretražiti ključne riječi 'COM port'."

Pretragom su pronađene mnoge reference na Microsoftov komponentni objektni model (koji se također naziva COM), kao i reference na MSComm. MSComm je klasa C ++ koju Microsoft isporučuje za razgovor sa serijskim priključcima. Pogledao sam primjere i zaprepastio se koliko bi koda bilo potrebno da se izvede tako jednostavna stvar kao što je upisivanje bajtova u serijski port na 110 baud. Sve što sam želio je otvoriti pomračeni serijski priključak, postaviti brzinu prijenosa i strpati nekoliko bajtova - ne stvoriti novu klasu aplikacija poboljšanih serijskom komunikacijom!

Ispred mog monitora sjedio je Blue Dot receptor za moj Java Ring, i pomislio sam u sebi: "Aha! Ljudi iz Dallas Semiconductora smislili su kako razgovarati sa serijskim priključkom na računalu. Pogledajmo što rade. " Nakon pregledavanja izvornog koda tvrtke za Win32, bilo je jasno da razgovor sa serijskim priključcima neće biti jednostavan zadatak.

Java u pomoć

U ovom trenutku svog vikenda razmišljao sam da bih možda odvukao jedan od svojih Unix strojeva u laboratorij kako bih na njemu kodirao program , umjesto da koristim ono što sam već imao. Tada sam se sjetio svog iskustva s Java Ringom i paketom java.comm tvrtke Sun. Odlučio sam umjesto toga nastaviti tim putem.

Što nudi java.comm?

API za komunikaciju Java - ili java.comm - pruža metodu neovisnu o platformi za pristup serijskim i paralelnim priključcima s Jave. Kao i kod drugih Java API-ja poput JFC-a, JDBC-a i Java 3D-a, određena razina indirektnosti prisiljena je na programera da izolira ideju platforme o tome „što je serijski port“ od programskog modela. U slučaju dizajna javax.comm, stavke poput naziva uređaja, koje se razlikuju od platforme do platforme, nikada se ne koriste izravno. Tri sučelja API-ja pružaju pristup serijskim i paralelnim priključcima neovisno o platformi. Ova sučelja pružaju pozive metoda za popis dostupnih komunikacijskih priključaka, upravljanje zajedničkim i ekskluzivnim pristupom lukama i upravljanje određenim značajkama priključaka kao što su brzina prijenosa podataka, generiranje pariteta i kontrola protoka.

Kad sam vidio primjer SimpleWrite.java u dokumentaciji i usporedio njegovih 40 redaka koda sa 150 do 200 redaka koda koje sam gledao u C, znao sam da je rješenje pri ruci.

Apstrakcija na visokoj razini za ovaj paket je klasa javax.comm.CommPort. CommPortKlasa definira vrste stvari koje bi obično učiniti s lukom, koji uključuje dobivanje InputStreami OutputStreamobjekte koji su I / O kanali za luku. TheCommPortklasa također uključuje metode za kontrolu veličina međuspremnika i podešavanje načina na koji se postupa s unosom. Budući da sam znao da ove klase podržavaju protokol Dallas Semiconductor One-Wire (protokol koji uključuje dinamičke promjene brzine prijenosa i potpunu transparentnost bajtova koji se prenose), znao sam da API javax.comm mora biti fleksibilan. Ono što se ugodno iznenadilo bilo je koliko su predavanja bila tijesna: imali su taman dovoljno fleksibilnosti da završe posao i nema više. Malo je bilo nepotrebnog bloatwarea u obliku "praktičnih metoda" ili podrške modemskih protokola kao što su Kermit ili xmodem.

Pratitelj razreda CommPortje javax.comm.CommPortIdentifierrazred. Ova klasa apstrahira odnos između naziva porta na određenom sustavu (to jest, "/ dev / ttya" na Unix sustavima i "COM1" na Windows sustavima) i načina na koji se luke otkrivaju. Statička metoda getCommPortIdentifiersće navesti sve poznate komunikacijske priključke u sustavu; nadalje, addPortNamemetodom možete dodati vlastita imena luka za pseudo komunikacijske priključke .

CommPortKlasa je zapravo sažetak, a ono što ste dobili natrag od pozivanje na openPortu CommPortIdentifierpodrazred CommPortda je bilo ParallelPortili SerialPort. Svaka od ove dvije potklase ima dodatne metode koje vam omogućuju upravljanje samom lukom.

Snaga Jave

Možete raspravljati o stvarnosti „pisati jednom, trčanje bilo gdje” sve što želite, ali ja ću vam reći iz iskustva da za pojedinačnog ili vijčanim čak jednostavnih multithreaded ne-GUI aplikacija, Java je tu . Točnije, ako želite napisati program koji se izvodi na Unix sustavima, Win32 i Mac sustavima i može pristupiti serijskom portu, tada je Java jedino rješenje danas.

Prednost je u tome što je potrebno manje resursa za održavanje koda koji radi na velikom broju platformi - a to smanjuje troškove.

Brojni programi dijele zahtjev da imaju prilično nizak nivo pristupa serijskom portu. Izraz niska razina u ovom kontekstu znači da program ima pristup sučeljima koja mu omogućuju promjenu načina rada u letu i izravno uzorkovanje i promjenu stanja hardverskih pinova za kontrolu protoka. Osim mog PDP-8 projekta, Dallas Semiconductor trebao je koristiti svoja sučelja Blue Dot na serijskim priključcima za razgovor s iButtonom s Javom. Uz to, proizvođači mikroprocesora imaju ocjenjivačke ploče koje koriste serijski priključak za komunikaciju i učitavanje programa. Sve ove aplikacije sada se mogu potpuno i prenosivo napisati na Javi - prilično moćan izraz.

Sva ova moć upravljanja paralelnim i serijskim priključcima glavnog računala dolazi iz biblioteke javax.comm. Davanje Java programerima pristupa lukama otvara potpuno novi skup aplikacija koje ciljaju ugrađene sustave. U mom slučaju, dao mi je mogućnost da svoj TTY emulator čitača papirnate vrpce u potpunosti napišem na Javi.

Kako se možete igrati s tim stvarima?

Da biste dobili kopiju najnovije distribucije javax.comm, prvo se morate prijaviti kao programer na Java Developer Connection (JDC) ako to već niste učinili. (Pogledajte Resurse.) JDC je besplatan i kao član dobit ćete rani pristup Java tečajevima koji će na kraju biti dio konačnog proizvoda.

Go to the Java Communications API section and download the latest javax.comm archive file. Unpack the file and install the shared libraries (yes, the Java virtual machine needs native code to talk to the ports -- fortunately for you, you don't have to write it), and install the comm.jar file. Finally, add the comm.jar file to your CLASSPATH variable.

Once the comm.jar file is stored in the lib directory of your Java installation, and the win32comm.dll is stored in the bin directory of your Java installation, you can compile and run all the examples that come with the download. I encourage you to look them over as there is lots of good information nestled in with the source code.

Where does this leave the PDP-8?

So, what's happened with the PDP-8? I thought you'd never ask! After reading the README document that came with the javax.comm distribution, then scanning the JavaDocs for the javax.comm package, I put together an application class called SendTape. This class simulates a paper-tape reader by opening the serial port and stuffing bytes over it at 110 baud. The code for this class is shown here:

import javax.comm.*; import java.io.*; public class SendTape { static final int LEADER = 0; static final int COLLECT_ADDR = 1; static final int COLLECT_DATA = 2; static final int COLLECT_DATA2 = 3; /* This array holds a copy of the BIN format loader */ static byte binloader[] = { (byte) 0x80,(byte) 0x80,(byte) 0x80,(byte) 0x80, ... (byte) 0x80,(byte) 0x80, }; 

The code fragment above is the first part of the SendTape class. This class begins by implicitly importing all classes in the javax.comm package and the java.io packages. The SendTape class then defines some constants and pre-initializes a byte array to contain the BIN Loader program I mentioned earlier. I included the BIN Loader because it is always needed when initializing the memory of the PDP-8 and I kept losing track of where I had last stored the file containing its image in RIM format. With this crucial paper tape image embedded in the class in this way, I always have the ability to load it with this class.

 /** * This method runs a mini-state machine that gives * a useful human readable output of what is happening * with the download. */ static int newState(int oldState, byte b) { ... } 

Nakon inicijalizacije, imate kod za metodu newState, prikazanu gore, koja prati sadržaj papirnate trake (bilo da se radi o informacijama o adresi ili informacijama o programiranju). Gornja metoda također ispisuje poruku za svako mjesto memorije na PDP-8 koje je inicijalizirano.

Dalje imate mainmetodu koja je prikazana u nastavku; otvara datoteku i čita je. Zatim kôd otvara serijski priključak i postavlja svoje komunikacijske parametre.