This is an automated email from the ASF dual-hosted git repository. vipulrahane pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-mcumgr.git
The following commit(s) were added to refs/heads/master by this push: new 1f9d4da samples/smp_svr: Update of Zephyr sample (#62) 1f9d4da is described below commit 1f9d4da3b8a7dd6a730924ecbcb387be6631ba00 Author: de-nordic <56024351+de-nor...@users.noreply.github.com> AuthorDate: Tue Feb 11 18:57:20 2020 +0000 samples/smp_svr: Update of Zephyr sample (#62) The Zephyr version of mcumgr/smp_svr sample has been updated with current (commit d380622a) version of source code from Zephyr repository: zephyrpoject-rots/zephyr/tree/master/samples/subsys/mgmt/mcumgr/smp_svr Signed-off-by: Dominik Ermel <dominik.er...@nordicsemi.no> --- samples/smp_svr/zephyr/CMakeLists.txt | 16 +- samples/smp_svr/zephyr/README.rst | 280 +++++++++++++++++++++ samples/smp_svr/zephyr/dts.overlay | 10 - samples/smp_svr/zephyr/prj.conf | 15 +- .../zephyr/{prj.conf.tiny => prj_tiny.conf} | 16 +- samples/smp_svr/zephyr/sample.yaml | 12 + samples/smp_svr/zephyr/src/main.c | 68 +++-- 7 files changed, 333 insertions(+), 84 deletions(-) diff --git a/samples/smp_svr/zephyr/CMakeLists.txt b/samples/smp_svr/zephyr/CMakeLists.txt index 723108d..562ead4 100644 --- a/samples/smp_svr/zephyr/CMakeLists.txt +++ b/samples/smp_svr/zephyr/CMakeLists.txt @@ -1,3 +1,4 @@ +cmake_minimum_required(VERSION 3.13.1) # Top-level CMakeLists.txt for the skeleton application. # # Copyright (c) 2017 Open Source Foundries Limited @@ -7,23 +8,10 @@ # This provides a basic application structure suitable for communication using # mcumgr. It can be used as a starting point for new applications. -cmake_minimum_required(VERSION 3.14) - -# Zephyr uses Device Tree (DT) to describe some board hardware configuration. -# -# See the Zephyr documentation for more information on DT: -# http://docs.zephyrproject.org/devices/dts/device_tree.html -set(DTC_OVERLAY_FILE "${CMAKE_CURRENT_SOURCE_DIR}/dts.overlay") - # Standard Zephyr application boilerplate. include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE) -project(NONE) - -assert_exists(DTC_OVERLAY_FILE) +project(smp_svr) target_sources(app PRIVATE src/main.c ) - -zephyr_link_libraries_ifdef(CONFIG_FILE_SYSTEM_NFFS NFFS) -zephyr_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) diff --git a/samples/smp_svr/zephyr/README.rst b/samples/smp_svr/zephyr/README.rst new file mode 100644 index 0000000..fefcb52 --- /dev/null +++ b/samples/smp_svr/zephyr/README.rst @@ -0,0 +1,280 @@ +.. _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:`device_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. + +* 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 :zephyr_file:`samples/hello_world` +sample provided by Zephyr, documented in the :ref:`hello_world` section. + +Edit :zephyr_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. diff --git a/samples/smp_svr/zephyr/dts.overlay b/samples/smp_svr/zephyr/dts.overlay deleted file mode 100644 index 7e73db7..0000000 --- a/samples/smp_svr/zephyr/dts.overlay +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Basic Device Tree overlay file. - */ - -/ { - chosen { - /* Use uart0 for the mcumgr UART transport. */ - zephyr,uart-mcumgr = &uart0; - }; -}; diff --git a/samples/smp_svr/zephyr/prj.conf b/samples/smp_svr/zephyr/prj.conf index dfa64c1..fe7fdcd 100644 --- a/samples/smp_svr/zephyr/prj.conf +++ b/samples/smp_svr/zephyr/prj.conf @@ -11,20 +11,18 @@ CONFIG_BOOTLOADER_MCUBOOT=y CONFIG_BT_L2CAP_TX_MTU=260 CONFIG_BT_RX_BUF_LEN=260 -# Enable the Bluetooth and shell mcumgr transports. +# Enable the Bluetooth (unauthenticated) and shell mcumgr transports. CONFIG_MCUMGR_SMP_BT=y +CONFIG_MCUMGR_SMP_BT_AUTHEN=n CONFIG_MCUMGR_SMP_SHELL=y #CONFIG_MCUMGR_SMP_UART=y -# Bluetooth support requires a net_buf user_data size >= 7. -CONFIG_NET_BUF_USER_DATA_SIZE=8 - # Enable flash operations. CONFIG_FLASH=y -# Enable the NFFS file system. +# Enable the LittleFS file system. CONFIG_FILE_SYSTEM=y -CONFIG_FILE_SYSTEM_NFFS=y +CONFIG_FILE_SYSTEM_LITTLEFS=y # Required by the `taskstat` command. CONFIG_THREAD_MONITOR=y @@ -38,8 +36,3 @@ CONFIG_MCUMGR_CMD_FS_MGMT=y CONFIG_MCUMGR_CMD_IMG_MGMT=y CONFIG_MCUMGR_CMD_OS_MGMT=y CONFIG_MCUMGR_CMD_STAT_MGMT=y - -### nRF5 specific settings - -# Specify the location of the NFFS file system. -CONFIG_FS_NFFS_FLASH_DEV_NAME="NRF5_FLASH_DRV_NAME" diff --git a/samples/smp_svr/zephyr/prj.conf.tiny b/samples/smp_svr/zephyr/prj_tiny.conf similarity index 71% rename from samples/smp_svr/zephyr/prj.conf.tiny rename to samples/smp_svr/zephyr/prj_tiny.conf index c078980..9f526ba 100644 --- a/samples/smp_svr/zephyr/prj.conf.tiny +++ b/samples/smp_svr/zephyr/prj_tiny.conf @@ -15,21 +15,18 @@ CONFIG_BOOTLOADER_MCUBOOT=y CONFIG_BT_L2CAP_TX_MTU=260 CONFIG_BT_RX_BUF_LEN=260 -# Enable the Bluetooth and UART mcumgr transports. +# Enable the Bluetooth (unauthenticated) and UART mcumgr transports. CONFIG_MCUMGR_SMP_BT=y +CONFIG_MCUMGR_SMP_BT_AUTHEN=n #CONFIG_MCUMGR_SMP_SHELL=y CONFIG_MCUMGR_SMP_UART=y -# Bluetooth support requires a net_buf user_data size >= 7. -CONFIG_NET_BUF_USER_DATA_SIZE=7 +# Disable Bluetooth unused features +CONFIG_BT_GATT_READ_MULTIPLE=n # Enable flash operations. CONFIG_FLASH=y -# Enable the NFFS file system. -#CONFIG_FILE_SYSTEM=y -#CONFIG_FILE_SYSTEM_NFFS=y - # Required by the `taskstat` command. CONFIG_THREAD_MONITOR=y @@ -42,8 +39,3 @@ CONFIG_STATS=y CONFIG_MCUMGR_CMD_IMG_MGMT=y CONFIG_MCUMGR_CMD_OS_MGMT=y CONFIG_MCUMGR_CMD_STAT_MGMT=y - -### nRF5 specific settings - -# Specify the location of the NFFS file system. -#CONFIG_FS_NFFS_FLASH_DEV_NAME="NRF5_FLASH" diff --git a/samples/smp_svr/zephyr/sample.yaml b/samples/smp_svr/zephyr/sample.yaml new file mode 100644 index 0000000..0bde1d8 --- /dev/null +++ b/samples/smp_svr/zephyr/sample.yaml @@ -0,0 +1,12 @@ +sample: + description: Simple Management Protocol sample + name: smp svr +common: + harness: bluetooth + tags: bluetooth +tests: + sample.mcumg.smp_svr.nrf51: + extra_args: CONF_FILE="prj_tiny.conf" + platform_whitelist: nrf51_pca10028 + sample.mcumg.smp_svr.nrf52: + platform_whitelist: nrf52_pca10040 nrf52840_pca10056 diff --git a/samples/smp_svr/zephyr/src/main.c b/samples/smp_svr/zephyr/src/main.c index 4a21974..b3023ea 100644 --- a/samples/smp_svr/zephyr/src/main.c +++ b/samples/smp_svr/zephyr/src/main.c @@ -8,18 +8,14 @@ #include <zephyr.h> #include <string.h> #include <stdlib.h> -#include <bluetooth/bluetooth.h> -#include <bluetooth/conn.h> -#include <bluetooth/gatt.h> #include <stats/stats.h> -#include <mgmt/smp_bt.h> #include <mgmt/buf.h> #ifdef CONFIG_MCUMGR_CMD_FS_MGMT #include <device.h> #include <fs/fs.h> -#include <nffs/nffs.h> #include "fs_mgmt/fs_mgmt.h" +#include <fs/littlefs.h> #endif #ifdef CONFIG_MCUMGR_CMD_OS_MGMT #include "os_mgmt/os_mgmt.h" @@ -31,8 +27,12 @@ #include "stat_mgmt/stat_mgmt.h" #endif -#define DEVICE_NAME CONFIG_BT_DEVICE_NAME -#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1) +#ifdef CONFIG_MCUMGR_SMP_BT +#include <bluetooth/bluetooth.h> +#include <bluetooth/conn.h> +#include <bluetooth/gatt.h> +#include <mgmt/smp_bt.h> +#endif /* Define an example stats group; approximates seconds since boot. */ STATS_SECT_START(smp_svr_stats) @@ -48,15 +48,18 @@ STATS_NAME_END(smp_svr_stats); STATS_SECT_DECL(smp_svr_stats) smp_svr_stats; #ifdef CONFIG_MCUMGR_CMD_FS_MGMT -static struct nffs_flash_desc flash_desc; - -static struct fs_mount_t nffs_mnt = { - .type = FS_NFFS, - .mnt_point = "/nffs", - .fs_data = &flash_desc, +FS_LITTLEFS_DECLARE_DEFAULT_CONFIG(cstorage); +static struct fs_mount_t littlefs_mnt = { + .type = FS_LITTLEFS, + .fs_data = &cstorage, + .storage_dev = (void *)DT_FLASH_AREA_STORAGE_ID, + .mnt_point = "/lfs" }; #endif +#ifdef CONFIG_MCUMGR_SMP_BT +static struct k_work advertise_work; + static const struct bt_data ad[] = { BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), BT_DATA_BYTES(BT_DATA_UUID128_ALL, @@ -64,18 +67,13 @@ static const struct bt_data ad[] = { 0xd3, 0x4c, 0xb7, 0x1d, 0x1d, 0xdc, 0x53, 0x8d), }; -static const struct bt_data sd[] = { - BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN), -}; - -static void advertise(void) +static void advertise(struct k_work *work) { int rc; bt_le_adv_stop(); - rc = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), - sd, ARRAY_SIZE(sd)); + rc = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0); if (rc) { printk("Advertising failed to start (rc %d)\n", rc); return; @@ -87,7 +85,7 @@ static void advertise(void) static void connected(struct bt_conn *conn, u8_t err) { if (err) { - printk("Connection failed (err %u)\n", err); + printk("Connection failed (err 0x%02x)\n", err); } else { printk("Connected\n"); } @@ -95,8 +93,8 @@ static void connected(struct bt_conn *conn, u8_t err) static void disconnected(struct bt_conn *conn, u8_t reason) { - printk("Disconnected (reason %u)\n", reason); - advertise(); + printk("Disconnected (reason 0x%02x)\n", reason); + k_work_submit(&advertise_work); } static struct bt_conn_cb conn_callbacks = { @@ -113,12 +111,12 @@ static void bt_ready(int err) printk("Bluetooth initialized\n"); - advertise(); + k_work_submit(&advertise_work); } +#endif void main(void) { - struct device *flash_dev; int rc; rc = STATS_INIT_AND_REG(smp_svr_stats, STATS_SIZE_32, "smp_svr_stats"); @@ -126,17 +124,9 @@ void main(void) /* Register the built-in mcumgr command handlers. */ #ifdef CONFIG_MCUMGR_CMD_FS_MGMT - flash_dev = device_get_binding(CONFIG_FS_NFFS_FLASH_DEV_NAME); - if (!flash_dev) { - printk("Error getting NFFS flash device binding\n"); - } else { - /* set backend storage dev */ - nffs_mnt.storage_dev = flash_dev; - - rc = fs_mount(&nffs_mnt); - if (rc < 0) { - printk("Error mounting nffs [%d]\n", rc); - } + rc = fs_mount(&littlefs_mnt); + if (rc < 0) { + printk("Error mounting littlefs [%d]\n", rc); } fs_mgmt_register_group(); @@ -151,6 +141,9 @@ void main(void) stat_mgmt_register_group(); #endif +#ifdef CONFIG_MCUMGR_SMP_BT + k_work_init(&advertise_work, advertise); + /* Enable Bluetooth. */ rc = bt_enable(bt_ready); if (rc != 0) { @@ -161,12 +154,13 @@ void main(void) /* Initialize the Bluetooth mcumgr transport. */ smp_bt_register(); +#endif /* The system work queue handles all incoming mcumgr requests. Let the * main thread idle while the mcumgr server runs. */ while (1) { - k_sleep(1000); + k_sleep(K_MSEC(1000)); STATS_INC(smp_svr_stats, ticks); } }