2012-06-14 66 views
0

我在Java中从串口读取数据时遇到了一个奇怪的问题。Java串口IO读取

我已经通过在其中工作的罚款线程轮询方法来读取串口数据,但我有一个要求,我需要将数据写入到串行端口和读回ACK。将数据写入串口是成功的,但我无法读回数据。这里有两个读取操作,一个在主线程中,另一个在主线程中。

一旦我接收串行写入数据我暂停其从串行端口使用标志读取数据的线程,并开始再次一次写入完成串口读取数据,但我无法读取数据。我写操作后禁止读取串口,并启用线程读取串口的线程,这里我看到串口的ACK数据。

任何可以建议是怎么回事错这个串行读操作?它不是缓冲读/写操作。

+0

我不确定我遵循你的逻辑。你好像你一次从三个不同的线索阅读,这听起来不是一个好主意。 – gobernador

+0

它不是三个不同的线程,而是两个线程,一个线程轮询连续读取,另一个线程在主线程中读取,只有当它执行写操作时才读取 –

+1

虽然我仍然不知道这个原因,但我相信我理解问题。我相信他是说主线程发送一个写命令,并且有一个读(ACK-Checker),之后应该看到一个ACK,并且在另一个线程(让我们称之为“一般阅读器”)中读取一个读做每一个其他的阅读操作。问题似乎是,当他从主线程写入时,该ACK检查器没有看到ACK。如果他禁用了“ACK-checker”,那么“通用阅读器”在进行正常轮询(通常不应该)时会看到ACK。它是否正确? – Xantham

回答

0

我强烈建议只使用一个专用线程来访问串口读取。最可靠的解决方案曾经是一个中断处理程序,将所有接收到的数据铲除到线程安全状态机。尝试从多个线程读取串行端口会导致问题。串口IO不关心你“暂停了你的线程”,由于上下文切换,数据可能已经被获取并丢失。

所以干脆继续读什么进来,如果ACK预期并获得通过旗语通知主线程。在一个肮脏残酷简化的伪代码:

主线程循环:

{ 
    serialReaderThread.isAckExpected = true 
    sendWriteCommand(); 
    ackReceivedSemaphore.wait(); 
} 

串行读线程循环:

{ 
    readData(); 
    if(isAckExpected && data == ack) { 
    mainThread.ackReceivedSemaphore.notify(); 
    isAckExpected = false 
    } 
} 

您需要发送的写命令之前设置isAckExpected,因为如果你的串行同行速度足够快,您甚至可以在sendWriteCommand甚至返回之前获得回应。

+0

感谢Vvtmarin:实际上它只是在我为读取串行数据创建的线程上,我将主线程称为程序启动或创建线程(主线程) –

0

您不应该尝试从串口读取不同的线程。正确的架构是让单线程完成读取,并通过多个队列将传入数据分发给感兴趣的客户端。

你将不得不由读线程给出的数据是“正常的读取处理”线程。当您需要执行写入/确认序列时,正在执行写入/确认的线程会临时将自己注册到读取线程并转移数据流。

你仍然需要处理数据的任何交织(即写入请求之后,但在接收到ACK接收正常的数据),但最多也就是你的应用程序。