USB serial devices and the unexpected side-effects of serial enumeration (BSOD, with solutions!)

I got a WDF_VIOLATION BSOD (0x0000010D) in Windows 7 (x64) when I connected a dev board via USB serial today. It was an alarming error I’ve never seen before…

… but I suspect it’s more common for those in the hardware community and not always well-understood.

Note: While the discussion below centers around the ESP32 with the CP210x USB to UART bridge, it’s a general problem if your COM drivers allow “serial enumeration” of a serially connected device (a way to detect old, legacy input devices like mice). The ESP32 happens to be particularly “chatty” when it’s connected via USB, which is why it was more likely to trigger this issue. That said, the ESP32 isn’t the problem – it’s just more likely to trigger this latent issue.

This isn’t the first time I’ve connected my new ESP32 but I’ve been doing more with it, including reset tests. However, that triggered something unexpected last night – Windows tried to install a Microsoft Mouse HID driver for the board when I plugged it in, which seemed very odd as it’s definitely not emulating a mouse. Today, I plugged it in again, reset the board, tried opening the COM port in PuTTY (which I use for serial comms) and boom – BSOD 0x0000010D (WDF_VIOLATION – Windows Driver Framework violation)!

For whatever reason the minidump didn’t save, but I noted the fault number and determined it was probably some recently changed or added driver. Since that spurious mouse driver was the last one I noticed, and since it was noted as mis-installed (which is why it was even more memorable), I focused on that (and the board itself).

I learned that Windows (7 for sure and probably other releases) installs the driver for the CP210x USB to UART bridge with “serial enumeration” functionality: if it sees “M” in the initial COM stream for a newly connected device, it tries to enumerate that device as a mouse:

http://community.silabs.com/t5/Interface-Knowledge-Base/What-is-the-serial-enumeration-driver-and-why-would-I-need-it/ta-p/160921

This can go very, very wrong for a serial device that isn’t a mouse, particularly for something like the ESP32 which sends a lot of data when it resets. That the ESP32 (or other such devices) would do this isn’t a problem – it just happens to trigger this unwanted side-effect more readily than most. For an enumerating driver this data is interpreted as coming from a serial mouse, and that’s when the problems start. The system then tries (and partially or wholly fails) to install a mouse driver for the non-mouse USB device. It filters that stream as if it were a mouse and can eventually lead to a BSOD.

Updating the driver via Windows’ device manager (automatic download) didn’t help: I got a newer version that still enumerated the ESP32 as a mouse as soon as it interpreted an “M” in the initial data stream. (It’s not clear if the enumerator is reading an actual “M” at 115200 baud or interpreting an “M” from the garbage it sees at the 1200 baud speed such enumeration normally occurs at… either way, it’s the driver, not the board.)

Some COM port drivers will allow you to selectively disable the serial enumeration feature, but not the ones for this Silicon Labs chip. So I installed the latest VCP driver without serial enumeration directly from their website:

http://www.silabs.com/products/mcu/pages/usbtouartbridgevcpdrivers.aspx#windows

Now the ESP32 is no longer enumerated as a mouse. This should prevent future BSODs of this unique and cryptic nature (as well as a more obscure effect – “crazy mouse”: depending on the data stream, the system may manage to install a mouse driver and read random data from a non-mouse device as valid mouse inputs).

There are a few things one can do to alleviate this sort of issue. As noted, if the advanced settings for the COM port driver have a direct way to disable serial enumeration, try that first. In the present case, updating to a non-enumerating driver was the simplest route. If neither of these is an option there are other ways, but they may or may not work as well:

http://stackoverflow.com/questions/9226082/device-misdetected-as-serial-mouse

As an aside, the fact that this caused a BSOD at all is cause for concern… I’d expect the enumerator (and/or the partially-installed mouse driver) to handle spurious data more gracefully. It’s not clear in what exact driver my BSOD got triggered, but it seems unnecessary for a misunderstood “mouse” to crash a system.

(Theoretically, if you transmitted data that was properly formatted valid mouse data over the COM interface, you could emulate a mouse, but normally you don’t want a dev board being misunderstood as a HID (human interface device) like this. At best, garbage in – garbage out. At worse, a crashed system.)

You can learn more about serial enumeration here:

https://blogs.msdn.microsoft.com/doronh/2006/11/13/what-is-the-serial-enumeration-protocol/

Leave a Reply

Your email address will not be published. Required fields are marked *

*