none
Communicating with USB CDC device. RRS feed

  • Question

  • Hi,

    I know this is not exactly a driver development but I though I can get a better answer here as the problem may have nothing to do with .net.

    I'm using the SerialPort .net class to communicate with a USB CDC device, I use the Write method to write a message and ReadByte to read the response (which is usually 2 bytes) one byte at the time. The problem I'm having is that sometimes the ReadByte method timesout even though the response was sent by the device and received by the USB stack in Windows as I can see it in a USB sniffer. Any ideas why this is happening?

    • Changed type Doron Holan [MSFT] Monday, January 20, 2014 9:00 PM
    • Changed type Fernan82.Net Sunday, January 26, 2014 5:08 AM Because it was a question.
    Monday, January 20, 2014 6:37 PM

Answers

  • To me it sounds like the driver is not handling the race between receiving the read io request and the data arriving from the hardware. Also remember that software will take some time to process the USB traffic before the driver sees it.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    • Marked as answer by Fernan82.Net Sunday, January 26, 2014 5:08 AM
    Tuesday, January 21, 2014 2:58 AM

All replies

  • The problem is not specific to .net's SerialPort class, the same thing happens if I use Win32's WriteFile and ReadFile on a C app. I also noticed that if I sleep for 1ms after sending the command and before calling ReadByte it doesn't timeout so it seems that it times out if I call ReadByte (or ReadFile in C) before the data has been received. The delay is unacceptable so I need to find a real solution. Any ideas?
    Monday, January 20, 2014 10:16 PM
  • Thanks for replying. There's no real serial port. It uses the usbser.sys driver that comes with windows. The device is a microcontroller with a built-in USB module. Also I can see the response on the USB sniffer so the problem is not on the device end.
    Monday, January 20, 2014 10:42 PM
  • If I spin the cpu while SerialPort.BytesToRead == 0 before calling SerialPort.ReadByte() everything works as it should except for CPU usage. That confirms that ReadByte() (or ReadFile) are timing out if the packet has not arrived when I call it. The packet is definitely arriving while ReadByte or ReadFile are blocking as I've set the timeout for 5 seconds and the longest I'm having to spi the cpu is a few miliseconds.
    Monday, January 20, 2014 11:01 PM
  • This is what I used for testing, it sends 0xFF to the device whenever I do that the device replies 0x0002 (that's the invalid command response. If I remove the Sleep(1) from this code it will hang on ReadFile after a couple seconds.

    	HANDLE com_port;
    	unsigned char data = 0xFF;
    	DWORD data_written;
    	DWORD data_in;
    
    	com_port = CreateFile(TEXT("COM3"),
    		GENERIC_READ | GENERIC_WRITE,
    		0,
    		NULL,
    		OPEN_EXISTING, 
    		0,
    		NULL);
    
    	if (!com_port)
    		return 0;
    
    	while (1)
    	{
    		if (!WriteFile(com_port, (LPVOID) &data, 1, &data_written, NULL))
    			return 0;
    
    		if (!data_written)
    			return 0;
    
    		Sleep(1);
    		if (!ReadFile(com_port, (LPVOID) &data_in, 2, &data_written, NULL))
    			return 0;
    
    		if (!data_written || data_written < 2)
    			return 0;
    
    		printf(".");
    	}
    


    Monday, January 20, 2014 11:45 PM
  • To me it sounds like the driver is not handling the race between receiving the read io request and the data arriving from the hardware. Also remember that software will take some time to process the USB traffic before the driver sees it.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    • Marked as answer by Fernan82.Net Sunday, January 26, 2014 5:08 AM
    Tuesday, January 21, 2014 2:58 AM
  • To me it sounds like the driver is not handling the race between receiving the read io request and the data arriving from the hardware. Also remember that software will take some time to process the USB traffic before the driver sees it.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Could it be the chipset drivers? I will try on a different PC later on, I doubt it could be usbser.sys.

    What software are you referring to? the driver's? The USB analyzer I'm talking about is a software sniffer so by the time it sees it it should've been processed by the driver.

    Also if I set a short timeout timeout and retry the read it still timesout so the IO request is somehow discarding the data before timing out. For now I'm just busy waiting until I know the data is there, that works just fine but it is a problem because of CPU usage.

    Tuesday, January 21, 2014 6:01 PM
  • You're right, but I'm not actually using that code, my client app is written in c#. That's just something I wrote real quick to test that the problem was not with .NET's SerialPort class (and it's not bailing out, it hangs on ReadFile). On c# I use SerialPort.ReadByte which always reads one byte at once. I'll update once I test it on another PC, I've been a little busy today. Thanks
    Wednesday, January 22, 2014 2:57 AM
  • To me it sounds like the driver is not handling the race between receiving the read io request and the data arriving from the hardware. Also remember that software will take some time to process the USB traffic before the driver sees it.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.


    It looks like you were right. I've just tried it on three other PCs and it only happens with this one. I didn't tried it before because once I got with working with the CPU spinning workaround this became low priority but it looks like that's what it was. Thank you.
    Sunday, January 26, 2014 5:12 AM