串口IOException

Serial port IOException

我在我的设备上使用 .NET 串行端口 (CF 3.9)。当我尝试发送帧时出现以下错误:

2019-02-07 10:26:39,414 [218497034] ERROR Communication.Serial.ControlCommunication - System.IO.IOException: IOException
at System.IO.Ports.SerialStream.WinIOError(Int32 errorCode, String str)
at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
at System.IO.Ports.SerialPort.Open()
at Communication.Serial.ControlCommunication.WriteFrame(FrameType frameType, Byte[] frame, SamplerDataAddress samplerDataAddress)
at Communication.Serial.ControlCommunication.SerialWriteWithoutDelay(Byte[] frame, Int32 delay, SamplerDataAddress samplerDataAddress)
at Communication.Serial.ControlCommunication.SerialWrite(Byte[] frame, Int32 delay)
at Communication.Serial.ControlCommunication.ExternalThread()
at System.Threading.ThreadHelper.ThreadStartHelper(ThreadHelper t)
at System.Threading.ThreadHelper.ThreadStartHelper()

2019-02-07 10:26:39,467 [165216466] ERROR Communication.Serial.ControlCommunication - System.IO.IOException: IOException
at System.IO.Ports.SerialStream.WinIOError(Int32 errorCode, String str)
at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
at System.IO.Ports.SerialPort.Open()
at Communication.Serial.ControlCommunication.WriteFrame(FrameType frameType, Byte[] frame, SamplerDataAddress samplerDataAddress)
at Communication.Serial.ControlCommunication.SerialWriteWithoutDelay(Byte[] frame, Int32 delay, SamplerDataAddress samplerDataAddress)
at Communication.Serial.ControlCommunication.SerialWrite(Byte[] frame, Int32 delay)
at Communication.Serial.ControlCommunication.RemoveOutput(ControlCommand command)
at Communication.Devices.ExternalLighting.ExternalLighting.SetLightingState(Boolean enabled)
at Communication.Devices.ExternalLighting.ExternalLighting.CheckState()
at Communication.Devices.ExternalLighting.ExternalLighting.Update()
at Communication.Serial.ControlCommunication.ExternalThread()
at System.Threading.ThreadHelper.ThreadStartHelper(ThreadHelper t)
at System.Threading.ThreadHelper.ThreadStartHelper()

WriteFrame方法:

    private void WriteFrame(FrameType frameType, byte[] frame, SamplerDataAddress samplerDataAddress = SamplerDataAddress.None)
    {
        try
        {
            lock (serialPort)
            {
                if (serialPort.IsOpen)
                    serialPort.Close();

                serialPort.Open();

                if (serialPort != null && serialPort.IsOpen)
                {
                    switch (frameType)
                    {
                        case FrameType.xx:
                            serialPort.RtsEnable = false;
                            byte[] versionFrame = ControlMethods.SendVersionReq();
                            serialPort.Write(versionFrame, 0, versionFrame.Length);
                            serialPort.BaseStream.Flush();
                            Thread.Sleep(10);
                            serialPort.RtsEnable = true;

                            Thread.Sleep(130);
                            if (serialPort.BytesToRead > 0)
                            {
                                byte[] received = new byte[serialPort.BytesToRead];
                                serialPort.Read(received, 0, serialPort.BytesToRead);

                                if (frame != null)
                                    log.Info("CheckFekoIOVersionAndCrcErrors frame: " + BitConverter.ToString(frame));

                                ControlMethods.EvaluateVersionResponse(received);
                            }

                            break;
                        case FrameType.xy:
                            serialPort.RtsEnable = false;
                            var countFrame = ControlMethods.GetFekoResetsCount();
                            serialPort.Write(countFrame, 0, countFrame.Length);
                            serialPort.BaseStream.Flush();
                            Thread.Sleep(10);
                            serialPort.RtsEnable = true;

                            Thread.Sleep(200);
                            if (serialPort.BytesToRead > 0)
                            {
                                byte[] response = new byte[serialPort.BytesToRead];
                                serialPort.Read(response, 0, serialPort.BytesToRead);

                                if (response != null)
                                    log.Info("CheckFekoIOVersionAndCrcErrors frame: " + BitConverter.ToString(response));

                                ControlMethods.EvaluateFekoResetsFrame(response);
                            }                                    

                            break;
                        case FrameType.xyz:
                            serialPort.RtsEnable = false;
                            serialPort.Write(frame, 0, frame.Length);
                            serialPort.RtsEnable = true;

                            if (samplerDataAddress != SamplerDataAddress.None)
                                Thread.Sleep(200);

                            if (samplerDataAddress == SamplerDataAddress.GetTemperature)
                                frameLog.Debug("WriteFrame frame sended" + BitConverter.ToString(frame));

                            SerialDataReceived(serialPort, null, samplerDataAddress);
                            break;
                    }
                    serialPort.Close();
                }
                else
                {
                    log.Info("Try to reopen serial port");

                    int serialPortOpenCounter = 0;
                    while (serialPortOpenCounter++ < 3 && !OpenSerialPort());
                }
            }
        }
        catch(Exception exc)
        {
            log.Error(exc);
        }
    }

我如何理解和解决这个异常?

在应用程序中通信是多线程的,WriteFrame由几个线程访问。在我的测试设备上一切正常,但在客户的设备上(设备站在室外)我遇到了上述错误。

使用 Rs-485。

经过更多研究,请看看这个:

http://zachsaw.blogspot.com/2010/07/net-serialport-woes.html

引用:

How do you fix it in the interim? Simple. Before you call SerialPort.Open(), simply open the serial port by calling CreateFile and SetCommState's fAbortOnError to false. Now you can safely open the serial port without worrying that it might throw an IOException. I've whipped up a sample workaround in C# that you could use as a reference.

祝你好运!