SMP Server Sample
This sample application implements a Simple Management Protocol (SMP) server. SMP is a basic transfer encoding for use with the MCUmgr management protocol. For more information about MCUmgr and SMP, please see Device Management.
This sample application supports the following mcumgr transports by default:
smp_svr enables support for the following command groups:
The MCUboot bootloader is required for
img_mgmtto function properly. More information about the Device Firmware Upgrade subsystem and MCUboot can be found in MCUboot.
mcumgrcommand-line tool only works with Bluetooth Low Energy (BLE) on Linux and macOS. On Windows there is no support for Device Firmware Upgrade over BLE yet.
Installing the mcumgr cli
To interact remotely with the management subsystem on a device, we need to have the
mcumgr installed. Follow the instructions in the Command-line Tool section
of the Management subsystem documentation.
Building a BLE Controller
This section is only relevant for Linux users
If you want to try out Device Firmware Upgrade (DFU) over the air using Bluetooth Low Energy (BLE) and do not have a built-in or pluggable BLE radio, you can build one and use it following the instructions in Using the controller with BlueZ.
Building and flashing MCUboot
The below steps describe how to build and run the MCUboot bootloader. Detailed instructions can be found in the MCUboot documentation page.
The Zephyr port of MCUboot is essentially a normal Zephyr application, which means that
we can build and flash it like normal using
west, like so:
west build -b <board> -d build_mcuboot bootloader/mcuboot/boot/zephyr west flash -d build_mcuboot
Substitute <board> for one of the boards supported by the sample, see
Building the sample application
The below steps describe how to build and run the
smp_svr sample in
smp_svr sample comes in different flavours.
To build the bluetooth sample:
west build \ -b nrf52dk_nrf52832 \ samples/subsys/mgmt/mcumgr/smp_svr \ -- \ -DEXTRA_CONF_FILE=overlay-bt.conf
To build the serial sample with file-system and shell management support:
west build \ -b frdm_k64f \ samples/subsys/mgmt/mcumgr/smp_svr \ -- \ -DEXTRA_CONF_FILE='overlay-serial.conf;overlay-fs.conf;overlay-shell-mgmt.conf'
To build the serial sample with USB CDC_ACM backend:
west build \ -b nrf52840dk_nrf52840 \ samples/subsys/mgmt/mcumgr/smp_svr \ -- \ -DEXTRA_CONF_FILE=overlay-cdc.conf \ -DDTC_OVERLAY_FILE=usb.overlay
To build the shell sample:
west build \ -b frdm_k64f \ samples/subsys/mgmt/mcumgr/smp_svr \ -- \ -DEXTRA_CONF_FILE='overlay-shell.conf'
The UDP transport for SMP supports both IPv4 and IPv6. In the sample, both IPv4 and IPv6 are enabled, but they can be enabled and disabled separately.
To build the UDP sample:
west build \ -b frdm_k64f \ samples/subsys/mgmt/mcumgr/smp_svr \ -- \ -DEXTRA_CONF_FILE=overlay-udp.conf
Signing the sample image
A key feature of MCUboot is that images must be signed before they can be successfully
uploaded and run on a target. To sign images, the MCUboot tool
imgtool can be used.
To sign the sample image we built in a previous step:
west sign -t imgtool -- --key bootloader/mcuboot/root-rsa-2048.pem
The above command creates an image file called
zephyr.signed.bin in the
For more information on image signing and
west sign, see the Signing Binaries
Flashing the sample image
zephyr.signed.bin file from the previous to image slot-0 of your
board. See Flash map for details on flash partitioning.
To upload the initial image file to an empty slot-0, we simply use
west flash will automatically detect slot-0 address and confirm
west flash --bin-file build/zephyr/zephyr.signed.bin
We need to explicitly specify the signed image file, otherwise the non-signed version will be used and the image won’t be runnable.
Sample image: hello world!
smp_svr app is ready to run. Just reset your board and test the app
mcumgr command-line tool’s
echo functionality, which will
send a string to the remote target device and have it echo it back:
sudo mcumgr --conntype ble --connstring ctlr_name=hci0,peer_name='Zephyr' echo hello hello
mcumgr --conntype serial --connstring "/dev/ttyACM0,baud=115200" echo hello hello
mcumgr --conntype udp --connstring=[192.168.1.1]:1337 echo hello hello
And using IPv6
mcumgr --conntype udp --connstring=[2001:db8::1]:1337 echo hello hello
mcumgr command-line tool requires a connection string in order
to identify the remote target device. In the BT sample we use a BLE-based
connection string, and you might need to modify it depending on the
BLE controller you are using.
In the following sections, examples will use
<connection string> to represent
--conntype <type> and
Device Firmware Upgrade (DFU)
Now that the SMP server is running on your board and you are able to communicate
with it using
mcumgr, you might want to test what is commonly called
“OTA DFU”, or Over-The-Air Device Firmware Upgrade. This works for both BT and UDP.
The general sequence of a DFU process is as follows:
Build an MCUboot enabled application, see Building the sample application
Sign the application image, see Signing the sample image
Upload the signed image using
Listing the images on the device using
Mark the uploaded image for testing using
Reset the device remotely using
Confirm the uploaded image using
Direct image upload and Image mapping to MCUboot slot
Currently the mcumgr supports, for direct upload, 4 target images, of which first two are mapped into MCUboot primary (slot-0) and secondary (slot-1) respectively.
image upload command may be provided optional
-e -n <image> parameter that will
select target image for upload; when parameter is no provided, 0 is assumed, which means “default
behaviour”, and it performs upload to the “image-1”, the MCUboot secondary slot.
For clarity, here is DTS label to slot to
<image> translation table:
-e option actually means “no erase”, and is provided to the mcumgr
to prevent it from sending erase command to target, before updating image.
The options is always needed when
-n is used for image selection,
as the erase command is hardcoded to erase slot-1 (“image-1”),
regardless of which slot is uploaded at the time.
Upload the signed image
To upload the signed image, use the following command:
sudo mcumgr <connection string> image upload build/zephyr/zephyr.signed.bin
At the beginning of the upload process, the target might start erasing
the image slot, taking several dozen seconds for some targets. This might
cause an NMP timeout in the management protocol tool. Use the
-t <timeout-in-seconds option to increase the response timeout for the
mcumgr command line tool if this occurs.
List the images
We can now obtain a list of images (slot-0 and slot-1) present in the remote target device by issuing the following command:
sudo mcumgr <connection string> image list
This should print the status and hash values of each of the images present.
Test the image
In order to instruct MCUboot to swap the images we need to test the image first, making sure it boots:
sudo mcumgr <connection string> image test <hash of slot-1 image>
Now MCUBoot will swap the image on the next reset.
There is not yet any way of getting the image hash without actually uploading the
image and getting the hash by using the
image list command of
We can reset the device remotely to observe (use the console output) how MCUboot swaps the images:
sudo mcumgr <connection string> reset
Upon reset MCUboot will swap slot-0 and slot-1.
Confirm new image
The new image is now loaded into slot-0, but it will be swapped back into slot-1 on the next reset unless the image is confirmed. To confirm the new image:
sudo mcumgr <connection string> image confirm
Note that if you try to send the very same image that is already flashed in slot-0 then the procedure will not complete successfully since the hash values for both slots will be identical.
Download file from File System
SMP server supports downloading files from File System on device via
mcumgr. This is useful with FS log backend, when files are stored in
non-volatile memory. Build and flash both MCUboot and smp_svr applications and
download command, e.g.:
mcumgr --conntype serial --connstring='dev=/dev/ttyACM0,baud=115200' \ fs download /lfs/log.0000 ~/log.txt