Has anybody sucessfully enabled SMP (software management protocol) over SHELL using a UART ?

I'm fairly new to Zephyr and initially I'm hoping someone can point me to an example where SMP over UART can be used to update a firmware image slot.  Google seems to have a lot of information relating to KConfig options that no longer seem to exist with regards to using the SMP protocol via Zephyr shell - and browsing through KConfig I cant quite seem to find something that works or a document that explains things nicely.   The typical Google response would be 'do this' (below) but it seems the KConfig options are renamed or missing

# Enable the Zephyr shell subsystem
CONFIG_SHELL=y
CONFIG_SHELL_BACKEND_SERIAL=y

# Enable the Simple Management Protocol (SMP)
CONFIG_MCUMGR=y
CONFIG_MCUMGR_TRANSPORT_SHELL=y
# You may also need general SMP support
CONFIG_MCUMGR_SMP=y

# Enable specific command groups as needed (examples)
CONFIG_MCUMGR_CMD_IMG_MGMT=y    # Image management (for DFU)
CONFIG_MCUMGR_CMD_OS_MGMT=y     # OS management commands (e.g., reset, tasks)
CONFIG_MCUMGR_CMD_FS_MGMT=y     # File system management
  • Hi,

    The Shell transport is included when you use the smp_svr sample and build for Bluetooth by including overlay-bt.conf as an extra Kconfig file. With that, you can observe that you get normal shell working over UART, and that you can also use SMP over the same UART shell (I tested this with AuTerm). As you can see in that sample, these are the key configs for enabling Shell over UART and use mcumgr shell transport:

    # Enable the Shell mcumgr transport.
    CONFIG_BASE64=y
    CONFIG_CRC=y
    CONFIG_SHELL=y
    CONFIG_SHELL_BACKEND_SERIAL=y
    CONFIG_MCUMGR_TRANSPORT_SHELL=y
    

    Additionally, you need the more generic mcumgr configs shown in the prj.conf of the same sample.

  • So trying to figure out why shell isnt working I set up a debug session with MCUBoot    I found this in main.c.


       
    if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
            BOOT_LOG_ERR("Unable to find bootable image");

            mcuboot_status_change(MCUBOOT_STATUS_NO_BOOTABLE_IMAGE_FOUND);

    #ifdef CONFIG_BOOT_SERIAL_NO_APPLICATION
            /* No bootable image and configuration set to remain in serial
             * recovery mode
             */
            boot_serial_enter();
    #elif defined(CONFIG_BOOT_USB_DFU_NO_APPLICATION)
            rc = usb_enable(NULL);
            if (rc && rc != -EALREADY) {
                BOOT_LOG_ERR("Cannot enable USB");
            } else {
                BOOT_LOG_INF("Waiting for USB DFU");
                wait_for_usb_dfu(K_FOREVER);
            }
    #endif

            FIH_PANIC;
        }
    I ended up stuck on FIH_PANIC at the bottom.   So I enabled 'CONFIG_BOOT_SERIAL_NO_APPLICATION' in prj.conf to enable  'boot_serial_enter()'    And then got told I need ' 'CONFIG_MCUBOOT_SERIAL' as a dependency.  So I also added that to prjk.conf.
    And finally the build now fails.....
    C:/Code/zephyr/bootloader/mcuboot/boot/boot_serial/src/boot_serial_encryption.c:114:31: warning: 'struct enc_data' declared inside parameter list will not be visible outside of this definition or declaration
    114 | decrypt_region_inplace(struct enc_data *enc_data,
    | ^~~~~~~~
    C:/Code/zephyr/bootloader/mcuboot/boot/boot_serial/src/boot_serial_encryption.c: In function 'decrypt_region_inplace':
    C:/Code/zephyr/bootloader/mcuboot/boot/boot_serial/src/boot_serial_encryption.c:169:30: warning: passing argument 1 of 'boot_enc_decrypt' from incompatible pointer type [-Wincompatible-pointer-types]
    169 | boot_enc_decrypt(enc_data,
    | ^~~~~~~~
    | |
    | struct enc_data *
    In file included from c:\code\zephyr\bootloader\mcuboot\boot\bootutil\src\bootutil_priv.h:44,
    from C:/Code/zephyr/bootloader/mcuboot/boot/boot_serial/src/boot_serial_encryption.c:10:
    C:/Code/zephyr/bootloader/mcuboot/boot/bootutil/include/bootutil/enc_key.h:73:44: note: expected 'struct enc_key_data *' but argument is of type 'struct enc_data *'
    73 | void boot_enc_decrypt(struct enc_key_data *enc_state,
    | ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
    C:/Code/zephyr/bootloader/mcuboot/boot/boot_serial/src/boot_serial_encryption.c: In function 'decrypt_image_inplace':
    C:/Code/zephyr/bootloader/mcuboot/boot/boot_serial/src/boot_serial_encryption.c:265:37: error: incompatible type for argument 1 of 'decrypt_region_inplace'
    265 | rc = decrypt_region_inplace(enc_data, fa_p, hdr, size, sect_size);
    | ^~~~~~~~
    | |
    | struct enc_key_data
    C:/Code/zephyr/bootloader/mcuboot/boot/boot_serial/src/boot_serial_encryption.c:114:41: note: expected 'struct enc_data ' but argument is of type 'struct enc_key_data'
    114 | decrypt_region_inplace(struct enc_data *enc_data,
    | ~~~~~~~~~~~~~~~~~^~~~~~~~
    C:/Code/zephyr/bootloader/mcuboot/boot/boot_serial/src/boot_serial_encryption.c:274:5: warning: implicit declaration of function 'boot_enc_zeorize'; did you mean 'boot_enc_zeroize'? [-Wimplicit-function-declaration]
    274 | boot_enc_zeorize(&enc_data);
    | ^~~~~~~~~~~~~~~~
    | boot_enc_zeroize
    C:/Code/zephyr/bootloader/mcuboot/boot/boot_serial/src/boot_serial_encryption.c:275:22: warning: passing argument 1 of 'boot_state_clear' from incompatible pointer type [-Wincompatible-pointer-types]
    275 | boot_state_clear(&state);
    | ^~~~~~
    | |
    | struct boot_loader_state **
    In file included from c:\code\zephyr\bootloader\mcuboot\boot\bootutil\src\bootutil_priv.h:37:
    C:/Code/zephyr/bootloader/mcuboot/boot/bootutil/include/bootutil/bootutil.h:89:49: note: expected 'struct boot_loader_state *' but argument is of type 'struct boot_loader_state **'
    89 | void boot_state_clear(struct boot_loader_state *state);
    | ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
    [126/355] Building C object zephyr/CMakeFiles/zephyr.dir/lib/os/cbprintf_nano.c.obj
    ninja: build stopped: subcommand failed.
    FATAL ERROR: command exited with status 1: 'C:\Program Files\CMake\bin\cmake.EXE' --build 'c:\Code\zephyr\bootloader\mcuboot\boot\zephyr\build'

    (venv_zephyr) c:\Code\zephyr\bootloader\mcuboot\boot\zephyr>
    So I presume I misunderstand something!
  • Hi,

    The error as you see comes from not having a bootable image. Is that intentional, did you only program the bootloader, or should you also have programmed an application? That said, using CONFIG_BOOT_SERIAL_NO_APPLICATION=y is fine, as entering serial recovery mode on no bootable application can make sense. But you should not have ended up here in the first place. Also, it was not clear to me originally that you wanted to use serial recovery (where you have UART transport in the bootloader in addition to / instead of, doing the transport in the application as you do with SMP. What is the goal?

    I am also not sure why you get these errors, so I wonder if we can backtrack a bit. Did you start of with an sample (like the smp svr sample)? Can you share details or perhaps your full project (both code and configuration files like prj.conf) so I get a better understanding of what you are doing? I would recommend starting with the smp svr sample first and perhaps also go through lesson 9 in nRF Connect SDK Intermediate to get a better understanding of the bootloader and DFU in the nRF Connect SDK.

  • Hi,

    Thanks for your reply.  I've just started with the MCUBoot repo and tried to build a suit MCUBoot from there (west build etc) and just modified the overlay file like this for my board:-

    / {
        chosen {
            zephyr,code-partition = &boot_partition;
            zephyr,uart-mcumgr = &usart1;
        };

        aliases {
            mcuboot-button0 = &user_button; // Link the alias to your button
            mcuboot-led0 = &green_led_1; // Link the alias to your button
        };
    };


    and all is good until I add 'CONFIG_MCUBOOT_SERIAL=y'


    Is this a bug ?  When RSA enabled and serial enabled at the same time?  Note that I can build an encrypted app and 'STMProg' it onto the board, and the bootloader decrypts it......

    CONFIG_MCUBOOT_SERIAL=y

    CONFIG_BOOT_ENCRYPT_IMAGE=y
    CONFIG_BOOT_SIGNATURE_TYPE_RSA=y
    CONFIG_BOOT_ENCRYPTION_KEY_FILE="enc-rsa2048-priv.pem"
    CONFIG_BOOT_SIGNATURE_KEY_FILE="root-rsa-2048.pem"

     and the compilation fails.

    C:/Code/zephyr/bootloader/mcuboot/boot/boot_serial/src/boot_serial_encryption.c: In function 'decrypt_image_inplace':
    C:/Code/zephyr/bootloader/mcuboot/boot/boot_serial/src/boot_serial_encryption.c:265:37: error: incompatible type for argument 1 of 'decrypt_region_inplace'
    265 | rc = decrypt_region_inplace(enc_data, fa_p, hdr, size, sect_size);
    | ^~~~~~~~
    | |
    | struct enc_key_data


    All I'm trying to do (but it's so hard -- bits of info picked up from here or there, Google tells me out of date tips like its fact.....)  is just get a bootloader working with ideally, SMP over serial or SMP over SHELL ( so I can have the shell).
    I want to be able to write an encrypted f/ware image onto my target onto image bank1, via the MCUMgr scripts, and then reset the board and watch the bootloader decrypt /copy image1 to image0 and then jump into the app.

    I also like the 'hold the user button, while momentarily pressing RESET, to get into the bootloader functionality, which I can make work (although SMP still doesnt seem to be working, and thats without SMP over shell and console off etc)

    And lastly, when I try to enabled ' CONFIG_MCUMGR_TRANSPORT_SHELL=y'   I get more compile errors.
    (I'm not even trying to use CONFIG_ZCBOR=y, but somehow its getting pulled in twice).

    hyr/bootloader/mcuboot/boot/boot_serial/src/zcbor_bulk.c:14: first defined here
    collect2.exe: error: ld returned 1 exit status
    ninja: build stopped: subcommand failed.
    FATAL ERROR: command exited with status 1: 'C:\msys64\ucrt64\bin\cmake.EXE' --build 'C:\Code\zephyr\bootloader\mcuboot\boot\zephyr\build'

    Kind Regards, Nick

  • Hi,

    Yes, I can get compile errors. But I would like to backtrack a bit to your previous post, it looks like you may be off on a slightly wrong path. Normally, MCUboot is built by sysbuild when you build your application and I am having problems understanding your project layout and how you configure things. I suggest you do as demonstrated in the SMP server sample. You should also have a look at Enabling a bootloader chain using sysbuild. Lastly, as bootloader and DFU can be complex, I suggest having a look at lesson 9 in nRF Connect SDK Intermediate.

    If you still have problems, please share the project along with build logs and description so that I can get a better understanding of what you are doing.

Related