文章目录

  • 前言
  • 一、开发前准备
  • 二、开发java项目时所依赖的RXTXcom.jar包(window)
  • 三、开发java代码(window)
  • 四、开发java项目后进行测试(window)
  • 五、打包后jar包测试环境配置(liunx)
  • 六、打包后jar包虚拟串口的创建,第一种方式(liunx)
  • 七、打包后jar包虚拟串口的创建,第二种方式(liunx)
  • 八、出现bug问题,一定得看这里!!!
  • 后言


前言

本次的背景是在一个服务器数据会从R422串口发送数据到R232串口服务器。

开发任务就是在接收数据的服务器上开发一个java程序能监听这个数据并进行数据分析

所以使用的技术大概扯到java ,RXTXcom ,串口 。

不过大部分人会因为电脑上面没有串口而无法测试,所以这个时候就需要虚拟的串口工具进行测试了。这个测试呢分两个部分,一个是在window上面测试,一个是在虚拟环境Centos7上面测试。

java 串口 linux java串口服务器_java


一、开发前准备

在让你们借鉴前,先给你们看本次我所用到的基本环境,好让你们有所对比。
本机系统: window10
虚拟机系统: Centos7
java版本:jdk 1.8
开发工具:Idea2019
服务器视图化工具:finalshell3.0
虚拟机控制工具:VMware 16

我这边提供一些测试工具用品,都是我经过测试使用的,可以没毛病。如果想要其他的什么工具或者软件也可以评论区要哦

链接:https://pan.baidu.com/s/1vJCZr1cA6Hd2C62-a3Xhfg 提取码:cs20

java 串口 linux java串口服务器_linux_02


二、开发java项目时所依赖的RXTXcom.jar包(window)

(1)去下载有关自己系统的jar包(是那个系统就下那个包)

下载地址:http://fizzed.com/oss/rxtx-for-java

java 串口 linux java串口服务器_java_03


(2)把下载好的文件放到java,也就是jdk文件下对应的地方

java 串口 linux java串口服务器_centos_04


(3)给springboot项目,或者maven项目配置一下这个jar包

java 串口 linux java串口服务器_java 串口 linux_05


三、开发java代码(window)

这里只发一小部分代码,注意我这个项目的主要目的就是去监听数据,其他功能各位看好加

package com.wl.myclocksource.utils;

import gnu.io.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.TooManyListenersException;


public class SerialPortUtil {

    private static final Logger logger = LoggerFactory.getLogger(SerialPortUtil.class);

    private static SerialPortUtil serialPortUtil = null;

    static {
        //在该类被ClassLoader加载时就初始化一个SerialTool对象
        if (serialPortUtil == null) {
            serialPortUtil = new SerialPortUtil();
        }
    }

    //私有化SerialTool类的构造方法,不允许其他类生成SerialTool对象
    private SerialPortUtil() {
    }

    /**
     * 获取提供服务的SerialTool对象
     *
     * @return serialPortUtil
     */
    public static SerialPortUtil getSerialPortUtil() {
        if (serialPortUtil == null) {
            serialPortUtil = new SerialPortUtil();
        }
        return serialPortUtil;
    }


    /**
     * 查找所有可用端口
     *
     * @return 可用端口名称列表
     */
    public   ArrayList<String> findPort() {
        //获得当前所有可用串口
        Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers();

        ArrayList<String> portNameList = new ArrayList<>();

        //将可用串口名添加到List并返回该List
        while (portList.hasMoreElements()) {
            String portName = portList.nextElement().getName();
            portNameList.add(portName);
        }

        return portNameList;
    }

    /**
     * 打开串口
     *
     * @param portName 端口名称
     * @param baudrate 波特率
     * @param databits 数据位
     * @param parity   校验位(奇偶位)
     * @param stopbits 停止位
     * @return 串口对象
//     * @throws SerialPortParameterFailure 设置串口参数失败
//     * @throws NotASerialPort             端口指向设备不是串口类型
//     * @throws NoSuchPort                 没有该端口对应的串口设备
//     * @throws PortInUse                  端口已被占用
     */
    public  SerialPort openPort(String portName, int baudrate, int databits, int parity, int stopbits)  {

        try {
            //通过端口名识别端口
            CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);

            //打开端口,并给端口名字和一个timeout(打开操作的超时时间)
            CommPort commPort = portIdentifier.open(portName, 2000);

            //判断是不是串口
            if (commPort instanceof SerialPort) {

                SerialPort serialPort = (SerialPort) commPort;
                try {
                    //设置一下串口的波特率等参数
                    serialPort.setSerialPortParams(baudrate, databits, stopbits, parity);
                } catch (UnsupportedCommOperationException e) {
//                    throw new SerialPortParameterFailure();
                }

                //System.out.println("Open " + portName + " sucessfully !");
                return serialPort;
            } else {
                //不是串口
//                throw new NotASerialPort();
                logger.error("不是串口");
            }
        } catch (NoSuchPortException e1) {
            logger.error("没有找到端口");
            e1.printStackTrace();
//            throw new NoSuchPort();
        } catch (PortInUseException e2) {
            logger.error("端口被占用");
            e2.printStackTrace();
//            throw new PortInUse();
        }
        return null;
    }

    /**
     * 关闭串口
     *
     * @param serialPort 待关闭的串口对象
     */
    public  void closePort(SerialPort serialPort) {
        if (serialPort != null) {
            serialPort.close();
            serialPort = null;
        }
    }

    /**
     * 往串口发送数据
     *
     * @param serialPort 串口对象
     * @param order      待发送数据
//     * @throws SendDataToSerialPortFailure        向串口发送数据失败
//     * @throws SerialPortOutputStreamCloseFailure 关闭串口对象的输出流出错
     */
    public  void sendToPort(SerialPort serialPort, byte[] order)  {
        OutputStream out = null;
        try {
            out = serialPort.getOutputStream();
            out.write(order);
            out.flush();
        } catch (IOException e) {
//            throw new SendDataToSerialPortFailure();
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                    out = null;
                }
            } catch (IOException e) {
//                throw new SerialPortOutputStreamCloseFailure();
                e.printStackTrace();
            }
        }
    }

    /**
     * 从串口读取数据
     *
     * @param serialPort 当前已建立连接的SerialPort对象
     * @return 读取到的数据
//     * @throws ReadDataFromSerialPortFailure     从串口读取数据时出错
//     * @throws SerialPortInputStreamCloseFailure 关闭串口对象输入流出错
     */
    public  byte[] readFromPort(SerialPort serialPort)  {

        InputStream in = null;
        byte[] bytes = null;

        try {
            in = serialPort.getInputStream();
            int bufflenth = in.available();        //获取buffer里的数据长度

            while (bufflenth != 0) {
                bytes = new byte[bufflenth];    //初始化byte数组为buffer中数据的长度
                in.read(bytes);
                bufflenth = in.available();
            }
        } catch (IOException e) {
            e.printStackTrace();
//            throw new ReadDataFromSerialPortFailure();
        } finally {
            try {
                if (in != null) {
                    in.close();
                    in = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
//                throw new SerialPortInputStreamCloseFailure();
            }
        }

        return bytes;

    }

    /**
     * 添加监听器
     *
     * @param port     串口对象
     * @param listener 串口监听器
//     * @throws TooManyListeners 监听类对象过多
     */
    public  void addListener(SerialPort port, SerialPortEventListener listener)  {

        try {
            //给串口添加监听器
            port.addEventListener(listener);
            //设置当有数据到达时唤醒监听接收线程
            port.notifyOnDataAvailable(true);
            //设置当通信中断时唤醒中断线程
            port.notifyOnBreakInterrupt(true);
        } catch (TooManyListenersException e) {
//            throw new TooManyListeners();
            logger.error("太多监听器");
            e.printStackTrace();
        }
    }

    /**
     * 删除监听器
     *
     * @param port     串口对象
     * @param listener 串口监听器
//     * @throws TooManyListeners 监听类对象过多
     */
    public  void removeListener(SerialPort port, SerialPortEventListener listener) {
        //删除串口监听器
        port.removeEventListener();
    }

  
}

四、开发java项目后进行测试(window)

(1)创建两个虚拟串口,使用VspdPro_CN_Free工具

java 串口 linux java串口服务器_centos_06


(2)启动项目监听功能

java 串口 linux java串口服务器_串口通信_07


(3)使用串口调试工具

java 串口 linux java串口服务器_java_08


五、打包后jar包测试环境配置(liunx)

(1)安装好liunx版的jdk 1.8

java 串口 linux java串口服务器_linux_09


(2)去下载有关自己系统的jar包(是那个系统就下那个包)

下载地址:http://fizzed.com/oss/rxtx-for-java

java 串口 linux java串口服务器_串口通信_10

(3)把下载好的文件放到java,也就是jdk文件下对应的地方

java 串口 linux java串口服务器_java_11


(4)然后就可以启动项目不报错了

java 串口 linux java串口服务器_centos_12


六、打包后jar包虚拟串口的创建,第一种方式(liunx)

(1)创建一个物理串行端口(因为你在window上也有开启虚拟端口,会认为你的虚拟端口就是物理端口)

java 串口 linux java串口服务器_java_13


(2)开启之后就连接上了,就可以使用串口调测助手进行测试

java 串口 linux java串口服务器_串口通信_14


(3)可以通过命令进行监控,也可以用minicom软件监控

# 发送消息
echo hello >/dev/ttyS1

# 监听消息,但是好像不太灵
cat /dev/ttyS1

java 串口 linux java串口服务器_java 串口 linux_15


使用minicom的监听工具

java 串口 linux java串口服务器_linux_16

(4)这个东西是有局限的
就是不知道为什么两个虚拟端口通是通了,但是就是java项目也就启动不了了,显示端口被占用了,也不知道解决方式,因为没试过。


七、打包后jar包虚拟串口的创建,第二种方式(liunx)

(1)创建一个管道进行连接测试

java 串口 linux java串口服务器_linux_17


(2)开启Putty软件进行配置

java 串口 linux java串口服务器_java 串口 linux_18


开启PuTTY软件

java 串口 linux java串口服务器_linux_19


(3)开启java项目进行测试,或者你也可以输入echo 、cat 等命令

java 串口 linux java串口服务器_centos_20


八、出现bug问题,一定得看这里!!!

(1)查看串口命令
查看串口命令
查看串口是否可用 可以对串口发送数据比如对com1口,echo hello > /dev/ttyS0
查看串口名称使用 ls -l /dev/ttyS* 一般情况下串口的名称全部在dev下面,如果你没有外插串口卡的话默认是dev下的ttyS* ,一般ttyS0对应com1,ttyS1对应com2,当然也不一定是必然的;
查看串口驱动:cat /proc/tty/driver/serial
查看串口设备:dmesg | grep ttyS*

(2)在传输数据的时候可能会报错。

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f1c7dacdd9d, pid=94106, tid=0x00007f1c7e3a9700
#
# JRE version: Java(TM) SE Runtime Environment (8.0_151-b12) (build 1.8.0_151-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.151-b12 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  [librxtxSerial.so+0x6d9d]  read_byte_array+0x3d
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/initpath/clock_20201113001/hs_err_pid94106.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#

这个时候可以参考我写的另一个解决方案:

后言

ヾ(•ω•`)o

这篇博客我找了很多的博客,然后自己经过测试后写出来的。

之前没整过串口这个东西,现在需要了就开整了。

欢迎各位大佬或小伙伴一起讨论

我这个项目是用来接受标准时间格式的R422线传过来的,然后进行修改系统时间,需要的可以参考。
项目源码在这:
链接:https://pan.baidu.com/s/1Kik4uPokinctlDXILkKh6g 提取码:qxel

( ゚д゚)つBye