Java obtient un support série avec le nouveau package javax.comm

L'API Java Communications (alias javax.comm) est une extension standard proposée qui permet aux auteurs d'applications de communication d'écrire un logiciel Java qui accède aux ports de communication d'une manière indépendante de la plate-forme. Cette API peut être utilisée pour écrire un logiciel d'émulation de terminal, un logiciel de télécopie, un logiciel de lecteur de carte à puce, etc.

Développer un bon logiciel signifie généralement avoir des interfaces clairement définies. Le diagramme de haut niveau des couches d'interface API est illustré dans cette figure.

Dans cet article, nous allons vous montrer comment utiliser javax.comm pour communiquer avec un périphérique série basé sur RS-232. Nous discuterons également de ce que l'API javax.comm fournit et de ce qu'elle ne fournit pas. Nous présenterons un petit exemple de programme qui vous montre comment communiquer avec le port série à l'aide de cette API. À la fin de l'article, nous détaillerons brièvement comment cette API javax.comm fonctionnera avec d'autres pilotes de périphériques, et nous passerons en revue les exigences pour effectuer un port natif de cette API sur un système d'exploitation spécifique.

Contrairement aux pilotes classiques, qui viennent avec leurs propres modèles de communication d'événements asynchrones, l'API javax.comm fournit une interface de style événement basée sur le modèle d'événement Java (package java.awt.event). Disons que nous voulons savoir s'il y a de nouvelles données sur le tampon d'entrée. Nous pouvons le découvrir de deux manières: en sondant ou en écoutant . Avec l'interrogation, le processeur vérifie périodiquement le tampon pour voir s'il y a de nouvelles données dans le tampon. Lors de l'écoute, le processeur attend qu'un événement se produise sous la forme de nouvelles données dans le tampon d'entrée. Dès que de nouvelles données arrivent dans le tampon, il envoie une notification ou un événement au processeur.

Parmi les différentes interfaces série disponibles, deux des plus populaires sont les normes RS-232C et RS-422, qui définissent les niveaux des signaux électriques et la signification des différentes lignes de signaux. Les interfaces série à faible vitesse synchronisent généralement les données sous forme d'onde carrée, la coordination d'horloge étant assurée par les bits de démarrage et d'arrêt.

RS-232 signifie Recommander Standard 232 ; le C fait simplement référence à la dernière révision de la norme. Les ports série de la plupart des ordinateurs utilisent un sous-ensemble de la norme RS-232C. La norme RS-232C complète spécifie un connecteur «D» à 25 broches, dont 22 broches sont utilisées. La plupart de ces broches ne sont pas nécessaires pour les communications normales avec un PC, et en effet, la plupart des nouveaux PC sont équipés de connecteurs mâles de type D n'ayant que 9 broches. Pour plus d'informations sur RS-232, consultez la section Ressources.

Remarque: Pour comprendre ce que d'autres pilotes ont fait dans le passé, jetez un œil à la termiopage de manuel Unix ou à OpenBSD Unix, une variante de la source du pilote BSD Unix. Ceci est disponible gratuitement sur Internet. Veuillez consulter la section Ressources pour plus d'informations.

L'API javax.comm: ce qui est fourni

L'API javax.comm fournit les fonctionnalités suivantes aux développeurs:

  • Une spécification API complète pour les ports de communication série et parallèle. (Dans cet article, nous considérons uniquement les ports série.) Sans une API commune dans vos efforts de développement, la charge de travail augmentera car vous devrez fournir une prise en charge des périphériques série.

  • Contrôle total de tous les paramètres de tramage série (bits d'arrêt en bauds, parité, bits / trame) ainsi que contrôle manuel ou automatique des lignes de contrôle de flux. Normalement, en RS-232, il y a deux lignes de signal et le reste est destiné aux lignes de contrôle. Selon le type de communication (synchrone ou asynchrone), le nombre de lignes de commande sélectionnées peut varier. Cette API permet d'accéder aux signaux de contrôle sous-jacents.

    Un bref détournement ici peut vous aider à comprendre quelque chose sur la parité et les bits de démarrage et d'arrêt. La parité a été ajoutée à RS-232 car les lignes de communication peuvent être bruyantes. Disons que nous envoyons ASCII 0 , qui en hexadécimal équivaut à 0x30 (ou 00110000 en binaire), mais en cours de route, quelqu'un passe en tenant un aimant, ce qui fait changer l'un des bits. En conséquence, au lieu d'envoyer 8 bits comme prévu, un bit supplémentaire est ajouté à la première chaîne de bits envoyée, ce qui rend la somme totale des bits envoyés pair ou impair. voilà ! Vous avez la parité.

    Des bits de démarrage et d'arrêt ont été ajoutés au protocole de communication série pour permettre aux récepteurs de se synchroniser sur les caractères envoyés. La parité d'un bit ne permet pas la correction d'erreur - seulement la détection. Les solutions à ce problème proviennent de protocoles superposés aux API série. La plupart des communications série de nos jours utilisent des protocoles de bloc avec des sommes de contrôle (une fonction mathématique qui peut être générée sur le récepteur et comparée à la somme de contrôle transmise) qui permettent de détecter des erreurs sur des groupes de bits plus importants. Lorsque vous communiquez avec votre FAI via PPP, les paquets peuvent être de 128 octets par paquet avec une somme de contrôle. S'ils correspondent, vous êtes sûr à 99,999% que les données sont correctes.

    Il y a des cas où ce schéma ne fonctionne pas. Par exemple, lors de l'envoi de commandes critiques à des appareils très éloignés du système solaire, des protocoles de correction directe peuvent être utilisés. Des protocoles de correction directe sont nécessaires car il peut ne pas y avoir de temps pour une retransmission, et l'espace a beaucoup de bruit électromagnétique.

    Bon, revenons à la liste des fonctionnalités fournies par l'API javax.comm!

  • Les E / S de base via une sous-classe de flux d'E / S Java. Pour l'entrée et la sortie, l'API javax.comm utilise des flux; le concept de flux doit être familier à tous les programmeurs Java. Il est important de réutiliser les concepts Java lors de la création de nouvelles fonctionnalités ou les API deviendront peu maniables.

  • Flux qui peuvent être étendus pour fournir un contrôle de flux client et des contrôles de seuil. Par exemple, vous pouvez souhaiter une alerte lorsqu'il y a 10 caractères dans la mémoire tampon ou lorsqu'il ne reste plus que 10 emplacements pour les caractères. Le contrôle de flux est important lorsque les deux appareils connectés via une interface ne peuvent pas suivre l'un l'autre. Sans contrôle de flux, vous pouvez avoir des dépassements ou des sous - exécutions . Dans la condition de dépassement, vous avez reçu des données avant qu'elles ne soient traitées, donc elles ont été perdues; dans le sous-système, vous étiez prêt pour les données mais elles n'étaient pas disponibles. Habituellement, ces conditions se produisent au niveau de l'USART (Universal Synchronous Asynchronous Receiver Transmitter), qui est un matériel qui convertit les octets en une forme d'onde série avec une synchronisation pour correspondre à la vitesse de transmission.

    The javax.comm API uses the Java event model to provide notification of various signal line changes as well as buffer status. State changes refer to well-defined signals specified in the RS-232 standard. For example, carrier detect is used by a modem to signal that it has made a connection with another modem, or it has detected a carrier tone. Making the connection or detecting a carrier tone is an event. Event detection and notification of changes is implemented in this API.

What is not provided

The javax.comm API does not provide:

  • Line discipline type processing, dialer management, or modem management. Line discipline refers to additional processing of input or output characters. For example, one common post-processing option is the conversion of CR to CR LF. These terms have their origins in the early days of teletypes. CR (carriage return) means to simple-return the carriage to the left margin; in the Arabic world, this would be the right margin. LF (line feed) advances the printing area up by one. When bitmap screens and laser printers came along, these terms became less important.

    Dialer management and modem management are additional applications that can be written using the javax.comm API. Dialer management typically provides an interface to the modem management's AT command interface. Almost all modems have an AT command interface. This interface is documented in modem manuals.

    Perhaps a little example will make this concept clear. Suppose we have a modem on COM1 and we want to dial a phone number. A Java dialer management application will query for the phone number and interrogate the modem. These commands are carried by javax.comm, which does no interpretation. To dial the number 918003210288, for example, the dialer management probably sends an "AT," hoping to get back an "OK," followed by ATDT918003210288. One of the most important tasks of dialer management and modem management is to deal with errors and timeouts.

  • GUI for serial port management. Normally, serial ports have a dialog box that configures the serial ports, allowing users to set parameters such as baud rate, parity, and so on. The following diagram depicts the objects involved in reading and/or writing data to a serial port from 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.