您的位置:首页 > 编程语言 > Java开发

Windows下的java串口开发环境配置(2)

2011-01-11 17:29 411 查看
上一篇关于串口环境配置的文章的好像有很多人关注。可能是因为网上关于java做串口开发的帮助文档比较少。能为大家提供一些帮助,实在是欣慰之至。

最近在帮朋友做一个串口操作的小软件,有机会尝试了一下串口开发。在此过程中也碰到了一些问题。这些问题都已经解决了,我将我的方案写出来,第一可以让木有经验的朋友借鉴,第二也算是抛砖引玉,哪位朋友有更好idea也可以拿出来分享。

1.“Windows下的java串口开发环境配置”中介绍的是开发环境,那么开发出来的东西如何发布呢?

上一篇关于串口开发的文章中介绍的只是开发环境的配置,用户不可能都装上eclipse然后设置这些环境,也不可能告诉用户copy一个神马文件到一个神马目录。他们更喜欢double click。所以做出来的东西,用法当然是越弱智越好。那么与操作系统相关的dll文件等,应该如何处置呢?

我将dll文件放入到[project]/lib目录中,然后在启动文件中通过一个虚拟机参数来指定它的位置。我的启动文件如下:

@ECHO off
ECHO DM_HOME=%DM_HOME%
IF "%DM_HOME%"=="" GOTO needDMHome

setlocal ENABLEDELAYEDEXPANSION
set LIBDIR=%DM_HOME%/lib
set CONFIGDIR=%DM_HOME%/config
FOR /R %LIBDIR% %%i in (*.jar) do set CLSP=!CLSP!;%%i
SET CLASSPATH=!CLSP!;%CONFIGDIR%
java -DDM_HOME=%DM_HOME% -Djava.library.path=%LIBDIR% -classpath %CLASSPATH% com.yb.dm.Main >nul 2>&1
goto end
:needDMHome
ECHO Please set environment variable 'DM_HOME' at first.
:end


各位看官应该都能看懂吧,做了一个循环,将[project]/lib下的jar文件都append到classpath中。另外把[project]/conf中的配置文件也append到classpath中。关键的地方在这里:

-Djava.library.path=%LIBDIR%

这个与eclipse中的native library location是一个意思。

2.我发现了一个莫名其妙的异常。

上代码吧。把所有的代码都贴出来有点不现实,因为博文不是毕业论文,不用凑字数,是吧?我帖一个完整的类的源代码出来,我觉得各位看官应该有能力把它改到可以跑起来。

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.Properties;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import com.yb.dm.common.Constant;
public class Serial extends SerialBase {
public final String PORT_OWER = "DM";
private boolean isOpen;
private String portName;
private SerialPort serialPort;
private Reader inputStream;
private Writer outputStream;
private Queue<String> response = new ArrayBlockingQueue<String>(1);
private byte[] lock = new byte[0];
private int maxTry;

private int interval;
private Properties prop = new Properties();
Serial() {
loadProperties();
portName = prop.getProperty(Constant.KEY_SER_PORT_NAME);
myLog.debug("Port name:" + portName);
isOpen = false;
maxTry = Integer.valueOf(prop.getProperty(Constant.KEY_SER_MAX_TRY));
interval = Integer.valueOf(prop.getProperty(Constant.KEY_SER_INTERVAL));
init();
}
private void init() {
if (isOpen) {
myLog.warn("Try to initial an opened port.");
close();
}
try {
CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(portName);
serialPort = (SerialPort) portId.open(PORT_OWER, Integer.valueOf(prop.getProperty(Constant.KEY_SER_TIME_OUT)));
setParam();
inputStream = new InputStreamReader(serialPort.getInputStream());
myLog.debug("Got input stream.");
outputStream = new OutputStreamWriter(serialPort.getOutputStream());
myLog.debug("Got output stream.");
serialPort.notifyOnDataAvailable(true);
serialPort.addEventListener(new SerialPortEventListener(){
public void serialEvent(SerialPortEvent event) {
switch (event.getEventType()) {
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:
myLog.debug("There is data available, try to read it.");
readComm();
break;
default:
break;
}
}
});
isOpen = true;
myLog.debug(portName + " Opened.");
} catch (Exception e) {
myLog.fatal(e);
throw new RuntimeException(e);
}
}
//	public void refresh() {
//		if (isOpen) {
//			try {
//				close();
//			} catch (Exception e) {
//				inputStream = null;
//				outputStream = null;
//				isOpen = false;
//			}
//		}
//		init();
//	}
@Override
public boolean testConnection() {
boolean result = false;
try {
write(Constant.HANDSHAKE_CMD);
String reply = read();
if (Constant.HANDSHAKE_RSP.equals(reply)) {
myLog.debug("No DREC button on test platform.");
myLog.debug("Valid response. Establish connection successfully.");
setDREC(false);
result = true;
} else if (Constant.HANDSHAKE_RSP_DREC.equals(reply)) {
myLog.debug("DREC button on test platform.");
myLog.debug("Valid response. Establish connection successfully.");
setDREC(true);
result = true;
} else {
myLog.debug("Invalid response. Establish connection unsuccessfully.");
}
} catch (Exception e) {
myLog.fatal(e);
myLog.error("Failed to establish connection.");
}
return result;
}
@Override
public void close() {
if (isOpen) {
myLog.info("Closing " + portName + "...");
try {
inputStream.close();
outputStream.close();
serialPort.notifyOnDataAvailable(false);
serialPort.removeEventListener();
serialPort.close();
isOpen = false;
myLog.info(portName + " has been closed.");
} catch (IOException e) {
myLog.fatal("Failed to close " + portName + ".");
throw new RuntimeException(e);
}
} else {
myLog.warn("Close an un-initialized port " + portName + ".");
}
}
private void readComm() {
final int LENGTH = 16;
char[] inChars = new char[LENGTH];
int count = 0;
int off = 0;
try {
while ((count = inputStream.read(inChars, off, LENGTH - off)) > -1) {
myLog.debug(count + " chars readed.");
off += count;
}
} catch (Exception e) {
if ("Underlying input stream returned zero bytes".equals(e.getMessage())) {
myLog.debug("OFF=" + off);
myLog.debug("COUNT=" + count);
char[] temp = new char[off];
System.arraycopy(inChars, 0, temp, 0, off);
String got = new String(temp);
myLog.debug("RESPONSE=" + got);
synchronized (lock) {
response.add(got);
}
} else {
myLog.fatal(e);
throw new RuntimeException();
}
}
}
@Override
public String read() {
String reply = null;
try{
for (int i = 0; i < maxTry; i++) {
synchronized (lock) {
reply = response.poll();
}
if (reply == null) {
Thread.sleep(interval);
} else {
break;
}
}
} catch (InterruptedException e) {
myLog.fatal(e);
throw new RuntimeException(e);
}
return reply;
}
@Override
public void write(String outString) {
try {
myLog.debug("SEND=" + outString);
outputStream.write(outString);
outputStream.flush();
} catch (IOException e) {
myLog.fatal("Error occured in data writing.");
throw new RuntimeException(e);
}
}
private void loadProperties() {
try {
Reader reader = new BufferedReader(new InputStreamReader(this
.getClass().getResourceAsStream("/" + Constant.SER_CONF_FILE)));
prop.load(reader);
reader.close();
} catch (IOException e) {
myLog.fatal(e);
throw new RuntimeException(e);
}
}
@Override
public String getPortName() {
return portName;
}
private void setParam() throws UnsupportedCommOperationException {
int baud = Integer.valueOf(prop.getProperty(Constant.KEY_SER_BAUD));
int dataBit = Integer.valueOf(prop.getProperty(Constant.KEY_SER_DATA_BIT));
int stopBit = Integer.valueOf(prop.getProperty(Constant.KEY_SER_STOP_BIT));
int verBit = Integer.valueOf(prop.getProperty(Constant.KEY_SER_VERIFY_BIT));
myLog.debug("Baud      :" + baud);
myLog.debug("Data bit  :" + dataBit);
myLog.debug("Stop bit  :" + stopBit);
myLog.debug("Verify bit:" + verBit);
serialPort.setSerialPortParams(baud, dataBit, stopBit, verBit);
}
}


注意readComm方法中有一段异常处理,我不知道为什么每次读完串口的数据都会抛这样一个异常。有这方面经验的朋友可以提出来一起探讨一下。我捕获这个异常,并将它作为读入结束的一个标志。虽然功能上没有问题,但总觉得心里有个疙瘩。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: