zephyr/samples/subsys/mgmt/mcumgr/smp_svr
Sebastian Bøe 55ee53ce91 cmake: Prepend 'cmake_minimum_required()' into 'app' build scripts
Prepend the text 'cmake_minimum_required(VERSION 3.8.2)' into the
application and test build scripts.

Modern versions of CMake will spam users with a deprecation warning
when the toplevel CMakeLists.txt does not specify a CMake
version. This is documented in bug #8355.

To resolve this we include a cmake_minimum_required() line into the
toplevel build scripts. Additionally, cmake_minimum_required is
invoked from within boilerplate.cmake. The highest version will be
enforced.

This patch allows us to afterwards change CMake policy CMP000 from OLD
to NEW which in turn finally rids us of the verbose warning.

The extra boilerplate is considered more acceptable than the verbosity
of the CMP0000 policy.

Signed-off-by: Sebastian Bøe <sebastian.boe@nordicsemi.no>
2018-08-15 04:06:50 -07:00
..
src Bluetooth: samples: Make use of BT_LE_ADV_OPT_USE_NAME 2018-07-23 14:45:58 +03:00
CMakeLists.txt cmake: Prepend 'cmake_minimum_required()' into 'app' build scripts 2018-08-15 04:06:50 -07:00
README.rst samples: subsys: mgmt: mcumgr: smp_svr: documentation update 2018-08-08 10:12:28 +02:00
prj.conf
prj_tiny.conf
sample.yaml

README.rst

.. _smp_svr_sample:

SMP Server Sample
#################

Overview
********

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 :ref:`mgmt`.

This sample application supports the following mcumgr transports by default:

    * Shell
    * Bluetooth

``smp_svr`` enables support for the following command groups:

    * ``fs_mgmt``
    * ``img_mgmt``
    * ``os_mgmt``
    * ``stat_mgmt``

Caveats
*******

* The Zephyr port of `smp_svr` is configured to run on a Nordic nRF52x MCU. The
  application should build and run for other platforms without modification, but
  the file system management commands will not work.  To enable file system
  management for a different platform, adjust the
  :option:`CONFIG_FS_NFFS_FLASH_DEV_NAME` setting in :file:`prj.conf` accordingly.

* The MCUboot bootloader is required for ``img_mgmt`` to function
  properly. More information about the Device Firmware Upgrade subsystem and
  MCUboot can be found in :ref:`mcuboot`.

* The :file:`mcumgr` command-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.

Building a BLE Controller (optional)
************************************

.. note::
   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
:ref:`bluetooth-hci-uart-bluez`.

Building and Running
********************

The below steps describe how to build and run the ``smp_svr`` sample in
Zephyr. Where examples are given, they assume the sample is being built for
the Nordic nRF52 Development Kit (``BOARD=nrf52_pca10040``).

If you would like to use a more constrained platform, such as the nRF51 DK, you
should use the :file:`prj_tiny.conf` configuration file rather than the default
:file:`prj.conf`.

Step 1: Build MCUboot
=====================

Build MCUboot by following the instructions in the :ref:`mcuboot`
documentation page.

Step 2: Flash MCUboot
======================

Flash the resulting image file to address 0x0 of flash memory.
This can be done in multiple ways.

Using make or ninja:

.. code-block:: console

   make flash
   # or
   ninja flash

Using GDB:

.. code-block:: console

   restore <path-to-mcuboot-zephyr.bin> binary 0

Step 3: Build smp_svr
=====================

``smp_svr`` can be built for the nRF52 as follows:

.. zephyr-app-commands::
    :zephyr-app: samples/subsys/mgmt/mcumgr/smp_svr
    :board: nrf52_pca10040
    :build-dir: nrf52_pca10040
    :goals: build

.. _smp_svr_sample_sign:

Step 4: Sign the image
======================

.. note::
   From this section onwards you can use either a binary (``.bin``) or an
   Intel Hex (``.hex``) image format. This is written as ``(bin|hex)`` in this
   document.

Using MCUboot's :file:`imgtool.py` script, sign the :file:`zephyr.(bin|hex)`
file you built in Step 3. In the below example, the MCUboot repo is located at
:file:`~/src/mcuboot`.

.. code-block:: console

   ~/src/mcuboot/scripts/imgtool.py sign \
        --key ~/src/mcuboot/root-rsa-2048.pem \
        --header-size 0x200 \
        --align 8 \
        --version 1.0 \
        --slot-size <image-slot-size> \
        <path-to-zephyr.(bin|hex)> signed.(bin|hex)

The above command creates an image file called :file:`signed.(bin|hex)` in the
current directory.

Step 5: Flash the smp_svr image
===============================

Upload the :file:`signed.(bin|hex)` file from Step 4 to image slot-0 of your
board.  The location of image slot-0 varies by board, as described in
:ref:`mcuboot_partitions`.  For the nRF52 DK, slot-0 is located at address
``0xc000``.

Using :file:`nrfjprog` you don't need to specify the slot-0 starting address,
since :file:`.hex` files already contain that information:

.. code-block:: console

    nrfjprog --program <path-to-signed.hex>

Using GDB:

.. code-block:: console

    restore <path-to-signed.bin> binary 0xc000

Step 6: Run it!
===============

.. note::
   If you haven't installed :file:`mcumgr` yet, then do so by following the
   instructions in the :ref:`mcumgr_cli` section of the Management subsystem
   documentation.

.. note::
   The :file:`mcumgr` command-line tool requires a connection string in order
   to identify the remote target device. In this sample we use a BLE-based
   connection string, and you might need to modify it depending on the
   BLE controller you are using.


The ``smp_svr`` app is ready to run.  Just reset your board and test the app
with the :file:`mcumgr` command-line tool's ``echo`` functionality, which will
send a string to the remote target device and have it echo it back:

.. code-block:: console

   sudo mcumgr --conntype ble --connstring ctlr_name=hci0,peer_name='Zephyr' echo hello
   hello


Step 7: Device Firmware Upgrade
===============================

Now that the SMP server is running on your board and you are able to communicate
with it using :file:`mcumgr`, you might want to test what is commonly called
"OTA DFU", or Over-The-Air Device Firmware Upgrade.

To do this, build a second sample (following the steps below) to verify
it is sent over the air and properly flashed into slot-1, and then
swapped into slot-0 by MCUboot.

Build a second sample
---------------------

Perhaps the easiest sample to test with is the :file:`samples/hello_world`
sample provided by Zephyr, documented in the :ref:`hello_world` section.

Edit :file:`samples/hello_world/prj.conf` and enable the required MCUboot
Kconfig option as described in :ref:`mcuboot` by adding the following line to
it:

.. code-block:: console

   CONFIG_BOOTLOADER_MCUBOOT=y

Then build the sample as usual (see :ref:`hello_world`).

Sign the second sample
----------------------

Next you will need to sign the sample just like you did for :file:`smp_svr`,
since it needs to be loaded by MCUboot.
Follow the same instructions described in :ref:`smp_svr_sample_sign`,
but this time you must use a :file:`.bin` image, since :file:`mcumgr` does not
yet support :file:`.hex` files.

Upload the image over BLE
-------------------------

Now we are ready to send or upload the image over BLE to the target remote
device.

.. code-block:: console

   sudo mcumgr --conntype ble --connstring ctlr_name=hci0,peer_name='Zephyr' image upload signed.bin

If all goes well the image will now be stored in slot-1, ready to be swapped
into slot-0 and executed.

.. note::

   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:

.. code-block:: console

   sudo mcumgr --conntype ble --connstring ctlr_name=hci0,peer_name='Zephyr' 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:

.. code-block:: console

   sudo mcumgr --conntype ble --connstring ctlr_name=hci0,peer_name='Zephyr' image test <hash of slot-1 image>

Now MCUBoot will swap the image on the next reset.

Reset remotely
--------------

We can reset the device remotely to observe (use the console output) how
MCUboot swaps the images:

.. code-block:: console

   sudo mcumgr --conntype ble --connstring ctlr_name=hci0,peer_name='Zephyr' reset

Upon reset MCUboot will swap slot-0 and slot-1.

The new image is the basic ``hello_world`` sample that does not contain
SMP or BLE functionality, so we cannot communicate with it using
:file:`mcumgr`. Instead simply reset the board manually to force MCUboot
to revert (i.e. swap back the images) due to the fact that the new image has
not been confirmed.

If you had instead built and uploaded a new image based on ``smp_svr``
(or another BLE and SMP enabled sample), you could confirm the
new image and make the swap permanent by using this command:

.. code-block:: console

   sudo mcumgr --conntype ble --connstring ctlr_name=hci0,peer_name='Zephyr' 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.