本次的背景是在一个服务器数据会从R422串口发送数据到R232串口服务器。
开发任务就是在接收数据的服务器上开发一个java程序能监听这个数据并进行数据分析
所以使用的技术大概扯到java ,RXTXcom ,串口 。
不过大部分人会因为电脑上面没有串口而无法测试,所以这个时候就需要虚拟的串口工具进行测试了。这个测试呢分两个部分,一个是在window上面测试,一个是在虚拟环境Centos7上面测试。
在让你们借鉴前,先给你们看本次我所用到的基本环境,好让你们有所对比。
本机系统: window10
虚拟机系统: Centos7
java版本:jdk 1.8
开发工具:Idea2019
服务器视图化工具:finalshell3.0
虚拟机控制工具:VMware 16
我这边提供一些测试工具用品,都是我经过测试使用的,可以没毛病。如果想要其他的什么工具或者软件也可以评论区要哦
链接:https://pan.baidu.com/s/1vJCZr1cA6Hd2C62-a3Xhfg
提取码:cs20
(1)去下载有关自己系统的jar包(是那个系统就下那个包)
下载地址:http://fizzed.com/oss/rxtx-for-java
(2)把下载好的文件放到java,也就是jdk文件下对应的地方
(3)给springboot项目,或者maven项目配置一下这个jar包
这里只发一小部分代码,注意我这个项目的主要目的就是去监听数据,其他功能各位看好加
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();
}
}
(1)创建两个虚拟串口,使用VspdPro_CN_Free工具
(1)安装好liunx版的jdk 1.8
(2)去下载有关自己系统的jar包(是那个系统就下那个包)
下载地址:http://fizzed.com/oss/rxtx-for-java
(3)把下载好的文件放到java,也就是jdk文件下对应的地方
(4)然后就可以启动项目不报错了
(1)创建一个物理串行端口(因为你在window上也有开启虚拟端口,会认为你的虚拟端口就是物理端口)
(2)开启之后就连接上了,就可以使用串口调测助手进行测试
(3)可以通过命令进行监控,也可以用minicom软件监控
# 发送消息
echo hello >/dev/ttyS1
# 监听消息,但是好像不太灵
cat /dev/ttyS1
(4)这个东西是有局限的
就是不知道为什么两个虚拟端口通是通了,但是就是java项目也就启动不了了,显示端口被占用了,也不知道解决方式,因为没试过。
(1)创建一个管道进行连接测试
(2)开启Putty软件进行配置
开启PuTTY软件
(3)开启java项目进行测试,或者你也可以输入echo 、cat 等命令
(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
#
这个时候可以参考我写的另一个解决方案:https://blog.csdn.net/weixin_43943548/article/details/109843689
ヾ(•ω•`)o
这篇博客我找了很多的博客,然后自己经过测试后写出来的。
之前没整过串口这个东西,现在需要了就开整了。
欢迎各位大佬或小伙伴一起讨论
我这个项目是用来接受标准时间格式的R422线传过来的,然后进行修改系统时间,需要的可以参考。
项目源码在这:
链接:https://pan.baidu.com/s/1Kik4uPokinctlDXILkKh6g
提取码:qxel
( ゚д゚)つBye