4

一点历史:我们有一个应用程序,最初是在很多年前编写的(1998 年是 PVCS 的第一个日期,但该应用程序比它早 5 年,因为它最初是一个 DOS 程序)。此应用程序通过串行与硬件进行通信。当我们使用 Windows XP 时,我们开始收到应用程序在运行一小段时间后死机的报告。似乎串行通讯刚刚“死亡”,应用程序处于卡住状态。从这种情况中恢复的唯一方法是重新启动应用程序。

我能找到的关于这个问题的唯一信息显然是 Windows 消息系统会错过接收到的信息,缓冲区会填满,系统会卡住。这段信息被留在了一个旧的word文档中,但没有证据支持这一点。它还提到这仅在高波特率 (115200+) 下普遍存在。

解决方案是为客户提供USB->串行转换器以及硬件。

今天:我们正在开发一个新版本的硬件,它将在网络和串行端口上运行。因此,为了让我能够处理网络代码,减去我们使用VSCOM NetCom113设备的实际硬件。它还在用户(即:我的)机器上安装了一个虚拟通信端口。

现在我已经将网络代码与应用程序集成,看起来 NetCom 设备表现出与物理 commport 相同的行为。这是不可取的,因为我需要应用程序运行时间超过 ~30 秒。

谷歌发现我们遇到的零问题。

我想知道:

  • 有谁之前经历过这个吗?如果是这样,您做了什么来解决/解决问题?
  • 有没有人对文档的原始作者是否正确以及我可以做些什么来测试该理论有任何建议?

不幸的是,我无法发布代码,因为串行代码与系统的其余部分紧密耦合,但如果您对此有疑问,我可以回答有关它的问题。

更新:

  • 代码是使用 Win32 Comm 例程编写的 - 所以我使用的是 CreateFile、ReadFile。还有对 GetOverlappedResult 的明智调用。
  • 它本身并没有挂起,只是通讯停止了。您可以访问菜单,单击按钮,但没有任何东西可以与连接的硬件交互。使用realterm你可以看到没有数据进出。
  • 我认为对 windows 消息的引用是问题是 windows 内部的。数据已经到达,但内核错过了它,因此没有告诉系统的其余部分。
  • 不使用流量控制。
  • 编写一个“简单”的测试很困难,因为代码是紧密耦合的,底层协议非常复杂,需要大量工作。
4

4 回答 4

2

您使用的是 DOS 风格的串行代码,还是 Win32 CreateFile 方法?

如果是前者,请非常怀疑:如果可能的话,我会转换为后者。

如果是后者,你知道它挂在什么样的系统调用上吗?您是否处于阻塞读取呼叫中?还是重叠的 I/O 调用?或等待事件?(我不确定我是否有足够的经验来提供帮助,但这些都是我想到的问题)

您还可以检查队列大小,您可以使用SetupComm函数进行设置。

我不买“Windows 消息系统”的东西——这听起来很可疑;您可以编写从不使用 Windows 消息的优秀 Win32 串行 i/o 代码。

编辑:您的重叠 I/O 是否使用事件?我似乎记得一些关于自动重置事件偶尔会错过触发的事情……非常仔细地检查重叠的 I/O 调用,看看你是否正确处理了可能的结果。也许有一种方法可以通过自动取消重叠的 i/o 并重新启动另一个读取来使您的代码更加健壮。(我认为问题出在读取的一半,而不是写入的一半?)

编辑 2:一个建议:假设 win32 端丢失了一个字节或数据包,并且您的设备处于死锁状态,因为它们都希望彼此响应某些东西,您能否定期调整串行 I/O 的另一端发送某种类型的带有递增计数器的“ping”数据包?(并在 PC 端记录 ping 数据包;这样您就可以查看是否遗漏了任何数据)

于 2009-02-19T14:33:15.877 回答
1

你确定你的流量控制设置正确吗?DTR、RTS 等...

-亚当

于 2009-02-19T14:48:37.977 回答
0

不确定这是否适合您,但如果您可以使用 C#.NET 重写代码,您就可以访问那里的 SerialPort 类。它可能会解决您的问题。我知道很多基于 Win32 API 的用于硬件 I/O 端口的遗留代码在 XP 中由于时间问题往往会失败(对 MIDI 有一点经验)。

另外,我不知道您是否可以在 Vista 中使用 Win32 串行端口访问方法,这样可能会阻止未来的 MS 操作系统使用您的代码。

于 2009-06-24T17:23:05.673 回答
0

我编写了使用 USB / 蓝牙串行端口的应用程序并且从未遇到过问题。使用蓝牙,我已经看到很长一段时间的比特率(持续)为 800,000 bps。大多数人没有正确实施该端口。

我的串口

于 2009-02-20T23:08:24.150 回答