Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve error java.io.IOException: Input/output error in nativeavailable for Serial Communication?

I have Arm processor which is AllWinner A13 ,RAM- 512mb, and OS- Linaro 13.01 Ubuntu (means debian). Now i m making Serial Communication program for /dev/ttyS0. i made simple program for Two Way Serial Communication in java with netbeans. In my processor i short rx-tx of ttyS0 for loop back coonection checking. Means what ever i send through Serial port that i get return back. but i get error. i installed openjdk-7, librxtx-java on my processor. my code and error is below. If any have idea or solution then please suggest to me.

package serialcomm_linaro;


import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class TwoWaySerialComm
{
    public TwoWaySerialComm()
    {
        super();
    }

    void connect ( String portName ) throws Exception
    {
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
        if ( portIdentifier.isCurrentlyOwned() )
        {
            System.out.println("Error: Port is currently in use");
        }
        else
        {
            CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);

            if ( commPort instanceof SerialPort )
            {
                SerialPort serialPort = (SerialPort) commPort;
                serialPort.setSerialPortParams(115200,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);

                InputStream in = serialPort.getInputStream();
                OutputStream out = serialPort.getOutputStream();

                (new Thread(new SerialReader(in))).start();
                (new Thread(new SerialWriter(out))).start();

            }
            else
            {
                System.out.println("Error: Only serial ports are handled by this example.");
            }
        }     
    }

    /** */
    public static class SerialReader implements Runnable 
    {
        InputStream in;

        public SerialReader ( InputStream in )
        {
            this.in = in;
        }

        public void run ()
        {
            byte[] buffer = new byte[1024];
            int len = -1;
            try
            {
                while ( ( len = this.in.read(buffer)) > -1 )
                {
                    System.out.print(new String(buffer,0,len));
                }
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }            
        }
    }

    /** */
    public static class SerialWriter implements Runnable 
    {
        OutputStream out;

        public SerialWriter ( OutputStream out )
        {
            this.out = out;
        }

        public void run ()
        {
            try
            {                
                int c = 0;
                while ( ( c = System.in.read()) > -1 )
                {
                    this.out.write(c);
                }                
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }            
        }
    }

    public static void main ( String[] args )
    {
        try
        {
            (new TwoWaySerialComm()).connect("/dev/ttyS0");
        }
        catch ( Exception e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

my out is below . In this out i just send 123 and i get return back 23 first and then 1111... more time, and then errore. Instead of 111111.... i want only return back 123.

enter code here
RXTX Warning:  Removing stale lock file. /var/lock/LCK..ttyS0
123
23
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111



java.io.IOExcepti on: Input/output error in nativeavailable
        at gnu.io.RXTXPort.nativeavailable(Native Method)
        at gnu.io.RXTXPort$SerialInputStream.read(RXTXPort.java:1429)
        at gnu.io.RXTXPort$SerialInputStream.read(RXTXPort.java:1341)
        at serialcomm_linaro.TwoWaySerialComm$SerialReader.run(TwoWaySerialComm.java:66)
        at java.lang.Thread.run(Thread.java:722)
like image 349
Jay Avatar asked Mar 22 '13 10:03

Jay


1 Answers

I hadn't tried serial communication over RXTX in a loopback scenario, but that shouldn't matter. The only thing that looks a bit suspicious is the part where you give the instance of the input stream to the SerialReader. I recommend that you pass SerialPort instance to both constructors, and every time you need to read from/write to the port's stream, use a stream getter, e.g. for reading:

 public static class SerialReader implements Runnable 
{
    SerialPort serialPort;

    public SerialReader ( SerialPort serialPort )
    {
        this.serialPort = serialPort;
    }

    public void run ()
    {
        byte[] buffer = new byte[1024];
        int len = -1;
        try
        {
            while ( ( len = serialPort.getInputStream().read(buffer)) > -1 )
            {
                System.out.print(new String(buffer,0,len));
            }
        }
        catch ( IOException e )
        {
            e.printStackTrace();
        }            
    }
}

please feedback.

UPDATE:

From my personal experience RXTX is a buggy solution. This however does not mean that this situation is caused by an underlying RXTX bug. It might be because the serial port isn't setup correctly, but in your case it is a standard port name with standard connection parameters. As a loooong shot, try replacing the baudrate 115200 with 9600, but that probably won't help. I can offer three paths from here:

  • try debugging the RXTX code - you might get more insight on what's happening
  • read the serial line troubleshooting
  • consider other Java solutions for serial communication, like JSSC instead of RXTX.

UPDATE:

I'm afraid I have been inattentive and jumped ahead. JSSC native libraries (.so,.dll) are inside the jssc.jar so they are loaded "automatically". With RXTX they come outside the jar file so you need to set the java.library.path system property in order for the JVM to find and load them or you'll get an UnsatisfiedLinkError.

You can open the JSSC jar file by a double click, and it will open in an archiver because it is actually a zip file. As with RXTX, you will notice that the native libs files are organized in directories named like operating systems (windows, linux, RXTX has Mac_OS_X and Solaris also).

Inside these directories there are the native libs files, the .so, dll., and .jnilib types of files, which are named after computer architectures. That's the broader meaning of the word, these are short codes for instruction set architectures (ISA). The instruction set defines the set of instructions (commands) for a CPU. In other words, there are many different CPU models (like your AllWinner A13) that conform to the same instruction set. The native libs source code is compiled to produce the executables (.so,...) which is a bunch of instructions from that same instruction set.

The reason why you got the UnsatisfiedLinkError with JSSC might be because you're on an unsupported architecture, and the corresponding native lib is being is searched for in an unexistent directory. The ISA short codes, which are also the names of these directories for JSSC are x86 and PPC architectures, both 32 and 64 bit variant. RXTX has many other's but I think that none of them is equivalent to ARMv7 which is the ISA of your AllWinner A13 CPU.

You can determine your architecture by executing this command in terminal:

uname -m

On my linux it ouputs:

x86_64

which means that it is a 64bit Intel 8086 architecture. Both JSSC and RXTX have implemented this architecture. If your architecture isn't implemented (supported) than you can't use these libraries to connect to serial port on that computer. In that case you must write your own or obtain a suitable implementation.

If the architecture matches and there are still native errors you might try recompiling the native libs sources. The sources are provided for both RXTX and JSSC.

UPDATE:

If your architecture is armv7l that means that JSSC, RXTX and JavaComm (approximatley said, RXTX "ancestor") in their current state are useless in your scenario.

I didn't manage to find any other open source java library for serial communication. If that is really true, you'd need to write your own native library conforming to the interface of the one of the above libraries to make them useful. In other words, you'd need to write a C program (something like this: 1, 2) with functionality of serial communication and JNI interface to the Java library.

In the sense of the answer completness, I'll mention a commercial product SerialIO which does support some ARM architectures (don't know if your is one of them). But if you decide for that solution, you can always send a query to their support.

like image 72
linski Avatar answered Oct 03 '22 14:10

linski