AN_344 FT51A DFU_Sample

Application Note
AN_344
FT51A DFU Sample
Version 1.0
Issue Date: 2015-12-21
This document provides a guide for using the FT51A development
environment to incorporate DFU (Device Firmware Upgrade) support in
firmware.
Use of FTDI devices in life support and/or safety applications is entirely at the user’s risk, and the
user agrees to defend, indemnify and hold FTDI harmless from any and all damages, claims, suits
or expense resulting from such use.
Future Technology Devices International Limited (FTDI)
Unit 1, 2 Seaward Place, Glasgow G41 1HH, United Kingdom
Tel.: +44 (0) 141 429 2777 Fax: + 44 (0) 141 429 2758
Web Site: http://ftdichip.com
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
Table of Contents
1 Introduction .............................................................. 4
1.1 Overview .............................................................................4
1.2 Features ..............................................................................4
1.3 Limitations ..........................................................................4
1.4 Scope ..................................................................................4
2 DFU Overview ............................................................ 5
2.1 DFU Library Overview ..........................................................5
2.2 Firmware Overview .............................................................6
2.2.1
Run-Time Mode .............................................................................................. 6
2.2.2
DFU Mode ...................................................................................................... 7
2.2.1
FT51 Libraries ................................................................................................ 7
2.3 Host PC Application Overview .............................................7
3 DFU Firmware ............................................................ 9
3.1 USB Descriptors ..................................................................9
3.1.1
Run-Time Descriptors ...................................................................................... 9
3.1.2
DFU Descriptors ........................................................................................... 11
3.1.3
Descriptor Selection ...................................................................................... 13
3.2 USB Class Requests ........................................................... 14
3.3 USB Reset Handler ............................................................ 15
3.4 Timer ................................................................................. 16
3.5 Device Detach-Attach ........................................................ 16
4 DFU Application ....................................................... 17
4.1 libusb-win32 .....................................................................17
4.1.1
Installing libusb-win32 Driver ......................................................................... 17
4.2 WinUSB ............................................................................. 17
4.2.1
Installing WinUSB Driver ............................................................................... 17
4.3 Loading Firmware Files ..................................................... 17
4.4 Programming DFU Interfaces ............................................ 17
2
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
5 Possible Improvements ........................................... 18
5.1 Obfuscating DFU Commands ............................................. 20
5.2 Adding Manifestation Checks............................................. 20
5.3 Recovery ........................................................................... 20
5.4 Security ............................................................................. 20
6 Contact Information ................................................ 21
Appendix A – References ............................................. 23
Document References ............................................................... 23
Acronyms and Abbreviations..................................................... 23
Appendix B – List of Tables & Figures .......................... 24
List of Figures ........................................................................... 24
Appendix C – Revision History ..................................... 25
3
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
1 Introduction
This application note documents the FT51A DFU library and provides an example firmware project
for the FT51A and host PC application. The host PC application will communicate with the firmware
on the FT51A to update the contents of the FT51A MTP Flash. All communication is via the USB
interface.
1.1 Overview
The DFU firmware project and host PC application together demonstrate a reusable method for
implementing firmware updates to an FT51A device. The FT51A need only be connected to a host
PC via the USB interface.
The DFU firmware is added to the normal functional firmware programmed into the FT51A and is
only activated when special commands are sent by the host PC. It can therefore be built-in to any
FT51A firmware and used when required.
An example application would be to allow Field Service Engineers to update firmware on devices
embedded in industrial machinery, or end users to apply an update to a device based on an
FT51A.
1.2 Features
The DFU library has the following features:
-
Open source library layered on FT51A USB Library.
Can be added to existing firmware by adding an interface to the configuration descriptor.
Ability to download firmware from host PC to device.
User firmware implements the USB requests. This allows non-standard methods to be
implemented to add obfuscation.
1.3 Limitations
The DFU library has the following limitations:
-
No manifestation stage. The device cannot support manifestation and cannot therefore
process a firmware image before programming.
As with most firmware updates, it is imperative that the firmware download is not interrupted
either by power interruption or by interrupting the programming application as the data
downloaded immediately overwrites the contents of the MTP Flash rendering the existing contents
invalid.
A recovery method is to use the FT51A programmer/debugger module and the “FT51prg.exe” tool
to re-load valid code to the MTP Flash. Details on this tool can be found in Application Note
AN_289 FT51A Programming Guide. The executable and source code for “FT51prg.exe” are
available in the FT51A Software Development Kit.
1.4 Scope
The guide is intended for developers who are creating applications, extending FTDI provided
applications or implementing example applications for the FT51A.
In the reference of the FT51A, an “application” refers to firmware that runs on the FT51A;
“libraries” are source code provided by FTDI to help user’s access specific hardware features of the
chip.
The FT51A Tools are currently only available for Microsoft Windows platform and are tested on
Windows 7 and Windows 8.1.
4
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
2 DFU Overview
The DFU protocol and requirements are documented in the Device Firmware Upgrade 1.1
specification:
http://www.usb.org/developers/docs/devclass_docs/DFU_1.1.pdf
The FT51A implementation is for devices which are capable of downloading and can optionally
perform any detach-attach sequence to switch between DFU and run-time modes.
Due to the memory constraints of the FT51A it is not practical to implement manifestation. This
would require storing and validating the firmware before programming the MTP Flash.
2.1 DFU Library Overview
The DFU library uses the FT51A USB library and calls the following functions:
-
USB_transfer()
USB_stall_endpoint()
It is contained in a single source code file “ft51_usb_dfu.c” and has a library header
“ft51_usb_dfu.h”.
The DFU Attributes supported by the library, as described in the bmAttributes field of the DFU
Functional Descriptor, are bitWillDetach and bitCanDnload. The bitManifestationTolerant and
bitCanUpload features are not supported.
Calls to the library are made by the firmware when class requests are received for the DFU
interface or when a bus state change on the USB is detected.
Additionally there is a timer handler which must be called every millisecond to implement the
detach timer described in the specification.
The DFU library implements a state machine to provide the functionality required by the DFU
specification. A schematic of the state machine is shown in Figure 2.1. Run-time mode states are
red and DFU mode states are blue.
The “USB Reset” transitions can be either performed by the host resetting the USB or by the
device detaching from the USB. If the bitWillDetach attribute is set then the device must perform
detach. If it is not set then the host must reset the USB.
5
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
DFU_DETACH
request
appIDLE
appDETACH
USB Reset
dfuIDLE
TIMEOUT
DFU_DNLOAD
request
DFU_CLRSTATUS
request
USB Reset
dfuERROR
DFU_DNLOAD
invalid request
DFU_GET_STATUS
request
DFU_DNLOAD
request
DFU_GET_STATUS
request
dfuMANIFESTWAIT-RESET
dfuDNLOAD-IDLE
dfuMANIFESTSYNC
dfuDNLOAD-SYNC
DFU_DNLOAD
end request
Figure 2.1 DFU States
2.2 Firmware Overview
The firmware is specifically written to allow it to be adapted and easily included in other FT51A
projects.
Firmware will initialise and configure the FT51A as normal, setting up the USB device as required.
It will however, add some code to the USB standard requests handlers to support the DFU library.
The only libraries required are the FT51A USB library and parts of the FT51A General Config
library. If LED indicators are desired then the IOMUX library can be added to configure output pins
for LEDs.
2.2.1
Run-Time Mode
When in run-time mode, the firmware will return a configuration descriptor containing the normal
functions of the FT51A firmware plus one additional interface descriptor for the DFU. This is the
DFU functional descriptor.
The firmware will decode standard and vendor requests as normal, but check for class requests
which are addressed to the DFU interface. If these are found then a function in the DFU library will
be called. From run-time mode the DFU can check the status and state of the DFU state machine
and initiate a DFU_DETACH to transition into DFU mode.
6
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
If the bitWillDetach attribute is not set the DFU_DETACH request will start a timer and continue.
If a USB reset is observed before the timer expires then the DFU state machine will move to DFU
mode.
If the bitWillDetach attribute is set the device will detach from the USB using a call to the USB
library. The host will see this as a disconnection and will re-enumerate the device when it
reattaches to the USB.
With both methods a function handler for USB reset events will call the DFU library to change from
run-time to DFU mode.
2.2.2
DFU Mode
When DFU mode is entered, the normal functions of the firmware are not available and the
firmware will return different device and configuration descriptors. This will have a single interface
describing the DFU mode. The device will be re-enumerated by the host and the new device and
configuration descriptors read.
Standard USB requests will be handled as normal, but class requests to the DFU interface (this
may be a different interface number in DFU mode from the run-time mode) will be passed to the
DFU library.
If the bitWillDetach attribute is not set the device will rely on the host performing a USB reset
when programming is finished, otherwise the device will detach from the USB and force the host to
re-enumerate the device.
Again, the function handler for USB reset events must also call the DFU library to change from DFU
back to run-time mode and resetting the FT51A to run the newly programmed firmware.
2.2.3
FT51A Libraries
The DFU firmware uses the FT51A USB library, DFU library, general config library and the IOMUX
library. The IOMUX library is not used in the example code but is included to allow further
functionality to be added.
2.2.4
WinUSB Drivers
The firmware will use WCID (Windows Compatible ID) to tell a Microsoft Windows operating
system that is requires WinUSB to be installed for the DFU interface. This is achieved by the
firmware responding to a Microsoft defined string descriptor to identify the device as supporting
WCID and providing the host PC with a vendor request code for the next stage of WCID.
The second stage tells the host PC which drivers to load for the device by responding to a set of
vendor requests with information required.
When this is successfully completed the DFU interface is accessible to host PC applications using
the WinUSB API. It is also compatible with libusb for Windows.
Please note that the WinUSB drivers will need to be installed when the device is first connected.
They will also need to be installed when the device changes from run-time mode to DFU mode.
Each time the driver is loaded it may go to Windows Update to check for newer drivers.
2.3 Host PC Application Overview
The host PC application recommended is dfu-util. This can be obtained from http://dfuutil.sourceforge.net/
It uses the libusb library to communicate with the device via Microsoft WinUSB drivers.
The dfu-util program is a command line application that programs a binary file onto the device.
The FT51A Eclipse plugin has a Post Build step to produce a “.bin” binary file from the IHX (Intel
HeX file) output file using the makebin utility supplied by SDCC.
7
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
The format of the dfu-util command line is typically as follows:
dfu-util –D filename.bin
Refer to the documentation for dfu-util for further options.
The first time dfu-util switches the device from run-time to DFU mode it may timeout waiting for
Windows to install the WinUSB driver. Re-running dfu-util when this process is complete will recommence the firmware update correctly.
8
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
3 DFU Firmware
The firmware included in the example code demonstrates implementing run-time mode
descriptors, DFU mode descriptors, switching from run-time to DFU mode and updating firmware.
It has no run-time features; however, these can be added by extending the run-time configuration
descriptor and adding code for the features.
The control endpoint max packet size is defined in the header of the firmware code for
convenience along with the Product IDs (PIDs) used in the example. The setting of
bMaxPacketSize0 in the device descriptor MUST match the size of the control endpoint max packet
size set in the “ep_size” member of the USB_ctx structure when the USB library is initialised.
The following code is used to set the packet sizes for the control endpoint for both the device
descriptor and USB initialisation.
// USB Endpoint Zero packet size (both must match)
#define USB_CONTROL_EP_MAX_PACKET_SIZE 8
#define USB_CONTROL_EP_SIZE USB_EP_SIZE_8
The DFU library does not calculate addresses from the block numbers passed in the DFU_DNLOAD
request. The application specifies both the size of the programming block and calculates the
address. This increases the flexibility of the library and allows the application to set block sizes and
even how addresses are calculated.
The maximum block size for the DFU library is 64 bytes as defined in DFU_MAX_BLOCK_SIZE in
“ft51_usb_dfu.h”. This can be changed to a smaller value by modifying the definition of
DFU_BLOCK_SIZE.
#define DFU_BLOCK_SIZE DFU_MAX_BLOCK_SIZE
3.1 USB Descriptors
The DFU firmware stores two sets of device descriptors and configuration descriptors. It stores a
single table of string descriptors as the strings for run-time and DFU modes can be selected by the
descriptors as needed from the same table.
The USB class, subclass and protocols along with other general USB definitions are found in the file
“ft51_usb.h” library include file.
3.1.1
Run-Time Descriptors
The first set of descriptors is the run-time set. The device descriptor contains the VID and PID for
the run-time function.
9
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
USB_device_descriptor device_descriptor_runtime =
{
.bLength = 0x12,
.bDescriptorType = 0x01,
.bcdUSB = USB_BCD_VERSION_2_0,
.bDeviceClass = USB_CLASS_DEVICE,
.bDeviceSubClass = USB_SUBCLASS_DEVICE,
.bDeviceProtocol = USB_PROTOCOL_DEVICE,
.bMaxPacketSize0 = USB_CONTROL_EP_MAX_PACKET_SIZE,
.idVendor = USB_VID_FTDI,
// 0x0403 (FTDI)
.idProduct = DFU_USB_PID_RUNTIME, // 0x0fed
.bcdDevice = 0x0101,
.iManufacturer = 0x01, // String 1
.iProduct = 0x02,
// String 2
.iSerialNumber = 0x03, // String 3
.bNumConfigurations = 0x01
};
The configuration descriptor would normally contain interface descriptors and endpoint descriptors
for the run-time function. These are not implemented in this example.
The last interface descriptor, and the only one in this configuration descriptor, is for a DFU
interface that implements no endpoints. All DFU communication is through the control endpoints to
the DFU interface.
The USB class of Application Specific allows the subclass to specify that it is a Device Firmware
Update (DFU) and the protocol indicates that this is Run-Time mode.
10
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
// Structure containing layout of configuration descriptor
struct config_descriptor_runtime
{
USB_configuration_descriptor configuration;
USB_interface_descriptor interface;
USB_dfu_functional_descriptor functional;
};
struct config_descriptor_runtime config_descriptor_runtime =
{
.configuration.bLength = 0x09,
.configuration.bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION,
.configuration.wTotalLength = sizeof(struct config_descriptor_runtime),
.configuration.bNumInterfaces = 0x01,
.configuration.bConfigurationValue = 0x01,
.configuration.iConfiguration = 0x00,
.configuration.bmAttributes = USB_CONFIG_BMATTRIBUTES_VALUE,
.configuration.bMaxPower = 0xFA, // 500 mA
// ---- INTERFACE DESCRIPTOR for DFU Interface ---.interface.bLength = 0x09,
.interface.bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
.interface.bInterfaceNumber = DFU_USB_INTERFACE_RUNTIME,
.interface.bAlternateSetting = 0x00,
.interface.bNumEndpoints = 0x00,
.interface.bInterfaceClass = USB_CLASS_APPLICATION, // Application Specific Class
.interface.bInterfaceSubClass = USB_SUBCLASS_DFU,
// Device Firmware Update
.interface.bInterfaceProtocol = USB_PROTOCOL_DFU_RUNTIME, // Runtime Protocol
.interface.iInterface = 0x05, // String 5
// ---- FUNCTIONAL DESCRIPTOR for DFU Interface ---.functional.bLength = 0x09,
.functional.bDescriptorType = USB_DESCRIPTOR_TYPE_DFU_FUNCTIONAL,
.functional.bmAttributes = USB_DFU_BMATTRIBUTES_CANDNLOAD, // bitCanDnload
.functional.wDetatchTimeOut = DFU_TIMEOUT, // suggest 8192ms
.functional.wTransferSize = DFU_BLOCK_SIZE,// typically 64 bytes
.functional.bcdDfuVersion = USB_BCD_VERSION_DFU_1_1, // DFU Version 1.1
};
The DFU functional descriptor contains a field called bmAttributes. This describes the sections of
the DFU specification that are supported by the implementation.
The DFU library supports firmware downloading and device detach-attach. It does not support
uploading or manifestation. Therefore the bmAttributes mask needs the “bitCanDnload” bit set,
and “bitWillDetach” can be set or clear. It is not set in this example for clarity.
The “bitCanUpload” and “bitManifestationTolerant” must be clear.
3.1.2
DFU Descriptors
The device descriptor contains the VID and PID for the DFU function. This may or may not be the
same as the run-time VID and PID.
11
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
USB_device_descriptor device_descriptor_dfumode =
{
.bLength = 0x12,
.bDescriptorType = USB_DESCRIPTOR_TYPE_DEVICE,
.bcdUSB = USB_BCD_VERSION_2_0,
.bDeviceClass = USB_CLASS_DEVICE,
.bDeviceSubClass = USB_SUBCLASS_DEVICE,
.bDeviceProtocol = USB_PROTOCOL_DEVICE,
.bMaxPacketSize0 = USB_CONTROL_EP_MAX_PACKET_SIZE,
.idVendor = USB_VID_FTDI,
// 0x0403 (FTDI)
.idProduct = DFU_USB_PID_DFUMODE, // 0x0fee
.bcdDevice = 0x0101,
.iManufacturer = 0x01,
.iProduct = 0x04,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01
};
The configuration descriptor for DFU will contain only an interface descriptor and a functional
descriptor for the DFU interface.
The USB class, subclass and protocol indicate that this device is now in DFU mode.
// Structure containing layout of configuration descriptor
struct config_descriptor_dfumode
{
USB_configuration_descriptor configuration;
USB_interface_descriptor interface;
USB_dfu_functional_descriptor functional;
};
struct config_descriptor_dfumode config_descriptor_dfumode =
{
.configuration.bLength = 0x09,
.configuration.bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION,
.configuration.wTotalLength = sizeof(struct config_descriptor_dfumode),
.configuration.bNumInterfaces = 0x01,
.configuration.bConfigurationValue = 0x01,
.configuration.iConfiguration = 0x00,
.configuration.bmAttributes = USB_CONFIG_BMATTRIBUTES_VALUE,
.configuration.bMaxPower = 0xFA, // 500 mA
// ---- INTERFACE DESCRIPTOR for DFU Interface ---.interface.bLength = 0x09,
.interface.bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
.interface.bInterfaceNumber = DFU_USB_INTERFACE_DFUMODE,
.interface.bAlternateSetting = 0x00,
.interface.bNumEndpoints = 0x00,
.interface.bInterfaceClass = USB_CLASS_APPLICATION, // Application Specific Class
.interface.bInterfaceSubClass = USB_SUBCLASS_DFU,
// Device Firmware Update
.interface.bInterfaceProtocol = USB_PROTOCOL_DFU_DFUMODE, // Runtime Protocol
.interface.iInterface = 0x05, // String 5
// ---- FUNCTIONAL DESCRIPTOR for DFU Interface ---.functional.bLength = 0x09,
.functional.bDescriptorType = USB_DESCRIPTOR_TYPE_DFU_FUNCTIONAL,
.functional.bmAttributes = USB_DFU_BMATTRIBUTES_CANDNLOAD, // bitCanDnload
.functional.wDetatchTimeOut = DFU_TIMEOUT, // suggest 8192ms
.functional.wTransferSize = DFU_BLOCK_SIZE,// typically 64 bytes
.functional.bcdDfuVersion = USB_BCD_VERSION_DFU_1_1,
};
12
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
The same bmAttributes mask must appear for the DFU functional descriptor in both run-time and
DFU modes.
3.1.3
Descriptor Selection
The standard request handler for GET_DESCRIPTOR requests needs to select the run time or DFU
mode descriptors. The firmware is responsible for ensuring the correct descriptors are returned to
the host PC.
Determining if the firmware is in run-time
dfu_is_runtime() function from the DFU library.
or DFU
mode
is achieved
by
calling the
A non-zero response will select the run-time mode descriptors and a zero response, the DFU mode
descriptors.
FT51_STATUS standard_req_get_descriptor(USB_device_request *req)
{
uint8_t
*src = NULL;
uint16_t
length = req->wLength;
uint8_t
hValue = req->wValue >> 8;
uint8_t
lValue = req->wValue & 0x00ff;
uint8_t
i, slen;
switch (hValue)
{
case USB_DESCRIPTOR_TYPE_DEVICE:
if (dfu_is_runtime())
{
src = (char *)&device_descriptor_runtime;
}
else
{
src = (char *)&device_descriptor_dfumode;
}
if (length > sizeof(USB_device_descriptor)) // too many bytes requested
length = sizeof(USB_device_descriptor); // Entire structure.
break;
case USB_DESCRIPTOR_TYPE_CONFIGURATION:
if (dfu_is_runtime())
{
src = (char *)&config_descriptor_runtime;
if (length > sizeof(config_descriptor_runtime))
length = sizeof(config_descriptor_runtime);
}
else
{
src = (char *)&config_descriptor_dfumode;
if (length > sizeof(config_descriptor_dfumode))
length = sizeof(config_descriptor_dfumode);
}
break;
// too many bytes requested
// Entire structure.
// too many bytes requested
// Entire structure.
The FT51A USB library will return the structure pointed to by the standard_req_get_descriptor()
function.
Note that string descriptor selection is not shown in this code sample. It does not depend on the
selection of run-time or DFU modes.
13
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
3.2 USB Class Requests
The firmware is responsible for handling USB class requests. It must determine if the firmware is
in run-time or DFU mode and whether a request has been directed to the DFU interface. This must
not interfere with other class requests that may be decoded in the firmware.
The first check is that the class request is aimed at an interface:
FT51_STATUS class_req_cb(USB_device_request *req)
{
FT51_STATUS
status = FT51_FAILED;
uint8_t
interface = LSB(req->wIndex) & 0x0F;
// For DFU requests ensure the recipient is an interface...
if ((req->bmRequestType & USB_BMREQUESTTYPE_RECIPIENT_MASK) ==
USB_BMREQUESTTYPE_RECIPIENT_INTERFACE)
{
If this is correct then the firmware must check if it is in run-time or DFU mode before checking the
interface number. The interface number for the DFU mode may differ from that of the run-time
mode.
if (dfu_is_runtime())
{
if ((interface == DFU_USB_INTERFACE_RUNTIME))
{
switch (req->bRequest)
{
case USB_CLASS_REQUEST_DETACH:
dfu_class_req_detach(req->wValue);
// Only uncomment if bitWillDetach is set in bmAttributes
//usb_detach_attach();
status = FT51_OK;
break;
case USB_CLASS_REQUEST_GETSTATUS:
dfu_class_req_getstatus();
status = FT51_OK;
break;
case USB_CLASS_REQUEST_GETSTATE:
dfu_class_req_getstate();
status = FT51_OK;
break;
}
}
}
For run-time mode, only the DFU_DETACH, DFU_GETSTATUS and DFU_GETSTATE requests are
valid. All other requests will fail and stall the control endpoint.
The example shows that the DFU_DETACH request will not perform a detach as “bitWillDetach” is
not set in the DFU functional descriptor.
If it is not in run-time mode then a different set of requests are valid.
14
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
else
{
if (interface == DFU_USB_INTERFACE_DFUMODE)
{
switch (req->bRequest)
{
case USB_CLASS_REQUEST_DNLOAD:
dfu_class_req_download(req->wValue * DFU_MAX_BLOCK_SIZE, req->wLength);
status = FT51_OK;
break;
case USB_CLASS_REQUEST_GETSTATUS:
dfu_class_req_getstatus();
if (dfu_is_wait_reset())
{
// Only uncomment if bitWillDetach is set in bmAttributes
//usb_detach_attach();
}
status = FT51_OK;
break;
case USB_CLASS_REQUEST_GETSTATE:
dfu_class_req_getstate();
status = FT51_OK;
break;
case USB_CLASS_REQUEST_CLRSTATUS:
dfu_class_req_clrstatus();
status = FT51_OK;
break;
case USB_CLASS_REQUEST_ABORT:
dfu_class_req_abort();
status = FT51_OK;
break;
default:
case USB_CLASS_REQUEST_UPLOAD:
// Unknown or unsupported request.
break;
}
}
}
}
return status;
}
In this mode, the DFU_DNLOAD, DFU_GETSTATUS, DFU_CLRSTATUS, DFU_GETSTATE and
DFU_ABORT requests are valid. DFU_UPLOAD is specifically checked for and disallowed although
ignoring it would have the same effect.
Again the device will not perform any detach as “bitWillDetach” is not set in the DFU functional
descriptor. The DFU_GETSTATUS request is the trigger for a detach-attach sequence when it is
set.
3.3 USB Reset Handler
Transitions from the appDETACH state to the dfuIDLE state and from dfuMANIFEST-WAIT-RESET
state to appIDLE are controlled by the USB reset handler function. This is set by the “reset”
member of the USB_ctx structure when the USB library is initialised.
When the reset occurs the dfu_reset() function should be called. If the new firmware which has
been downloaded is to be run then the function will return a non-zero value. If no further action is
required then it will return zero.
15
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
void reset_cb(uint8_t status)
{
(void) status;
USB_set_state(DEFAULT);
if (dfu_reset())
{
device_revert();
}
}
In this way, when the dfuMANIFEST-WAIT-RESET state is reached the application will wait until a
USB bus reset from the host (or a disconnect event) before loading and running the new
application from MTP Flash.
A reset occurring when in appDETACH state will move the DFU state to dfuIDLE. This would be
noticed the next time the firmware calls dfu_is_runtime().
3.4 Timer
The DFU needs a millisecond timer to accurately return to the appIDLE state from the appDETACH
state. The dfu_timer() function in the DFU library should be called every millisecond to enable
this.
void detach_interrupt(const uint8_t flags)
{
(void)flags; // Flags not currently used
// The DFU detach timer must be called once per millisecond
dfu_timer();
// Reload the timer
TH0 = MSB(MICROSECONDS_TO_TIMER_TICKS(1000));
TL0 = LSB(MICROSECONDS_TO_TIMER_TICKS(1000));
}
void detach_timer_initialise(void)
{
// Register our own handler for interrupts from Timer 0
interrupts_register(detach_interrupt, interrupts_timer0);
// Timer0 is controlled by TMOD bits 0 to 3, and TCON bits 4 to 5.
TMOD &= 0xF0; // Clear Timer0 bits
TMOD |= 0x01; // Put Timer0 in mode 1 (16 bit)
// Set the count-up value so that it rolls over to 0 after 1 millisecond.
TH0 = MSB(MICROSECONDS_TO_TIMER_TICKS(1000));
TL0 = LSB(MICROSECONDS_TO_TIMER_TICKS(1000));
TCON &= 0xCF; // Clear Timer0's Overflow and Run flags
TCON |= 0x10; // Start Timer0 (set its Run flag)
}
3.5 Device Detach-Attach
A function is provided that will detach and then reattach the device from the USB. This is only
required if “bitWillDetach” is set in the DFU functional descriptor.
16
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
void usb_detach_attach(void)
{
// Short delay
ms_timer = 10; while (ms_timer > 0);
// Disable USB device to force an reset
USB_finalise();
ms_timer = 10; while (ms_timer > 0);
// Start the USB device.
usb_setup();
}
17
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
4 WCID Selection
The Windows Compatible ID (WCID) method is used to select the WinUSB driver for the DFU
interface.
4.1 WCID String Descriptor
The first step is to respond to a USB String Descriptor request for string number 0xEE with an
application specific vendor request code to use for the rest of the WCID process.
This firmware defines the vendor request code to be 0xf1. This can be any value from 0x00 to
0xff.
#define WCID_VENDOR_REQUEST_CODE
0xF1
A macro is defined in ft51_usb.h to craft a Microsoft WCID string descriptor from the required
vendor request code.
__code uint8_t wcid_string_descriptor[USB_MICROSOFT_WCID_STRING_LENGTH] = {
USB_MICROSOFT_WCID_STRING(WCID_VENDOR_REQUEST_CODE)
};
When responding to a GET_DESCRIPTOR request for a string the special case is added for the
Microsoft WCID string descriptor.
case USB_DESCRIPTOR_TYPE_STRING:
// Special case: WCID descriptor
if (lValue == USB_MICROSOFT_WCID_STRING_DESCRIPTOR)
{
src = (uint8_t *)wcid_string_descriptor;
length = sizeof(wcid_string_descriptor);
break;
}
After this string descriptor check has been performed then the normal string descriptors can be
processed and returned.
4.2 WCID Vendor Requests
Once Windows has determined that a device supports WCID then it will issue vendor requests to
get further information. This information determines which driver is installed and what GUIDs can
be assigned to an interface to identify it to applications.
This firmware will request the WinUSB driver and provide a GUID for a device interface.
Once the vendor request is confirmed as the correct vendor request code then the firmware will
respond with a compatible ID or a device GUID.
if (req->bRequest == WCID_VENDOR_REQUEST_CODE)
{
if (req->bmRequestType & USB_BMREQUESTTYPE_DIR_DEV_TO_HOST)
{
switch (req->wIndex)
{
case USB_MICROSOFT_WCID_FEATURE_WINDEX_COMPAT_ID:
if (length > sizeof(wcid_feature_runtime)) // too many bytes requested
length = sizeof(wcid_feature_runtime); // Entire structure.
// Return a compatible ID feature descriptor.
if (dfu_is_runtime())
18
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
{
USB_transfer(USB_EP_0, USB_DIR_IN,
(uint8_t *) &wcid_feature_runtime, length);
status = FT51_OK;
}
else
{
USB_transfer(USB_EP_0, USB_DIR_IN,
(uint8_t *) &wcid_feature_dfumode, length);
status = FT51_OK;
}
break;
case USB_MICROSOFT_WCID_FEATURE_WINDEX_DEVICE_GUID:
if (length > sizeof(wcid_device_guid_dfu)) // too many bytes requested
length = sizeof(wcid_device_guid_dfu); // Entire structure.
// Return a compatible ID feature descriptor.
if (((dfu_is_runtime()) && (req->wValue == DFU_USB_INTERFACE_RUNTIME))
|| ((!dfu_is_runtime()) && (req->wValue == DFU_USB_INTERFACE_DFUMODE)))
{
USB_transfer(USB_EP_0, USB_DIR_IN,
(uint8_t *) &wcid_device_guid_dfu, length);
status = FT51_OK;
}
break;
}
Run-time mode and DFU mode compatible IDs are required since the interface number of the DFU
interface may differ between the two modes.
The GUID defined in this application for the FT51A is "{1eaaaa95-1bd6-49c2-b4ae286583f61227}".
19
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
5 Possible Improvements
The lack of a manifestation stage could allow unwanted, unauthorised or unverified firmware to be
programmed on the device.
If required then some additional checking can be done to protect the device.
5.1 Obfuscating DFU Commands
A simple method would be to change the DFU requests so that they did not match the
specification. The host PC application would also change to match this.
Changes could be as simple as changing the values for bRequest in the SETUP token or adding
additional steps into the DFU state machine.
A host PC application could conceivably issue disguised or undocumented commands to the FT51A
to enable the DFU mode without the DFU interface appearing in the run-time mode configuration
descriptor.
Note: A USB analyser can be used to reverse engineer these changes.
5.2 Adding Manifestation Checks
A manifestation phase could be implemented by downloading the firmware twice. The first pass
could check the validity and checksum of the download and the second pass program the firmware
into the MTP Flash.
An alternative method, which would provide a non-secure manifestation check, would be to
program the MTP Flash with code and at the same time validate it. If the validation does not
succeed then the Shadow RAM could be committed back to the MTP Flash to overwrite the
downloaded firmware. This would not provide a secure solution to validating firmware.
A simpler method would be to implement manifestation in blocks. This could be in the form of
some encryption or validation checksum. The blocks would have to be smaller than the available
__xdata area on the FT51A.
All these methods add to the size of the code required to implement DFU on the FT51A.
5.3 Recovery
As implemented, a failed download may have programmed some MTP Flash memory but not
completed the whole program. In this case the firmware could “commit” the Shadow RAM contents
back to MTP Flash rather than rely on the host PC application trying again. It could result in
corrupt firmware on the device if the device is power cycled with the MTP Flash in an inconsistent
state.
5.4 Security
Some firmware could be secured using the TOP_SECURITY_LEVEL register. This can prevent write
access to certain parts of the MTP Flash. It could therefore be manipulated to prevent access to
portions of code while allowing other parts to be modified.
20
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
6 Contact Information
Head Office – Glasgow, UK
Branch Office – Tigard, Oregon, USA
Future Technology Devices International Limited
Unit 1, 2 Seaward Place, Centurion Business Park
Glasgow G41 1HH
United Kingdom
Tel: +44 (0) 141 429 2777
Fax: +44 (0) 141 429 2758
Future Technology Devices International Limited
(USA)
7130 SW Fir Loop
Tigard, OR 97223-8160
USA
Tel: +1 (503) 547 0988
Fax: +1 (503) 547 0987
E-mail (Sales)
E-mail (Support)
E-mail (General Enquiries)
[email protected]
[email protected]
[email protected]
E-Mail (Sales)
E-Mail (Support)
E-Mail (General Enquiries)
[email protected]
[email protected]
[email protected]
Branch Office – Taipei, Taiwan
Branch Office – Shanghai, China
Future Technology Devices International Limited
(Taiwan)
2F, No. 516, Sec. 1, NeiHu Road
Taipei 114
Taiwan , R.O.C.
Tel: +886 (0) 2 8791 3570
Fax: +886 (0) 2 8791 3576
Future Technology Devices International Limited
(China)
Room 1103, No. 666 West Huaihai Road,
Shanghai, 200052
China
Tel: +86 21 62351596
Fax: +86 21 62351595
E-mail (Sales)
E-mail (Support)
E-mail (General Enquiries)
E-mail (Sales)
E-mail (Support)
E-mail (General Enquiries)
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
Web Site
http://ftdichip.com
Distributor and Sales Representatives
Please visit the Sales Network page of the FTDI Web site for the contact details of our distributor(s) and sales
representative(s) in your country.
System and equipment manufacturers and designers are responsible to ensure that their systems, and any Future Technology
Devices International Ltd (FTDI) devices incorporated in their systems, meet all applicable safety, regulatory and system-level
performance requirements. All application-related information in this document (including application descriptions, suggested
FTDI devices and other materials) is provided for reference only. While FTDI has taken care to assure it is accurate, this
information is subject to customer confirmation, and FTDI disclaims all liability for system designs and for any applications
assistance provided by FTDI. Use of FTDI devices in life support and/or safety applications is entirely at the user’s risk, and the
user agrees to defend, indemnify and hold harmless FTDI from any and all damages, claims, suits or expense resulting from
such use. This document is subject to change without notice. No freedom to use patents or other intellectual property rights is
implied by the publication of this document. Neither the whole nor any part of the information contained in, or the product
described in this document, may be adapted or reproduced in any material or electronic form without the prior written consent
of the copyright holder. Future Technology Devices International Ltd, Unit 1, 2 Seaward Place, Centurion Business Park,
Glasgow G41 1HH, United Kingdom. Scotland Registered Company Number: SC136640
21
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
22
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
Appendix A – References
Document References
FTDI MCU web page: http://www.ftdichip.com/MCU.html
SDCC web page: http://sdcc.sourceforge.net
Eclipse CDT web page: http://www.eclipse.org/cdt
GnuWin32 make web page: http://gnuwin32.sourceforge.net/packages/make.htm
GnuWin32 coreutils web page: http://gnuwin32.sourceforge.net/packages/coreutils.htm
Eclipse SDCC web page: http://eclipse-sdcc.sourceforge.net
Hex2Bin web page: http://hex2bin.sourceforge.net
MinGW web page: http://www.mingw.org
GDB online documentation web page: https://sourceware.org/gdb/onlinedocs/gdb
USB Test and Measurement Class specification:
http://www.usb.org/developers/docs/devclass_docs/USBTMC_1_006a.zip
USB Device Firmware Update Class specification:
http://www.usb.org/developers/docs/devclass_docs/DFU_1.1.pdf
Acronyms and Abbreviations
Terms
Description
DFU
Device Firmware Upgrade
MTP Flash
Multiple Time Program – non-volatile memory used to store program code
on the FT51A.
SDCC
Small Device C Compiler
USB
Universal Serial Bus
USB-IF
USB Implementers Forum
23
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
Appendix B – List of Tables & Figures
List of Figures
Figure 2.1 DFU States.......................................................................................................... 6
Figure 4.1 Installing Device Driver Message ......................................................................... 17
Figure 4.2 Device Driver Software Not Installed Message ....................................................... 17
Figure 4.3 Device Manager Entry for FT51 Runtime ............................................................... 17
Figure 4.4 Windows Security Confirmation Box ..................................................................... 17
Figure 4.5 Update Driver Software Confirmation Box ............................................................. 17
24
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited
Application Note
AN_344 FT51A DFU Sample
Version 1.0
Document Reference No.: FT_001122
Clearance No.: FTDI# 481
Appendix C – Revision History
Document Title:
AN_344 FT51 DFU Sample
Document Reference No.:
FT_001122
Clearance No.:
FTDI# 481
Product Page:
http://www.ftdichip.com/FTProducts.htm
Document Feedback:
Send Feedback
Revision
Changes
Date
1.0
Initial Release
2015-12-21
25
Product Page
Document Feedback
Copyright © 2015 Future Technology Devices International Limited