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

Detailed DFU Application Interface Documentation

I need to implement DFU in a Unity3D application. I have tried to integrate the Android SDK library that you have on github. They are not integrating very well.

I have a lot of BLE experience and if I understand exactly the steps to implement sending a ZIP file payload over the DFU service and characteristics then I could probably do it without your library. This would also be good because I need this to work on iOS as well and being able to do it myself in C# code would be great because then I don't have to do native code for each.

The problem is that the documentation all assumes you are using the library you have provided.

Is there anything special that the library does? Does it actually break open the ZIP file and send the different parts over or does it just open a connection and send the ZIP file and have the firmware on the Nordic part do the work? If the previous then I would like to know the simple commands to implement that.

Parents
  • A detailed description of the DFU protocol can be found in the bootloader section of the infocenter.

    Here is a very coarse overview:

    The app opens the zip file and sends the meta information first (which the bootloader can choose to say "nope" to), then the binary firmware data in chunks, checked via CRC32. Once the last checksum is OK, the command to "execute" the update is sent.

  • I have been reading through the bootloader section in infocenter and am still not clear on exactly what to do.

    Maybe I am looking in the wrong place. Just to be clear I am working on SDK 15.3.

    Most of the information I am finding looks to be from the device side and not the mobile app.

    Can you give me some specific pointers? It would be nice to have a detailed description of 1. send these bytes, 2. expect this response or 2, 3. Now send these bytes, etc.

  • The buttonless service is used to reboot your device into DFU bootloader mode. In that mode you device will only have DFU service and DFU Control Point and DFU Packet characteristics inside (except from Generic Attribute and Generic Access, of course).

    How to use this service is explained here: Buttonless Secure DFU Service

    For non-bonded devices, the bootloader will advertise with a different MAC address (+1). The phone needs to scan for it to connect to it. Our libraries take care of it automatically, but you need to make sure you connect to the proper device. Remember, that on iOS you don't have MAC address, so you can't compare it with the previous one. iOS DFU Library is using peripheralSelector, and the selection (starting from DFU from SDK 14) is using "Set advertisement name" feature (see the first link, command 0x02).

    After you jumped to bootloader mode successfully, you need to check in what state your device is. You do this by setting the object to COMMAND. You will get the offset and CRC32 of the object. For fresh update both will be 0. If an update has started and may be resumed, they'll contain the proper values for you to compare (if cry doesn't match, or you don't want to resume, you always may start again by creating new COMMAND object). Then you need to follow the BLE Transport: Device Firmware Update process.

    Regarding your question about the ZIP file. ZIP file contains 3 or 5 files. One is always the manifest.json, which specifies the names of 2 or 4 other files. In one ZIP file there may be an update for App only, or SoftDevice+Bootloader and App. Or any of them alone. The dat file is generated using nrfutil tool. The same tool may be used to read the content for the zip file, including decoding the dat files. The dat files are using Protobuf to encode the firmware size, type, hw type, required soft device(s), signature, crc, etc. They are to be sent prior to the firmware for validation. Bootloader may reject the firmware based on the init packet.

    I would recommend first trying the bootloader using nRF Connect for Android or iOS. Check if your ZIP file is working. Then examine the log. All packets are logged there in a semi-human-readable way. This should give you more momentum. Good luck.

    When you're done, and you'd like to contribute you project, we can always link to your implementation, just like we already have react-native and Flutter wrappers.

    BR, Aleksander

  • Thank you for the detailed response.

    I have been able to implement DFU in my code with some success, but not final success. I am doing this by trying to follow the Android code and a lot of trial and error.

    First I have to thank whoever wrote the DFU firmware. It is awesome that when I mess up the process the device just times out after a little bit and returns to normal operation. THANK YOU!!!

    I have 2 .zip files with different versions of my firmware that I can verify the version when it is in normal operation.

    I am able to use the iOS DFU app from Nordic to update my device with both of these files and verify that the version is changing when I check it.

    When I do the same thing using my own app, everything seems to work because I don't get any errors and the CRC values all match at every step.

    I do the dat file with no errors. I then do the bin file with no errors. I execute each object at the end with no errors. The offsets are all what I expect.

    When I send the last execute command on the last packet the device response correctly and then automatically reboots all by itself as expected.

    The device then enters normal operation, but when I check the version it is not the one I think I just sent. I have tried both versions of my .zip and the reported version during normal operation never changes.

    What could be going wrong and how do I figure that out?

  • If you get a success from the last execute, when the offset is equal to the fw size, and the device reboots, it should swap banks. You may verify that they were swapped by downloading the fw using nRF Connect for PC and comparing hex files. If they were swapped, try resetting Bluetooth in iPhone. Maybe it's cache? Do you read values to verify, or check services?

  • The other option I can see is that you flash incorrect versions of fw. On version A you flash A again, and on B - B. When doing dfu in our app you flash the right versions.

  • As far as I can tell I am not getting any errors. The last execute is for the full size of the fw and the checksum matches on the last packet.

    I have my own characteristic that I can ask for the internal version of my firmware that I am setting. I am checking this value. It will report an embedded version number that I hard code into the fw. It is not changing.

    When I use the Nordic DFU app to update my device this internal version does change. I am using the same zip file in both cases. That tells me that it has to be something I am doing, but I can't figure out what I am doing wrong or how to figure this out.

    Any more ideas would be greatly appreciated.

Reply
  • As far as I can tell I am not getting any errors. The last execute is for the full size of the fw and the checksum matches on the last packet.

    I have my own characteristic that I can ask for the internal version of my firmware that I am setting. I am checking this value. It will report an embedded version number that I hard code into the fw. It is not changing.

    When I use the Nordic DFU app to update my device this internal version does change. I am using the same zip file in both cases. That tells me that it has to be something I am doing, but I can't figure out what I am doing wrong or how to figure this out.

    Any more ideas would be greatly appreciated.

Children
  • Hi Tony,

    Sorry for the late reply. My advise is to test using the debug version of the bootloader, that way you will get the log output from the BL and that may help you find where it goes wrong.

    Run first a DFU with the nRF Connect appen, and then with your own app and compare the logs to see if there is any differences.

    And as it was said before, getting sucess in the last execute response should mean that the app will swap bank 1 with 0 and the DFU should have worked..

    BR,

    Marjeris

  • I appreciate you getting back to me.

    I was able to get it working. Turns out it was my firmware version I was switching between didn't communicate correctly with my other hardware to give the right responses. Once I got that figured out everything works good.

    Thank you for the help.

Related