Zephyr buttonless DFU over uart when my application uses uart async for comms

Using 54L15 DK for testing. Zephyr toolchain & SDK both v3.02. I have been through the DevAcadamy exercise which uses Blinky for its example, now I want to integrate into my own application.

My application uses the uart async adapter for both a CLI and data output. (Note the CLI is legacy code based around the uart callback, not using Zephyr's own CLI. The output is all done by printk).

How does the MCUMGR interact with the application's uart handling?

Secondly can you confirm that it's OK to enable both uart and BLE transports for DFU concurrently?

Thanks

Parents
  • Hello,

    Sorry for the late reply. 

    You say "buttonless dfu over UART", do you mean serial recovery, or DFU from the application?

    How does the MCUMGR interact with the application's uart handling?

    The bootloader itself (MCUBOOT) is not active when the application is running, so if you are talking about DFU over UART, then this will be running from the application. 

    Did you try DFU over UART in DevAcademy?

    The easiest would be to keep the device in some DFU state, that can pipe all the UART into the DFU handling when it is in this state. It is not trivial to keep this shell functionality running while doing a DFU.

    Best regards,

    Edvin

  • Hi

    Excuse me if I get some terminology wrong, I mean DFU from application. Yes I have done DevAcadamy nRF Connect SDK Intermediate lesson 9 Exercise 1 "DFU over UART". I'm referring to section 5 "Add DFU over UART to the application." here.

    Because it's a tutorial it's a little bit light on detail but it seems that Zephyr has a hook in to the uart backend to look for an escape character? All the tutorial basically says is "do ABC and it will work"

    (Previously using old SDK I would use nrf_power_gpregret_set() and reboot. Our companion app has a special command to enable DFU)

    So, how would you pipe uart data into DFU which I assume is buried in Zephyr's internals?

    I may have to re-write my code to use shell rather than manually handling uart data, but either way I'd like to understand the mechanism and options I have. As mentioned in my original post I would like DFU to be enabled for both BLE and uart if possible.

    Regards

    EDIT: It looks like I can't use Zephyr's shell after all. I thought it would co-exist with mcumgr but it does not, so I need to find a way of invoking a uart-based DFU whilst otherwise allowing my app to use the uart.

  • Hello,

    Sorry for the late reply.

    I believe that if you intend to put the device in "DFU mode", I would recommend that you look into serial recovery, where the bootloader will handle the UART directly. This also allows you to have a larger application, because you don't need to have room for the old application at the same time as the new is being transferred.

    If you want the application to handle the UART transport, instead of the bootloader (so in other words, if you don't want to use "Serial Recovery", then I believe the handler you are looking for is the "int dfu_target_write()". I am not sure it is trivial to adopt this handler to handle both custom data and at the same time handle DFU over UART data. 

    Best regards,

    Edvin

  • OK, but from the DevAcadamy tutorial:

    3.1 To enable Serial Recovery, we must set CONFIG_MCUBOOT_SERIAL and to enable transport over UART, we must set BOOT_SERIAL_UART. Since these are both for the MCUboot child image, we must set them in mcuboot.conf.

    Won't setting this block my application from using the UART for normal operations? This is the crux of my requirement: I need the same UART for normal operations and for DFU. Remotely, so no buttons or whatever, I start the process by code.

    The "old" SDK bootloader worked perfectly. I could reboot into DFU, then either upgrade or let it time out and boot normally.

    Edit: I found this on zephyrproject.org. Is this the only way to achieve it? I really don't want to be patching SDK files if I can help it.

  • No. The bootloader and application doesn't run at the same point in time. This means that when the bootloader is done, before starting the application, it willl call nrf_cleanup_peripheral() (from v3.2.1\bootloader\mcuboot\boot\zephyr\nrf_cleanup.c), which will disable and clean up the UART before starting the application, meaning that you can use the UART as you want to in your application. Just make sure that CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL=y is set. (This is set by default, unless it is specifically set to "n" in your application).

    If you set

    CONFIG_BOOT_SERIAL_WAIT_FOR_DFU=y
    and
    CONFIG_BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT=1000

    Then it will wait for 1000ms after booting up in DFU mode, to see if it receives any DFU commands from mcumgr. If not, it will start the application. You can of course set the CONFIG_BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT higher than 1000ms.

    Best regards,

    Edvin

Reply
  • No. The bootloader and application doesn't run at the same point in time. This means that when the bootloader is done, before starting the application, it willl call nrf_cleanup_peripheral() (from v3.2.1\bootloader\mcuboot\boot\zephyr\nrf_cleanup.c), which will disable and clean up the UART before starting the application, meaning that you can use the UART as you want to in your application. Just make sure that CONFIG_MCUBOOT_NRF_CLEANUP_PERIPHERAL=y is set. (This is set by default, unless it is specifically set to "n" in your application).

    If you set

    CONFIG_BOOT_SERIAL_WAIT_FOR_DFU=y
    and
    CONFIG_BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT=1000

    Then it will wait for 1000ms after booting up in DFU mode, to see if it receives any DFU commands from mcumgr. If not, it will start the application. You can of course set the CONFIG_BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT higher than 1000ms.

    Best regards,

    Edvin

Children
  • OK that works thank you. For some reason booting into the app takes a few seconds longer than the timeout but that's pretty trivial. I'll need a sizeable timeout to allow the user to run Auterm and connect which means a incurring a delay on boot up but that'll have to be a "feature" Slight smile It's a shame you can't use GPREGRET, maybe request it as a patch?

    I still need to address part B of my original query - mixing serial recovery & FOTA - but I'll split that into a separate ticket

    Regards,

    Nick

Related