Anp.Stm32.UsbDfu
1.0.0
dotnet add package Anp.Stm32.UsbDfu --version 1.0.0
NuGet\Install-Package Anp.Stm32.UsbDfu -Version 1.0.0
<PackageReference Include="Anp.Stm32.UsbDfu" Version="1.0.0" />
<PackageVersion Include="Anp.Stm32.UsbDfu" Version="1.0.0" />
<PackageReference Include="Anp.Stm32.UsbDfu" />
paket add Anp.Stm32.UsbDfu --version 1.0.0
#r "nuget: Anp.Stm32.UsbDfu, 1.0.0"
#:package Anp.Stm32.UsbDfu@1.0.0
#addin nuget:?package=Anp.Stm32.UsbDfu&version=1.0.0
#tool nuget:?package=Anp.Stm32.UsbDfu&version=1.0.0
Anp.Stm32.UsbDfu
STM32 USB DFU/DFUse Library for .NET
A pure managed .NET library for STM32 USB DFU/DFUse operations — device discovery, firmware update, memory read/write/erase, and DFUse memory layout parsing. No external dependencies — all USB communication is handled through direct P/Invoke to OS-native APIs.
Features
- Full DFU lifecycle — device discovery, flash erase (mass and selective), firmware write, read-back verification, exit to application
- Multiple USB backends — WinUSB, STTub30 (legacy), and libusb-1.0, with automatic backend resolution from device path or platform
- Cross-platform — Windows (.NET Framework 4.8 / .NET 8.0), Linux and macOS (.NET 8.0 via libusb). Also targets .NET Standard 2.0.
- DFUse memory layout parsing — supports complex flash topologies including dual-bank, with graceful fallback when descriptors are unavailable
- Device discovery and monitoring — built-in enumeration and polling-based device watcher for plug/unplug detection
- Progress reporting — determinate and indeterminate progress events suitable for CLI and GUI applications
- Pure managed code — no native wrappers, COM references, or NuGet native dependencies to manage
Installation
Install from NuGet:
dotnet add package Anp.Stm32.UsbDfu
Or via the Package Manager Console:
Install-Package Anp.Stm32.UsbDfu
Quick Start
Enumerate and Update
// Discover connected STM32 DFU devices
var devices = DfuDeviceDiscovery.Enumerate();
if (devices.Count == 0)
return;
using (var device = devices[0])
{
device.ProgressChanged += (s, e) => Console.WriteLine(e.Message);
device.Open();
byte[] firmware = File.ReadAllBytes("firmware.bin");
device.UpdateFirmware(firmware, eraseAllFlash: false, verify: true);
device.ExitDfuMode();
}
Configure Discovery Defaults
Discovery defaults control which devices are found by DfuDeviceDiscovery.Enumerate() and by DfuDeviceWatcher. Both use the same shared defaults, so configuring once applies everywhere:
DfuDeviceDiscovery.ConfigureDefaults(options =>
{
options.VendorId = 0x0483; // STMicroelectronics (null to match any VID)
options.ProductId = 0xDF11; // DFU mode (null to match any PID)
options.AllowedBackends = UsbBackends.WinUsb; // Or WinUsb | StTub30, LibUsb, Auto
options.ProbeDeviceInfo = true; // Briefly open each device to read product name
// and serial number during enumeration
});
ConfigureDefaults is thread-safe — changes take effect on subsequent discovery calls without affecting any enumeration already in progress. When ProbeDeviceInfo is true, the watcher will also probe newly arrived devices so that DisplayName and SerialNumber are populated immediately in the DeviceArrived event.
Watch for Devices
using (var watcher = new DfuDeviceWatcher(pollInterval: TimeSpan.FromSeconds(2)))
{
watcher.DeviceArrived += (s, e) =>
{
Console.WriteLine($"Connected: {e.Device.DisplayName}");
};
watcher.DeviceRemoved += (s, e) =>
{
Console.WriteLine($"Removed: {e.DevicePath}");
};
watcher.Start();
// ...
watcher.Stop();
}
Create a Device from a Known Path
If you already have a device path from external discovery (e.g. using PnpDeviceToolkit or another PnP monitoring solution), you can create a DfuDevice directly:
// Device path obtained from external PnP discovery / monitoring
string devicePath = @"\\?\usb#vid_0483&pid_df11#...#{dee824ef-729b-4a0e-9c14-b7117d33a817}";
using (var device = new DfuDevice(devicePath, UsbBackends.Auto, probeDeviceInfo: true))
{
device.Open();
// Read 1024 bytes from flash start
byte[] data = device.ReadMemory(0x08000000, 1024);
}
This is useful when integrating with applications that already have their own device enumeration, want finer control over PnP notifications (RegisterDeviceNotification / WMI / DeviceInformationStatics), or need to monitor non-DFU interfaces alongside DFU devices.
Memory Operations
Read and write operations work with any memory region accessible through DFU — flash, RAM, option bytes, OTP, etc. Erase operations apply to flash only.
Read
device.Open();
// Read from flash
byte[] firmware = device.ReadMemory(startAddress: 0x08000000, numBytes: 4096);
// Read option bytes
byte[] optionBytes = device.ReadMemory(startAddress: 0x1FFF7800, numBytes: 16);
Erase
// Mass erase (entire flash)
device.EraseAllFlash();
// Selective erase (block-aligned range)
device.EraseFlashBlocks(startAddress: 0x08000000, endAddress: 0x0800FFFF);
Write
byte[] data = File.ReadAllBytes("data.bin");
// Flash must be erased before writing
device.EraseFlashBlocks(0x08000000, 0x08000000 + (uint)data.Length - 1);
device.WriteMemory(data, startAddress: 0x08000000);
Firmware Update
byte[] firmware = File.ReadAllBytes("firmware.bin");
// Erase, write, and verify in one call
device.UpdateFirmware(firmware, eraseAllFlash: false, verify: true);
Remove Read Protection
// WARNING: This erases all flash and resets the device.
// A transport exception is expected after this operation.
try
{
device.RemoveReadProtection();
}
catch (DfuTransportException)
{
// Expected — device has reset
}
DFUse Memory Map
STM32 devices in DFU mode expose their memory layout via USB string descriptors. The library parses these automatically and makes them available for inspection:
device.Open();
// List all memory regions reported by the device
IReadOnlyList<string> regions = device.GetMemoryRegionNames();
// e.g. ["Internal Flash", "Option Bytes"]
// Get the parsed layout for a specific region
MemoryLayout flash = device.GetMemoryRegionLayout("Internal Flash");
Console.WriteLine($"Flash: {flash.StartAddress:X8}..{flash.EndAddress:X8}, {flash.Blocks.Count} blocks");
// Or get everything at once
IReadOnlyList<MemoryLayout> allRegions = device.GetMemoryRegions();
Configuration
Mass Erase Timeout
Mass erase duration varies by device. The default timeout is 40 seconds. Adjust if needed:
device.MassEraseTimeout = TimeSpan.FromSeconds(60);
Erase Strategy
By default, full-flash erase uses the DFUse mass erase command. To force block-by-block erase:
device.PreferMassEraseForFullErase = false;
Note: if the device's DFUse memory layout cannot be parsed (fallback layout), mass erase is used regardless of this setting because block boundaries are unknown.
USB Backends
| Backend | Platform | Driver | Notes |
|---|---|---|---|
| WinUSB | Windows | WinUSB (inbox) | Recommended. Install with Zadig or a custom INF. |
| STTub30 | Windows | STTub30 | Legacy. Deprecated by ST, incompatible with Memory Integrity. |
| LibUsb | Linux, macOS, Windows | libusb-1.0 | Requires libusb-1.0 installed. On Windows, requires libusb-1.0.dll on PATH or next to the library, uses WinUSB. |
Backend selection is automatic — the library infers the backend from the device path and platform. To override:
var device = new DfuDevice(path, backend: UsbBackends.WinUsb);
Target Frameworks
- .NET Framework 4.8
- .NET Standard 2.0
- .NET 8.0
The library uses C# 7.3 language features for broad toolchain compatibility.
Exception Hierarchy
All library-specific exceptions derive from DfuException:
| Exception | Meaning |
|---|---|
DfuException |
Base class for all DFU errors |
DfuTransportException |
USB transport failure (includes backend, device path, native error code) |
DfuDeviceNotOpenException |
Operation attempted on a closed device |
DfuVerificationException |
Read-back verification mismatch (includes offset and address) |
InvalidDfuStateException |
Device reported an unexpected DFU state |
Limitations
No read-modify-write. Flash write operations require the target range to be erased first. The library does not perform read-modify-write internally — erase granularity is always at the block level as defined by the DFUse memory layout. If you need to update a portion of a block without losing adjacent data, read the full block first, merge your changes, erase, and write back. The parsed
MemoryLayoutand itsBlockscollection provide the block boundaries needed to implement this.Single-consumer.
DfuDevicedoes not support concurrent operations. Callers must serialize access if sharing a device instance across threads.Polling-based watcher.
DfuDeviceWatcheruses periodic enumeration rather than OS-level PnP notifications. For lower-latency or more granular plug/unplug detection, use an external PnP monitoring solution (e.g. PnpDeviceToolkit) and constructDfuDeviceinstances directly from discovered paths.
References
- USB DFU 1.1 Specification — USB-IF Device Firmware Upgrade specification
- AN3156 — STMicroelectronics DFUse protocol application note
- WinUSB API — Microsoft WinUSB documentation
- libusb — Cross-platform USB access library
License
MIT — see LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 is compatible. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.8
- No dependencies.
-
.NETStandard 2.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 216 | 2/16/2026 |