【问题标题】:Java serial port IO readingJava串口IO读取
【发布时间】:2012-06-14 16:16:33
【问题描述】:

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

我必须通过工作正常的线程中的轮询方法从串行端口读取数据,但我需要将数据写入串行端口并读回 ACK。向串口写入数据成功,但我无法读回数据。这里有两个读操作,一个在线程中,一个在主线程中。

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

任何人都可以提出这个串行读取操作出了什么问题吗?它不是缓冲的读/写操作。

【问题讨论】:

  • 我不确定我是否遵循您的逻辑。您似乎正在同时阅读三个不同的线程,这听起来不是一个好主意。
  • 不是三个不同的线程,而是两个线程,一个线程连续轮询串行读取,另一个在主线程中,只有在执行写操作时才读取
  • 虽然我仍然不知道这是什么原因,但我相信我理解这个问题。我相信他是说主线程发送了一个写入命令,其中有一个读取(ACK-Checker),之后应该看到一个 ACK​​,并在另一个线程中读取(我们称之为“普通读取器”)执行所有其他读取操作。问题似乎是当他从主线程写入时,ACK-checker 没有看到 ACK。如果他禁用“ACK-checker”,那么“普通读者”在进行正常轮询时会看到 ACK(通常不应该这样做)。这是正确的吗?
  • 是的 Xantham,感谢您以适当的方式提出我的问题。

标签: java io serial-port


【解决方案1】:

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

所以只需继续阅读进来的内容,如果预期并获得 ACK,则通过信号量通知主线程。在一个肮脏残酷简化的伪代码中:

主线程循环:

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

串行阅读器线程循环:

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

您需要在发送写入命令之前设置isAckExpected,因为如果您的串行对等体足够快,您可能会在您的sendWriteCommand 甚至返回之前得到响应。

【讨论】:

  • 感谢 Vvtmarin:实际上它只是在我为读取串行数据而创建的线程上,我将主线程称为程序启动或创建线程(main)的位置
【解决方案2】:

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

您将拥有一个“正常读取处理”线程,该线程由读取线程提供数据。当您需要执行 write/ack 序列时,执行 write/ack 的线程将临时将自己注册到读取线程并转移数据流。

您仍然需要处理任何数据交错(即在写入请求之后但在收到 ack 之前接收到正常数据),但这取决于您的应用程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-13
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    相关资源
    最近更新 更多