DFU Runtime Device Stack
LibXR::USB::DfuRuntimeClass provides the Runtime DFU interface used while the application firmware is already running.
It only handles runtime DETACH. It does not implement DNLOAD / UPLOAD itself. After the host requests an upgrade, the device jumps to the board-level bootloader once the configured timeout expires.
1. Class and Construction
1.1 LibXR::USB::DfuRuntimeClass
Constructor:
using JumpCallback = void (*)(void*);
LibXR::USB::DfuRuntimeClass dfu_rt(
jump_to_bootloader,
jump_ctx,
50,
"XRUSB DFU RT");
Parameters:
jump_to_bootloader: board-level jump callback executed after timeoutjump_ctx: callback contextdetach_timeout_ms: defaultDETACHtimeoutinterface_string: interface string, default"XRUSB DFU RT"
If webusb_landing_page_url and webusb_vendor_code are provided, the class also publishes an additional WebUSB BOS capability.
By default, the runtime DFU path also exposes a WinUSB MS OS 2.0 descriptor set through the shared DfuInterfaceClassBase, using function-scoped WinUSB metadata.
2. Interface and Descriptors
DfuRuntimeClass contributes one interface only, does not use an IAD, and does not allocate extra data endpoints.
GetInterfaceCount() = 1HasIAD() = falsebInterfaceClass = 0xFEbInterfaceSubClass = 0x01bInterfaceProtocol = 0x01
Key fields of the Runtime DFU Functional Descriptor:
bmAttributes- includes
WillDetachwhenjump_to_bootloaderis available - otherwise stays
0
- includes
wDetachTimeOut- comes from the constructor, or later from the
DETACHrequestwValue
- comes from the constructor, or later from the
wTransferSize = 0bcdDFUVersion = 0x0110
3. Request Handling
Runtime DFU mainly handles these class requests:
| Request | Behavior |
|---|---|
DETACH | accepted only in APP_IDLE, records timeout and enters APP_DETACH |
GETSTATUS | returns current state and remaining timeout |
GETSTATE | returns current DFU state |
Notes:
DETACHdoes not jump immediately- the real effect of
DETACHis “record the deadline, then wait for externalProcess()calls” - if there is no
jump_to_bootloadercallback,DETACHreturns not supported
4. Runtime Behavior
Runtime DFU requires periodic external calls to Process():
dfu_rt.Process();
Process() does only one thing:
- when
detach_pending_is set and the timeout has expired, calljump_to_bootloader(jump_ctx)
So this path can live in:
- the main loop
- a periodic task
- a timed scheduler entry
It does not require a dedicated background thread, but something must call Process() periodically. Otherwise the host can issue DETACH, but the device will never actually jump into the bootloader.
5. Usage Example
#include "dfu/dfu_runtime.hpp"
static void JumpToBootloader(void*)
{
BoardJumpToBootloader();
}
LibXR::USB::DfuRuntimeClass dfu_rt(JumpToBootloader, nullptr, 50);
// USB class list: {{&dfu_rt}}
// usb_dev.Init();
// usb_dev.Start();
for (;;)
{
dfu_rt.Process();
}
6. Relation to DFU Bootloader
- Runtime DFU: exposes
DETACHin application mode and jumps into bootloader after timeout - DFU Bootloader: handles
DNLOAD / UPLOAD / manifestin bootloader mode
If your project does not use a separate bootloader, this class is usually unnecessary.