奇怪的串口读/写行为

时间:2012-10-01 11:25:05

标签: .net serial-port

在我的.Net控制台应用程序中,我有以下方法将少量字节(大约20个)写入串行端口,然后读取响应(同样不超过20个字节)。它用于与外部硬件设备通信 - 向其发送数据请求并获取请求的值。

我已经删除了多余的代码,端口初始化,变量声明等,但你仍然可以看到它在做什么: -

var sw = new Stopwatch();
sw.Start();

// Write the "request" bytes.
_port.Write(buffer, 0, buffer.Length);

Console.WriteLine("After write: {0}", sw.ElapsedMilliseconds);
sw.Restart();

// Wait for response, but timeout after 100ms.
var timeoutCount = 0;
while (_port.BytesToRead == 0 && timeoutCount < 100)
{
    Thread.Sleep(1);
    timeoutCount++;
}

Console.WriteLine("Waited: {0}, #loops: {1}", sw.ElapsedMilliseconds, timeoutCount);

if (_port.BytesToRead == 0)
{
    // Timed-out..
    return null;
}

// Read the response.
var receivedData = new byte[_port.BytesToRead];
_port.Read(receivedData, 0, receivedData.Length);

return receivedData;

我的应用程序在紧密(几乎连续)的循环中调用上面的代码。您会注意到我添加了几个Console.WriteLines来输出一些时间,我看到非常一致的数字如下: -

After write: 0
Waited: 14, #loops: 1
After write: 0
Waited: 14, #loops: 1
After write: 0
Waited: 14, #loops: 1
...and so on...

很明显,写入发生的速度非常快,而且应用程序也很快到达,因为应用程序只通过while循环一次,尽管我很困惑为什么它显示14ms时它只执行一次{{ {1}}。

奇怪的是,如果我在PC上做其他事情,比如打开另一个窗口,让Chrome运行,或者只是移动鼠标,那么我会看到这样的数字: -

Thread.Sleep(1)

这更像是我对串口代码(如我的)的期望,而不是我在PC“空闲”时看到的神秘的14ms。关于发生了什么的任何想法?

这导致我出现问题,因为我的应用程序需要每100毫秒执行大约12次写入/读取。你可以从第二组时间(每个几毫秒)看到这很容易实现,但是当PC“空闲”时,每次写入/读取需要14ms,导致我的应用程序定期丢失数据(在外部更新)设备每100毫秒)。

1 个答案:

答案 0 :(得分:0)

您似乎有实时要求,但您正在使用非实时系统(Windows)进行开发。 Sleep(1)告诉操作系统你的线程至少1ms不能被重新激活,因此它会消失至少1ms,并且当调度程序到达时它会返回。

鼠标移动似乎使其表现更好的原因是因为它导致所有鼠标移动事件更频繁地调用调度程序。

考虑使用实时操作系统,或者不依赖于窗口进行调度,但如果您的_port.write()阻塞系统调用(如WaitForSingleObject或Sleep)可能会很困难。你也可以考虑放弃任何实时要求,只要你从串口获取它就可以了。

相关问题