I/O exception error when using serialport.open()

I faced a similar problem as reported in this thread, but I managed to solve the problem!

I am using STM32F2xx for the VCP!

And indeed it was my firmware problem. I forgot to include serial port settings in my USB callback!

The process of connecting a serial port from PC and firmware:

  1. When a PC opens a serial port communication, the PC will send some command into the "configuration endpoint"
  2. In the firmware, it would have a callback and the firmware will provide all the USB information (they call it a USB descriptor)
  3. USB information is the configuration of each endpoint, (for example, latency, data size transmission, and type of USB - high speed or low speed)
  4. Once the firmware has completed sending all the information, the PC will acknowledge and USB communication is successfully opened
  5. Then, the PC will send a command to get the serial port settings from the firmware
  6. Serial port settings are baudrate, data parity, and bit length.
  7. In firmware, it should reply the serial port settings back to PC (my mistake occurs here; I didn’t not send any serial port settings back to the PC)
  8. If successful, PC will start the serial port communication!
  9. If failed, PC will give an open serial port error (but, do note that this error sometimes is bypassed)

In STM32 firmware code:

static int8_t CDC_Control_FS (uint8_t cmd, uint8_t* pbuf, uint16_t length)
{
    switch (cmd) {
       case CDC_GET_LINE_CODING:
        {
            // I was missing this part
            uint32_t baudrate = 9600;
            pbuf[0] = (uint8_t)(baudrate);
            pbuf[1] = (uint8_t)(baudrate >> 8);
            pbuf[2] = (uint8_t)(baudrate >> 16);
            pbuf[3] = (uint8_t)(baudrate >> 24);
            pbuf[4] = 0;
            pbuf[5] = 0;
            pbuf[6] = 8;
            break;
        }:
....

I ran into the same situation. I am trying to connect serial communication to my 3G USB Dongle (Huawei E303F) at /dev/ttyUSB0. I use Mono in Raspbian (Raspberry Pi 2). On my development PC and macOS, my program runs fine. But when I deploy it into Raspbian, I got the IOException Broken Pipe error on Serial.Open().

It took me three days of debugging, and I tried all possible solutions. Finally I found that I have to set...

serialPort.DtrEnable = true;
serialPort.RtsEnable = true;

Before calling .Open().


This comes from the serial port driver; it is unhappy about one of the settings. With baudrate being a good candidate, drivers tend to allow only up to 115200. Albeit that this should not be a restriction when this is a dedicated CAN bus product.

The best way to tackle this is by using Sysinternals' Portmon utility; you can see what is being sent to the driver. Observe it for Terminate first; that's your known-to-work baseline. Then tinker with SerialPort properties until the initialization commands, as you see them in PortMon, sent by your program matches Termite's. Just the values, not the order. If that doesn't pan out either then take it to the parking lot and back over it with your car several times and buy another brand.


Update: it certainly looks like a baudrate problem. That's an issue in .NET; it is not going to ignore the driver's error return code like your terminal emulator programs do. The actual value should not matter since you are talking to an emulated serial port. There is however a possible issue with the CAN bus speed; rates are variable and it isn't clear to me how they are negotiated. This tended to be done with DIP switches in the olden days, and it may well be that the driver wants you to specify the speed through the baudrate setting. There ought to be something about it on the box or in the manual. Typical speeds are 40, 250 or 500 kbit/s. The manufacturer certainly would know; give them a call.


And so our thrilling tale comes to a close. It was firmware the whole time (i.e. the code on the embedded device). We changed up a few functions and essentially poked around, chopped, added and altogether cleaned up the code and voila, the code is working. This pic sums it up pretty well. Curse you firmware!!

However, the bug described in my (lengthy) question still persists for many people and I know there are lots of people out there who still have it. All I can say is good luck and quadruple check your firmware (apparently triple checking it isn't enough these days).