【问题标题】:How to solve error java.io.IOException: Input/output error in nativeavailable for Serial Communication?如何解决错误 java.io.IOException: Input/output error in nativeavailable for Serial Communication?
【发布时间】:2013-03-22 10:18:37
【问题描述】:

我有 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();
        }
    }
}

我的输出在下面。在这个输出中,我只发送 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)

【问题讨论】:

    标签: java rxtx serial-communication


    【解决方案1】:

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

     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();
            }            
        }
    }
    

    请反馈。

    更新:

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

    • 尝试调试 RXTX 代码 - 您可能会更深入地了解正在发生的事情
    • 阅读serial line troubleshooting
    • 考虑其他用于串行通信的 Java 解决方案,例如 JSSC 而不是 RXTX。

    更新:

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

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

    在这些目录中,有以computer architectures 命名的原生库文件、.so、dll. 和 .jnilib 类型的文件。这是这个词的广义含义,这些是instruction set architectures (ISA) 的短代码。指令集定义了 CPU 的指令集(命令)。换句话说,有许多不同的 CPU 型号(如您的 AllWinner A13)符合相同的指令集。本机库源代码被编译以生成可执行文件(.so,...),这是来自同一指令集的一堆指令。

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

    您可以通过在终端中执行以下命令来确定您的architecture

    uname -m
    

    在我的 linux 上输出:

    x86_64
    

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

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

    更新:

    如果您的架构是 armv7l,这意味着 JSSC、RXTX 和 JavaComm(近似说,RXTX“祖先”)在您的场景中是无用的。

    我没有找到任何其他用于串行通信的开源 Java 库。如果确实如此,您需要编写符合上述库之一的接口的自己的本机库,以使它们有用。换句话说,您需要编写一个具有serial communicationJNI 接口的Java 库的C 程序(类似于:12)。

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

    【讨论】:

    • 感谢您的回复。在这里,我使用环回场景来测试我通过串行端口发送的内容是否返回给我。在将这个程序用于激光和 X 射线部分之前,我必须对其进行很好的检查和测试。
    • 我按照你说的试过了,但还是出现了那个旧错误。
    • 感谢您早日回复对我的帮助。现在我将一一尝试您的选择。
    • 我在尝试使用 jSSC-0.9.0-Release.zip (jssc.jar) 时出错。我提取该 jssc 文件夹并将 jssc.jar 使用到我在 ubuntu 上的 javaApp 中,它给出了类似运行的错误:线程“main”中的异常 java.lang.UnsatisfiedLinkError: jssc.SerialNativeInterface.openPort(Ljava/lang/String;)I at jssc .SerialNativeInterface.openPort(Native Method) at jssc.SerialPort.openPort(SerialPort.java:143) at serialcomm_linaro.Main.main(Main.java:25) Java 结果:1 BUILD SUCCESSFUL(总时间:2 秒)
    • UnsatifsfiedLinkError 表示代码尝试使用一些外部库(Linux 为 .so,Windows 为 .dll)但找不到它们。您需要找到这些文件所在的目录并将其设置为系统属性。请参阅here 如何。但这很奇怪,我上次使用它时没有必要。我得看看,请反馈。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-21
    • 2016-11-03
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多