nRF Dongle 52840 DFU over Mesh

Dear fellow Developers,

I'm finishing a project where I have to implement the DFU over Mesh protocol in a series of firmware running on a nRF 52840 Dongle. While I was able to solve most of the problems so far, there's still a major one that is bugging me:

I managed to complete the whole procedure of Device Firmware Update over Mesh, where a Distributor was able to distribute the Firmware to several targets, successfully the vast majority of times. The device remains provisioned, the services offered show the correct update (so to verify, together with the version number that the service is indeed updated), and I'm able to use them seamlessly.

Problem is, whenever the update is completed, if I detach the nRF 52840 Dongle from its USB port (hence turning it off) it always reboots in "Open DFU Bootloader" mode. Unplugging and re-plugging the device doesn't produce any effect.

I also tried the following directive so to apply the firmware at a later stage, but this was unsuccessful. 

mesh models dfd start 0 0 0 0

mesh models dfd apply

I feel like there are major incompatibilities between the Dongle Bootloader and MCUBoot and I was wondering if any of you have any idea on how to overcome these.

Thank you in advance,

Ale

Parents
  • Hi Ale, 
    The problem with the dongle is that by default it has the original bootloader from nRF5 SDK, in addition to the MCUBoot bootloader that you have flashed (I assume). 

    The nRF5 bootloader on each booting up will check and verify if the firmware (MCUBoot + your application) remain the same by using hash check. 
    In your case the distributor receive the image and maybe update the firmware when you do mesh DFU update. The NRF5 bootloader doesn't recognize this change and will switch to bootloader mode because it detects a hash check fail. 

    My suggestion is either to use a nRF52 DK as the hardware backend (there isn't a nRF5 bootloader on it) or solder a header on the  P1 port on the dongle to erase the bootloader and use it as a DK. You may then need to create a new board and re-configure the memory of the dongle similar to what on the DK. 

  • Dear Hung Bui,

    Thank you very much for your kind answer. We will work towards your solutions: either having a DK as Distributor or by removing the Dongle Bootloader.

    Just for curiosity: do you know whether there is a way to update the hash in software so to have the Dongle properly load?
    This is just out of curiosity as I'm pretty sure the SOC won't have the DFU Bootloader therefore we won't have that kind of problems in production.

    If you don't know, don't worry: I'll try to do some research myself anyway in the meantime (and, if I find any solution, I'll post it here :) )

    Thank you again and kind regards,

    Ale

    EDIT: I still haven't researched the topic yet but I thought a little bit about it: the weird thing is that in order for the Firmware to be updated, the Dongle does indeed reboot successfully. So, there's an inconsistent situation in which the first reboot successfully passes the hash check, but all the subsequent ones fail.

  • Hi Ale, 

    Sorry that I missed the part that you use the dongle on all of your devices. I thought that you only use the dongle on the distributor but not on the target. 

    The dongle is not a development platform so we don't suggest to use it in the initial phase of development. I agree that it's a good device on mass testing but the correct behavior should be verified before you start mass testing. 

    Soldering hundreds of header on the dongle can be an issue.
    My assumption is that when you flash the dongle with your application, you were using the merged.hex file that contains both the MCUBoot and the mesh application, is it correct ? Did you flash it via the nrf Connect Desktop Programmer application ? 

    If it's the case, it explain why the Legacy Bootloader complained about CRC. 

    What you need to do is instead of flashing the MCUBoot and application merged, you instead only flash the MCUBoot and then after that use MCUBoot recovery mode to receive the Mesh application. This way the Legacy Bootloader only check the MCUBoot, not the application when booting up. 
    Please take a look at the documentation here: https://docs.zephyrproject.org/latest/boards/arm/nrf52840dongle_nrf52840/doc/index.html#option-2-using-mcuboot-in-serial-recovery-mode

    You can use dfu_application.zip to flash the application with mcumgr


    Maybe not related but I looked at this ticket from you: Error when building BT mesh DFU OTA Target on Dongle 52840 (struct.error: ushort format requires 0

    I saw that you have modified legacy_bootloader_storage from 0xe0000 to 0xe8000. 
    Do you have an explanation for that ? 
    The legacy bootloader starts at 0xe0000 not 0xe8000, by configure that you are risking overwriting the legacy bootloader. 

  • Dear Hung Bui,

    Once again, thank you for your kindness and your attention to details. I indeed used the nrf Connect Desktop Programmer application to flash the merged.hex file onto the Dongles.

    I'll try the way you just suggested, flashing only mcuboot in order to keep the CRC stable.

    About the last consideration, at first I indeed tried to keep the space for the legacy bootloader minimized but quickly realized that it wasn't really an option: even if I put a smaller partition the bootloader would just use the full 0x20000 sized partition anyway.

    As of today, I've restored the legacy_bootloader_storage and also renamed it to legacy_bootloader in order to avoid conflicts with the settings_storage partitions used by Zephir's settings subsystem: unless specified explicitly, the configuration would automatically look for a partition including the "settings" name. Furthermore, i decreased the number of static partitions declared in the pm_static file and added the CONFIG_BOARD_HAS_NRF5_BOOTLOADER together with CONFIG_FLASH_LOAD_OFFSET and CONFIG_FLASH_LOAD_SIZE.

    Now the example kinda fully works, with the only exception of that reboot into the "Open DFU Bootloader".

    I'll try to only program mcuboot right now, I'll get back to you as soon as I'm done with it.

    Also: as mentioned in an edit before, the weird thing is that the device reboots correctly the first time, but goes into bootloader mode next reboot. Might this be because the reboot following the DFU over Mesh only reboots the application and not mcuboot itself?

    Again, thank you for your help, it really is appreciated.

    Have a good afternoon,

    Ale

  • Hi again, 

    alebldn said:
    Might this be because the reboot following the DFU over Mesh only reboots the application and not mcuboot itself?

    It's kind of correct. The device reboot before the image swap happens (hence no CRC issue) the bootloader will jump to the MCUBoot and then MCUBoot swap the image. The next reset after that will run into CRC issue. 

  • Dear Hung Bui,

    unfortunately I'm coming back with bad news as I wasn't yet able to build the MCUBoot application into the Dongle to make it properly work. I'm not really confident in using this mixed environment as I'm kind of new to developing Nordic applications.

    I've been trying to follow the steps in the guide you posted but it resulted in errors when building the very first step. I've been trying to use the vscode extension to build the sample "mcuboot" (compatible with the Dongle) but the result was the same:

    CMake Error at /opt/nrfconnect/ncs/v2.5.0/zephyr/cmake/modules/extensions.cmake:2274 (message):
      No such file or directory: TINYCRYPT_DIR:
      '~/Desktop/NordicWorkspaces/ext/tinycrypt/lib'
    Call Stack (most recent call first):
      CMakeLists.txt:40 (assert_exists)

    (the sample folder's path is "~/Desktop/NordicWorkspaces/nordic_bt_dfu_workspace/zephyr")

    I've been trying to move the cloned mcuboot repository around, including inside the zephyr folder but the result was the same.

    I've been trying to modify the CMakeLists.txt file to replace the "get_filename_component" (changed in version 3.20 (I'm using version 3.20.5)) in order to match BOOT_DIR and MCUBOOT_DIR with the proper directories so to actually (and successfully) avoid this error, but still resulting in duplicated functions problem when linking the program.

    I've also tried using the "with_mcuboot" sample to try and flash in another image and, while i got the whole project working, the mcumgr tool was stuck in the attempt, not being able to flash anything. Programmer app doesn't show anything in the device box so trying to flash images using the "enable MCUBoot" settings checked would not actually work.

    Do you have any suggestions? Mind you trying to compile the sample yourself to check whether there actually are errors I'm facing? If so, do you suggest downgrading CMake to version < 3.20?

    Thank you very much for your patience,

    Ale

  • Hi Alessandro,

    I assume you have managed to build the DFU target mesh application for nRF52840 dongle. Correct ? 
    If you have, then you don't need to build the MCUBoot separately. 
    What you need to do is to add this file in to a child_image folder in your project to enable MCUBoot's serial recovery mode: 
    6574.mcuboot.conf

    It should look like this: 


    Then you build your application as normal. The reason I suggested this because in the target&distributor, the MCUBoot is already built. You don't need to build MCUBoot separately as in the guide from Zephyr. 

    You can find the file zephyr.hex in the build\mcuboot folder:
     

    You can use this zephyr.hex in nRF Programmer to upload to the dongle. 

    The change in the file I provided above is to allow serial recovery mode. Then you can continue with the instruction in the guide I provided to create the .zip file for the mesh application (build\zephyr\zephyr.hex) then upload it via mcumgr. 

    Please be noted that, from what I get from mesh team, the dongle is not supported by the DFU mesh solution. We haven't tested with the dongle. It's expected that you will need to get familiar with the DFU chain and know how to adapt it to the mesh application. 

Reply
  • Hi Alessandro,

    I assume you have managed to build the DFU target mesh application for nRF52840 dongle. Correct ? 
    If you have, then you don't need to build the MCUBoot separately. 
    What you need to do is to add this file in to a child_image folder in your project to enable MCUBoot's serial recovery mode: 
    6574.mcuboot.conf

    It should look like this: 


    Then you build your application as normal. The reason I suggested this because in the target&distributor, the MCUBoot is already built. You don't need to build MCUBoot separately as in the guide from Zephyr. 

    You can find the file zephyr.hex in the build\mcuboot folder:
     

    You can use this zephyr.hex in nRF Programmer to upload to the dongle. 

    The change in the file I provided above is to allow serial recovery mode. Then you can continue with the instruction in the guide I provided to create the .zip file for the mesh application (build\zephyr\zephyr.hex) then upload it via mcumgr. 

    Please be noted that, from what I get from mesh team, the dongle is not supported by the DFU mesh solution. We haven't tested with the dongle. It's expected that you will need to get familiar with the DFU chain and know how to adapt it to the mesh application. 

Children
  • Hi again, 
    I got a tip from our team that if you want to re-flash the dongles you can get one of these cable: https://www.tag-connect.com/product-category/products/cables/10-pin-target

    It will allow you to program the dongle on the pogo pins next to the P1 port. You can connect a DK to the dongle and erase nRF5 Bootloader. This way you can use the dongle as you wish. (You will need to define a new board because now the MBR and Legacy bootloader is removed)

  • Dear Hung Bui, I'm back with some mixed news. Some of them are good, others are meh.

    Best news: After a lot of trials during the weekend I managed to make it all work and, indeed you were right: by only using the MCUBoot image, the nrf5 bootloader does indeed allow the firmware to be booted even after the update. Massive thank you for this!

    Unfortunately, to get there, it was all but trivial: first, for some reason, mcumgr was not (and still isn't) able to upload the firmware whatsoever. The upload phase is stuck at 0bytes, even if i launch the command using sudo (I'm on linux). Changing the owner rights of the /dev/ttyACM0 file doesn't really produce any different effect and nor does changing the accessibility through chmod.I am able to read the console through /dev/ttyACM0 but I'm not able to upload anything using ./mcumgr. In case you're wondering, I installed mcumgr as specified in the github page using go install. I also used nrfutil as specified in the tutorial, downloading not from github but instead from the non-deprecated page in your site. Through it, I also installed nrf5-sdk-tools.

    In the end neither mcumgr nor nrfutil were used to flash the firmware in the dongle. this is not the solution i was looking for but still it's a first step towards it:

    • Using nRF Connect Programmer I flashed the merged.hex image containing both MCUBoot AND DFU Target first.
    • Still using nRF Connect Programmer I then flashed MCUBoot image zephyr.hex contained in the mcuboot subfolder.

    This way, the application did still run properly but the resulting hash in the nrf5 bootloader belongs only to MCUBoot. This way, the device does reboot properly even after the update and the update itself sticks.

    I'll also talk about this with some colleague of mine to see if I can find a better solution.

    Thank you very much for your help, you're the best.

    Ale

  • Hi Ale, 

    One thing need to be double checked is to make sure that you have put the MCUBoot to serial recovery mode on the dongle. 

    In the mcuboot.conf I sent I have set CONFIG_MCUBOOT_INDICATION_LED=y. So it's expected that one of the LED should turn on when you press the switch when you plug the device to USB port. 

    But anyway, if it works now and the trick of flashing using nRF Connect Programmer you did seems to be a good trick. You don't even need to use mcumgr separately then I don't see a problem with that :) 

  • About that: you're once again right, I was so excited I had it working I completely forgot to mention that.

    No, unfortunately, the indication led does not work. I also tried to create an overlay to change led but it didn't really seem to work at all. I don't even get warnings at build time so I wouldn't really know what to expect. A first guess would be to maybe change the pm_static file?

    Anyway, the important thing is that right now we're able to update via DFU OTA hundreds of Dongles. The very first phase of configuring them all is going to be rusty but will do for the early testings.

    Of course, if you have any suggestions related to the errors of mcumgr not uploading and the led not showing up, I'm always happy to hear some advice. Slight smile

    Thank you very much,

    Have a good evening!

Related