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

nRF5 DFU over serial

We are implementing a DFU controller to perform DFU over serial for the nRF52832.

Our reference is the nRF5 SDK v15.3.0 DFU Serial documentation (Nordic/SDK/nRF_SDK_15.3.0_docs/nrf5/lib_dfu_transport_serial.html).

The documentation has a message sequence chart that describes Transfer of an Init Packet, and Transfer of a firmware Image.

I'm find the description regarding transfer of a firmware image a bit ambiguous. It says the firmware image is split up into several data objects that are transferred consecutively.  For example if the image is 10k and the maximum object size is 4k, then 3 data objects must be transferred.   Presumably two 4k objects followed by a 2k object.

1) Is the Select command required at the start of each data object, or just once when the firmware image transfer is started?

2) Is the execute command sent at the end of each data object, or just once at the end of the entire firmware image transfer?

2) Once all the data has been transferred (3 data objects in the example) is it necessary to do one more Select command immediately followed by an execute command?

3) At what point does the boot-loader know the entire image has been downloaded and start the application.  Does it attempt to do this on every execute command?

In our case we have found the Select response returns a maximum object size of 4096 bytes.  Our firmware image is not a multiple of 4096 bytes, so I my difficulty is understanding what happens when the last data object, which is less than the maximum object size,  is transferred.

Parents
  • Hi Phil, 

    I actually made an example of DFU controller running on nRF52 that you can have a look: https://devzone.nordicsemi.com/nordic/short-range-guides/b/software-development-kit/posts/getting-started-with-nordics-secure-dfu-bootloader#h108sjziaxo3m81rkgr1has5r1d72qtu

    I would suggest to test the example and review the code. If you still have any question, please let me know. 

  • I've narrowed my problem down to a specific issue.  I cannot send a Create data object command with size other than 0x1000 (4096).  This size is the max_size returned by the SELECT data object request.

    Create data object: size = 512:    [01 02 00 02 00 00].  Response [60 01 03]: status = missing or invalid parameter

    Create data object: size = 4096:  [01 02 00 10 00 00].  Response [60 01 01]:  status = success

    I notice in your example code that you send a Create data object command at the start of each data object transfer.  Each one, except the last, has size=4096. The size of the last one is the length of the remaining bytes of the firmware image.  This is exactly what we intend to do.  I also notice you are never checking the response to the Create data object command (or any commands).  Does this actually work?

    Does the number of bytes transferred for each data object have to equal the size in the Create data object command?  Could we just always create a data object of max_size and just send fewer bytes where necessary before sending the EXECUTE command?

  • Hi Phil, 

    The firmware I made was quite a long time ago so I don't remember all the detail. 

    But the way it works in our bootloader is that you only set the data object size once, for all packets. And the last packet is the only exception. You don't need to set the data object size for the last packet. The bootloader detect that automatically because the size of the image is sent at the beginning already. 

    If you have a look at the on_data_obj_create_request() function in nrf_dfu_req_handler.c you can find an error log "NRF_LOG_ERROR("Object size must be page aligned");" Data object size need to be page aligned, so either 4096 or 8192 and so on. 

  • Yes, thanks.  I had found that after looking through the boot-loader.  Your code sets the data object length of the last object to the length of the remaining firmware image bytes.  It also looks like the code in the boot-loader requires the last data object length to be equal to the length of the remaining bytes. I might be wrong here.  However, the issue is that I was requesting a data object size less than 4096 bytes that was not the last data object.  The SDK15.3.0 DFU documentation is not clear on this.

    My problem is that the firmware size is in the init packet, which sent to the boot-loader successfully.  However, I was down-loading a test image while developing my DFU protocol code.  This is writing a generated test pattern into the nRF52 ROM and the total length was much less than the firmware image length.

    By the way, we are implementing the DFU controller as a state machine.  We process the response to every command sent to the boot-loader. We set the PRN to 1 at the start to get a response to every write data packet.  That way the DFU is self-timing and the offset returned in the response to write commands keeps track of the progress. Also there is no need to request a CRC just before the execute command as this is returned in the write data response.

    Thanks for your help.  Much appreciated.

  • I'm glad that you figured out most of the stuff. Let me know if you still have any issue transferring the image. 

Reply Children
No Data
Related