Example For Using UART DFU on NRF52832 on both sides of communications

Hello,

I am trying to figure out which example is the closest fit for our design. We are using a 2 processor solution in our product, and the firmware for the NRF52832 has to be able to be upgraded via the UART connection to the main processor. I have found some examples here, but usually it's using a PC application or over the air which does not apply to our design. Also, I'm confused abut some of the examples on the side of the NRF52832 in terms of performing the update. There are references to a "full modem" update, but what is meant by modem? This will be a simple direct UART communication update, is this done via the application on the Nordic chip or can it be done via the bootloader directly?

This has to be a common approach, I'm just unsure where to start. Note I am using the latest SDK release 1.9.1.

Thanks for your help.

Regards,

Pam

  • Pamela Keiles said:
    Can I include all support for the firmware image update via the UART within the bootloader code? And if so, is the smp protocol the only option?

    Yes, you can do this. If you want to perform a UART DFU through mcuboot you need to use smp/mcumgr protocol. However, only a limited set of commands are supported, as you see here: https://github.com/nrfconnect/sdk-mcuboot/blob/v1.8.99-ncs1/boot/boot_serial/src/boot_serial.c#L502-L527 

    If you want to drop the smp/mcumgr, you need to modify MCUboot, which might require less work that using the smp/mcumgr protocol (where you need to implement the protocol on the client side).

    The modification of mcuboot, will happen to the function boot_serial_input(), and instead of parsing the incoming messages as mcumgr commands, you simply store the image blocks right into flash where it belongs.

    Please let me know what approach you prefer, and I will assist you with the implementation.

  • Hi Simon,

    Another option is to not rely on the bootloader for the update itself but perform the flash programming within my application. Since there are 2 slots, the current running application can do the flash write directly to the other slot. Then after it confirms the programming is correct (via a checksum or header/tail data check?), call the correct routines within the bootloader to mark the new image as active and execute the reset. Does that sound doable? I'm assuming the flash driver routines can just be called directly?

    Thanks,

    Pam

  • Yes this is absolutely possible.

    Pamela Keiles said:
    Then after it confirms the programming is correct (via a checksum or header/tail data check?),

    This is actually done by the bootloader, all you need from the current running application, is to place the image into the secondary slot. Then on reset, the mcuboot will check if there is a valid image present in secondary slot and swap it with the image in the primary slot if that's the case. Then, it will boot the new image.

    Pamela Keiles said:
    call the correct routines within the bootloader to mark the new image as active and execute the reset.

    This should be done from within the image itself, like it's done in the https_update sample, so mcuboot won't revert back to the old image on the next reet.

    The reason it mcuboot will revert back the images on the next reset is to prevent the product from being bricked, for example if the new firmware is faulty, and causes the device to crash.

    Let me create a detailed list of how things happen (when performing a dfu through the application)

    1. Application receives the image, and places it in the secondary slot
    2. The device resets
      1. This can be done externally by pressing a button, or within the application itself using sys_reboot() (see \zephyr\lib\os\reboot.c)
    3. MCUboot will run first after a reboot and it can see that there is a new image in secondary slot. It will then check if the image is valid (see MCUboot-->Integrity check)
    4. If a valid image is present in the secondary slot, mcuboot wil swap it with the image in the primary slot
    5. MCUboot will then boot the new update that are now present in the primary slot
    6. The new update will run, and needs to confirm itself ( like it's done in the https_update sample), so MCUboot won't revert back on the next reset
    Pamela Keiles said:
    I'm assuming the flash driver routines can just be called directly?

    Yes, you can. Check out the flash API: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.0/zephyr/reference/peripherals/flash.html#overview. Take a look at the example \zephyr\samples\drivers\soc_flash_nrf to see how to use this API. The http_update sample uses the Stream Flash API (through \nrf\include\dfu\dfu_target_stream.h), so that might be worth taking a look at.

    Good luck and best regards,

    Simon

  • Hi Simon,

    I'm going to try and work with the flash erase/write routines directly for the firmware update. I do remember seeing an API to call within I think mcuboot which can be used to set the newly downloaded image as valid and switch the active image slot. Do you know where this is described or an example of its usage?

    Thanks,

    Pam

  • Are you referring to boot_write_img_confirmed()? This is present inside a file named mcuboot.h, but it is located inside the zephyr repository, not mcuboot. This will not perform any validation checks or do any swapping, but just mark it as "confirmed". It should be run from the application.

    You don't need to care about the validation or swapping of the image. This will happen automatically in mcuboot when it's booted:

    Best regards,

    Simon

Related