How to fix dfu-util, STM, WinUSB, Zadig, Bootloaders and other Firmware Flashing issues on Windows
I'm pretty happy with Windows 10 as my primary development box. It can do most anything I want, run a half-dozen Linuxes, and has a shiny new open source Terminal, and has great support for Docker now.
For years - YEARS I SAY - Windows has been a huge hassle when you want to flash the firmware of various devices over USB.
The term "dfu" means Device Firmware Update and dfu-util is the Device Firmware Update Utility, natch.
Very often I'll find myself with a device like a Particle Photon, Wilderness Labs Meadow, or some STM32 device that uses the ST Bootloader.
The Mac and Linux instructions usually say something like "plug it in and party on" but folks like myself with Windows have to set up a WinUSB Driver (libusb-win32 or libusbK) as dfu-util uses those libraries to speak to USB devices.
If you plug in a device, the vast majority of Windows users want the device to 'just work.' My non-technical parent doesn't want Generic USB drivers so they can flash the firmware on their mouse. I, however, as an aristocrat, sometimes want to do low-level stuff and flash an OS on a Microcontroller.
Today, the easiest way to swap the "inbox" driver with WinUSB is using a utility called Zadig. Per their docs:
Zadig is a Windows application that installs generic USB drivers,
such as WinUSB, libusb-win32/libusb0.sys or libusbK, to help you access USB devices.
It can be especially useful for cases where:
- you want to access a device using a libusb-based application
- you want to upgrade a generic USB driver
- you want to access a device using WinUSB
If you follow the instructions when flashing a device and don't have the right USB driver installed you'll likely get an error like this:
Cannot open DFU device 0483:df11
That's not a lot to go on. The issue is that the default "inbox" driver that Windows uses for devices like this isn't set up for Generic USB access with libraries like "libusb."
Install a generic USB driver for your device - WinUSB using Zadig
Run Zadig and click Options | List All Devices.
Here you can see me finding the ST device within Zadig and replacing the driver with WinUSB. In my case the device was listened under STM32 Bootloader. Be aware that you can mess up your system if you select something like your WebCam instead of the hardware device you mean to select.
In this state, you can see in the Device Manager that there's an "STM Device in DFU Mode."
Now I run Zadig and replace the driver with WinUSB. Here's the result. Note the SUCCESS and the changed Driver on the left.
Here the STM32 Bootloader device now exists in Universal Serial Bus Devices in Device Manager.
Now I can run dfu-util --list again. Note the before and after in the screenshot below. I run dfu-util --list and it finds nothing. I replace the bootloader with the generic WinUSB driver and run dfu-util again and it finds the devices.
At this point I can follow along and flash my devices per whatever instructions my manufacturer/project/boardmaker intends.
NOTE: When using dfu-util on Windows, I recommend you either be smart about your PATH and add dfu-util, or better yet, make sure the dfu-util.exe and libusb.dlls are local to your firmware so there's no confusion about what libraries are being used.
I'd love to see this extra step in Windows removed, but for now, I hope this write up makes it clearer and helps the lone Googler who finds this post.
Sponsor: Develop Xamarin applications without difficulty with the latest JetBrains Rider: Xcode integration, JetBrains Xamarin SDK, and manage the required SDKs for Android development, all right from the IDE. Get it today