[Beta] Jump to system memory boot from user application by fpistm · Pull Request #710 · stm32duino/Arduino_Core_STM32

@matthijskooijman @fpistm

This adds support for the DFU runtime protocol, which allows resetting
into the bootloader using a DFU command. This allows e.g. dfu-util to
handle the complete firmware upload, including the needed reset.

This consists of a number of changes:
 - An extra interface is added to the USB configuration descriptor. This
   descriptor has two parts (interface descriptor and functional
   descriptor) which together indicate to a host that this device
   supports DFU.
 - Control packets to this new interface are detected by the CDC code an
   forwarded to a new USBD_DFU_Runtime_Control() function.
 - This new function handles the DFU GET_STATE, GET_STATUS and
   DFU_DETACH commands. The former are optional, but simple enough, the
   latter is mandatory and handles resetting into the bootloader.
 - The CDC device descriptor is changed to become a composite device
   (CDC and DFU). This allows operating systems (in particular Windows,
   Linux did not really need this) to identify two different subdevices,
   and install different drivers for each (on Windows, this is serusb
   for the CDC part and WinUSB/libusb for the DFU part). Without this,
   dfu-util on Windows could not access the DFU commands when the serial
   driver was loaded.

   Because the CDC functionality already exposes two interfaces (which
   together form a single serial port), an IAD (Interface Association
   Descriptor) is inserted before these interfaces to group them
   together in a single subdevice. No IAD is needed for the DFU
   interface, since it is just a single interface.

   To become a composite device, the device class must be changed from
   CDC to a composite device class. This was originally class 0/0/0, but
   together with the IAD, a new EF/2/1 deviceclass was also introduced,
   which is used now.

Note that this only adds descriptors and a command handler on the
default control endpoint, so no extra (scarce) endpoints are used by
this, just a bit of memory.

This commit is still a bit rough, because:
 - The DFU descriptors and code are now pulled in directly by the CDC
   code (and HID is not supported yet). Ideally, there should be some
   kind of pluggable USB library where different interfaces can be
   registered independent of each other (see also
   stm32duino#687).
 - The interface number is hardcoded in the DFU descriptor.
 - The reset to bootloader happens immediately, while it might be better
   to wait a short while to allow the current USB transaction to
   complete.
 - DFU support is unconditionally advertised, while not all boards might
   support DFU.