简体   繁体   English

是什么导致Mono下SerialPort.Write中的零星错误?

[英]What is causing sporadic error in SerialPort.Write under Mono?

I'm using a USB connection (FTDI) from Linux to an Arduino Nano under Mono. 我正在使用从Linux到Mono下的Arduino Nano的USB连接(FTDI)。 This mostly works but after a while I get, at a seemingly random time, a TimeoutException attempting to Write to the SerialPort. 这通常可以正常工作,但是过了一会儿之后,我在看似随机的时间内收到一个TimeoutException尝试写入SerialPort。 Apparently (see the FIXME and associated bug report ), any error in Write will result in a TimeoutException, and there is no delay in timing, so I think it is fair to assume that it isn't actually a timeout, but just an error. 显然(请参阅FIXME和相关的错误报告 ),Write中的任何错误都将导致TimeoutException,并且计时没有延迟,因此我认为可以假设它实际上不是超时,而只是一个错误而已。

Mono code: 单声道代码:

// FIXME: this reports every write error as timeout
if (write_serial (fd, buffer, offset, count, write_timeout) < 0)
    throw new TimeoutException("The operation has timed-out");

Here (see write_serial) is the Mono wrapper being called, which appears to turn any error result from "poll" or "write" into a simple -1 error result. 此处 (请参阅write_serial)是被调用的Mono包装器,它似乎会将“轮询”或“写入”中的任何错误结果转换为简单的-1错误结果。

Mono Helper: 单声道助手:

int
write_serial (int fd, guchar *buffer, int offset, int count, int timeout)
{
    struct pollfd pinfo;
    guint32 n;

    pinfo.fd = fd;
    pinfo.events = POLLOUT;
    pinfo.revents = POLLOUT;

    n = count;

    while (n > 0)
    {
        ssize_t t;

        if (timeout != 0) {
            int c;

            while ((c = poll (&pinfo, 1, timeout)) == -1 && errno == EINTR)
                ;
            if (c == -1)
                return -1;
        }       

        do {
            t = write (fd, buffer + offset, n);
        } while (t == -1 && errno == EINTR);

        if (t < 0)
            return -1;

        offset += t;
        n -= t; 
    }

    return 0;
}

I've had no problems communicating from Windows/.NET to the same device and using the same write code (you'll see below). 从Windows / .NET到同一设备并使用相同的编写代码,我没有任何问题(您将在下面看到)。

This leaves me at a bit of a loss as to how to even diagnose this without writing some extensive C tests that I hope would reproduce the same IO patterns and timing as my current code does. 这使我对如何甚至不编写一些广泛的C测试就无法诊断这一点感到茫然,我希望这些测试能够重现与当前代码相同的IO模式和时序。 There are port sniffers, but that would merely capture the data, not diagnose and error. 有端口嗅探器,但是那只会捕获数据,而不是诊断和错误。 Is there perhaps a way to catch and log IO errors in the Linux kernel? 也许有一种方法可以捕获和记录Linux内核中的IO错误?

My code is pretty straight forward. 我的代码非常简单。 Here is the relevant snippet: 以下是相关代码段:

    _port = new SerialPort(portName, Configuration.BaudRate);
    _port.NewLine = "\n";
    _port.ReadTimeout = Configuration.StartupCommandTimeout; // 7000ms
    _port.WriteTimeout = Configuration.StartupCommandTimeout;
    _port.Open();

    _port.WriteLine(command);

This always happens away from the main thread, though may not always occur on the same thread that the port was constructed, read from, and otherwise written to. 尽管不一定总是在端口构造,读取和写入的同一线程上发生,但这总是在主线程之外发生。

Using Mono version 3.2.8, though the code below is from Master as doesn't appeared to have changed. 使用Mono版本3.2.8,尽管下面的代码来自Master,因为似乎没有更改。 I'm running Ubuntu 15.10 on ARM. 我在ARM上运行Ubuntu 15.10。

In my control system I have many threads executing simultaneously. 在我的控制系统中,我有许多线程同时执行。 By giving increased thread priority (ThreadPriority.AboveNormal) to the actor (essentially thread) which services the serial port, I seem to have minimized or possibly eliminated the problem. 通过为服务于串行端口的actor(本质上是线程)赋予更高的线程优先级(ThreadPriority.AboveNormal),我似乎已将问题最小化或消除了。 Perhaps Linux is more sensitive to serial port service starvation issues than Windows, or it is the varying hardware. 也许Linux对串行端口服务匮乏问题比Windows更敏感,或者它是变化的硬件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM