středa 16. července 2008

Serial port v Jave aneb RXTX

Jakožto spokojený uživatel linuxu jsem dost odstíněn od windows. Bohužel to sebou přináší i určité problémy, kdy potřebuji portovat aplikaci na windows.

Ano, java je multiplatformní, jenže pouze do chvíle, kdy potřebujete přistupovat k sériovému portu a číst z něj data. K tomuto účelu existuje několik možností, které ovšem v jave znamenají implementovat funkčnost pouze pro daný OS.

Nic není tak černé, a proto existuje možnost, jak donutit vaši aplikaci, aby uměla komunikovat se sériovým portem na více OS. To vše bez nutnosti měnit stávající kód.

Ta možnost je přes RXTX. Kromě klasického COMx umí i LPT či USB.

Samotná implementace je víceméně jednoduchá:

  • nakopírují se příslušné knihovny (u linuxu do usr/lib/ a u windows do jre/bin).

  • přes JNI se zavolají příslušné metody z knihoven daných OS

  • otevře se port, zaregistruje listener a již mohu číst či zapisovat.


Jelikož na notebooku používám redukci mezi USB a sériovým portem, trochu jsem se bál samotného zprovoznění. Opak je pravdou. Přes identifikaci zařízení "/dev/ttyUSB0" jsem byl schopen se spojit stejně jako přes COM1 na windows.

Pro testovací účely jsem si napsal malý prográmek, který se snaží dohledat všechny porty. Podle identifikace je poté možné port otevřít a čekat, zda z portu přijdou nějaká data.

Ke stažení: Testovací program pro poslouchání portů

5 komentářů:

  1. Mam takove neblahe tuseni, ze to je knihovna, kterou jsme take pouzivali a dostala nas do potizi. Nefungovala pod 64b systemem a horsi vec byla, ze obsahovala memory leaky, takze se nam aplikace komunikujici po seriaku do 2 hodin odstrelila na OutOfMemoryException. Ponekud problem v mission critical aplikaci. Reseni bylo, ze na server, na kterem aplikace bezi se reinstalil na linux a funguje se pres /dev/ttyX. Jeste byla nutna nejaka konfigurace portu v linuxu, ale to uz byla trivka. Zaroven se nam kupodivu i vrstva zajistujici komunikaci pres seriovy port zjednodusila ;-) Tahle udalost je asi 2 roky stara, ale kdyz koukam do zmen, tak nic od zacatku roku 2006 :-(

    OdpovědětSmazat
  2. Pekne niekedy vyskusam, ale nebolo by lepsie namiesto JNI pouzivat JNA? Je to priame volanie metody z DLLky. Alebo su uz tie DLLky(SO) skompilovane v JNI a mozem ich pouzit priamo v jave?

    OdpovědětSmazat
  3. Funguje to úplne spoľahlivo. Používam to v jednej aplikácie kde načítavam čiarový kód.

    OdpovědětSmazat
  4. to ARny: Mam pocit, ze zmenu volani neovlivnis. Samotne rozhrani, ktere se ma pouzit je standardizovano podle JSR. Do knihoven jsem primo nekoukal. Stacilo je nastavit na library.path a o zbytek se stara RXTX implementace.

    OdpovědětSmazat
  5. V J2ME (Personal Profile 1.1) je podpora seriového portu standardní součástí JCL - CommConnection.java, nástupce staršího externího balíčku javax.comm. Enumeraci portů vám triviálně udělá
    String ports = System.getProperty("microedition.commports");
    Analogicky jako v C# kde máte rovněž triviální
    string[] serialPortNames = System.IO.Ports.SerialPort.GetPortNames();
    Je kuriozní že v J2SE/J2ME musíte používat nějaké third-party knihovny a dokonce JNI. Ani se tomu nechce věřit, takhle to java proti C# asi nevyhraje.

    OdpovědětSmazat

Když programátor založí a řídí firmu

Jako malý jsem chtěl být popelářem. Ani ne tak proto, že bych měl nějaký zvláštní vztah k odpadkům, ale hrozně se mi líbilo, jak...