Mono SerialPort类有多稳固?

时间:2014-05-28 22:26:06

标签: c# mono

我有一个应用程序,除其他外,使用SerialPort与Digi XBee协调器无线电进行通信。

这个代码可以在.NET下的桌面上运行。

在Quo板和WindRiver Linux上运行Mono时,由于校验和验证错误,尝试接收和解码来自网络中其他无线电的消息时,我的失败率大约为99%。

我测试过的事情:

  1. 我使用轮询进行串口,而不是事件,因为Mono不支持事件驱动的串行。所以这个问题与事件无关。
  2. 默认USB协调器使用FTDI芯片组,但我换掉使用原型板和Prolific USB转串口转换器,我看到相同的故障率。我认为这消除了FTDI驱动程序的问题。
  3. 我将代码更改为从不尝试双工通信。它发送或接收。同样的错误。
  4. 我将代码更改为一次读取一个字节,而不是按传入数据包中的大小标识符大小调整的块。同样的错误。
  5. 我看到了各种远程设备(智能插头,墙壁路由器,LTH),因此它不是特定于远程设备的。
  6. 来自其他设备的请求或未经请求的消息发生错误。
  7. 我查看了一些未通过校验和的原始数据包,并且手动计算得到了相同的结果,因此校验和计算本身是正确的。
  8. 查看数据,我看到在数据包中间看起来像是数据包标题(即在数据包标题中指示的长度内)。这让我觉得我失去了"一些字节,导致后续数据包数据被读入先前的数据包。
  9. 同样,这在桌面上工作正常,但为了完整性,这是接收器代码的核心(为简洁起见,删除了错误检查):

    do
    {
        byte[] buffer;
    
        // find the packet start
        byte @byte = 0;
    
        do
        {
            @byte = (byte)m_port.ReadByte();
        } while (@byte != PACKET_DELIMITER);
    
        int read = 0;
    
        while(read < 2)
        {
            read += m_port.Read(lengthBuffer, read, 2 - read);
        }
    
        var length = lengthBuffer.NetworkToHostUShort(0);
    
        // get the packet data
        buffer = new byte[length + 4];
    
        buffer[0] = PACKET_DELIMITER;
        buffer[1] = lengthBuffer[0];
        buffer[2] = lengthBuffer[1];
    
        do
        {
           read += m_port.Read(buffer, 3 + read, (buffer.Length - 3) - read);
        } while (read < (length + 1));
    
        m_frameQueue.Enqueue(buffer);
        m_frameReadyEvent.Set();
    } while (m_port.BytesToRead > 0);
    

    我只能想到可能发生故障的两个地方 - Mono SerialPort实现或位于USB堆栈上方的WindRiver串行端口驱动程序。我倾向于认为WindRiver有一个好的驱动力。

    为了增加混乱,我们通过Mono在同一台设备上(在不同的应用程序中)运行Modbus Serial,这种情况可以正常工作几天,这有点证明了Mono。

    有没有其他人有使用Mono SerialPort的经验?它结实吗?片状?关于可能会发生什么的任何想法?

1 个答案:

答案 0 :(得分:8)

    m_port.Read(lengthBuffer, 0, 2);

这是一个错误,你不能保证你实际上读了两个字节。只有一个非常常见,串口很慢。您必须使用Read()的返回值进行检查。请注意您在第二次使用时是如何做到的。除了循环之外,简单的替代方法是只调用两次ReadByte()。