DFU AT commands
This page describes AT commands related to Device Firmware Update (DFU) operations. These commands allow you to update the application firmware, delta modem firmware, full modem firmware, or the MCUboot second-stage bootloader through UART.
Note
The DFU commands use data mode to receive firmware data. See the Data mode section for more information about data mode.
DFU types
The following DFU image types are supported:
0- Application firmware (MCUboot)1- Delta modem firmware
2- Full modem firmware
3- MCUboot second-stage bootloader self-update. Only available when the device uses the NSIB (B0) and MCUboot as a second-stage bootloader. The host must stream the signed image for the inactives0/s1slot.
Caution
If the full modem firmware update fails after firmware data has been programmed to modem flash, the modem remains unusable until a successful update is completed.
DFU initialize #XDFUINIT
The #XDFUINIT command initializes the DFU target for a specific image type.
Set command
The set command initializes the DFU target.
Syntax
AT#XDFUINIT=<type>[,<size>]
The parameters and their defined values are the following:
- <type>
Integer. The DFU image type as specified in the DFU types section.
- <size>
Integer. The total firmware image size in bytes. Required for application (type
0), delta modem firmware (type1), and MCUboot bootloader (type3) updates.
For full modem firmware (type 2), the command triggers an immediate reboot into bootloader mode.
The #XDFUINIT, #XDFUWRITE, and #XDFUAPPLY commands use the same modem DFU area as the #XFOTA and #XNRFCLOUDFOTA commands.
For delta modem firmware (type 1), they return ERROR in one of the following cases:
A FOTA update started with the
#XFOTAor#XNRFCLOUDFOTAcommand is in progress.Such an update is downloaded, but not yet activated.
When one of these commands succeeds, it reserves the modem DFU area for direct DFU until the modem is reset, for example with the #XMODEMRESET or #XRESET command.
While the area is reserved, the #XFOTA and #XNRFCLOUDFOTA commands cannot start a modem firmware update or erase the modem DFU area.
Example
AT#XDFUINIT=0,123456
OK
AT#XDFUINIT=2
// device reboots into bootloader mode
Bootloader mode ready
Read command
The read command is not supported.
Test command
The test command tests the existence of the command and provides information about the type of its subparameters.
Syntax
AT#XDFUINIT=?
Response syntax
#XDFUINIT: <list of supported types>,<size>
Example
AT#XDFUINIT=?
#XDFUINIT: (0,1,2,3),<size>
OK
DFU write #XDFUWRITE
The #XDFUWRITE command writes firmware data to the DFU target.
The command enters data mode to receive the firmware chunk.
Set command
The set command initiates a firmware data write operation.
Syntax
AT#XDFUWRITE=<type>,<addr>,<len>
The parameters and their defined values are the following:
- <type>
Integer. The DFU image type as specified in the DFU types section.
- <addr>
Integer. The address offset for the data.
- <len>
Integer. The length of the data chunk to write.
After the command returns OK, the nRF91M1 module enters data mode to receive exactly <len> bytes of firmware data.
When the data has been received and written, the nRF91M1 module sends a #XDFU unsolicited notification with the status.
For delta modem firmware (type 1), the command returns ERROR under the same conditions as the #XDFUINIT command.
Example
AT#XDFUWRITE=0,0,4096
OK
// 4096 bytes of firmware data
#XDATAMODE: 0
#XDFU: 0,1,0
Read command
The read command is not supported.
Test command
The test command tests the existence of the command and provides information about the type of its subparameters.
Syntax
AT#XDFUWRITE=?
Response syntax
#XDFUWRITE: <list of supported types>,<addr>,<len>
Example
AT#XDFUWRITE=?
#XDFUWRITE: (0,1,2,3),<addr>,<len>
OK
DFU apply #XDFUAPPLY
The #XDFUAPPLY command finalizes the firmware update and schedules it for activation.
Set command
The set command applies the firmware update.
Syntax
AT#XDFUAPPLY=<type>
The parameters and their defined values are the following:
- <type>
Integer. The DFU image type as specified in the DFU types section.
For application (type 0), delta modem firmware (type 1), and MCUboot bootloader (type 3), the update is scheduled and will be activated on the next reset, which can be done with the AT#XRESET command.
For full modem firmware (type 2), the command applies the current segment (bootloader or firmware) and triggers a reboot if needed.
For delta modem firmware (type 1), the command returns ERROR under the same conditions as the #XDFUINIT command.
Example
AT#XDFUAPPLY=0
OK
#XDFU: 0,2,0
AT#XRESET
OK
Ready
Read command
The read command is not supported.
Test command
The test command tests the existence of the command and provides information about the type of its subparameters.
Syntax
AT#XDFUAPPLY=?
Response syntax
#XDFUAPPLY: <list of supported types>
Example
AT#XDFUAPPLY=?
#XDFUAPPLY: (0,1,2,3)
OK
DFU unsolicited notification #XDFU
The nRF91M1 module sends the #XDFU unsolicited notification to report the status of DFU write and apply operations.
Unsolicited notification
#XDFU: <type>,<operation>,<status>
The parameters and their defined values are the following:
- <type>
Integer. The DFU image type as specified in the DFU types section.
- <operation>
1- Data write completed.2- Apply update completed.
- <status>
0- Success.-1- Failure.
Complete DFU examples
The following sections showcase a complete example of application, delta modem, and full modem firmware update.
Application firmware update
The following example shows a complete application firmware update:
// Note the current application version (major.minor.patch from app/VERSION)
AT#XSMVER
#XSMVER: "v1.99.0-7-gdf00f46-dirty","3.3.0-rc1"
OK
// Initialize DFU for application firmware (total size 123456 bytes)
AT#XDFUINIT=0,123456
OK
// Write first chunk (4096 bytes at offset 0)
AT#XDFUWRITE=0,0,4096
OK
// 4096 bytes of firmware data
#XDATAMODE: 0
#XDFU: 0,1,0
// Write second chunk (4096 bytes at offset 4096)
AT#XDFUWRITE=0,4096,4096
OK
// 4096 bytes of firmware data
#XDATAMODE: 0
#XDFU: 0,1,0
// ... continue writing chunks ...
// Apply the update
AT#XDFUAPPLY=0
OK
#XDFU: 0,2,0
// Reset to activate the new firmware
AT#XRESET
OK
Ready
// Verify the VERSION prefix increased (here 1.99.0 -> 1.99.1)
AT#XSMVER
#XSMVER: "v1.99.1-8-gf0fd0f46-dirty","3.3.0-rc1"
OK
Delta modem firmware update
The following example shows a complete delta modem firmware update:
// Note the current modem firmware
AT%SHORTSWVER
%SHORTSWVER: nrf91x1_2.0.0
OK
// Initialize DFU for delta modem firmware (total size 65536 bytes)
AT#XDFUINIT=1,65536
OK
// Write first chunk (4096 bytes at offset 0)
AT#XDFUWRITE=1,0,4096
OK
// 4096 bytes of firmware data
#XDATAMODE: 0
#XDFU: 1,1,0
// Write second chunk (4096 bytes at offset 4096)
AT#XDFUWRITE=1,4096,4096
OK
// 4096 bytes of firmware data
#XDATAMODE: 0
#XDFU: 1,1,0
// ... continue writing chunks ...
// Apply the update
AT#XDFUAPPLY=1
OK
#XDFU: 1,2,0
// Reset the modem to activate the new firmware
AT#XMODEMRESET
#XMODEMRESET: 0
OK
// Verify that the modem is running the new firmware
AT%SHORTSWVER
%SHORTSWVER: nrf91x1_2.0.4
OK
Full modem firmware update
The following example shows a complete full modem firmware update.
Important
If the update fails after the first 8 kB block of firmware data has been programmed, the modem remains unusable until a successful update is performed. The bootloader remains intact for retries. Ensure a reliable connection between the host and nRF91M1 module, and stable power supply before starting the update.
The full modem update consists of two phases:
Bootloader segment - Writes the bootloader data.
Firmware segment - Writes the firmware data.
Note
Firmware segment data is buffered and programmed to modem flash in 8 kB blocks.
A #XDFU: 2,1,0 notification means the data was accepted, not that it was programmed.
With contiguous writes of 8 kB or less, the first block is programmed during the write that brings the total amount of firmware data to 8 kB or more.
If that write fails, the modem rejected the firmware, for example, because it is an older version.
In that case, the existing modem firmware is left untouched, and you can return to normal mode with the AT#XRESET command.
If a later write or AT#XDFUAPPLY fails, the modem remains unusable until a full modem firmware update is completed successfully.
// Note the current firmware version of the modem
AT%SHORTSWVER
%SHORTSWVER: nrf91x1_2.0.0
OK
// Initialize DFU for full modem firmware
AT#XDFUINIT=2
// device reboots
Bootloader mode ready
// Phase 1: Write bootloader segment
AT#XDFUWRITE=2,0,4096
OK
// 4096 bytes of bootloader data
#XDATAMODE: 0
#XDFU: 2,1,0
// ... continue writing bootloader chunks ...
// Apply bootloader segment (switches to firmware segment mode)
AT#XDFUAPPLY=2
OK
#XDFU: 2,2,0
// Phase 2: Write firmware segments
// Warning: Data is programmed to modem flash in 8 kB blocks. A failure after the first block is programmed leaves the modem unusable until the update is completed successfully.
AT#XDFUWRITE=2,0,4096
OK
// 4096 bytes of firmware data
#XDATAMODE: 0
#XDFU: 2,1,0
// ... continue writing firmware chunks ...
// Apply firmware segment (triggers reboot)
AT#XDFUAPPLY=2
OK
#XDFU: 2,2,0
// device reboots
Ready
// Verify that the modem is running the new firmware
AT%SHORTSWVER
%SHORTSWVER: nrf91x1_2.0.4
OK
MCUboot firmware update
Important
NSIB (B0) uses monotonic counter values to prevent rollback of the MCUboot bootloader. When performing an MCUboot DFU, the host must ensure that the new MCUboot image has a strictly higher monotonic counter value than the currently running MCUboot to avoid update failure.
Updates for MCUboot images are limited to 40 slots.
The following example shows a complete MCUboot firmware update:
// Query the current slot for MCUboot image
AT#XBOOTINFO=1
#XBOOTINFO: 0
OK
// Download the correct MCUboot image for the inactive slot.
// The default NCS image names for MCUboot are:
// - Slot 0: signed_by_mcuboot_and_b0_mcuboot.bin
// - Slot 1: signed_by_mcuboot_and_b0_s1_image.bin
// In this example, the device is currently running slot 0, so the host should download the signed image for slot 1, which is signed_by_mcuboot_and_b0_s1_image.bin.
// Note the current monotonic counter value for MCUboot
AT#XBOOTINFO=0
#XBOOTINFO: 1
OK
// Initialize DFU for MCUboot firmware (total size 23456 bytes)
AT#XDFUINIT=3,23456
OK
// Write first chunk (4096 bytes at offset 0)
AT#XDFUWRITE=3,0,4096
OK
// 4096 bytes of firmware data
#XDATAMODE: 0
#XDFU: 3,1,0
// Write second chunk (4096 bytes at offset 4096)
AT#XDFUWRITE=3,4096,4096
OK
// 4096 bytes of firmware data
#XDATAMODE: 0
#XDFU: 3,1,0
// ... continue writing chunks ...
// Apply the update
AT#XDFUAPPLY=3
OK
#XDFU: 3,2,0
// Reset to activate the new firmware
AT#XRESET
OK
Ready
// Verify that the monotonic counter value for MCUboot was updated
AT#XBOOTINFO=0
#XBOOTINFO: 2
OK
// (Optional) Verify that the MCUboot slot was switched
AT#XBOOTINFO=1
#XBOOTINFO: 1
OK
DFU host example
See app/scripts/sm_dfu_host.py for an example of how to implement a DFU host. The script demonstrates the DFU AT command flow and can be used as a starting point for custom implementations.
Install dependencies:
pip install -r app/scripts/requirements.txt
Note
cbor2 5.8.0 does not work with the sm_dfu_host.py script due to a known bug introduced in that version.
Versions older and newer than that work.
See cbor2 bug for more information.
Usage
python sm_dfu_host.py --port <serial_port> --baudrate <baud> --file <path-to-firmware> --type <dfu_type>
Where <dfu_type> is one of: application, modem-delta, or modem-full.
After the DFU transfer completes:
Note
Applying application and delta modem firmware can take some time.
For application updates, reset the device to activate the new firmware:
python sm_dfu_host.py --port <serial_port> --baudrate <baud> --reset
For delta modem updates, reset the modem to apply the update:
python sm_dfu_host.py --port <serial_port> --baudrate <baud> --modem-reset
Full modem updates handle the reset automatically.
To check if the device is operating in normal mode:
python sm_dfu_host.py --port <serial_port> --baudrate <baud> --ping
Note
Ping will return an error if the device is in bootloader mode.