STM32 DFU -- Device Firmware Upgrade
DFU Class Requests
Get Status
The Host employs the DFU_GETSTATUS request to facilitate synchronization with the device.
This status gives information on the execution of the previous request: in progress/OK/Fail/...
The device responds to the DFU_GETSTATUS request with a payload packet containing the following data:
Clear Status
Each time the device detects and reports an error indication status to the host in response to a DFU_GETSTATUS request, it enters the dfuERROR state.
After reporting any error status, the device can not leave the dfuERROR state, until it has received a DFU_CLRSTATUS request.
Upon receipt of DFU_CLRSTATUS, the device sets status to OK and move to the dfuIDLE state.
Once the device is in the dfuIDLE state it is then able to move to other states.
Device State
The state reported is the current state of the device up to transmission of the response.
The values specitifed in the bState field are identical to those reported in DFU_GETSTATUS.
DFU_ABORT request
The DFU_ABORT request forces the device to exit from any other state and return to the DFU_IDLE state.
The device sets the OK status on receipt of this request. For more information, see the corresponding state transition summary.
STM32 DFU bootloader commands
The DFU_DNLOAD and DFU_UPLOAD requests are mainly used to perform simple Write Memory and Read Memory operations.
They are also used to initiate the integrated bootloader commands (write, read unprotect, erase, set address, etc.).
The DFU_GETSTATUS command then triggers the command execution.
In the DFU download request the command is selected through the wValue parameter in the USB request structure.
If wValue = 0 then the data sent by the host after the request is a bootloader command code.
The first byte is the command code and the other bytes (if any) are the data related to this command.
In the DFU upload request the command is selected through the wValue parameter in the USB request structure.
If wValue = 0 then Get Command is selected and performed.
1. This operation is allowed but not effective: the bootloader does not return an error but the operation is not executed since the sectors are write-protected.
This applies only to the Flash memory. It does not apply to the RAM memory or the option byte area.
2. This operation is allowed but has no meaning since the memory is not protected.
3. In this case, both the Flash memory (from 0x0800 0000) and the RAM are erased. The option byte area is reset to default values.
DFU_UPLOAD Read memory
The Read memory operation is selected when wValue > 1.
The host requests the device to send a specified number of data bytes (wLength) from valid memory address (see note) of
the internal Flash memory, embedded RAM, system memory or from the option bytes.
Note: Refer to Section 4: DFU_UPLOAD request commands for more details about the valid memory addresses for the device you are using.
The allowed number of bytes to be read depends on the memory target:
• For the internal Flash memory, embedded RAM and system memory: read size can be from 2 to 2048 bytes
• For the option bytes: read size should be equal to the option byte block size
• For other memory locations, refer to the section "Important considerations” depending on the product in AN2606.
The address, from which the host requests to read data, is computed using the value of wBlockNumber (wValue) and the address pointer according to the following formula:
Address = ( (wBlockNum – 2) × wTransferSize) + Address_Pointer, < wTransferSize is the length of the requested data buffer.>
The address pointer should be previously specified through a Set Address Pointer command (using a DFU_DNLOAD request).
Otherwise (if no address was previously specified) the device assumes that it is the internal Flash start address (0x08000000).
If the Flash Read Protection is enabled, the Read operation is not performed and the returned device status is (Status = dfuERROR, State = errVENDOR)
whatever the target (internal Flash memory, embedded RAM, system memory or option bytes).
DFU_UPLOAD Get
This command is selected when wValue = 0.
The host requests to read the commands supported by the bootloader.
After receiving this command, the device returns N bytes representing the command codes.
The STM32 sends bytes as follows (N = 4):
Byte 1: 0x00 - Get command
Byte 2: 0x21 - Set Address Pointer
Byte 3: 0x41 - Erase
Byte 4: 0x92 - Read Unprotect
Before issuing an Upload request, the host has to check that the device is in a correct state (dfuIDLE or dfuUPLOAD-IDLE state) and that there is no error reported in the status.
If the device is not in the required state/status, the host has to clear any error (DFU_CLRSTATUS request) and get the new status until the device returns to dfuIDLE state.
DFU_DNLOAD request commands
The download request is used to perform different commands.
The command selection is done through the value of parameter wValue in the USB request structure.
The following operations are supported:
• Write Memory (wValue > 1)
• Set Address Pointer (wValue = 0 and first byte = 0x21)
• Erase (wValue = 0 and first byte = 0x41)
• Read Unprotect (wValue = 0 and first byte = 0x92)
• Leave DFU (leave DFU mode and Jump to application)
1. Operations needing System Reset are: Read Unprotect command and Write operations to the option bytes.
2. After returning to the dfuDNBUSY state, the device executes the requested operation and performs a system reset.
The host may simply wait for the next enumeration or perform Get status again
but the device will not be able to respond, unless it fails to execute the requested operation.
DFU_DNLOAD Write Memory (wValue >1)
The Write memory operation is selected when wValue > 1.
The host requests the device to receive a specified number of data bytes (wLength) to load them into valid memory addresses (see note) in
internal Flash memory, embedded RAM or option bytes.
Note: Refer to Section 4: DFU_UPLOAD request commands for more details about the valid memory addresses for the device you are using.
The allowed number of bytes to be written depends on the memory target:
• For the internal Flash memory and embedded RAM: write size can be from 2 to 2048 bytes
• For the option bytes: write size should be equal to the option byte block size
• For other memory locations, refer to the section "Important considerations” depending on the product in AN2606.
Note: A different write size is possible for the option bytes but it is recommended to write the entire block at a time in order to ensure data integrity.
When the target is the option byte area, the address pointer must always be the start address of the option bytes, otherwise, the request is not performed.
The Write memory operation is effectively executed only when a DFU_GETSTATUS request is issued by the host.
If the status returned by the device is not dfuDNBUSY, then an error has occurred.
A second DFU_GETSTATUS request is needed to check if the command has been correctly executed, except when the destination is the option byte area
(in this case the device is immediately reset after the write operation completion).
If the received address is wrong or unsupported, the device status is then (Status = dfuERROR, State = errTARGET).
The address, to which the host requests to write data, is computed using the value of wBlockNumber (wValue)
and the address pointer according to the same formula as for an upload request:
Address = ((wBlockNum – 2) × wTransferSize) + Addres_Pointer, where:
– wTransferSize: length of the data buffer sent by the host
– wBlockNumber: value of the wValue parameter
If the Flash Read Protection is enabled, the Write memory operation is not performed and the returned device status is (Status = dfuERROR, State = errVENDOR)
whatever the target (internal Flash, embedded RAM or option bytes).
If the Write memory command is issued to the option byte area, all options are erased before writing the new values,
and at the end of the command the bootloader generates a system reset to take into account the new configuration of the option bytes.
Note:
1 When writing to the RAM, you should take care not to overlap the first RAM memory used by the bootloader firmware.
2 No error is returned when performing write operations on write protected sectors.
DFU_DNLOAD Set Address Pointer (wValue=0 and first byte = 0x21)
The Set Address Pointer command is selected when wValue = 0 and the first byte of the buffer sent by the host is 0x21.
The buffer length should be 5 (the four remaining bytes are the address bytes, LSB first (32-bit address format)).
The host sends a DFU_DNLOAD request with the above mentioned parameters to set the address pointer value
used for computing the start address for Read and Write memory operations.
The STM32 receives bytes as follows:
Byte 1: 0x21 - Set Address Pointer command
Byte 2: A[7:0] - LSB of the address pointer
Byte 3: A[15:8] - Second byte of the address pointer
Byte 4: A[22:16] - Third byte of the address pointer
Byte 4: A[31:23] - MSB of the address pointer
After sending the Set Address Pointer command, the host has to send the DFU_GETSTATUS request.
The Set AddressPointer command is effectively executed only when a DFU_GETSTATUS request is issued by the host.
If the status returned by the device is not dfuDNBUSY, then an error has occurred.
A second DFU_GETSTATUS request is needed to check if the command has been correctly executed.
If the received address is wrong or unsupported, the device status is then (Status = dfuERROR, State = errTARGET).
The allowed locations for address pointer values are valid memory addresses (see note) in the internal Flash memory, embedded RAM, system memory and option bytes.
Note:
1 Refer to Section 4: DFU_UPLOAD request commands for more details about the valid memory addresses for the device you are using.
2 The Set Address Pointer command is allowed and executed when the Flash Read Protection is enabled or disabled.
DFU_DNLOAD Erasse (wValue=0 and first byte = 0x41)
The Erase command is selected when wValue = 0 and the first byte of the buffer sent by the host is 0x41.
The buffer length may be 5 bytes (the four remaining bytes are the address bytes, LSB first) for the page erase operation
or only 1 byte (only the command byte) for the Mass erase operation.
The host sends a DFU_DNLOAD request with the above parameters to erase one page of the internal Flash memory or to perform a mass erase of this Flash memory.
The device receives the bytes as follows (page erase):
Byte 1: 0x41 - Erase command
Byte 2: A[7:0] - LSB of the page address
Byte 3: A[15:8] - Second byte of the page address
Byte 4: A[22:16] - Third byte of the page address
Byte 4: A[31:23] - MSB of the page address
Or, if a 1-byte command is received:
The STM32 receives the bytes as follows (Mass Erase):
After sending an Erase command, the host has to send a DFU_GETSTATUS request.
The Erase command is effectively executed only when a DFU_GETSTATUS request is issued by the host.
If the status returned by the device is not dfuDNBUSY, then an error has occurred.
A second DFU_GETSTATUS request is needed to check if the command has been correctly executed.
If the received page address is wrong or unsupported, the device status is then (Status = dfuERROR, State = errTARGET).
If the Flash Read Protection is active, then the device returns the status (Status = dfuERROR, State = errVENDOR) and the erase operation is ignored by the device.
The allowed Erase page addresses are internal Flash memory addresses.
Note: No error is returned when performing Erase operations on write protected sectors.
DFU_DNLOAD Read Unprotect (wValue=0 and first byte = 0x92)
The Read Unprotect command is selected when wValue = 0 and the first byte of the buffer sent by the host is 0x92.
The buffer length should be only 1 byte (only the command byte).
The host sends a DFU_DNLOAD request with the above parameters to remove the read protection of the internal Flash memory.
The device receives the byte as follows:
Byte 1: 0x92 - Read Unprotect command
After sending a Read Unprotect command, the host has to send a DFU_GETSTATUS request.
The Read Unprotect command is effectively executed only when a DFU_GETSTATUS request is issued by the host.
If the status returned by the device is not dfuDNBUSY, then an error has occurred. After this operation,
the device removes the Read Protection and, consequently, both the internal Flash and the embedded RAM are fully erased.
Hence, just after executing this command, the device disconnects itself and executes a system reset.
In this case, the device is not able to respond to a second Get Status request.
And the host has to wait until the device is enumerated again.
A second DFU_GETSTATUS request may also be issued (if the device is still connected) to check if the command has been correctly executed.
If the device fails to execute the command it returns an error status (depending on the error type).
DFU_DNLOAD Leave DFU(Leave DFU mode and jump to application)
It is possible to exit DFU mode (and bootloader) and jump to a loaded application (in the internal Flash or in the embedded RAM) using the DFU download request.
The Host sends a DFU_DNLOAD request with 0 data length (no data stage after the request) in order to inform the device that it will have to exit DFU mode.
The device acknowledges this request if the current state is dfuDNLOAD-IDLE or dfuIDLE.
The DFU Leave operation is effectively executed only when a DFU_GETSTATUS request is issued by the host.
If the status returned by the device is not dfuMANIFEST, then an error has occurred.
After this operation, the device performs the following:
• it disconnects itself
• it initializes the registers of the peripherals used by the bootloader to their default reset values
• it initializes the user application’s main stack pointer
• it jumps to the memory location programmed in the received ‘address pointer + 4’, which corresponds to the address of the application’s reset handler
For example if the received address is 0x0800 0000, the bootloader will jump to the memory location programmed at address 0x0800 0004.
In general, the host should send the base address where the application to jump to is programmed.
The address pointer has to be set (using the Set Address Pointer command) before launching the Leave DFU routine,
otherwise, the bootloader will jump to the default address (internal Flash memory start address: 0x08000000).
The address pointer can also be set through the last Write Memory operation:
if a download operation is performed, the address pointer used for this download will be stored and used later for the jump.
Note: If the address pointer points to an address that does not contain executable code, then the device is reset and, depending on the state of the boot pins,
may re-enter the bootloader mode.
Since the bootloader DFU application is not manifestation-tolerant, the device will not be able to respond to host requests after a manifestation phase is completed.
A second DFU_GETSTATUS request may also be issued (if the device is still connected) to check if the command has been correctly executed.
If the device fails to execute the command it returns an error status (depending on the error type).
Note:
1 The Jump to application works only if the user application sets the vector table correctly to point to the application address.
2 When performing a jump from the bootloader to a loaded application code which uses the USB IP, the user application has to disable all pending USB interrupts
and reset the core before enabling interrupts. Otherwise, a pending interrupt (issued from the bootloader code) may interfere with the user code and cause a functional failure.
This procedure is not needed after exiting the system memory boot mode.