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

  • Hi Simon,

    Those "other DFU examples" are related to using external flash, I'm trying to write to the internal flash directly with the new application image.

    What is the point of defining the flash partitions in the board.dts file if they are ignored by the partition manager? I'm assuming I can't just not use the partition manager? This design approach seems to be so over-complicated for what I am trying to do.

    Sorry to complain, but I've been doing this work for well over 30 years and I find that this whole Zephyr approach is not very user friendly and is very time consuming.

    Thanks for your help and regards,

    Pam

  • Pamela Keiles said:
    Those "other DFU examples" are related to using external flash, I'm trying to write to the internal flash directly with the new application image.

    Yes, I was just trying to point you to an example that shows how the pm_static.yml file might be used. Sorry for the confusion.

    Pamela Keiles said:
    What is the point of defining the flash partitions in the board.dts file if they are ignored by the partition manager?

    The reason it is set in the dts file is because that's how was done in Zephyr upstream (NCS contains a downstream version of Zephyr). Also if you don't have a multi image build, the DTS files will be used. Nordic created the Partition Manager to handle multi image builds, because DTS must be set before Kconfig (when building the project, it will first go through the DTS file and set the memory layout, then it will look at all the configurations (Kconfig, prj.conf and so on)). If DTS would be used, we would need to have an own dts file for all possible configurations.

    Be aware that Kconfig and the devicetree in Zephyr is inherited from Linux (see the Zephyr Wikipedia page), which was written for computers with more memory and resources. Zephyr is open source and work in progress.

    Hopefully we will soon get the same solution in NCS as Zephyr upstream now uses, the system device tree.

    Pamela Keiles said:
    I'm assuming I can't just not use the partition manager?

    That is correct. You need to use the Partition Manager for now

    Pamela Keiles said:
    This design approach seems to be so over-complicated for what I am trying to do.

    Actually, your project is quite simple. You don't need to add any pm_static.yml file or do anything. Just build your project with CONFIG_BOOTLOADER_MCUBOOT=y in the prj.conf, and then check the generated file <sample>/build/partitions.yml or (<sample>\build\zephyr\include\generated\pm_config.h). Look for two things, the start address of secondary slot(mcuboot_secondary) and the size of secondary slot

    Now you just need to write your new uploaded image to that location. I also think you can just use the generated macros from pm_config.h to get the size and address of the secondary slot. 

    Please get back to me if you encounter any issues with this.

    Pamela Keiles said:
    Sorry to complain, but I've been doing this work for well over 30 years and I find that this whole Zephyr approach is not very user friendly and is very time consuming.

    I understand your frustration. Zephyr is quite different from other approaches. It is more abstract and moves you further away from the bare metal drivers, and it is a lot of new stuff to learn if you're new to this. 

    This texts may be an instersting read: https://www.zephyrproject.org/leveraging-open-source-software-in-your-software-development-kit-nordic-semiconductors-experience-with-the-zephyr-rtos/

    Best regards,

    Simon

  • Hi Simon,

    Thank you so much for the detailed response. I was also working with our local application engineer on investigating an approach to use the serial DFU update within mcuboot directly. The downside of this approach is having to support with one of the mcumgr protocols on the main processor downloading the image (newtmgr or smp possibly). I think that might require more development time than the approach we have already been discussing here.

    What I was struggling with was creating a partition manager yml file from scratch to ensure static addresses. But now I see I can copy the build generated yml file as a starting point and adjust it if needed. I don't like the dynamic approach because if something changes in the future with the bootloader itself (programmed during manufacturing), then I have to worry about any possible addressing changes. I believe it's safer to use a static file and ensure the flash sections remain fixed.

    I'll work with what we've already outlined and use my own very simple protocol or even xmodem to do the UART transfer from the main processor and flash programming.

    The only part that still seems wrong to me is that whatever is specified in the flash data structure within the device tree file is meaningless. However it is still required to do the build (I tried removing it as a test). I suppose though as you say this is still a work in progress.

    Thanks again, hopefully I have enough now to get this design piece working quickly.

    Best regards,

    Pam

  • Pamela Keiles said:
    I was also working with our local application engineer on investigating an approach to use the serial DFU update within mcuboot directly. The downside of this approach is having to support with one of the mcumgr protocols on the main processor downloading the image (newtmgr or smp possibly).

    Actually, you can modify mcuboot serial recovery (perform DFU update within mcuboot directly) to not use the mcumgr protocol, like I explained earlier. Be aware that if you perform DFU through the MCUboot, you put the image directly into the primary slot (not in the secondary slot like you do when performing the DFU through the application), and swapping won't happen. This is because mcuboot acts as the fallback recovery if the update fails.

    Simon said:
    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.

    Pamela Keiles said:
    Thanks again, hopefully I have enough now to get this design piece working quickly.

    Good luck with the implementation!

    Best regards,

    Simon

  • I just created an nRF Connect SDK solution that support DFU from chip to chip, check it out here: https://github.com/simon-iversen/ncs_samples/tree/master/central_smp_client_dfu 

    Best regards,

    Simon

Related