Search code examples
c#winformsserial-portcompact-framework

Serial port IOException


I'm using .NET serial port (CF 3.9) on my device. I'm getting following errors when I try to send frame:

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()

There is WriteFrame method:

    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);
        }
    }

How I can understand and resolve this exceptions?

In application communication is multithreading, WriteFrame is accesed by a few threads. On my test device all works fine but on client's device (device stands outdoor) I have got above errors.

Using Rs-485.


Solution

  • After doing a bit more research, please take a look at this:

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

    To quote:

    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.

    Good luck!