Java получава серийна поддръжка с новия пакет javax.comm

API на Java Communications (известен още като javax.comm) е предложено стандартно разширение, което позволява на авторите на комуникационни приложения да пишат Java софтуер, който осъществява достъп до комуникационните портове по независим от платформата начин. Този API може да се използва за писане на софтуер за емулация на терминали, софтуер за факс, софтуер за четене на смарт-карти и т.н.

Разработването на добър софтуер обикновено означава да имате някои ясно дефинирани интерфейси. Диаграмата на високо ниво на интерфейсните слоеве на API е показана на тази фигура.

В тази статия ще ви покажем как да използвате javax.comm за комуникация със серийно устройство, базирано на RS-232. Също така ще обсъдим какво предоставя javax.comm API и какво не. Ще ви представим малка примерна програма, която ви показва как да комуникирате със серийния порт с помощта на този API. В края на статията ще разкажем накратко как този javax.comm API ще работи с други драйвери на устройства и ще разгледаме изискванията за изпълнение на роден порт на този API към определена ОС.

За разлика от класическите драйвери, които идват със собствени модели за комуникация на асинхронни събития, javax.comm API предоставя интерфейс в стил събитие, базиран на модела на събитието Java (пакет java.awt.event). Да кажем, че искаме да знаем дали на входния буфер има нови данни. Можем да разберем това по два начина - чрез анкетиране или слушане . С анкетирането, процесорът периодично проверява буфера, за да види дали в буфера има нови данни. При прослушване процесорът изчаква събитие под формата на нови данни във входния буфер. Веднага след като в буфера пристигнат нови данни, той изпраща известие или събитие до процесора.

Сред различните налични серийни интерфейси два от най-популярните са стандартите RS-232C и RS-422, които определят нивата на електрическия сигнал и значението на различните сигнални линии. Нискоскоростните серийни интерфейси обикновено извеждат данните като квадратна вълна, с координация на часовника, осигурена от битове за стартиране и спиране.

RS-232 означава препоръчан стандарт 232 ; на C просто се отнася до последната ревизия на стандарта. Серийните портове на повечето компютри използват подмножество на стандарта RS-232C. Пълният стандарт RS-232C определя 25-пинов конектор "D", от които се използват 22 пина. Повечето от тези щифтове не са необходими за нормална компютърна комуникация и всъщност повечето нови компютри са оборудвани с мъжки конектори от тип D, имащи само 9 пина. За повече информация относно RS-232 вижте раздела Ресурси.

Забележка: За да разберете какво са правили други драйвери в миналото, разгледайте termioстраницата с ръководството на Unix или OpenBSD Unix, вариация на източника на BSD Unix драйвер. Това е достъпно безплатно в Интернет. Моля, вижте раздела Ресурси за повече информация.

API на javax.comm: Какво е предоставено

API на javax.comm предоставя следната функционалност на разработчиците:

  • Пълна спецификация на API за серийни и паралелни комуникационни портове. (В тази статия ние разглеждаме само серийни портове.) Без общ API във вашите усилия за разработка, работното натоварване ще се увеличи, защото ще трябва да осигурите поддръжка на серийни устройства.

  • Пълен контрол на всички параметри на серийното кадриране (битове за ограничаване на бода, паритет, битове / кадър), както и ръчен или автоматичен контрол на линиите за контрол на потока. Обикновено в RS-232 има две сигнални линии, а останалите са предназначени за контролни линии. В зависимост от типа комуникация (синхронна или асинхронна), броят на избраните контролни линии може да варира. Този API осигурява достъп до основните контролни сигнали.

    Краткото отклоняване тук може да ви помогне да разберете нещо за паритета и да започнете и спрете битовете. Паритетът е добавен към RS-232, тъй като комуникационните линии могат да бъдат шумни. Да приемем, че изпращаме ASCII 0 , което в шестнадесетично число е равно на 0x30 (или 00110000 в двоично), но по пътя някой минава, като държи магнит, което кара един от битовете да се променя. В резултат на това вместо да се изпращат 8 бита по предназначение, към първия низ от изпратени битове се добавя допълнителен бит, което прави общата сума на изпратените битове четна или нечетна. voilà ! Имате паритет.

    Битовете за стартиране и спиране бяха добавени към протокола за серийна комуникация, за да позволят на приемниците да синхронизират изпращаните символи. Еднобитовият паритет не позволява корекция на грешки - само откриване. Решенията за този проблем идват от протоколи, които са наслоени върху серийните API. Повечето серийни комуникации в наши дни използват блокови протоколи с контролни суми (математическа функция, която може да бъде генерирана на приемника и сравнена с предадената контролна сума), които позволяват да се откриват грешки на по-големи групи битове. Когато комуникирате с вашия ISP през PPP, пакетите могат да бъдат 128 байта на пакет с контролна сума. Ако те съвпадат, вие сте 99,999% сигурни, че данните са наред.

    Има случаи, при които тази схема не работи. Например, когато изпращате критични команди към устройства, които са много отдалечени в слънчевата система, могат да се използват протоколи за коригиране напред . Необходими са протоколи за коригиране напред, тъй като може да няма време за ретранслация и пространството има много електромагнитни шумове.

    Добре, върнете се към списъка с функционалности, предоставени от API на javax.comm!

  • Основните I / O чрез подклас на Java IO потоци. За вход и изход API на javax.comm използва потоци; концепцията за потоците трябва да е позната на всички Java програмисти. Важно е да използвате повторно концепциите на Java, когато изграждате нова функционалност, или API ще станат тромави.

  • Потоци, които могат да бъдат разширени, за да осигурят контрол на потока на клиента и контрол на прага. Например, може да искате предупреждение, когато в буфера има 10 знака или когато остават само 10 места за символи. Контролът на потока е важен, когато двете устройства, свързани чрез интерфейс, не могат да издържат едно на друго. Без контрол на потока можете да имате превишаване или недостигане . В условието за превишаване сте получили данни, преди да бъдат обработени, така че са загубени; в underrun бяхте готови за данни, но те не бяха налични. Обикновено тези условия се случват в USART (Universal Synchronous Asynchronous Receiver Transmitter), който е хардуер, който преобразува байтове във форма на серийна вълна с синхронизация, за да съответства на скоростта на предаване.

    API на javax.comm използва модела на Java събитие, за да предостави известие за различни промени в сигналната линия, както и за състоянието на буфера. Промените в състоянието се отнасят до добре дефинирани сигнали, посочени в стандарта RS-232. Например, откриването на носител се използва от модем, за да сигнализира, че е осъществил връзка с друг модем или е открил тон на носител. Осъществяването на връзката или откриването на тон на оператора е събитие. Откриването на събития и уведомяването за промените е внедрено в този API.

Какво не е предвидено

API на javax.comm не предоставя:

  • Обработка на типа дисциплина на линия, управление на набиране или управление на модем. Дисциплина на редове се отнася до допълнителна обработка на входни или изходни символи. Например, една често срещана опция за последваща обработка е конвертирането на CR в CR LF. Тези термини произхождат от ранните дни на телетипите. CR (връщане на каретката) означава просто връщане на каретката в лявото поле; в арабския свят това би било правилният марж. LF (линейно подаване) увеличава площта за печат с едно. Когато се появиха растерни екрани и лазерни принтери, тези термини станаха по-малко важни.

    Dialer управление и управление на модема са допълнителни приложения, които могат да бъдат написани с помощта на javax.comm API. Управлението на набиране обикновено осигурява интерфейс към командния интерфейс на управлението на модема. Почти всички модеми имат AT команден интерфейс. Този интерфейс е документиран в ръководства за модеми.

    Може би един малък пример ще направи тази концепция ясна. Да предположим, че имаме модем на COM1 и искаме да наберем телефонен номер. Приложение за управление на набиране на Java ще направи запитване за телефонния номер и ще разпита модема. Тези команди се носят от javax.comm, което не тълкува. За да наберете номера 918003210288, например, управлението на дайлера вероятно изпраща "AT", надявайки се да получи обратно "OK", последвано от ATDT918003210288. Една от най-важните задачи на управлението на набиране и управление на модем е справяне с грешки и изчаквания.

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