Последовательный порт IOException - PullRequest
0 голосов
/ 07 февраля 2019

Я использую последовательный порт .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.

1 Ответ

0 голосов
/ 12 февраля 2019

После более подробного исследования, пожалуйста, взгляните на это:

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

Цитата:

Как это исправить впромежуточный?Просто.Прежде чем вызывать SerialPort.Open (), просто откройте последовательный порт, вызвав CreateFile и присвойте fAbortOnError для свойства CreateCommState значение false.Теперь вы можете безопасно открыть последовательный порт, не беспокоясь о том, что он может вызвать IOException.Я подготовил образец обходного пути в C #, который вы можете использовать в качестве справочного материала.

Удачи!

...