- Published on
Communicating with a USB Device Using WinUSB 1: Overview
- Authors

- Name
- Daisuke Kobayashi
- https://twitter.com
Starting with this post, I am going to write a short series on how to communicate with USB devices using WinUSB.
Actually, I changed departments at the beginning of July and started doing embedded-related work. At first I only looked at a little H8 code, but at the end of July my manager asked me to create a USB driver for Windows 7 64bit, and I spent about a week researching and implementing it.
I had almost no embedded experience, and of course I had never written a device driver before, so I had no idea how it would go. In the end, though, just getting it to work turned out to be easier than I had expected.
These are my notes from that work. I eventually confirmed that bulk transfer worked using WinUSB. I do not claim to have a deep understanding of device driver development itself, so some parts may still be rough, but I hope this is helpful.
There is surprisingly little material in Japanese, and I could not find many references that clearly explained what you actually need to do to get something working, so I wanted to write about that specifically.
What it means to create a device driver
When I was suddenly told to create a USB device driver, I had no concrete picture of what that really meant. Normally, when you connect something like a mouse or keyboard over USB, the OS recognizes it automatically. But if the device uses a custom communication protocol, the OS does not know how to handle it on its own. The goal is to make the OS recognize the device and allow communication with it.
When you are hit with that concept all at once, it can be hard to know where to begin. In the end, though, the core is still communication between devices. So, as with any other kind of communication, you provide a way for the devices to communicate according to a protocol.
USB has several transfer modes: control transfer, bulk transfer, interrupt transfer, and isochronous transfer. Each mode differs in transfer speed and the kinds of use cases it is suited for. You need to implement the appropriate transfer mode on the USB device side, and also provide a way for the PC side to access the device using the same transfer mode.
How to create a device driver
Historically, Windows device drivers were built with a framework called WDM (Windows Driver Model). Today, however, drivers are created with the WDF (Windows Driver Foundation) toolkit.
Within WDF, there are three ways to build drivers.
- WDF Kernel-Mode Driver Framework (KMDF)
- WDF User-Mode Driver Framework (UMDF)
WinUsb.sysand the WinUSB API
As you move from 1 to 3, creating the driver gets easier, but the range of things you can do becomes smaller. This time I am going to create the device driver with option 3, WinUSB.
The transfer modes and OS versions currently supported by WinUSB are as follows. If you need another transfer mode or OS, you have to implement the driver with KMDF or UMDF.
Transfer modes:
- Control transfer, bulk transfer, and interrupt transfer (isochronous transfer is not supported)
OS:
- Windows XP SP2 and later, Windows Vista and later
To summarize, the work you need to do is roughly this.
- Implement control transfer, bulk transfer, or interrupt transfer on the USB device
- Install
WinUsb.sysas the function driver for the device - Communicate through the WinUSB API
In my case, step 1 had already been implemented as bulk transfer for the job, so I will skip that. Starting with the next post, I will describe steps 2 and 3.