javax.commを使用してJavaへの新しいポートを開く

Javaリングの開発キットで使用されていることを発見したとき、私はクラスのjavax.commパッケージを紹介されました。(javax.commの詳細については、リナルド・ディ・ジョルジョの参照Java開発者の月号にコラムをJavaWorld:「Javaは新しいjavax.commパッケージでシリアルサポートを取得します。」)JavaOneでプログラムをリングに取り込もうと急いでいるときに、さまざまな問題が発生しました。特に、リングとの通信でした。 Java Developer Connectionからディストリビューションをダウンロードし、それを使用してJavaリングと通信しようとしましたが失敗しました。後で、リングの問題を発見しました。ダラスセミコンダクタのレガシーAPIが正しくインストールされていませんでした。リングが機能しているので、私は基本的に通信パッケージを忘れていました。つまり、この物語の出発点である約1ヶ月前のある週末まで。

さまざまな理由で(主にゲームなどの高度にインタラクティブなシミュレーション環境に関係している)、私の「ラボ」のプライマリコンピューターはWindows 95を実行しています。しかし、この特定の週末には、別のコンピューターに関心がありました。多くの点で、Java Ringとほぼ同じくらい強力でした:Digital Equipment Corporation PDP-8 / e。

PDP-8は間違いなく最初の真のパーソナルコンピュータでした。1960年代後半に設計され、70年代に比較的大量に生産された、PDP-8は、1人の個人で持ち上げることができ、120ボルトの線電流で駆動され、コストは0,000未満でした。これらのコンピューターのほとんどには、テレタイプモデルASR-33端末という単一の周辺機器が付属しています。これはコンピューター用語の元の「TTY」です。

ASR-33テレタイプは、紙テープリーダーとパンチが付属した印刷端末でした。そうです、PDP-8のプログラムの主要な記憶媒体は、紙テープ、穴が開けられた1インチ幅の紙でした。

PDP-8は私が初めてプログラムしたコンピューターであり、それゆえ私の心の中で特別な場所を持っています。さらに、いくつかの偶然の事情により、私は適切なタイミングで適切な場所にいて、ジャンクとして廃棄される予定だったPDP-8をなんとか保存することができました。私の賞品の写真を以下に示します。

少し前のこの特別な週末に、私はPDP-8を復活させることにしました。それは、それらの貴重な初期の思い出を追体験し、娘が「ミーズリーオールド133MHzペンティアム」でどれだけ優れているかを示すためだけです。 「」

別のクラシックをシミュレートして、あるクラシックを復活させる

リバイバルの努力を始めるために、私はプログラムをPDP-8に入れなければなりませんでした。PDP-8では、これは3段階のプロセスに従うことで実現されます。

  1. ユーザーはフロントパネルのスイッチを使用して、短いプログラムを磁気コアメモリに「キー入力」します。このプログラムはRIMローダーと呼ばれ、その目的は、Read-in-Mode(RIM)形式の紙テープから別のプログラムをロードすることです。

  2. RIMローダーは紙テープをRIM形式でロードします。このテープには、BINローダーと呼ばれるプログラムが含まれています。このプログラムは、紙テープからバイナリ(BIN)形式でプログラムをロードできます。

  3. 最後に、BINローダーを実行して、BIN形式の紙テープにある本当に必要なプログラムをロードします。ふぅ!

これらの3つの手順を実行すると、実行するプログラムがコアメモリに保存されます。ユーザーが行う必要があるのは、開始アドレスを設定し、マシンに「実行」するように指示することだけです。

マシンを復活させるための私の努力では、ステップ1は問題ありませんでしたが、ステップ2はテレタイプでの紙テープリーダーの使用を含みました-そして私はテレタイプを持っていませんでした。もちろん、私デスクトップコンピュータを持っていたので、論理的な手順は、デスクトップで紙テープリーダーをシミュレートすることでした。

論理的およびプログラミングの観点から、紙テープリーダーのシミュレーションは簡単です。「テープ」からのデータを含むファイルを読み取り、ファイルがなくなるまで、110ボー(はい、1秒あたりわずか10文字)でシリアルポートに送信するだけです。SolarisシステムまたはFreeBSDシステムでCでプログラムを約10分で作成できましたが、UnixシステムではなくWindows95システムを使用していたことを忘れないでください。

悪いものから醜いものへ、そしてまた戻ってきます

私はこのプログラムをCで簡単に書くことができることを知っていたので、それが私の選択した言語でした。下手な選択。Visual C ++ 5.0のコピーを起動open()し、通信ポートを呼び出すsendtape.cという単純なプログラムを作成しました。それをRAWモード(オペレーティングシステムがシリアルポート上の何もユーザー入力として解釈しようとしないUnixのモード)に設定してから、コンパイルしようとしました。おっと、ioctl()関数はありませんtty-nada、zip、zilch!

問題ありません。「Microsoftソフトウェア開発者のネットワークライブラリ全体がCコンパイラでCDに収録されています。「COMポート」というキーワードで簡単に検索します。」

検索の結果、Microsoftコンポーネントオブジェクトモデル(COMとも呼ばれます)への参照と、MSCommへの参照が多数見つかりました。 MSCommは、Microsoftがシリアルポートと通信するために提供するC ++クラスです。私は例を見て、110ボーでシリアルポートにバイトを書き込むなどの単純なことを行うのにどれだけのコードが必要になるかに驚いた。私がやりたかったのは、ダーンシリアルポートを開き、ボーレートを設定し、数バイト下に詰め込むことだけでした。新しいクラスのシリアル通信拡張アプリケーションを作成するのではありません。

モニターの前に座っていたのは、JavaリングのBlue Dot受容体でした。「ああ、ダラスセミコンダクターの人々は、PCのシリアルポートと通信する方法を見つけました。彼らが何をしているのか見てみましょう。 「」Win32用の会社のソースコードを調べた後、シリアルポートとの通信が簡単な作業ではないことは明らかでした。

救助するJava

週末のこの時点で、すでに持っていたものを使用する代わりに、プログラムをコーディングするために、Unixマシンの1つをラボにドラッグするのではないかと考えていました。次に、SunのJavaRingとjava.commパッケージでの経験を思い出しました。私は代わりにその道を追求することにしました。

java.commは何を提供しますか?

Java Communications API(またはjava.comm)は、Javaからシリアルポートとパラレルポートにアクセスするためのプラットフォームに依存しない方法を提供します。 JFC、JDBC、Java3Dなどの他のJavaAPIと同様に、プログラマーは、プラットフォームの「シリアルポートとは何か」という概念をプログラミングモデルから分離するために、一定レベルの間接参照を強制されます。 javax.commデザインの場合、プラットフォームごとに異なるデバイス名などのアイテムが直接使用されることはありません。 APIの3つのインターフェースは、シリアルポートとパラレルポートへのプラットフォームに依存しないアクセスを提供します。これらのインターフェイスは、使用可能な通信ポートを一覧表示し、ポートへの共有および排他的アクセスを制御し、ボーレート、パリティ生成、フロー制御などの特定のポート機能を制御するためのメソッド呼び出しを提供します。

ドキュメントでSimpleWrite.javaの例を見て、その40行のコードをCで記述しようとしていた150〜200行のコードと比較したところ、解決策が手元にあることがわかりました。

このパッケージの高レベルの抽象化はクラスjavax.comm.CommPortです。このCommPortクラスは、ポートで通常行うことの種類を定義します。これには、ポートのI / Oチャネルである取得InputStreamおよびOutputStreamオブジェクトが含まれます。ザ・CommPortクラスには、バッファサイズを制御し、入力の処理方法を調整するためのメソッドも含まれています。これらのクラスがDallasSemiconductor One-Wireプロトコル(ボーレートの動的な変更と転送されるバイトの完全な透過性を伴うプロトコル)をサポートしていることを知っていたので、javax.commAPIは柔軟でなければならないことを知っていました。嬉しい驚きとして来たのは、クラスがどれほどタイトだったかということでした。彼らは仕事を成し遂げるのに十分な柔軟性を持っていて、それ以上はありませんでした。 「便利な方法」またはKermitやxmodemなどのモデムプロトコルのサポートという形で不要なブロートウェアはほとんどまたはまったくありませんでした。

A companion class to CommPort is the javax.comm.CommPortIdentifier class. This class abstracts the relationship between how a port is named on a particular system (that is, "/dev/ttya" on Unix systems, and "COM1" on Windows systems) and how ports are discovered. The static method getCommPortIdentifiers will list all known communication ports on the system; furthermore, you can add your own port names for pseudo communication ports using the addPortName method.

The CommPort class is actually abstract, and what you get back from an invocation of openPort in the CommPortIdentifier is a subclass of CommPort that is either ParallelPort or SerialPort. These two subclasses each have additional methods that let you control the port itself.

The power of Java

You can argue about the reality of "write once, run anywhere" all you want, but I will tell you from experience that for single- threaded or even simple multithreaded non-GUI applications, Java is there. Specifically, if you want to write a program that runs on Unix systems, Win32, and Mac systems, and can access the serial port, then Java is the only solution today.

The benefit here is that fewer resources are required to maintain code that runs on a large number of platforms -- and this reduces cost.

A number of applications share a requirement to have pretty low-level access to the serial port. The term low-level in this context means that a program has access to interfaces that allow it to change modes on-the-fly and directly sample and change the states of the hardware flow-control pins. Besides my PDP-8 project, Dallas Semiconductor needed to use its Blue Dot interfaces on serial ports to talk to the iButton with Java. In addition, the makers of microprocessors have evaluation boards that use a serial port for communications and program loading. All of these applications can now be completely, and portably, written in Java -- a pretty powerful statement.

All of this power to control the parallel and serial ports of the host machine comes from the javax.comm library. Giving Java programmers access to the ports opens up an entirely new set of applications that target embedded systems. In my case, it gave me the ability to write my TTY paper-tape reader emulator completely in Java.

How do you get to play with this stuff?

To get a copy of the latest javax.comm distribution, first you need to sign up as a developer on the Java Developer Connection (JDC) if you haven't done so already. (See Resources.) JDC is free, and as a member you will get early access to Java classes that will eventually be part of the final product.

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) { ... } 

初期化に続いて、newState紙テープの内容(アドレス情報またはプログラミング情報)を追跡する、上記のメソッドのコードがあります。上記の方法では、初期化されたPDP-8のメモリの場所ごとにメッセージも出力されます。

次にmain、以下に示すメソッドがあります。ファイルを開いて読み込みます。次に、コードはシリアルポートを開き、その通信パラメータを設定します。