javax.comm을 사용하여 Java에 대한 새 포트 열기

Java Ring 용 개발 키트에 사용 된 클래스를 발견했을 때 javax.comm 클래스 패키지를 소개 받았습니다. (javax.comm에 대한 자세한 내용 은 JavaWorld 5 월호에서 Rinaldo Di Giorgio의 Java 개발자 칼럼을 참조하십시오.: "Java는 새로운 javax.comm 패키지로 직렬 지원을 얻습니다.") JavaOne에서 프로그램을 내 링으로 가져 오기 위해 서두르는 동안 링과 통신하는 것이 아니라 다양한 문제에 부딪 혔습니다. Java Developer Connection에서 배포판을 다운로드했지만 Java Ring과 통신하는 데 실패했습니다. 나중에 내 반지의 문제를 발견했습니다. Dallas Semiconductor의 레거시 API가 올바르게 설치되지 않았습니다. 링이 작동하면서 기본적으로 통신 패키지를 잊었습니다. 즉, 한 달 전 어느 주말까지이 이야기의 출발점이된다.

여러 가지 이유로 (주로 게임과 같은 고도로 대화 형 시뮬레이션 환경과 관련이 있음) "실습실"의 기본 컴퓨터는 Windows 95를 실행합니다.하지만 이번 주말에 저는 다른 컴퓨터에 더 관심을 가졌습니다. 여러면에서 Java Ring : Digital Equipment Corporation PDP-8 / e만큼 강력했습니다.

PDP-8은 틀림없이 최초의 진정한 개인용 컴퓨터였습니다. 1960 년대 후반에 설계되어 70 년대에 비교적 많은 양으로 생산 된 PDP-8은 한 사람이 들어 올릴 수 있고 120V 라인 전류로 전원을 공급 받았으며 비용은 0,000 미만이었습니다. 이러한 컴퓨터의 대부분은 단일 주변 장치와 함께 제공됩니다. Teletype Model ASR-33 터미널-컴퓨터 용어의 원래 "TTY".

ASR-33 텔레타이프는 종이 테이프 리더와 펀치가 함께 제공되는 인쇄 단말기였습니다. 네, 그것은 PDP-8의 프로그램을위한 기본 저장 매체였습니다. 그것은 종이 테이프, 구멍이 뚫린 1 인치 너비의 종이였습니다.

PDP-8은 제가 프로그래밍 한 최초의 컴퓨터 였기 때문에 제 마음에 특별한 자리를 차지하고 있습니다. 또한 우연한 상황으로 인해 적시에 적절한 장소에 있었고 쓰레기로 폐기 될 PDP-8을 구했습니다. 내 상품 사진이 아래에 나와 있습니다.

얼마 전이 특별한 주말에 저는 소중한 초기 기억을 되 살리고 딸이 "메 즐리 형 133MHz 펜티엄"으로 얼마나 좋은지 보여주기 위해 PDP-8을 되살리기로 결정했습니다. "

다른 것을 시뮬레이션하여 하나의 고전을 되살리기

부흥 노력을 시작하려면 PDP-8에 프로그램을 추가해야했습니다. PDP-8에서는 다음 3 단계 프로세스를 통해이 작업을 수행합니다.

  1. 사용자는 전면 패널 스위치를 사용하여 짧은 프로그램을 자기 코어 메모리에 "키"합니다. 이 프로그램을 RIM 로더라고하며 그 목적은 읽기 모드 또는 RIM 형식 인 종이 테이프에서 다른 프로그램을로드하는 것입니다.

  2. RIM 로더는 종이 테이프를 RIM 형식으로로드합니다. 이 테이프에는 바이너리 (BIN) 형식으로 종이 테이프에서 프로그램을로드 할 수있는 BIN 로더라는 프로그램이 있습니다.

  3. 마지막으로 BIN Loader를 실행하여 BIN 형식의 종이 테이프에있는 정말 원하는 프로그램을로드합니다. 아휴!

이 세 단계를 거친 후 실행하려는 프로그램이 코어 메모리에 저장됩니다. 사용자가해야 할 일은 시작 주소를 설정하고 기계에 "이동"을 알리는 것입니다.

기계를 되살리려는 노력에서 1 단계는 문제가되지 않았지만 2 단계는 텔레타이프에서 종이 테이프 리더를 사용하는 것과 관련이 있었으며 저는 텔레타이프가 없었습니다. 물론, 내가 않았다 논리적 단계는 내 바탕 화면에 종이 테이프 판독기를 시뮬레이션 할 수 있었다, 그래서 내 데스크탑 컴퓨터가 있습니다.

논리적 및 프로그래밍 관점에서 종이 테이프 리더를 시뮬레이션하는 것은 간단합니다. "테이프"에서 데이터가 포함 된 파일을 읽고 파일을 다 사용할 때까지 110 보드 (예, 초당 10 자)로 직렬 포트로 보냅니다. 저는 솔라리스 시스템이나 FreeBSD 시스템에서 C로이 작업을 수행 할 수있는 프로그램을 약 10 분만에 작성할 수있었습니다.하지만 기억하세요. 저는 유닉스 시스템이 아니라 Windows 95 시스템에있었습니다.

나쁜 것에서 못생긴 것으로 그리고 다시

나는이 프로그램을 C로 쉽게 작성할 수 있다는 것을 알았 기 때문에 그것이 내가 선택한 언어였다. 나쁜 선택. 저는 Visual C ++ 5.0 사본을 가져 와서 open()통신 포트 를 호출 하는 sendtape.c라는 간단한 프로그램을 작성했습니다 . 난로를 설정하려고 RAW의 모드 다음 컴파일하려고합니다 (운영 체제가 사용자의 입력과 직렬 포트에 아무것도를 해석하려고하지 않습니다 유닉스에서 모드). ioctl()기능이나 tty기능이 없습니다 -nada, zip, zilch!

문제 없습니다. "C 컴파일러를 사용하여 전체 Microsoft 소프트웨어 개발자 네트워크 라이브러리가 CD에 들어 있습니다. 'COM 포트'키워드를 빠르게 검색하겠습니다."라고 생각했습니다.

검색 결과 Microsoft 구성 요소 개체 모델 (COM이라고도 함)에 대한 많은 참조와 MSComm에 대한 참조가 나타났습니다. MSComm은 Microsoft가 직렬 포트와 통신하기 위해 제공하는 C ++ 클래스입니다. 나는 예제를보고 110 보드에서 직렬 포트에 바이트를 쓰는 것과 같은 간단한 일을 수행하는 데 얼마나 많은 코드가 필요한지에 놀랐다. 내가하고 싶었던 것은 직렬 포트를 열고 전송 속도를 설정 한 다음 몇 바이트를 채우는 것이 었습니다. 직렬 통신이 강화 된 새로운 응용 프로그램을 만드는 것이 아닙니다!

모니터 앞에는 Java Ring을위한 Blue Dot 수용기가 있었는데 "Aha! Dallas Semiconductor의 사람들이 PC의 직렬 포트와 대화하는 방법을 알아 냈어요. 그들이 무엇을하는지 봅시다. " Win32에 대한 회사의 소스 코드를 살펴본 결과 직렬 포트와 대화하는 것이 간단한 작업이 아니라는 것이 분명했습니다.

구조에 자바

주말의이 시점에서, 나는 이미 가지고있는 것을 사용하는 대신에 프로그램을 코딩하기 위해 유닉스 머신 중 하나를 실험실로 끌고 갈 것이라고 생각 했습니다 . 그런 다음 Sun의 Java Ring 및 java.comm 패키지에 대한 경험을 기억했습니다. 대신 그 길을 택하기로 결정했습니다.

java.comm은 무엇을 제공합니까?

Java Communications API 또는 java.comm은 Java에서 직렬 및 병렬 포트에 액세스하기위한 플랫폼 독립적 인 방법을 제공합니다. JFC, JDBC 및 Java 3D와 같은 다른 Java API와 마찬가지로 프로그래머는 "직렬 포트가 무엇인지"에 대한 플랫폼의 개념을 프로그래밍 모델에서 분리해야합니다. javax.comm 디자인의 경우 플랫폼마다 다른 장치 이름과 같은 항목은 직접 사용되지 않습니다. API의 세 가지 인터페이스는 직렬 및 병렬 포트에 대한 플랫폼 독립적 액세스를 제공합니다. 이러한 인터페이스는 사용 가능한 통신 포트를 나열하고, 포트에 대한 공유 및 배타적 액세스를 제어하고, 전송 속도, 패리티 생성 및 흐름 제어와 같은 특정 포트 기능을 제어하는 ​​메서드 호출을 제공합니다.

문서에서 SimpleWrite.java 예제를보고 40 줄의 코드를 C로 작성하려고했던 150 ~ 200 줄의 코드와 비교했을 때 솔루션이 가까이 있다는 것을 알았습니다.

이 패키지의 상위 수준 추상화는 클래스 javax.comm.CommPort입니다. 이 CommPort클래스는 포트 에 대한 I / O 채널 인 가져 오기 InputStreamOutputStream개체를 포함하여 일반적으로 포트로 수행하는 작업의 종류를 정의합니다 . 그만큼CommPort클래스에는 버퍼 크기를 제어하고 입력 처리 방법을 조정하는 메서드도 포함되어 있습니다. 이러한 클래스가 Dallas Semiconductor One-Wire 프로토콜 (전송 속도의 동적 변경과 전송되는 바이트에 대한 완전한 투명성을 포함하는 프로토콜)을 지원한다는 것을 알고 있었기 때문에 javax.comm API가 유연해야한다는 것을 알았습니다. 즐거운 놀라움으로 다가온 것은 수업이 얼마나 빡빡했는지였습니다. 그들은 일을 끝내기에 충분한 유연성을 가지고 있었고 더 이상은 없었습니다. "편리한 방법"형태의 불필요한 블로 트웨어 나 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아래와 같은 방법이 있습니다. 파일을 열고 읽습니다. 그러면 코드가 직렬 포트를 열고 통신 매개 변수를 설정합니다.