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

Reset Bootloader for SDKv11.0.0 using DFU /HCI over UART

We are using another microcontroller to update the application firmware in an nRF51822 over the UART using the DFU HCI protocol from SDKv11.0.0.

The nRF51822 uses the HCI/UART bootloader from the example in SDKv11.0.0.  We have implemented the DFU HCI protocol as described in SDKv11.0.0, which sends a Start packet, then Init packet followed by data packets and finally a stop packet.  This works Ok when everything is correct.

Our problem is that if the application image is invalid  (ie: the application image CRC is invalid, or the image download isn't complete), then after receiving the DFU STOP  packet the nRF51822 remains in boot-loader mode as it should but we can't do another DFU.  When the DFU is restarted then the nRF51822 boot-loader fails to send ACK packets.   It doesn't always fail at the same point.  Sometimes it stops after the START packet and other times it goes until several DATA packets have been sent.

If the nRF51822 is reset, by either power off/on or via JLink (nrfgprog --reset), the the boot-loader starts again and can repeat the DFU Ok.

We don't have any means of doing a hardware reset of the nRF51822.  So once this situation occurs we are stuck.

Is there a software command to reset the boot-loader?

  • Hi, 

    If you have enabled the SoftDevice you can use sd_nvic_SystemReset, if not you can use nvic_systemreset(). 

    -Amanda H.

  • That does a software reset from within the nRF51822.  What I meant is software reset via DFU command so that the other microcontroller can reset the nRF51822 when it is boot-loader mode. Or at least a DFU command that restarts the boot-loader.

    So far I can only see there are 4 DFU command to control the bootloader: Start Packet, Init Packet, Data Packet and Stop packet.  I assumed that sending a Start packet DFU command would reset the boot-loader. However, that is not what we observe.

    If the DFU fails to complete, so the boot-loader doesn't run the application after the DFU Stop packet is sent, then the nRF51 remains in bootloader mode.  When another DFU is started, the bootloader fails and stops sending ACK packets after a couple of DFU command packets.  The only recovery mechanism so far is to reset the nRF51.  After a reset (power on or by JLink) the nRF51 restarts in boot-loader mode, because the application is invalid, and will correctly perform a DFU.

    Our problem is that we have no way of doing a hardware reset of the nRF51 from the other microocontroller.  We only have the UART connection and nRF51 GPIO pin P0.19 and P0.17.

    Is there a known reason why a DFU cannot be repeated while the nRF51 is in boot-loader mode?

  • This is the documentation from nRF5 SDKv11.0.0 for the serial DFU we are using:
    It only describes four DFU commands for controlling the boot-loader
  • The problem seems to be with SEQ and ACK numbers in the HCI header of the DFU packet.

    The DFU protocol packets have a 4-byte HCI header.  The first byte has two 3-bit fields; SEQ and ACK.  Our software was starting with SEQ=1, ACK=2 when the DFU Start packet is sent and incrementing these on every DFU packet sent to the nRF51.  

    By trial and error I found that DFU still works ok of these fields and not incremented, and can repeat a DFU if the application is invalid and the boot-loader keep running.

    Also it requires the SEQ=1, ACK=2.  Other values cause a DFU to fail.

    The reference for the HCI header is in the "Bluetooth Core Specification v5.00, Vol 4 Part D Three Wire UART Transport Layer". 

    The specification shows SEQ being incremented (mod 7) for each sent packet. Also there is a non-zero SEQ value in the response.  The nRF51 boot-loader response packets always have SEQ=0.

    It appears that the nRF51 bootloader doesn't follow the BLE specification for the HCI header.

    We only require to receive response packets so that we know when to send the next DFU command. We don't intend to implement packet re-transmissions so this will work for us.

  • Actually that didn't work.  Not incrementing SEQ and ACK resulted in our DFU command sequence running through to the end and being able to repeat DFU, but the boot-loader didn't actually flash any data into the application flash memory.

    So it is essential that SEQ increments.  And I think the problem is what the SEQ and ACK values are in the start packet when the DFU is repeated.  My guess is that the transport layer doesn't care that the DFU ended and the boot-loader didn't jump to the application.

    Is there any further information on how SEQ and ACK works with reliable packets in the HCI DFU?

Related