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.

  • 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.

  • I have 2 versions of my fw. The only difference is this internal version I have. One I have hard coded version 110 and the other is hard coded version 111.

    If I use the Nordic app to flash 110 in and then use my characteristic to get the version using my app I get 110. If I then flash in 111 using Nordic it changes to 111.

    If I use my own app to do it then the version doesn't change even though I don't get any errors.

Reply
  • I have 2 versions of my fw. The only difference is this internal version I have. One I have hard coded version 110 and the other is hard coded version 111.

    If I use the Nordic app to flash 110 in and then use my characteristic to get the version using my app I get 110. If I then flash in 111 using Nordic it changes to 111.

    If I use my own app to do it then the version doesn't change even though I don't get any errors.

Children
  • Here is the last bit of interaction between my app and the device:

    04-06 09:01:55.880 16705-16726/? I/UnityBluetoothLE: Checksumming from 0 for 37852 bytes
    04-06 09:01:55.881 16705-16726/? I/UnityBluetoothLE: Data object sent (CRC = B9E9FA25).
    04-06 09:01:55.882 16705-16726/? I/UnityBluetoothLE: Sending Calculate Checksum command (Op Code = 3)
    04-06 09:01:55.929 16705-16726/? I/UnityBluetoothLE: control bytes received: 60-03-01-DC-93-00-00-25-FA-E9-B9
    04-06 09:01:55.929 16705-16726/? I/UnityBluetoothLE: Checksum received (Offset = 37852, CRC = B9E9FA25)
    04-06 09:01:55.929 16705-16726/? I/UnityBluetoothLE: Executing firmware packet (Op Code = 4)
    04-06 09:01:56.285 16705-16726/? I/UnityBluetoothLE: control bytes received: 60-04-01
    04-06 09:01:56.285 16705-16726/? I/UnityBluetoothLE: Bytes remaining in firmware: 0
    04-06 09:01:56.287 16705-16726/? I/UnityBluetoothLE: Firmware Sent
    04-06 09:01:56.560 16705-16758/? I/UnityBluetoothLE: onConnectionStateChange
    04-06 09:01:57.573 16705-16726/? I/UnityBluetoothLE: Scanning for MYDEVICE
    04-06 09:01:57.574 16705-16726/? I/UnityBluetoothLE: Using api21scan
    04-06 09:01:57.574 16705-16726/? I/UnityBluetoothLE: Scan mode: 1
    04-06 09:01:58.093 16705-16726/? I/UnityBluetoothLE: Found MYDEVICE

    As you can see the final checksum matches what I calculated. You can also see that I send the Op Code 4 and get back 60-04-01 which indicates success.

    The next thing that happens is the device disconnects as you can see from my debug message of onConnectionStateChange. I then start scanning and find my normal device name instead of MYDEVICE DFU like I see when in DFU bootloader mode.

    I am not sure where to go from here. Does anyone have any suggestions?

  • The only reason why this could happen is that you flash 111 on 111 and expect 110, or flash 110 on 110 and expect 111. Perhaps can help from the fw side, but from mobile side receiving success at the end with correct CRC should mean the DFU worked.

  • Not sure what to say. I know I have 2 different versions and verify that because the final checksum is different between the 2. When I flash the same files using your mobile app it works. I thought maybe there was some step I was missing maybe, but couldn't find anything else to do by reviewing the Android source code.

    What all gets compared and verified by the DFU system? If the checksum matches, what else might be not matching? Is there some other step I have to take?

    Currently I upload the Init file and that checksum matches then I execute it and get a good response.

    Then I upload the bin file and that checksum matches and execute each block and get no errors and on the last one the device reboots all on its own.

    Is there maybe another step I missed that I should have seen by looking at the source code?

Related