This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Secure Serial DFU SDK13 – DFU post validate complete indication

Greetings,

I have an application where the DFU of a NRF52 is performed by another microcontroller via a serial port. Once the DFU is complete, the microcontroller turns off the entire system (including the NRF52). The issue I am encountering is associated with the steps performed by the bootloader after the complete application binary has been received.

I’ve noticed that the “nrf_dfu_postvalidate” step can take up to 10s. In the past I’ve waited until I have received a ping response back from the bootloader. This gave me some success. I have also tried a simple blocking delay of 15s after the DFU, but I do not like this approach. If the main microcontroller turns off the NRF52 before the DFU post-validate step is complete, the next time the NRF52 starts it stays in the bootloader mode. This means I have to perform the DFU process twice each time I wish to upgrade the NRF52 firmware.

Is there a way with the existing implemented SLIP OP codes to get confirmation from the bootloader that the new application has been validated and set to run next time it boots?

Note: I’m using SDK13 and the secure serial bootloader with slight modifications (UART without flow control, different pin mappings, WDT reset during DFU… etc). The application image I am updating is also large (120kB).

  • Hi,

    If you have a look here:

    image description

    The Response Execute Success will be sent after the nrf_dfu_postvalidate() step to check if the image's hash matches with the hash in the init packet but not after the bootloader setting is written to flash. So if you turn the power down right after that response, the bootloader setting won't be stored in flash.

    But I don't think it would take 10 seconds for the bootloader setting to be written. If you do dual bank update, the 10 seconds could be the time it takes to erase bank 1 and copy bank 0 over.

    Our suggestion is to send an extra UART response right before reset, inside on_dfu_complete(), but you need to put some delay (100ms for example) for the UART command to be send, before doing reset.

    Another option is to send a UART packet when the new app is checked in nrf_dfu_app_is_valid(). But this mean you will print something on UART every time the nRF52 starts.

    Regarding the response, you can re-send Response Execute Success and configure the DFU master to wait for 2 responses before power down. Or you can define a new opcode in side serial_dfu_op_code_t in nrf_serial_dfu.h

  • Hung,

    Although I have yet to read all of the information you've provided me, I thought it would be useful to attach a log of the bootloader debug messages. Here's the log file.

    As you can see, the time between the bootloader's the last response (142935) and when the new app is finally run (151240) is 8.3 seconds. This is typical from my experiments, but have encountered a case where it took 24.4 seconds! Unfortunately I wasn't logging the RTT statements during this test.

    My setup is a PCA10040 running SDK 13.0 + S332 v4.0.2. I have another microcontroller doing the DFU via a serial port (without hardware flow control). I have since added my own packet in the app. I was surprised that there wasn't an existing mechanism in the bootloader to indicate when the DFU update had been complete (including all post-DFU steps).

  • Hi RCT,

    As I mentioned, the mechanism is we verify everything is fine, and send a request to store the setting into flash. And then we send the Response Execute Success back. Meaning Response Execute Success is sent AFTER nrf_dfu_postvalidate() finished.

    From your log it clearly showed that postvalidate didn't take much time :

    [142640] :INFO:Doing postvalidate [142921] :INFO:Current bank is bank 1 [142921] :INFO:Running SD version check ============== [142921] :INFO:Successfully ran the postvalidation check!

    What took time was the repeated writing and erasing flash to swap the old image with the new one after reset. For large application, this process can take quite a lot of time, keep in mind that erasing one page can take up to 89ms as in the spec.

    My understanding is that we send the last response right after postvalidate but not after all the DFU process is finished because we don't want the DFU master to wait (for seconds) when the its task is already finished after sending the correct image.

    My suggestion is either to put a response sending inside nrf_dfu_app_is_valid() in the bootloader, or at the beginning of your application.

  • I presume it isn't a good idea to have the bootloader responding to ping requests while it is erasing the flash pages?

    Meanwhile I have added a ping response to my app which has solved my problem.

    Also poor use of wording on my behalf. When I wrote postvalidate I was thinking of all the processes (postvalidate, erasing flash...) the bootloader does after the host has finished sending the image to the bootloader.

  • You are correct, the CPU is freezing when flash operation is executing. So if there isn't enough buffer in UART peripheral, the ping command will be corrupted.

    In normal use case, the DFU master shouldn't worry about the DFU slave anymore after the the post validation return success. The DFU slave supposed to be able to swap the (validated) image and start new application normally.

    But I agree that it would be the best if we have a response after we replace the old image and verify the new image is valid. Or as you already have done, add a ping response in your app.

Related