如何解决错误 java.io.IOException: Input/output error in nativeavailable for Serial Communication?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15567869/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 20:05:21  来源:igfitidea点击:

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

javarxtxserial-communication

提问by Jay

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.

我有 Arm 处理器,它是 AllWinner A13、RAM-512mb 和 OS-Linaro 13.01 Ubuntu(指 debian)。现在我正在为 /dev/ttyS0 制作串行通信程序。我用netbeans在java中制作了简单的双向串行通信程序。在我的处理器中,我缩短了 ttyS0 的 rx-tx 用于环回连接检查。意味着我通过串行端口发送的返回值。但我得到错误。我在处理器上安装了 openjdk-7、librxtx-java。我的代码和错误如下。如果有任何想法或解决方案,请向我提出建议。

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.

我的输出在下面。在这个输出中,我只发送 123,然后我先返回 23,然后返回 1111...更多时间,然后出错。而不是 111111 .... 我只想返回 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)

回答by linski

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 SerialPortinstance 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:

我没有在环回场景中尝试通过 RXTX 进行串行通信,但这应该无关紧要。唯一看起来有点可疑的是您将输入流的实例提供给SerialReader. 我建议您将SerialPort实例传递给两个构造函数,并且每次需要读取/写入端口的流时,请使用流获取器,例如读取:

 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 experienceRXTX 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:

根据我的个人经验,RXTX 是一个有问题的解决方案。然而,这并不意味着这种情况是由潜在的 RXTX 错误引起的。这可能是因为串行端口设置不正确,但在您的情况下,它是具有标准连接参数的标准端口名称。作为一个 loooong 镜头,尝试用 9600 替换波特率 115200,但这可能无济于事。我可以从这里提供三种途径:

  • 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 JSSCinstead of RXTX.
  • 尝试调试 RXTX 代码 - 您可能会更深入地了解正在发生的事情
  • 阅读串口线故障排除
  • 考虑其他用于串行通信的 Java 解决方案,例如JSSC而不是 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.pathsystem property in order for the JVM to find and load them or you'll get an UnsatisfiedLinkError.

恐怕是我一不留神,就往前跳了。JSSC 本机库(.so、.dll)位于 jssc.jar 中,因此它们是“自动”加载的。对于 RXTX,它们位于 jar 文件之外,因此您需要设置java.library.path系统属性以便 JVM 找到并加载它们,否则您将收到 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).

您可以双击打开 JSSC jar 文件,它会在存档器中打开,因为它实际上是一个 zip 文件。与 RXTX 一样,您会注意到本机 libs 文件组织在类似操作系统(windows、linux、RXTX 也有 Mac_OS_X 和 Solaris)的目录中。

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.

在这些目录中有本地 libs 文件、.so、dll. 和 .jnilib 类型的文件,它们以计算机体系结构命名。这是该词的更广泛含义,它们是指令集架构 (ISA) 的短代码。指令集定义了 CPU 的指令集(命令)。换句话说,有许多不同的 CPU 型号(例如您的 AllWinner A13)符合相同的指令集。编译本机 libs 源代码以生成可执行文件 (.so,...),这是来自同一指令集的一堆指令。

The reason why you got the UnsatisfiedLinkError with JSSC mightbe 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 x86and PPCarchitectures, both 32 and 64 bit variant. RXTX has many other's but I think that none of them is equivalent to ARMv7which is the ISA of your AllWinner A13CPU.

您在 JSSC 中遇到 UnsatisfiedLinkError 的原因 可能是因为您处于不受支持的架构上,并且正在不存在的目录中搜索相应的本机库。ISA 短代码,也是 JSSC 的这些目录的名称,是x86PPC架构,32 位和 64 位变体。RXTX 有很多其他的,但我认为它们都不等同于ARMv7,它是您的AllWinner A13CPU的 ISA 。

You can determine your architectureby executing this command in terminal:

您可以通过在终端中执行此命令来确定您的架构

uname -m

On my linux it ouputs:

在我的 linux 上它输出:

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.

这意味着它是一个64 位的 Intel 8086 架构。JSSC 和 RXTX 都实现了这种架构。如果您的架构未实现(支持),则您无法使用这些库连接到该计算机上的串行端口。在这种情况下,您必须自己编写或获得合适的实现。

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

如果架构匹配并且仍然存在本机错误,您可以尝试重新编译本机库源。为RXTXJSSC提供了源代码。

UPDATE:

更新:

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

如果您的架构是armv7l这样,则意味着当前状态下的JSSC、RXTX 和JavaComm(大约说,RXTX“祖先”)在您的场景中是无用的。

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 Cprogram (something like this: 1, 2) with functionality of serial communicationand JNIinterface to the Java library.

我没有设法找到任何其他用于串行通信的开源 Java 库。如果这是真的,您需要编写自己的符合上述库之一的接口的本机库,以使它们有用。换句话说,您需要编写一个具有串行通信功能和Java 库的JNI接口的C程序(类似于:1, 2)。

In the sense of the answer completness, I'll mention a commercial product SerialIOwhich 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.

在回答完整性的意义上,我会提到一个商业产品SerialIO它确实支持一些 ARM 架构(不知道你是否是其中之一)。但是,如果您决定采用该解决方案,您可以随时向他们的支持人员发送查询。