UM0392
UM0392
User manual
Introduction
This manual describes the different development stages of a Device firmware upgrade
application, based on the DFU solution provided by STMicroelectronics (DfuSe).
Contents
2 Pre-development phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1 Gathering needed files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 STTube Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3 DfuSe programming interface files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4 Driver installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4.1 Licence key . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4.2 Interface GUID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4.3 Create an Inf file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3 Development phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.1 DFU Enumeration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.1.1 Get device information set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.1.2 Get number of elements in the device information set . . . . . . . . . . . . . . . 7
3.1.3 Get details about a device interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.1.4 Open the DFU driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.1.5 Get device descriptor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.1.6 Get DFU Descriptor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2 DFU Identification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2.1 Check for DFU protocol version . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2.2 Check for firmware operating mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.2.3 Check for supported DFU operations . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.3 DFU Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.3.1 General DFU operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.3.2 DETACH operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.3.3 RETURN operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.3.4 UPLOAD operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.3.5 ERASE operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.3.6 UPGRADE operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.4 DFU basic requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.4.1 DFU_DNLOAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.4.2 DFU_UPLOAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.4.3 DFU_GETSTATUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2/23
UM0392 Contents
3.4.4 DFU_GETSTATE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.4.5 DFU_ABORT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.5 Managing DFU Image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.5.1 Get Image settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.5.2 Create a DFU image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.5.3 Add an image element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.5.4 Remove an image element . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.5.5 Store a DFU Image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.5.6 Load a DFU Image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4 Document references . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
5 Revision history . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3/23
Device Firmware Upgrade STMicroelectronics Extension UM0392
The reason for creating this DFU extension is that the standard device firmware upgrade
protocol is too specialized in terms of protocol versus the target or the application.
This extension makes it easy to use DFU with all 8 or 32-bit microcontrollers, simply letting
the PC side know the target memory mapping. In addition, the DFU file format has been
updated, to be able to build DFU files from standard 8 or 32-bit s19, hex or bin formats. The
result is a new revision of the standard DFU revision 1.1, called DfuSe for Device firmware
upgrade STMicroelectronics Extension.
4/23
UM0392 Pre-development phase
2 Pre-development phase
5/23
Pre-development phase UM0392
In our case, we define two GUIDs, for DFU and Application modes
GUID_DFU = {3FE809AB-FB91-4CB5-A643-69670D52366E}
GUID_APP = {CB979912-5029-420a-AEB1-34FC0A7D5726}
Otherwise, GUIDs can be redefined according to the developer’s choice. To generate new
GUIDs use the GUIDgen Microsoft tool contained in this package.
Then with this customized inf file, the correct values will be entered in the registry while the
driver is installed.
6/23
UM0392 Development phase
3 Development phase
This gets a handle to a device information set that contains all installed devices that
matched the supplied parameters.
SP_DEVICE_INTERFACE_DATA DeviceData;
DeviceData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);
for (int Index = 0; SetupDiEnumDeviceInterfaces (info, NULL, & Guid,
Index,&DeviceData);Index++)
{
...
}
When there are no more interfaces, SetupDiEnumDeviceInterfaces function fails and returns
false, and GetLastError returns ERROR_NO_MORE_ITEMS.
7/23
Development phase UM0392
2. Allocate an appropriately sized buffer and call the function again to get the interface
details. The interface detail returned by this function consists of a device path that can
be passed to Win32 functions such as CreateFile.
PSP_INTERFACE_DEVICE_DETAIL_DATA detail;
detail=(PSP_INTERFACE_DEVICE_DETAIL_DATA) new BYTE[RequiredSize];
detail->cbSize=sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
SP_DEVINFO_DATA dev_info_data= {sizeof (SP_DEVINFO_DATA)};
if(SetupDiGetDeviceInterfaceDetail(info, &ifData, detail,
RequiredSize, NULL, &dev_info_data))
printf(detail->DevicePath);//DevicePath is the symbolic link of the
//DFU device.
Retrieve a specified Plug and Play device property, if SPDRP_DEVICEDESC value is set,
retrieved property is a REG_SZ string containing the description of a device.
8/23
UM0392 Development phase
HANDLE hDle;
if(STDFU_Open((LPSTR) detail->DevicePath, &hDle)==STDFU_NOERROR)
{ STDFU_Close(&hDle);}
HANDLE hDle;
USB_DEVICE_DESCRIPTOR DeviceDesc;
if (STDFU_GetDeviceDescriptor(&hDle, &DeviceDesc) == STDFU_NOERROR)
{
CString Tmp;
Tmp.Format("%04X", DeviceDesc.idVendor) ; Printf(Tmp);
Tmp.Format("%04X", DeviceDesc.idProduct); Printf(Tmp);
Tmp.Format("%04X", DeviceDesc.bcdDevice); Printf(Tmp);
}
HANDLE hDle;
DFU_FUNCTIONAL_DESCRIPTOR DFUDesc;
UINT DFUInterfaceNum;
UINT NbOfAlternates;
memset(&DFUDesc, 0, sizeof(DFUDesc));
if(STDFU_GetDFUDescriptor(&hDle,&DFUInterfaceNum,&NbOfAlternates,
&DFUDesc)==STDFUPRT_NOERROR)
{ ... }
9/23
Development phase UM0392
if((DFUDesc.bcdDFUVersion<0x011A)||(DFUDesc.bcdDFUVersion>=0x0120))
printf("Bad DFU protocol version. Should be 1.1A");
DFU_FUNCTIONAL_DESCRIPTOR DFUDesc;
UINT D1, D2;
memset(&m_CurrDevDFUDesc, 0, sizeof(DFUDesc));
STDFU_GetDFUDescriptor(&hDle,&D1,&D2,&DFUDesc);
10/23
UM0392 Development phase
The Operation attribute is used to identify the operation to be launched; it contains one of
the following codes:
(OPERATION_DETACH, OPERATION_RETURN, OPERATION_UPLOAD,
OPERATION_ERASE and OPERATION_UPGRADE).
Context.Operation = OPERATION_UPGRADE;
Context.bDontSendFFTransfersForUpgrade = TRUE;
The hImage attribute is a handle image pointer, used when a download, erase or upload
operation is to be launched.
Context.hImage=hImage;
The OperationCode argument contains a reference to the launched operation after calling
STDFUPRT_LaunchOperation API.
DWORD OperationCode;
11/23
Development phase UM0392
DFUThreadContext Context;
DWORD dwRet;
HANDLE hImage;
lstrcpy(Context.szDevLink, DFUName); // DFUName is the device
symbolic link
Context.DfuGUID=GUID_DFU;
Context.AppGUID=GUID_APP;
Context.Operation=OPERATION_DETACH;
Context.hImage=NULL;
dwRet=STDFUPRT_LaunchOperation(&Context, &OperationCode);
if (dwRet != STDFUPRT_NOERROR)
Context.ErrorCode=dwRet;
DWORD OperationCode;
DFUThreadContext Context;
DWORD dwRet;
HANDLE hImage;
Int TargetSel = 0;
CString Name;
lstrcpy(Context.szDevLink,DFUName);
Context.DfuGUID=GUID_DFU;
Context.AppGUID=GUID_APP;
Context.Operation=OPERATION_RETURN;
(STDFUPRT_CreateMappingFromDevice((LPSTR)(LPCSTR)DFUName,
&pMapping, &NbAlternates);
Name = pMapping[i].Name;
STDFUFILES_CreateImageFromMapping(&hImage, pMapping+TargetSel);
STDFUFILES_SetImageName(hImage, (LPSTR)(LPCSTR)Name);
STDFUFILES_FilterImageForOperation(hImage, pMapping + TargetSel,
OPERATION_RETURN, FALSE);
Context.hImage=hImage;
dwRet=STDFUPRT_LaunchOperation(&Context, &OperationCode);
if (dwRet!=STDFUPRT_NOERROR)
Context.ErrorCode=dwRet;
DWORD OperationCode;
int TargetSel=0;
PMAPPING pMapping;
STDFUPRT_CreateMappingFromDevice((LPSTR)(LPCSTR)DFUName,&pMapping+
TargetSel, &NbAlternates);
12/23
UM0392 Development phase
Then the pMapping record is used to extract the DFU image from the device, a name is
attributed to identify the image in the file.
HANDLE hImage;
CString Name = ‘dfu_image_name’;
STDFUFILES_CreateImageFromMapping(&hImage, pMapping+TargetSel);
STDFUFILES_SetImageName(hImage, (LPSTR)(LPCSTR)Name);
Before saving the image, a filter must be performed for the upload operation, using a
STDFUFILES_FilterImageForOperation call.
STDFUFILES_FilterImageForOperation(hImage, pMapping+TargetSel,
OPERATION_UPLOAD, FALSE);
When this is done, the upload operation can be launched using a DFUThreadContext class
instance.
When the operation is successfully terminated, the image is ready to be stored in a dfu file.
At this stage two cases arise, either to store the image in a new file or in an existing file.
WORD Vid=0x0483;
WORD Pid=0xDF11;
WORD Bcd=0x011A;
CString UpFileName = ‘new dfu file’;
dwRet=STDFUFILES_CreateNewDFUFile((LPSTR)(LPCSTR)UpFileName,&hFile,
Vid, Pid,Bcd);
The Vid, PID and Bcd values are used to identify the image as usable for devices with given
identifiers
dwRet=STDFUFILES_OpenExistingDFUFile((LPSTR)(LPCSTR)UpFileName,
&hFile, NULL, NULL, NULL, NULL);
13/23
Development phase UM0392
dwRet=STDFUFILES_AppendImageToDFUFile(hFile, Context.hImage);
DWORD OperationCode;
PDWORD pNbAlternates;
PMAPPING pMapping;
PHANDLE pHandle;
// Programming the operation contex
lstrcpy(Context.szDevLink, DFUName);
Context.DfuGUID=GUID_DFU;
Context.AppGUID=GUID_APP;
Context.Operation=OPERATION_ERASE;
Context.bDontSendFFTransfersForUpgrade= TRUE;
STDFUPRT_CreateMappingFromDevice((LPSTR)(LPCSTR)DFUName,&pMapping,
&NbAlternates);
STDFUFILES_CreateImageFromMapping(pHandle, pMapping);
STDFUFILES_FilterImageForOperation(hImage, m_pMapping+TargetSel,
OPERATION_ERASE, FALSE);
Context.hImage=hImage;
if( STDFUPRT_LaunchOperation(&Context, &OperationCode) !=
STDFUPRT_NOERROR)
{
Printf(‘Erase error’);
}
Note: As the download operation should be preceded by an Erase operation, the erase image can
be created as a duplication of the download image using the STDFUFILES_DuplicateImage
and then filtered for Erase.
14/23
UM0392 Development phase
DWORD OperationCode;
DWORD dwRet;
HANDLE hFile;
BYTE NbImages;
CString DownFileName = "DnLoadfilename.dfu";
dwRet=STDFUFILES_OpenExistingDFUFile((LPSTR)(LPCSTR)DownFileName,
&hFile, NULL, NULL, NULL, &NbImages);
When successful, the call returns a STDFUFILES_NOERROR value. The DFU file can
contain more than one image, in this case you must retrieve the suitable image for the
selected device interface, by comparing the device index to the Alternate value of all
available images.
int TargetSel=0;
BOOL bFound;
HANDLE hImage;
for(int i=0;i<NbImages;i++)
{
HANDLE Image;
BYTE Alt;
if(STDFUFILES_ReadImageFromDFUFile(hFile,i,
&Image)==STDFUFILES_NOERROR)
{
if(STDFUFILES_GetImageAlternate(Image,
&Alt)==STDFUFILES_NOERROR)
{
if (Alt==TargetSel)
{
hImage =Image;
bFound =TRUE;
break;
}
STDFUFILES_DestroyImage(&Image);
}
}
STDFUFILES_CloseDFUFile(hFile);
}
If the suitable image is recovered, and before programming the download operation you
must retrieve the mapping details from the device, and filter the image for download.
PMAPPING pMapping;
DWORD NbAlternates;
BOOL UpgradeOptimized = TRUE;
CString DFU_Name ; // Device symbolic link.
15/23
Development phase UM0392
The UpgradeOptimized Boolean value is used to indicate if the upgrade operation ignores
the FFh data
Now, one instance of DFUThreadContext class is to be created and programmed to launch
the operation.
DFUThreadContext Context;
lstrcpy (Context.szDevLink, DFU_Name);
Context.DfuGUID=GUID_DFU;
Context.AppGUID=GUID_APP;
Context.Operation=OPERATION_UPGRADE;
Context.bDontSendFFTransfersForUpgrade= TRUE;
Context.hImage=hImage;
dwRet=STDFUPRT_LaunchOperation(&Context, &OperationCode);
if (dwRet!=STDFUPRT_NOERROR)
{
Context.ErrorCode=dwRet;
}
3.4.1 DFU_DNLOAD
Download the given binary data into the device flash memory at the specified address. Use
the STDFU_Dnload to perform this request.
HANDLE hDle;
BYTE* pBuffer; // Data buffer to be downloaded
ULONG nBytes; // Size of data in byte
USHORT nBlock; // Block number
... // Copy data to be downloaded into pBuffer
if (STDFU_Open((LPSTR) DFUName, &hDle)==STDFU_NOERROR)
{
STDFU_Dnload(hDle, pBuffer, nBytes, nBlock)
STDFU_Close(&hDle);
}
3.4.2 DFU_UPLOAD
The purpose of Upload is to provide the capability to retrieve and archive the firmware of a
device. Use STDFU_Upload to perform this request.
16/23
UM0392 Development phase
HANDLE hDle;
BYTE* pBuffer; // buffer, the uploaded data will be copied to.
ULONG nBytes; // Size of data in byte
USHORT nBlock; // Block number
...
if (STDFU_Open((LPSTR) DFUName, &hDle)==STDFU_NOERROR)
{
STDFU_Upload(hDle, pBuffer, nBytes, nBlock)
STDFU_Close(&hDle);
}
3.4.3 DFU_GETSTATUS
To get the current DFU Status, use the STDFUPRT_GetOperationStatus method. The
LastDFUStatus record in the DFUThreadContext class instance given as second argument
will be updated, and you can retrieve the status using the bStatus attribute.
CString Tmp;
DFUThreadContext Context;
DWORD OperationCode;
... // programm Context for requested operation.
STDFUPRT_LaunchOperation(&Context, OperationCode)
// The OperationCode is the opeartion refrence returned by
//LaunchOperation call.
STDFUPRT_GetOperationStatus(OperationCode, &Context);
Tmp.Format("DFU Status: Context->LastDFUStatus.bStatus);
Printf(Tmp);
The user-mode software can use the basic STDFU_GetStatus API directly:
PHANDLE phDevice;
DFUSTATUS * DfuStatus;
...
STDFU_Getstatus(phDevice, DfuStatus);
3.4.4 DFU_GETSTATE
To get the current DFU State, use the STDFUPRT_GetOperationStatus method. The
LastDFUStatus record in the DFUThreadContext class instance given as second argument
will be updated, and you can retrieve the status using the bState attribute.
CString Tmp;
DFUThreadContext Context;
DWORD OperationCode;
... // programm Context for requested operation.
STDFUPRT_LaunchOperation(&Context, OperationCode)
// The OperationCode is the opeartion refrence returned by
//LaunchOperation call.
STDFUPRT_GetOperationStatus(OperationCode, &Context);
17/23
Development phase UM0392
The user-mode software can use the basic STDFU_GetState API directly:
UCHAR* pState;
PHANDLE phDevice;
...
STDFU_Getstate(phDevice,pState);
3.4.5 DFU_ABORT
To send an abort request to the DFU device use the STDFU_Abort method, knowing that
this request is sent automatically by the operation, to do this use the
STDFUPRT_StopOperation method.
DFUThreadContext Context;
PHANDLE phDevice;
...
// Send an Abort request to the DFU device.
STDFU_Abort(phDevice);
...
// Then stop a launched operation
// The OperationCode, retrives after STDFUPRT_LaunchOperation call
//references the operation to be stopped.
STDFUPRT_StopOperation(OperationCode, &Context);
int TargetSel=0;
BYTE NbAlternates;
18/23
UM0392 Development phase
PMAPPING pMapping;
HANDLE hImage;
CString Name = ‘dfu_image_name’;
BYTE NbAlternates;
HANDLE hImage;
CString Name = ‘dfu_image_name’;
HANDLE hImage;
DWORD ElementIndex = 0;
CString Name = ‘dfu_image_name’;
DFUIMAGEELEMENT Element;
BOOL bInsert=TRUE;//Element will be inserted at the specified index.
19/23
Development phase UM0392
HANDLE hImage;
DWORD ElementIndex = ...;
...
STDFUFILES_DestroyImageElement(hImage, ElementIndex);
20/23
UM0392 Document references
4 Document references
21/23
Revision history UM0392
5 Revision history
22/23
UM0392
Information in this document is provided solely in connection with ST products. STMicroelectronics NV and its subsidiaries (“ST”) reserve the
right to make changes, corrections, modifications or improvements, to this document, and the products and services described herein at any
time, without notice.
All ST products are sold pursuant to ST’s terms and conditions of sale.
Purchasers are solely responsible for the choice, selection and use of the ST products and services described herein, and ST assumes no
liability whatsoever relating to the choice, selection or use of the ST products and services described herein.
No license, express or implied, by estoppel or otherwise, to any intellectual property rights is granted under this document. If any part of this
document refers to any third party products or services it shall not be deemed a license grant by ST for the use of such third party products
or services, or any intellectual property contained therein or considered as a warranty covering the use in any manner whatsoever of such
third party products or services or any intellectual property contained therein.
UNLESS OTHERWISE SET FORTH IN ST’S TERMS AND CONDITIONS OF SALE ST DISCLAIMS ANY EXPRESS OR IMPLIED
WARRANTY WITH RESPECT TO THE USE AND/OR SALE OF ST PRODUCTS INCLUDING WITHOUT LIMITATION IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE (AND THEIR EQUIVALENTS UNDER THE LAWS
OF ANY JURISDICTION), OR INFRINGEMENT OF ANY PATENT, COPYRIGHT OR OTHER INTELLECTUAL PROPERTY RIGHT.
UNLESS EXPRESSLY APPROVED IN WRITING BY AN AUTHORIZED ST REPRESENTATIVE, ST PRODUCTS ARE NOT
RECOMMENDED, AUTHORIZED OR WARRANTED FOR USE IN MILITARY, AIR CRAFT, SPACE, LIFE SAVING, OR LIFE SUSTAINING
APPLICATIONS, NOR IN PRODUCTS OR SYSTEMS WHERE FAILURE OR MALFUNCTION MAY RESULT IN PERSONAL INJURY,
DEATH, OR SEVERE PROPERTY OR ENVIRONMENTAL DAMAGE. ST PRODUCTS WHICH ARE NOT SPECIFIED AS "AUTOMOTIVE
GRADE" MAY ONLY BE USED IN AUTOMOTIVE APPLICATIONS AT USER’S OWN RISK.
Resale of ST products with provisions different from the statements and/or technical features set forth in this document shall immediately void
any warranty granted by ST for the ST product or service described herein and shall not create or extend in any manner whatsoever, any
liability of ST.
Information in this document supersedes and replaces all information previously supplied.
The ST logo is a registered trademark of STMicroelectronics. All other names are the property of their respective owners.
23/23