Java는 새로운 javax.comm 패키지로 직렬 지원을받습니다.

Java Communications (일명 javax.comm) API는 통신 애플리케이션 작성자가 플랫폼 독립적 인 방식으로 통신 포트에 액세스하는 Java 소프트웨어를 작성할 수 있도록 제안 된 표준 확장입니다. 이 API는 터미널 에뮬레이션 소프트웨어, 팩스 소프트웨어, 스마트 카드 판독기 소프트웨어 등을 작성하는 데 사용할 수 있습니다.

좋은 소프트웨어를 개발한다는 것은 일반적으로 명확하게 정의 된 인터페이스를 갖는 것을 의미합니다. 이 그림에는 API 인터페이스 계층의 상위 수준 다이어그램이 나와 있습니다.

이 기사에서는 javax.comm을 사용하여 RS-232 기반 직렬 장치와 통신하는 방법을 보여줍니다. 또한 javax.comm API가 제공하는 것과 제공하지 않는 것에 대해서도 논의 할 것입니다. 이 API를 사용하여 직렬 포트와 통신하는 방법을 보여주는 간단한 예제 프로그램을 제공합니다. 기사의 끝에서이 javax.comm API가 다른 장치 드라이버와 어떻게 작동하는지 간략하게 설명하고이 API의 기본 포트를 특정 OS에 수행하기위한 요구 사항을 살펴 보겠습니다.

비동기 이벤트의 고유 한 통신 모델과 함께 제공되는 기존 드라이버와 달리 javax.comm API는 Java 이벤트 모델 (java.awt.event 패키지)을 기반으로하는 이벤트 스타일 인터페이스를 제공합니다. 입력 버퍼에 새 데이터가 있는지 알고 싶다고 가정 해 보겠습니다. 우리는 두 가지 방법으로 그것을 찾을 수 있습니다 -에 의해 폴링 또는 청취 . 폴링을 통해 프로세서는 버퍼에 새 데이터가 있는지 주기적으로 확인합니다. 수신 대기를 통해 프로세서는 입력 버퍼에서 새 데이터의 형태로 이벤트가 발생할 때까지 기다립니다. 새 데이터가 버퍼에 도착하자마자 프로세서에 알림 또는 이벤트를 보냅니다.

사용 가능한 다양한 직렬 인터페이스 중에서 가장 널리 사용되는 두 가지는 RS-232C 및 RS-422 표준으로, 전기 신호 레벨과 다양한 신호 라인의 의미를 정의합니다. 저속 직렬 인터페이스는 일반적으로 시작 및 중지 비트에 의해 제공되는 클록 조정과 함께 구형파로 데이터를 클록 출력합니다.

RS-232는 Recommend Standard 232를 나타냅니다 . C는 단순히 표준의 최신 버전을 의미합니다. 대부분의 컴퓨터에있는 직렬 포트는 RS-232C 표준의 하위 집합을 사용합니다. 전체 RS-232C 표준은 25 핀 "D"커넥터를 지정하며이 중 22 핀이 사용됩니다. 이러한 핀의 대부분은 일반 PC 통신에 필요하지 않으며 실제로 대부분의 새 PC에는 9 핀만있는 수 D 형 커넥터가 장착되어 있습니다. RS-232에 대한 자세한 내용은 리소스 섹션을 참조하십시오.

참고 : 다른 드라이버가 과거에 무엇을했는지 이해하려면 Unix termio매뉴얼 페이지 또는 BSD Unix 드라이버 소스의 변형 인 OpenBSD Unix를 참조하십시오. 인터넷에서 무료로 사용할 수 있습니다. 자세한 내용은 리소스 섹션을 참조하십시오.

javax.comm API : 제공되는 항목

javax.comm API는 개발자에게 다음 기능을 제공합니다.

  • 직렬 및 병렬 통신 포트에 대한 완전한 API 사양입니다. (이 기사에서는 직렬 포트만 고려합니다.) 개발 작업에 공통 API가 없으면 직렬 장치에 대한 지원을 제공해야하므로 워크로드가 증가합니다.

  • 모든 직렬 프레이밍 매개 변수 (보드 정지 비트, 패리티, 비트 / 프레임) 및 흐름 제어 라인의 수동 또는 자동 제어를 완벽하게 제어합니다. 일반적으로 RS-232에는 두 개의 신호 라인이 있으며 나머지는 제어 라인 용입니다. 통신 유형 (동기 또는 비동기)에 따라 선택한 제어 라인의 수가 다를 수 있습니다. 이 API는 기본 제어 신호에 대한 액세스를 제공합니다.

    여기서 간단한 전환은 패리티와 시작 및 중지 비트에 대해 이해하는 데 도움이 될 수 있습니다. 통신 회선에 잡음이있을 수 있기 때문에 RS-232에 패리티가 추가되었습니다. 16 진수로 0x30 (또는 바이너리로 00110000)과 같은 ASCII 0 을 보내지 만 누군가가 자석을 잡고 지나가는 과정에서 비트 중 하나가 변경된다고 가정 해 보겠습니다. 결과적으로 8 비트를 의도 한대로 전송하는 대신 전송 된 비트의 첫 번째 문자열에 추가 비트가 추가되어 전송 된 비트의 합계가 짝수 또는 홀수가됩니다. voilà ! 당신은 패리티가 있습니다.

    수신기가 전송되는 문자를 동기화 할 수 있도록 시작 및 중지 비트가 직렬 통신 프로토콜에 추가되었습니다. 1 비트 패리티는 오류 수정을 허용하지 않고 감지 만 허용합니다. 이 문제에 대한 해결책은 직렬 API 위에 계층화 된 프로토콜에서 비롯됩니다. 오늘날 대부분의 직렬 통신은 더 큰 비트 그룹에서 오류를 감지 할 수있는 체크섬 (수신기에서 생성되고 전송 된 체크섬과 비교할 수있는 수학적 함수)이있는 블록 프로토콜을 사용합니다. PPP를 통해 ISP와 통신 할 때 패킷은 체크섬이있는 패킷 당 128 바이트가 될 수 있습니다. 일치하면 99.999 % 데이터가 정상입니다.

    이 체계가 작동하지 않는 경우가 있습니다. 예를 들어 태양계에서 매우 멀리 떨어진 장치에 중요한 명령을 보낼 때 순방향 수정 프로토콜을 사용할 수 있습니다. 재전송 할 시간이없고 공간에는 전자기 노이즈가 많기 때문에 순방향 보정 프로토콜이 필요합니다.

    좋아요, javax.comm API가 제공하는 기능 목록으로 돌아 가세요!

  • Java IO 스트림의 하위 클래스를 통한 기본 I / O. 입력 및 출력의 경우 javax.comm API는 스트림을 사용합니다. 스트림의 개념은 모든 Java 프로그래머에게 익숙해야합니다. 새로운 기능을 구축하지 않으면 API가 다루기 어려워 질 때 Java 개념을 재사용하는 것이 중요합니다.

  • 클라이언트 흐름 제어 및 임계 값 제어를 제공하기 위해 확장 할 수있는 스트림. 예를 들어, 버퍼에 10 개의 문자가 있거나 문자에 대해 10 개의 위치 만 남아있을 때 경고를 원할 수 있습니다. 흐름 제어는 인터페이스를 통해 연결된 두 장치가 서로를 따라갈 수 없을 때 중요합니다. 흐름 제어가 없으면 오버런 또는 언더런 이 발생할 수 있습니다 . 오버런 상태에서는 데이터가 처리되기 전에 수신되어 손실되었습니다. 언더런에서 데이터에 대한 준비가되어 있었지만 사용할 수 없었습니다. 일반적으로 이러한 조건은 USART (Universal Synchronous Asynchronous Receiver Transmitter)에서 발생하며, 이는 바이트를 전송 속도와 일치하는 타이밍으로 직렬 파형으로 변환하는 하드웨어입니다.

    javax.comm API는 Java 이벤트 모델을 사용하여 다양한 신호 라인 변경 사항과 버퍼 상태에 대한 알림을 제공합니다. 상태 변경은 RS-232 표준에 지정된 잘 정의 된 신호를 나타냅니다. 예를 들어, 반송파 감지는 모뎀이 다른 모뎀과 연결했거나 반송파 톤을 감지했다는 신호를 보내는 데 사용됩니다. 연결하거나 캐리어 톤을 감지하는 것은 이벤트입니다. 이벤트 감지 및 변경 알림은이 API에서 구현됩니다.

제공되지 않는 것

javax.comm API는 다음을 제공하지 않습니다.

  • 회선 규칙 유형 처리, 다이얼러 관리 또는 모뎀 관리. 라인 규칙 은 입력 또는 출력 문자의 추가 처리를 나타냅니다. 예를 들어 일반적인 사후 처리 옵션 중 하나는 CR을 CR LF로 변환하는 것입니다. 이 용어는 텔레타이프의 초기에 유래되었습니다. CR (캐리지 리턴)은 캐리지를 왼쪽 여백으로 단순 리턴하는 것을 의미합니다. 아랍어 세계에서는 이것이 오른쪽 여백입니다. LF (줄 바꿈)는 인쇄 영역을 한 단계 위로 올립니다. 비트 맵 화면과 레이저 프린터가 등장했을 때 이러한 용어는 덜 중요해졌습니다.

    다이얼러 관리모뎀 관리 는 javax.comm API를 사용하여 작성할 수있는 추가 애플리케이션입니다. 다이얼러 관리는 일반적으로 모뎀 관리의 AT 명령 인터페이스에 대한 인터페이스를 제공합니다. 거의 모든 모뎀에는 AT 명령 인터페이스가 있습니다. 이 인터페이스는 모뎀 설명서에 설명되어 있습니다.

    아마도 작은 예가이 개념을 명확하게 해줄 것입니다. COM1에 모뎀이 있고 전화를 걸고 싶다고 가정합니다. Java 다이얼러 관리 응용 프로그램은 전화 번호를 쿼리하고 모뎀을 조사합니다. 이러한 명령은 해석이없는 javax.comm에 의해 수행됩니다. 예를 들어, 전화 번호 918003210288로 전화를 걸려면 전화 걸기 관리자가 "OK"를 받고 ATDT918003210288을 받기를 바라며 "AT"를 보낼 수 있습니다. 다이얼러 관리 및 모뎀 관리에서 가장 중요한 작업 중 하나는 오류 및 시간 초과를 처리하는 것입니다.

  • 직렬 포트 관리를위한 GUI. 일반적으로 직렬 포트에는 직렬 포트를 구성하는 대화 상자가있어 사용자가 전송 속도, 패리티 등과 같은 매개 변수를 설정할 수 있습니다. 다음 다이어그램은 Java에서 직렬 포트로 데이터를 읽거나 쓰는 것과 관련된 객체를 보여줍니다.

  • Support for X, Y, and Z modem protocols. These protocols provide support error detection and correction.

The programming basics

Too often, programmers dive right into a project and code interactively with an API on the screen without giving any thought to the problem they are trying to solve. To avoid confusion and potential problems, gather the following information before you start a project. Remember, programming devices usually requires that you consult a manual.

  1. Get the manual for the device and read the section on the RS-232 interface and RS-232 protocol. Most devices have a protocol that must be followed. This protocol will be carried by the javax.comm API and delivered to the device. The device will decode the protocol, and you will have to pay close attention to sending data back and forth. Not getting the initial set-up correct can mean your application won't start, so take the time to test things out with a simple application. In other words, create an application that can simply write data onto the serial port and then read data from the serial port using the javax.comm API.

  2. Try to get some code samples from the manufacturer. Even if they are in another language, these examples can be quite useful.

  3. Find and code the smallest example you can to verify that you can communicate with the device. In the case of serial devices, this can be very painful -- you send data to a device connected to the serial port and nothing happens. This is often the result of incorrect conditioning of the line. The number one rule of device programming (unless you are writing a device driver) is to make sure you can communicate with the device. Do this by finding the simplest thing you can do with your device and getting that to work.

  4. If the protocol is very complicated, consider getting some RS-232 line analyzer software. This software allows you to look at the data moving between the two devices on the RS-232 connection without interfering with the transmission.

Using the javax.comm API successfully in an application requires you to provide some type of interface to the device protocol using the serial API as the transport mechanism. In other words, with the exception of the simplest devices, there is usually another layer required to format the data for the device. Of course the simplest protocol is "vanilla" -- meaning there is no protocol. You send and receive data with no interpretation.

Overview of suggested steps for using javax.comm

In addition to providing a protocol, the ISO layering model used for TCP/IP also applies here in that we have an electrical layer, followed by a very simple byte transport layer. On top of this byte transport layer you could put your transport layer. For example, your PPP stack could use the javax.comm API to transfer bytes back and forth to the modem. The role of the javax.comm layer is quite small when looked at in this context:

  1. Give the javax.comm API control of some of the devices. Before you use a device, the javax.comm API has to know about it.

  2. Open the device and condition the line. You may have a device that requires a baud rate of 115 kilobits with no parity.

  3. Write some data and/or read data following whatever protocol the device you are communicating with requires. For example, if you connect to a printer, you may have to send a special code to start the printer and/or end the job. Some PostScript printers require you to end the job by sending CTRL-D 0x03.

  4. Close the port.

Initializing the javax.comm API registry with serial interface ports

The javax.comm API can only manage ports that it is aware of. The latest version of the API does not require any ports to be initialized. On start-up, the javax.comm API scans for ports on the particular host and adds them automatically.

You can initialize the serial ports your javax.comm API can use. For devices that do not follow the standard naming convention, you can add them explicitly using the code segment below.

// Register the device CommPort ttya = new javax.comm.solaris.SolarisSerial("ttya","/dev/ttya"); CommPortIdentifier.addPort(ttya,CommPortIdentifier.PORT_SERIAL); CommPort ttyb = new javax.comm.solaris.SolarisSerial("ttyb","/dev/ttyb"); CommPortIdentifier.addPort(ttyb,CommPortIdentifier.PORT_SERIAL); 

Opening and conditioning devices

This next code sample demonstrates how to add, condition, and open a device. Details on the specific method calls are in the API pages for javax.comm. This example sets the device called XYZSerialDevice to be accessible with name GenericSerialReader. The device connected on this line has a baud rate of 9600, 1 stop bit, a character of 8 bits (yes, they can be smaller), and no parity. The result of all of this is to provide two streams -- one for reading and another for writing.