Java erhält serielle Unterstützung mit dem neuen Paket javax.comm

Die Java Communications-API (auch bekannt als javax.comm) ist eine vorgeschlagene Standarderweiterung, mit der Autoren von Kommunikationsanwendungen Java-Software schreiben können, die plattformunabhängig auf Kommunikationsports zugreift. Diese API kann zum Schreiben von Terminalemulationssoftware, Faxsoftware, Smartcard-Lesesoftware usw. verwendet werden.

Gute Software zu entwickeln bedeutet normalerweise, einige klar definierte Schnittstellen zu haben. Das allgemeine Diagramm der API-Schnittstellenebenen ist in dieser Abbildung dargestellt.

In diesem Artikel zeigen wir Ihnen, wie Sie mit javax.comm mit einem seriellen Gerät kommunizieren, das auf RS-232 basiert. Wir werden auch diskutieren, was die javax.comm-API bietet und was nicht. Wir präsentieren ein kleines Beispielprogramm, das Ihnen zeigt, wie Sie mit dieser API mit der seriellen Schnittstelle kommunizieren. Am Ende des Artikels werden wir kurz beschreiben, wie diese javax.comm-API mit anderen Gerätetreibern zusammenarbeitet, und wir werden die Anforderungen für die Ausführung eines nativen Ports dieser API für ein bestimmtes Betriebssystem erläutern.

Im Gegensatz zu klassischen Treibern, die über eigene Kommunikationsmodelle für asynchrone Ereignisse verfügen, bietet die javax.comm-API eine Schnittstelle im Ereignisstil, die auf dem Java-Ereignismodell (Paket java.awt.event) basiert. Angenommen, wir möchten wissen, ob sich neue Daten im Eingabepuffer befinden. Wir können das auf zwei Arten herausfinden - durch Abfragen oder Zuhören . Beim Abrufen überprüft der Prozessor den Puffer regelmäßig, um festzustellen, ob sich neue Daten im Puffer befinden. Beim Abhören wartet der Prozessor darauf, dass ein Ereignis in Form neuer Daten im Eingabepuffer auftritt. Sobald neue Daten im Puffer ankommen, sendet es eine Benachrichtigung oder ein Ereignis an den Prozessor.

Unter den verschiedenen verfügbaren seriellen Schnittstellen sind zwei der beliebtesten die Standards RS-232C und RS-422, die die elektrischen Signalpegel und die Bedeutung verschiedener Signalleitungen definieren. Serielle Schnittstellen mit niedriger Geschwindigkeit takten Daten normalerweise als Rechteckwelle aus, wobei die Taktkoordination durch Start- und Stoppbits bereitgestellt wird.

RS-232 steht für Recommend Standard 232 ; Das C bezieht sich lediglich auf die neueste Version des Standards. Die seriellen Schnittstellen der meisten Computer verwenden eine Teilmenge des RS-232C-Standards. Der vollständige RS-232C-Standard spezifiziert einen 25-poligen "D" -Anschluss, von dem 22 Pins verwendet werden. Die meisten dieser Pins werden für die normale PC-Kommunikation nicht benötigt, und tatsächlich sind die meisten neuen PCs mit D-Steckern mit nur 9 Pins ausgestattet. Weitere Informationen zu RS-232 finden Sie im Abschnitt Ressourcen.

Hinweis: Um zu verstehen, was andere Treiber in der Vergangenheit getan haben, lesen Sie die Unix- termioHandbuchseite oder OpenBSD Unix, eine Variation der BSD Unix-Treiberquelle. Dies ist kostenlos im Internet verfügbar. Weitere Informationen finden Sie im Abschnitt Ressourcen.

Die javax.comm-API: Was wird bereitgestellt?

Die javax.comm-API bietet Entwicklern die folgenden Funktionen:

  • Eine vollständige API-Spezifikation für serielle und parallele Kommunikationsports. (In diesem Artikel werden nur serielle Schnittstellen betrachtet.) Ohne eine gemeinsame API in Ihren Entwicklungsbemühungen steigt die Arbeitslast, da Sie serielle Geräte unterstützen müssen.

  • Volle Kontrolle aller seriellen Rahmenparameter (Baud-Stop-Bits, Parität, Bits / Frame) sowie manuelle oder automatische Steuerung der Flusssteuerleitungen. Normalerweise gibt es in RS-232 zwei Signalleitungen und der Rest ist für Steuerleitungen vorgesehen. Abhängig von der Art der Kommunikation (synchron oder asynchron) kann die Anzahl der ausgewählten Steuerleitungen variieren. Diese API bietet Zugriff auf die zugrunde liegenden Steuersignale.

    Eine kurze Ablenkung hier kann Ihnen helfen, etwas über Parität zu verstehen und Bits zu starten und zu stoppen. RS-232 wurde um Parität erweitert, da Kommunikationsleitungen verrauscht sein können. Nehmen wir an, wir senden ASCII 0 , was in hex gleich 0x30 (oder 00110000 in binär) ist, aber auf dem Weg kommt jemand vorbei, indem er einen Magneten hält, wodurch sich eines der Bits ändert. Anstatt 8 Bits wie beabsichtigt zu senden, wird der ersten gesendeten Bitfolge ein zusätzliches Bit hinzugefügt, wodurch die Gesamtsumme der gesendeten geraden oder ungeraden Bits entsteht. voilà ! Du hast Parität.

    Dem seriellen Kommunikationsprotokoll wurden Start- und Stoppbits hinzugefügt, damit die Empfänger die gesendeten Zeichen synchronisieren können. Die Ein-Bit-Parität erlaubt keine Fehlerkorrektur - nur Erkennung. Lösungen für dieses Problem kommen von Protokollen, die über den seriellen APIs liegen. Die meisten seriellen Kommunikationen verwenden heutzutage Blockprotokolle mit Prüfsummen (eine mathematische Funktion, die auf dem Empfänger generiert und mit der übertragenen Prüfsumme verglichen werden kann), mit der Fehler bei größeren Gruppen von Bits erkannt werden können. Wenn Sie mit Ihrem ISP über PPP kommunizieren, können Pakete 128 Bytes pro Paket mit einer Prüfsumme enthalten. Wenn sie übereinstimmen, sind Sie zu 99,999% sicher, dass die Daten in Ordnung sind.

    Es gibt Fälle, in denen dieses Schema nicht funktioniert. Wenn Sie beispielsweise kritische Befehle an Geräte senden, die sich weit außerhalb des Sonnensystems befinden, können Vorwärtskorrekturprotokolle verwendet werden. Vorwärtskorrekturprotokolle sind erforderlich, da möglicherweise keine Zeit für eine erneute Übertragung vorhanden ist und der Raum viel elektromagnetisches Rauschen aufweist.

    Okay, zurück zur Liste der Funktionen, die von der javax.comm-API bereitgestellt werden!

  • Die Basis-E / A über eine Unterklasse von Java-E / A-Streams. Für die Eingabe und Ausgabe verwendet die javax.comm-API Streams. Das Konzept der Streams sollte allen Java-Programmierern bekannt sein. Es ist wichtig, Java-Konzepte wiederzuverwenden, wenn neue Funktionen erstellt werden, da sonst die APIs unhandlich werden.

  • Streams, die erweitert werden können, um Client-Flusskontrolle und Schwellenwertkontrolle bereitzustellen. Beispielsweise möchten Sie möglicherweise eine Warnung, wenn sich 10 Zeichen im Puffer befinden oder wenn nur noch 10 Stellen für Zeichen vorhanden sind. Die Flusskontrolle ist wichtig, wenn die beiden über eine Schnittstelle verbundenen Geräte nicht miteinander Schritt halten können. Ohne Flusskontrolle können Über- oder Unterläufe auftreten . Im Überlaufzustand haben Sie Daten erhalten, bevor sie verarbeitet wurden, sodass sie verloren gingen. Im Unterlauf waren Sie für Daten bereit, diese waren jedoch nicht verfügbar. Normalerweise treten diese Bedingungen beim USART (Universal Synchronous Asynchronous Receiver Transmitter) auf, einer Hardware, die Bytes in eine serielle Wellenform konvertiert, deren Timing der Baudrate entspricht.

    Die javax.comm-API verwendet das Java-Ereignismodell, um verschiedene Signalleitungsänderungen sowie den Pufferstatus zu benachrichtigen. Zustandsänderungen beziehen sich auf genau definierte Signale, die im RS-232-Standard angegeben sind. Beispielsweise wird die Trägererkennung von einem Modem verwendet, um zu signalisieren, dass es eine Verbindung mit einem anderen Modem hergestellt hat, oder es hat einen Trägerton erkannt. Das Herstellen der Verbindung oder das Erkennen eines Trägertons ist ein Ereignis. Die Ereigniserkennung und Benachrichtigung über Änderungen ist in dieser API implementiert.

Was ist nicht vorgesehen

Die javax.comm-API bietet nicht:

  • Verarbeitung von Leitungsdisziplinstypen, Dialer-Verwaltung oder Modemverwaltung. Zeilendisziplin bezieht sich auf die zusätzliche Verarbeitung von Eingabe- oder Ausgabezeichen. Eine übliche Nachbearbeitungsoption ist beispielsweise die Konvertierung von CR in CR LF. Diese Begriffe haben ihren Ursprung in den frühen Tagen der Teletypen. CR (Wagenrücklauf) bedeutet, den Wagen einfach zum linken Rand zurückzubringen; In der arabischen Welt wäre dies der richtige Rand. LF (Zeilenvorschub) erhöht den Druckbereich um eins. Als Bitmap-Bildschirme und Laserdrucker hinzukamen, wurden diese Begriffe weniger wichtig.

    Dialer-Management und Modem-Management sind zusätzliche Anwendungen, die mit der javax.comm-API geschrieben werden können. Die Dialer-Verwaltung bietet normalerweise eine Schnittstelle zur AT-Befehlsschnittstelle der Modemverwaltung. Fast alle Modems verfügen über eine AT-Befehlsschnittstelle. Diese Schnittstelle ist in Modemhandbüchern dokumentiert.

    Vielleicht macht ein kleines Beispiel dieses Konzept klar. Angenommen, wir haben ein Modem an COM1 und möchten eine Telefonnummer wählen. Eine Java-Dialer-Verwaltungsanwendung fragt nach der Telefonnummer und fragt das Modem ab. Diese Befehle werden von javax.comm ausgeführt, das keine Interpretation vornimmt. Um beispielsweise die Nummer 918003210288 zu wählen, sendet die Dialer-Verwaltung wahrscheinlich ein "AT", in der Hoffnung, ein "OK" zurück zu erhalten, gefolgt von ATDT918003210288. Eine der wichtigsten Aufgaben der Dialer- und Modemverwaltung ist die Behandlung von Fehlern und Zeitüberschreitungen.

  • GUI für die Verwaltung der seriellen Schnittstelle. Normalerweise verfügen serielle Schnittstellen über ein Dialogfeld, in dem die seriellen Schnittstellen konfiguriert werden, in dem Benutzer Parameter wie Baudrate, Parität usw. festlegen können. Das folgende Diagramm zeigt die Objekte, die beim Lesen und / oder Schreiben von Daten von Java auf eine serielle Schnittstelle beteiligt sind.

  • 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.