我正在编写一个应用程序,它使用 OpenNETCF.IO.Serial(开源,请参阅此处的串行代码)在 Windows CE 6.0 设备上进行串行通信。此应用程序在 Compact Framework 2.0 中使用 C# 编码。我不相信我将要描述的问题与这些细节特别相关,但在这方面我可能被证明是错误的。
我遇到的问题是,看似随机(读作:间歇性问题,我还不能可靠地复制),数据将无法传输或接收,直到设备本身重新启动。Windows CE 设备与运行完全不同的应用程序的系统通信。重新启动此其他系统并断开/重新连接通信电缆似乎无法解决此问题,只能重新启动 Windows CE 设备。
发生此问题的唯一迹象是缺少来自 OpenNETCF 触发的 TxDone 事件(在 OpenNETCF.IO.Serial 类中查找“TxDone();”),并且当我知道已连接的事实时没有接收到数据系统正在发送数据。
可以在我们的串行通信中发送和接收 1 - 255 (0x01 - 0xFF) 的任何字符值。空值被丢弃。
我的串行设置是 38400 波特、8 个数据位、无奇偶校验、1 个停止位(38400、8n1)。我已将输入和输出缓冲区大小设置为 256 字节。每当我们接收到 1 个或更多字符时发生 DataReceived 事件,并且当输出缓冲区中有 1 个或更多字节时发生传输,因为消息的长度是可变的。
不使用握手。由于这是 RS422,因此只使用了 4 个信号:RX+、RX-、TX+、TX-。
我收到一个“DataReceived”事件,我从输入缓冲区读取所有数据,并在我的代码中创建自己的缓冲区,以便在 DataReceived 事件之外空闲时解析它。当我收到一条命令消息时,我会发回一条快速确认消息。当其他系统收到来自 Windows CE 设备的命令消息时,它会返回一个快速确认消息。确认消息不会得到进一步的回复,因为它们的目的是简单的“是的,知道了”。在我的代码中,我通过多个线程接收/传输,所以我使用 lock 关键字,所以我不会在多个线程上同时传输多条消息。仔细检查代码表明我没有挂断任何锁。
在这一点上,我想知道我是否一直遗漏一些关于串行通信如何工作的明显内容,例如我是否需要设置一些变量或属性,而不是在输入缓冲区不为空时读取并写入传输缓冲区。
欢迎任何见解、检查选项、建议、想法等。这是我几个月来一直在努力解决的问题,我希望我在这里收到的答案或评论可以帮助解决这个问题。先感谢您。
编辑,2011 年 2 月 24 日:
(1) 我似乎只能在 Windows CE 设备正在与之通信的系统启动时重新创建错误,而不是每次启动。我还查看了信号,共模电压波动,但系统启动时出现的噪声幅度似乎与问题是否发生无关,我已经看到 25V 峰峰值没有问题,当 5V 峰值-to-peak 问题再次发生)。
问题听起来越来越与硬件相关,但我试图找出可能导致我看到的症状的原因,因为实际上没有任何硬件出现故障或关闭,至少在我能够达到的地方测量信号。很抱歉,但我无法提供任何类型的硬件零件编号,所以请不要询问正在使用的组件。
(2) 根据@ctacke 的建议,为了可维护性,我确保所有传输都经过同一个位置,我放入的线程安全基本上如下:
lock(transmitLockObj)
{
try
{
comPort.Output = data;
}
[various catches and error handling for each]
}
(3) 出现 UART OVERRUN 错误,在测试中,以 38400 波特的大约 300 毫秒时间间隔发送和接收 <10 个字节。一旦它得到一个错误,它就进入下一个循环迭代,并且不运行 ReadFile,并且不运行 TxDone 事件(或任何其他行检查过程)。此外,关闭和重新打开端口不仅无法解决此问题,而且在设备仍在运行时重新启动软件也无济于事。只有硬件重启。
我的 DataReceived 事件如下:
try
{
byte[] input = comPort.Input; //set so Input gets FULL RX buffer
lock(bufferLockObj)
{
for (int i = 0; i < input.Length; i++)
{
_rxRawBuffer.Enqueue(input[i]);
//timer regularly checks this buffer and parses data elsewhere
//there, it is "lock(bufferLockObj){dataByte = _rxRawBuffer.Dequeue();}"
//so wait is kept short in DataReceived, while remaining safe
}
}
}
catch (Exception exc)
{
//[exception logging and handling]
//hasn't gotten here, so no point in showing
}
然而,在测试中第一次 WriteFile 调用超时后,我开始收到 UART OVERRUN 错误。老实说,我看不到导致 UART OVERRUN 条件的代码。
想法?硬件或软件相关,我正在检查所有我能想到的检查。