Mcuboot updates through SMP troubles

So im trying to have a mechanism to update my mcuboot images through SMP.

The original issue was this : we had devices that had a version 0.9.8 with the nordic sdk 2.2.0, everything was fine with it we had mcuboot and serial recovery. It was all good, yet at one point we found some bugs and we needed to do some changes obviously as usual in development. So we reached that version 1.0.2 after a few iteration and its used nordic sdk 2.4.2, but we found out recently that device that had that merged.hex file flashed on, would not be able to do serial recovery anymore (not sure what caused this we think it might be some issue with the new sdk or anything else, anyways we didnt have serial recovery anymore).

So to solve this, we recently found that you could upgrade mcuboot through a SMP/DFU bluetooth update with the s0 or s1 signed file when doing a build like with a binary file named something like "signed_by_mcuboot_and_b0_s1_image_update.bin". So we figure out, oh so we only are using slot 0 right now since we only have one app binary, so logically well just update the next slot so S1. So I created a new pristine build with he sdk NRF 2.5.0 with mcuboot and I made sure that I raised the version in the child image with "CONFIG_FW_INFO_FIRMWARE_VERSION" value as well as the "CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION" (because I guess its a way to identify the version of mcuboot in the slot).And through our DFU app with were able to update the image.

So it seemed like everything worked. Then serial recovery was able back again. So I think that working, but now I am trying to test how could we update mcuboot again, in a case scenario that something happened again. I would guess logically that you just send it to s0 or s1 if a device didnt have the previous device (we have some devices that came from a base where mcuboot worked so they dont require that same update) I just redo a SMP / DFU / BT update and now when I list the image with the mcumgr.exe file (from the sample) the mcuboot version seemed to work.

Images:
image=0 slot=0
version: 1.0.2
bootable: false
flags:
hash: 8b1c7dcd78b8c1faefe01072c0089d50c07d4ee25e752f8972c3b8d74640c7d0
image=0 slot=1
version: 1.0.2
bootable: false
flags:
hash: 58c9c607c3a71ad27a93dc707760634eba4af734b6968413041d3b81170804c8
image=1 slot=0
version: 1.0.3
bootable: false
flags:
hash: fef35cad3e5a559dc47c152487ec20a7fa241fb94a0102834dbc64d3622eeafb
image=1 slot=1
version: 1.0.2
bootable: false
flags:
hash: 58c9c607c3a71ad27a93dc707760634eba4af734b6968413041d3b81170804c8

So im like cool cool. I see that 1.0.3 so I guess its probably my mcuboot version. So my guess is that image=1 (thingie) + slot=n number is like the place where mcuboot would be located in these wrapping of app.

So im like lets try again so I raise the number and repeat the same process with 1.0.4 and FW version 3. And then I run my list command from the mcumgr.exe and now its all over the place.

Can someone explain to me what does the Image=0 Slot=0 and all these differents state mean? Is Image=1 =>>> Mcuboot and Image=0 =>> the app ? And then you can decide to swap depending on what you prefer.

Also do MCUBoot version need to be higher than your app version ? Any help appreciated.

Parents
  • Hi,

    I am not sure if I understand exactly what is going wrong, so let me ask some questions to make it more clear to me:

    You are trying to update MCUboot with Serial Recovery, right?

    What is the thing that does not work?

    Here are some stuff which may be useful:

    My colleague has this sample: https://github.com/aHaugl/samples_for_NCS/tree/main/DFU/serial_recovery_nsib. See the readme for how to update the bootloader.

    You can see slot numbers from CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD docs.

    Regards,
    Sigurd Hellesvik

  • Yes thats what Im doing. Its just that I dont understand which slots goes to where. Like you have slots 0 and slots 1 and image 0 and image 1. So in theory you have like 4 differents spots for your images. The thing that I dont understand is that if in the future I need to update mcuboot for whatever reason, I want to know which slot I need to update without causing an issue. For some reason, after I did a few tests I noticed that the version field seemed to be random or not be the same as with the version reported from the Kconfig value CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION. So I was wondering if these were in their correct version or is it because the version reported in that data from mcumgr.exe is not the same as that kconfig value from zephyr documentation. I want to know which version goes where, in case I need to program a tool in the future for our technicians that may be not as technical either. (Basically they would just press a button to upgrade the mcuboot bootloader without having to worry about which slots/image spots to use) I just need to figure out which is the appropriate slot/image spot in that matter.

  • When you have enabled MCUboot and NSIB in an application, you will have 4 slots in your application:

    • s0 (mcuboot)
    • s1 (mcuboot)
    • mcuboot_primary (app)
    • mcuboot_secondary (app)

    MCUboot runs from either s0 or s1, whichever has the newest image version (CONFIG_FW_INFO_FIRMWARE_VERSION).

    the app always runs from mcuboot_primary.

    For DFU, the mcumgr library only knows about mcuboot_primary (-n 0 / -n 1) and mcuboot_secondary (-n 2).
    To update the app over serial recovery, upload directly to mcuboot_primary.
    To update mcuboot over serial recovery, upload to mcuboot_secondary. On reset, mcuboot will see that a new bootloader has been uploaded, and swap mcuboot_secondary into s0 or s1.

    Does this answer your question?

Reply
  • When you have enabled MCUboot and NSIB in an application, you will have 4 slots in your application:

    • s0 (mcuboot)
    • s1 (mcuboot)
    • mcuboot_primary (app)
    • mcuboot_secondary (app)

    MCUboot runs from either s0 or s1, whichever has the newest image version (CONFIG_FW_INFO_FIRMWARE_VERSION).

    the app always runs from mcuboot_primary.

    For DFU, the mcumgr library only knows about mcuboot_primary (-n 0 / -n 1) and mcuboot_secondary (-n 2).
    To update the app over serial recovery, upload directly to mcuboot_primary.
    To update mcuboot over serial recovery, upload to mcuboot_secondary. On reset, mcuboot will see that a new bootloader has been uploaded, and swap mcuboot_secondary into s0 or s1.

    Does this answer your question?

Children
  • Lets say I build my project and then I have these files generated. Here is a table of the files that I currently use and the understand I have of them, maybe from that perspective you would be able to help me lighten my understanding further.

    Filename Desc
    merged.hex Bootloader + Mcuboot + app (everything) to flash through 10 pins connector on the board
    app_update.bin App binaries for update through serial recovery or DFU update (but ONLY APP!)
    signed_by_mcuboot_and_b0_s0_image_update.bin Binaries to update mcuboot ? From B0 and Slot 0
    signed_by_mcuboot_and_b0_s1_image_update.bin Binaries to update mcuboot ? From B0 and Slot 1

    [ For your information for our devices in production we are obligated to pass through serial recovery or Bluetooth SMP/DFU as our boards are potted, therefore we cannot have an access to that 10 pins port on the board for NRF91 (that would have simplified alot of things although it wipes the memory). So I want to avoid to brick a board to the most of my capabilities, and you know if you flash something with serial recovery and dont stop, you can kind of brick your board if you arent careful. Luckily with non potted board I can just recover the board with nrfjprog through the JLink probe ]

    So in our case, at first we had a firmware that we flashed that had serial recovery working. After some changes overtime we created a more stable version of our firwmare and we wanted to release it on more devices, until we found out that serial recovery didnt seem to work anymore.

    So after attempts we found that it was possible to recover that feature through DFU by sending the signed_by_mcuboot_and_b0_s1_image_update.bin.

     RE: signed_by_b0_s1_image.bin vs signed_by_mcuboot_and_b0_s1_image_update.bin 

    From what I understood it was simple you just need to remember to use S0 or S1. Problem is that now we have 2 types of devices, those that had mcuboot with their keys working from the start and the other which needed a DFU update.

    If I have a device from the category 1 (the one that had a merged.hex that worked from the start with mcuboot) and use the apache mynewt-cli tool for mcumgr and list the images (with a image list call).

    I get that output

    Images:
    image=0 slot=0
    version: 1.1.6
    bootable: false
    flags:
    hash: 094da666c5288244f9278c8543c8502c81a41d7cce2e31b4bc8fe7522acad43f
    image=1 slot=0
    version: 1.1.6
    bootable: false
    flags:
    hash: 56ce692212812fcc1d280f02d6b3c4f13c4078419fd0a1b157d18db0e7337b70
    Split status: N/A (0)

    I expect that version: 1.1.6 as it is the same as my CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION.

    From what I understand one of those is mcuboot and the next one is the app. Tell me if Im wrong, that one of the thing I want to clarify.

    Then from category 2, let say we had a device with a wrong merged.hex with CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION that was set to 1.0.2.  Im being able to run my command to list the image with my apache newt-cli tool. I get this result as expected

    Images:
    image=0 slot=0
    version: 1.0.2
    bootable: false
    flags:
    hash: 8b1c7dcd78b8c1faefe01072c0089d50c07d4ee25e752f8972c3b8d74640c7d0
    image=1 slot=0
    version: 1.0.2
    bootable: false
    flags:
    hash: 335aa8f9b3275ee27a1558fb752063f72922775a0c94ae6ee3a4d018017f89aa
    Split status: N/A (0)

    But now I am not able to flash a binary to update the app from those ports for whatever reason. If I use the same baudrate (921600) and the same mtu (512), I get stuck at  0 B / 292.28 KiB [--------------------------------------------------------------------------------------------------]   0.00% and the firmware does not upload. Thats why I think serial recovery is not working for some reason? So therefore I would resort to that DFU update instead through bluetooth.

    So to recover the serial recovery feature, here are the steps I would follow : 

    1. I would increment the CONFIG_FW_INFO_FIRMWARE_VERSION field in child_image\mcuboot.conf

    2. I would update my CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION to 1.1.6

    3.  I would build my new firmware that I am sure that has working serial recovery through the nordic extension in vscode

    4. Then I would get the "signed_by_mcuboot_and_b0_s1_image_update.bin". (mentionned above)

    5. I would connect through bluetooth to my device 

    6. Then through the SMP server I would send the bits by bits of that file to update mcuboot.

    7. Then once its completed I would just need to restart the device 

    8. And now serial recovery works again like a charm.

    9. Then with the apache mynewt-cli tool I would list the images on my device and get this.

    Images:
    image=0 slot=0
    version: 1.0.2
    bootable: false
    flags:
    hash: 8b1c7dcd78b8c1faefe01072c0089d50c07d4ee25e752f8972c3b8d74640c7d0
    image=0 slot=1
    version: 1.0.2
    bootable: false
    flags:
    hash: 335aa8f9b3275ee27a1558fb752063f72922775a0c94ae6ee3a4d018017f89aa
    image=1 slot=0
    version: 1.0.2
    bootable: false
    flags:
    hash: d97f45512e795dba960fc20f2ce99b3228fa448fcd890f673b44d41351f9f912
    image=1 slot=1
    version: 1.0.2
    bootable: false
    flags:
    hash: 335aa8f9b3275ee27a1558fb752063f72922775a0c94ae6ee3a4d018017f89aa
    Split status: N/A (0)

    Its still the version 1.0.2 although now mcuboot works ??  and now I have two image and slots. I just want to know why that version is not being changed to 1.1.6. As the example mentionned before we need to be able to know which file to use either the signed_by_mcuboot_and_b0_s0_image_update.bin or the signed_by_mcuboot_and_b0_s1_image_update.bin and yet the version remains the same so I wouldnt know how to differentiate their version. Do you know if there is an alternative or if I am missing something there ? I guess maybe by the hash, but Im not sure how to decypher this or maybe if you have any link for that.

    ===========================

    Also if I do an update through serial for mcuboot, would I still use that "signed_by_mcuboot_and_b0_s1_image_update.bin" or the other one ? For some reason when I do, when I power off and power back on my device now I cannot access my device. I can still get back to serial recovery though but my app seems to be gone now. I guess the bootloader see the newer firmware and try to go to that slot which has no firmware except that mcuboot upgrade.

    ============================

    So in conclusion I have 2 problems

    1. DFU version is different from expected (or might be missing)

    2. Serial recovery mcuboot update missing steps.

  • Okay I reread your answer sorry about that. For some reason when I try to upload the image through -n2 it seems that I hang 

    mcumgr.exe --conntype=serial --connstring=dev=COM6,baud=921600,mtu=512 image upload signed_by_mcuboot_and_b0_s1_image_update.bin -e -n2

    I just get a NMP timeout. Although I made sure with a version with a lower 

    CONFIG_FW_INFO_FIRMWARE_VERSION 
  • KLarocqueEMFluids said:
    For some reason when I try to upload the image through -n2 it seems that I hang 

    This is typical if you do not have set CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD. Have you set this for MCUboot?

    Also, did you  test the sample I sent you in my first reply?
    If you make it work with the unchanged sample first, you will be familiar with the process when you do it with your own project after.

Related