Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

SDK v15 DFU Bootloader hangs on execute instruction

Hi, I'm migraing our project to the latest NRF5 SDK v15.0.0 (S132  v6.0.0). We were previously on v12.2.0  (S132 v3.0.0) using the BLE DFU Bootloader. I've  modified our bootloader code to match the example from the latest SDK. It compiles and runs on our board. We're using our own utility which implements the DFU procedure to upload the firmware to our device.

The utility is able to connect, switch the device to the bootloader and transfer the init packet. The problem arises when the first object has been transferred and  we issue an execute command. The device locks up and doesn't respond to any command (including the execute). If I break with gdb the cpu is always somewhere around address `0x0007c1ea`. It is a branch instruction to the same address... an infinite loop.

I tried the nRF Toolbox for Android, but it wasn't even able to switch to the bootloader. I assume it hasn't been updated to use the new 16-bit Buttonless Servicee UUID.


Is there any obvious reason  this could be happening?

Parents Reply
  • Hmm, looking at nrf_bootloader_dfu_timers.c I'm suspecting the infinite loop is occurring due to a failed `ASSERT` on a return code from the timer module in this function:

    static void timer_start(app_timer_t * p_timer, uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback)
    {
        ret_code_t err_code;
    
        timer_init();
    
        err_code = app_timer_stop(p_timer);
        ASSERT(err_code == NRF_SUCCESS);
    
        if (timeout_ms != 0)
        {
            //lint -save -e611 "Suspicious cast"
            err_code = app_timer_start(p_timer, APP_TIMER_TICKS(timeout_ms), (void *)callback);
            //lint -restore
            ASSERT(err_code == NRF_SUCCESS);
        }
    }

    I had to disable link time optimization to have the necessary debug symbols available in gdb for debugging. However, without the -flto flag the bootloader doesn't crash... So I'm at a loss on how I can debug this.

Children
  • Are you saying that everything works fine if you remove the -flto flag? This devzone case gives you a bit more information. If everything does work without this flag, could you not just remove the flag. It seems there is not too much performance difference from what I understand.

  • Yes, removing the -flto allows the bootloader to behave normally. I'm curious as to why this is happening. Of course I could remove the flag, but then I have to increase the size of the bootloader code (around 8kB seems to do the trick). It's not the end of the world, but a smaller bootloader is preferrable.

  • Not exactly sure why this is the case. This blog post says the following: 

    "NOTE: The safe thing to do is to assume that the flags that aren't included in the default Makefiles are just as interesting as the ones that are. For example, the Link Time Optimization (-flto) flag was dropped starting with SDK v9 when GCC was upgraded to v4.9. The rationale for this change isn't obvious but as far as I know it was intentional (and -flto hasn't been reintroduced)."

    This case might also be helpful. It seems that none of our examples are compiled with Link Time Optimization & therefore not tested either. Those are my best two guesses as to why this is the case. Hope that helps a bit!

  • Hi Bjorn, sorry to wake this old thread.

    However, I'm facing a related issue now. My current devices, which have been programmed with the secure bootloader from SDK v12.2.0, can't be updated with the new bootloader via OTA DFU, since the new bootloader size is different from the old (0x8000 vs 0x6000).

    After looking at the Makefile for the BLE Secure Bootloader, I can see that -flto is present in the CFLAGS, and the size is set to 0x6000 in the linker file. So I'm quite puzzled why the bootloader is misbehaving in my case.

    I'm thinking about trying a newer version of GCC and see if the bootloader works with link time optimization. Otherwise I need to open all my current devices and re-flash the firmware via SWD, which is really not an option.

  • Hi Bjorn, you can disregard my previous answer.

    There were some files that the secure bootloader example was compiling and I wasn't. Everything seems to be in order now.

Related