1.. _smp_svr_sample: 2 3SMP Server Sample 4################# 5 6Overview 7******** 8 9This sample application implements a Simple Management Protocol (SMP) server. 10SMP is a basic transfer encoding for use with the MCUmgr management protocol. 11For more information about MCUmgr and SMP, please see :ref:`device_mgmt`. 12 13This sample application supports the following mcumgr transports by default: 14 15 * Shell 16 * Bluetooth 17 18``smp_svr`` enables support for the following command groups: 19 20 * ``fs_mgmt`` 21 * ``img_mgmt`` 22 * ``os_mgmt`` 23 * ``stat_mgmt`` 24 25Caveats 26******* 27 28* The Zephyr port of ``smp_svr`` is configured to run on a Nordic nRF52x MCU. The 29 application should build and run for other platforms without modification. 30 31* The MCUboot bootloader is required for ``img_mgmt`` to function 32 properly. More information about the Device Firmware Upgrade subsystem and 33 MCUboot can be found in :ref:`mcuboot`. 34 35* The :file:`mcumgr` command-line tool only works with Bluetooth Low Energy (BLE) 36 on Linux and macOS. On Windows there is no support for Device Firmware 37 Upgrade over BLE yet. 38 39Building a BLE Controller (optional) 40************************************ 41 42.. note:: 43 This section is only relevant for Linux users 44 45If you want to try out Device Firmware Upgrade (DFU) over the air using 46Bluetooth Low Energy (BLE) and do not have a built-in or pluggable BLE radio, 47you can build one and use it following the instructions in 48:ref:`bluetooth-hci-uart-bluez`. 49 50Building and Running 51******************** 52 53The below steps describe how to build and run the ``smp_svr`` sample in 54Zephyr. Where examples are given, they assume the sample is being built for 55the Nordic nRF52 Development Kit (``BOARD=nrf52_pca10040``). 56 57If you would like to use a more constrained platform, such as the nRF51 DK, you 58should use the :file:`prj_tiny.conf` configuration file rather than the default 59:file:`prj.conf`. 60 61Step 1: Build MCUboot 62===================== 63 64Build MCUboot by following the instructions in the :ref:`mcuboot` 65documentation page. 66 67Step 2: Flash MCUboot 68====================== 69 70Flash the resulting image file to address 0x0 of flash memory. 71This can be done in multiple ways. 72 73Using make or ninja: 74 75.. code-block:: console 76 77 make flash 78 # or 79 ninja flash 80 81Using GDB: 82 83.. code-block:: console 84 85 restore <path-to-mcuboot-zephyr.bin> binary 0 86 87Step 3: Build smp_svr 88===================== 89 90``smp_svr`` can be built for the nRF52 as follows: 91 92.. zephyr-app-commands:: 93 :zephyr-app: samples/subsys/mgmt/mcumgr/smp_svr 94 :board: nrf52_pca10040 95 :build-dir: nrf52_pca10040 96 :goals: build 97 98.. _smp_svr_sample_sign: 99 100Step 4: Sign the image 101====================== 102 103.. note:: 104 From this section onwards you can use either a binary (``.bin``) or an 105 Intel Hex (``.hex``) image format. This is written as ``(bin|hex)`` in this 106 document. 107 108Using MCUboot's :file:`imgtool.py` script, sign the :file:`zephyr.(bin|hex)` 109file you built in Step 3. In the below example, the MCUboot repo is located at 110:file:`~/src/mcuboot`. 111 112.. code-block:: console 113 114 ~/src/mcuboot/scripts/imgtool.py sign \ 115 --key ~/src/mcuboot/root-rsa-2048.pem \ 116 --header-size 0x200 \ 117 --align 8 \ 118 --version 1.0 \ 119 --slot-size <image-slot-size> \ 120 <path-to-zephyr.(bin|hex)> signed.(bin|hex) 121 122The above command creates an image file called :file:`signed.(bin|hex)` in the 123current directory. 124 125Step 5: Flash the smp_svr image 126=============================== 127 128Upload the :file:`signed.(bin|hex)` file from Step 4 to image slot-0 of your 129board. The location of image slot-0 varies by board, as described in 130:ref:`mcuboot_partitions`. For the nRF52 DK, slot-0 is located at address 131``0xc000``. 132 133Using :file:`nrfjprog` you don't need to specify the slot-0 starting address, 134since :file:`.hex` files already contain that information: 135 136.. code-block:: console 137 138 nrfjprog --program <path-to-signed.hex> 139 140Using GDB: 141 142.. code-block:: console 143 144 restore <path-to-signed.bin> binary 0xc000 145 146Step 6: Run it! 147=============== 148 149.. note:: 150 If you haven't installed :file:`mcumgr` yet, then do so by following the 151 instructions in the :ref:`mcumgr_cli` section of the Management subsystem 152 documentation. 153 154.. note:: 155 The :file:`mcumgr` command-line tool requires a connection string in order 156 to identify the remote target device. In this sample we use a BLE-based 157 connection string, and you might need to modify it depending on the 158 BLE controller you are using. 159 160 161The ``smp_svr`` app is ready to run. Just reset your board and test the app 162with the :file:`mcumgr` command-line tool's ``echo`` functionality, which will 163send a string to the remote target device and have it echo it back: 164 165.. code-block:: console 166 167 sudo mcumgr --conntype ble --connstring ctlr_name=hci0,peer_name='Zephyr' echo hello 168 hello 169 170 171Step 7: Device Firmware Upgrade 172=============================== 173 174Now that the SMP server is running on your board and you are able to communicate 175with it using :file:`mcumgr`, you might want to test what is commonly called 176"OTA DFU", or Over-The-Air Device Firmware Upgrade. 177 178To do this, build a second sample (following the steps below) to verify 179it is sent over the air and properly flashed into slot-1, and then 180swapped into slot-0 by MCUboot. 181 182Build a second sample 183--------------------- 184 185Perhaps the easiest sample to test with is the :zephyr_file:`samples/hello_world` 186sample provided by Zephyr, documented in the :ref:`hello_world` section. 187 188Edit :zephyr_file:`samples/hello_world/prj.conf` and enable the required MCUboot 189Kconfig option as described in :ref:`mcuboot` by adding the following line to 190it: 191 192.. code-block:: console 193 194 CONFIG_BOOTLOADER_MCUBOOT=y 195 196Then build the sample as usual (see :ref:`hello_world`). 197 198Sign the second sample 199---------------------- 200 201Next you will need to sign the sample just like you did for :file:`smp_svr`, 202since it needs to be loaded by MCUboot. 203Follow the same instructions described in :ref:`smp_svr_sample_sign`, 204but this time you must use a :file:`.bin` image, since :file:`mcumgr` does not 205yet support :file:`.hex` files. 206 207Upload the image over BLE 208------------------------- 209 210Now we are ready to send or upload the image over BLE to the target remote 211device. 212 213.. code-block:: console 214 215 sudo mcumgr --conntype ble --connstring ctlr_name=hci0,peer_name='Zephyr' image upload signed.bin 216 217If all goes well the image will now be stored in slot-1, ready to be swapped 218into slot-0 and executed. 219 220.. note:: 221 222 At the beginning of the upload process, the target might start erasing 223 the image slot, taking several dozen seconds for some targets. This might 224 cause an NMP timeout in the management protocol tool. Use the 225 ``-t <timeout-in-seconds`` option to increase the response timeout for the 226 ``mcumgr`` command line tool if this occurs. 227 228List the images 229--------------- 230 231We can now obtain a list of images (slot-0 and slot-1) present in the remote 232target device by issuing the following command: 233 234.. code-block:: console 235 236 sudo mcumgr --conntype ble --connstring ctlr_name=hci0,peer_name='Zephyr' image list 237 238This should print the status and hash values of each of the images present. 239 240Test the image 241-------------- 242 243In order to instruct MCUboot to swap the images we need to test the image first, 244making sure it boots: 245 246.. code-block:: console 247 248 sudo mcumgr --conntype ble --connstring ctlr_name=hci0,peer_name='Zephyr' image test <hash of slot-1 image> 249 250Now MCUBoot will swap the image on the next reset. 251 252Reset remotely 253-------------- 254 255We can reset the device remotely to observe (use the console output) how 256MCUboot swaps the images: 257 258.. code-block:: console 259 260 sudo mcumgr --conntype ble --connstring ctlr_name=hci0,peer_name='Zephyr' reset 261 262Upon reset MCUboot will swap slot-0 and slot-1. 263 264The new image is the basic ``hello_world`` sample that does not contain 265SMP or BLE functionality, so we cannot communicate with it using 266:file:`mcumgr`. Instead simply reset the board manually to force MCUboot 267to revert (i.e. swap back the images) due to the fact that the new image has 268not been confirmed. 269 270If you had instead built and uploaded a new image based on ``smp_svr`` 271(or another BLE and SMP enabled sample), you could confirm the 272new image and make the swap permanent by using this command: 273 274.. code-block:: console 275 276 sudo mcumgr --conntype ble --connstring ctlr_name=hci0,peer_name='Zephyr' image confirm 277 278Note that if you try to send the very same image that is already flashed in 279slot-0 then the procedure will not complete successfully since the hash values 280for both slots will be identical. 281