我在Java中从串口读取数据时遇到了一个奇怪的问题。
我必须通过一个正常工作的线程中的轮询方法从串口读取数据,但我有一个要求,我需要将数据写入串口并读回ACK。将数据写入串行端口是成功的,但我无法读取数据。这里有两个读操作,一个是线程,另一个是主线程。
一旦我收到串行写入数据,我暂停了使用标志从串行端口读取数据的线程,并在写入完成后再次开始从串行端口读取数据,但我无法读取数据。我在写操作后禁用了读取串口,并启用了线程读取线程中的串口,这里我看到来自串口的ACK数据。
可以说明这个串行读操作出了什么问题吗?它不是缓冲读/写操作。
答案 0 :(得分:0)
您不应该尝试从串行端口读取不同的线程。正确的架构是让单个线程进行读取,并通过多个队列将传入的数据分发给感兴趣的客户端。
您将拥有一个由读取线程提供数据的“正常读取处理”线程。当您需要执行write / ack序列时,执行write / ack的线程将使用读取线程临时注册自身并转移数据流。
您仍然需要处理任何数据交错(即在写入请求之后但在收到确认之前收到的正常数据),但这取决于您的应用程序。
答案 1 :(得分:0)
我强烈建议只使用一个专用线程来访问串口读取。最可靠的解决方案曾经是一个中断处理程序,将所有接收的数据铲除到线程安全状态机。尝试从多个线程读取串行端口会调用问题。串口IO不关心你“暂停你的线程”,由于上下文切换,数据可能已经被取入和丢失。
因此,只需继续阅读内容,如果预期和获得ACK,请通过信号量通知主线程。在一个肮脏的残酷简化的伪代码中:
主线程循环:
{
serialReaderThread.isAckExpected = true
sendWriteCommand();
ackReceivedSemaphore.wait();
}
串行读取器线程循环:
{
readData();
if( isAckExpected && data == ack ) {
mainThread.ackReceivedSemaphore.notify();
isAckExpected = false
}
}
您需要在发送write命令之前设置isAckExpected
,因为如果您的串行对等体足够快,您可能会在sendWriteCommand
甚至返回之前得到响应。