About supposed bug in usbser.sys with CDC devices on some microcontrollers

I’ve seen gossip about a bug (?) in the in-box USB CDC driver (that’s usbser.sys) already for several years. The reported problem is occasional loss of whole packets on bulk endpoints (64 bytes for full-speed device, 512 bytes for high-speed device), not retried by the host and not noticed by the host (Windows) software: no error detected/indicated.

Always believed that the root cause of these errors are bugs of the device microcontrollers.

Yesterday a member of the STM32 user community posted a summary of observations how this “bug” reproduces on popular STM32’s. TL;DR he thinks that the problem indeed is on the Windows side (either usbser or lower USB stack).

Given that CDC USB devices are very widespread and important, can somebody in MS have a look and elevate this issue if it is real?

There is no buffering anywhere in the USB stack. If usbser.sys driver doesn’t have a read request queued up, then the USB host controller will not issue an IN token and the device will not be given an opportunity to send anything. USB data is all DMAed directly into or out of the URB. If there is no URB, then no data can be transferred.

It is interesting that the transfer is only 128 bytes. Bulk transfers should always fill the buffer completely unless the device returns a packet shorter than the packet size.

1 Like

Thank you Mr. Roberts for your attention. The firmware people state that the host does send the IN request - but somehow loses the data returned by the device. How this can be explained?

Is there something special in handling of incoming short packets, like the data can be lost sometimes?

Additional evidence from Segger, Windows 10+, unspecified device (microcontroller):

A usb analyzer can help. Even the host side wire shark usb trace can be useful. At least confirm what your ‘firmware guys’ are telling you.

Thanks for the reply. Do you know of any explanation that would explain this behavior? The packet shows up in a Wireshark USB trace (see linked thread), along with the prior IN token. It doesn’t seem like the USB hardware is causing this issue. Do you have any insight into what happens to the data and where it’s stored after being received by USB? What else is in the chain between the USB hardware and the windows serial port that pyserial uses? There’s a 16 kB buffer happening somewhere.

There is a Wireshark USB trace in the thread linked in the opening post. Does that satisfy what you’re looking for? If not, is there something else that would help to investigate the issue?

Maybe the following experiment can decide whether the culprit is usbser.sys (lack of buffering): install libusbK on the affected device instead of usbser, write a simple win32 app to read the data via libusb asynchronous API with 2-3 buffers and see if the data loss reproduces?

In my applications I rarely used raw serial transfers, usually X/Ymodem - even if single USB packet loss occurred, the protocol would retry and correct.

Back to the grind tomorrow and thanks for the heads up. We use PIC32MK microcontrollers from Microchip in USB CDC mode and going to see if we can recreate the problem.