如何解决错误java.io.IOException:串行通信的nativeavailable输入/输出错误?

Jay*_*Jay 4 java rxtx serial-communication

我有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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在外面.在这个我只发送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)
Run Code Online (Sandbox Code Playgroud)

lin*_*ski 5

在环回场景中我没有尝试通过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();
        }            
    }
}
Run Code Online (Sandbox Code Playgroud)

请反馈.

更新:

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

  • 尝试调试RXTX代码 - 您可以更深入地了解正在发生的事情
  • 阅读串行故障排除
  • 考虑用于串行通信的其他Java解决方案,例如JSSC而不是RXTX.

更新:

我担心我一直不专心而且跳了起来.JSSC本机库(.so,.dll)位于jssc.jar中,因此它们会"自动"加载.使用RXTX,它们位于jar文件之外,因此您需要设置java.library.path系统属性以便JVM查找并加载它们,否则您将获得UnsatisfiedLinkError.

您可以通过双击打开JSSC jar文件,它将在归档器中打开,因为它实际上是一个zip文件.与RXTX一样,您会注意到本机libs文件被组织在名为操作系统的目录中(Windows,Linux,RXTX也有Mac_OS_X和Solaris).

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

您使用JSSC获得UnsatisfiedLinkError的原因 可能是因为您使用的是不受支持的体系结构,并且在不存在的目录中搜索相应的本机lib.ISA短代码,也是JSSC这些目录的名称,是x86PPC架构,32位和64位变体.RXTX有许多其他的,但我认为它们都不等同于ARMv7,这是你的AllWinner A13 CPU 的ISA .

您可以通过在终端中执行此命令来确定您的体系结构:

uname -m
Run Code Online (Sandbox Code Playgroud)

在我的linux上它输出:

x86_64
Run Code Online (Sandbox Code Playgroud)

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

如果体系结构匹配且仍存在本机错误,则可以尝试重新编译本机libs源.为RXTXJSSC提供了源代码.

更新:

如果您的体系结构armv7l意味着JSSC,RXTX和JavaComm(近似表示,RXTX"祖先")处于当前状态在您的场景中毫无用处.

我没有找到任何其他用于串行通信的开源java库.如果确实如此,您需要编写符合上述库之一的接口的自己的本机库,以使它们有用.换句话说,你需要写一个ç程序(是这样的:1,2)用的功能串行通信JNI接口的Java库.

在答案完整性的意义上,我将提到商业产品SerialIO,它支持一些ARM架构(不知道你的是否是其中之一).但是,如果您决定使用该解决方案,则可以始终向其支持人员发送查询.