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

Issues with Buttonless DFU added to existing project

Hello:

We have a BLE project running on the BMD-300 from Rigado for which we want to add BLE DFU functionality. I am basing our development on the "ble_app_buttonless_dfu" project as well as the "secure_dfu_ble" for the bootloader. We are using NRF SDK 14.0.0 and IAR for our development. I have followed the great tutorial at "https://devzone.nordicsemi.com/b/blog/posts/getting-started-with-nordics-secure-dfu-bootloader" to generate the bootloader, bootloader options for application, merge bootloader+bootloader options, generate application,and load them up (also SD) with NRF GO. I set up the RTT logger on the main application.

I erase the chip, then I program the SD, then the bootloader, and then the application, and reset power. The unit always seems to be stuck in PC 0x13d6e of SoftDevice. Since it is a Hex I have no idea what it is doing there! I always have to attach to the running target and hit reset for the device to start performing properly. 

I was having issues with the bootloader not setting the vector table correctly to the app, so when I initialized my other HW the interrupts were getting sent to the bootloader!

To remedy this, I added a call to "nrf_dfu_svci_vector_table_unset()" at the start of the program.

However, now I am getting an NRF_ERROR_INVALID_STATE error on "sd_softdevice_enable()" when I initialize the stack (on ble_stack_init() ).

How is the correct way to add the Buttonless DFU functionality to the device? Is there an order of function that I should follow? should the DFU initialization happen before the HW initialization so the code sets up the correct vector table?

If you could provide any guidance I would be very grateful! I have spend too much time on this.

Thanks!

Parents
  • Hello, 

    The bootloader disables the softdevice before branching to the main application, so it should not return invalid state when you try to re-enable it from the app. Have you made any changes to the default bootloader code that may have changed this behavior?  Also, do you have a LF crystal in your design, or are you using the internal RC oscillator? 

    *EDIT*:

    Related to nrf_sdh_enable_request() returning invalid state: are you doing any fstorage operations prior to ble_stack_init()? Looks like the fstorage softdevice backend may enable the softdevice through nrf_sdh_request_continue();

Reply
  • Hello, 

    The bootloader disables the softdevice before branching to the main application, so it should not return invalid state when you try to re-enable it from the app. Have you made any changes to the default bootloader code that may have changed this behavior?  Also, do you have a LF crystal in your design, or are you using the internal RC oscillator? 

    *EDIT*:

    Related to nrf_sdh_enable_request() returning invalid state: are you doing any fstorage operations prior to ble_stack_init()? Looks like the fstorage softdevice backend may enable the softdevice through nrf_sdh_request_continue();

Children
  • Thank you for your response!

    I have not made any changes to the code of the BLE DFU (Other than WDT calls to feed the WDT on the bootloader!). As you can see with the code above the main application only does NRF_LOG and RTT - related code before calling BLE_init() which in turn calls ble_stack_init(). Could you please point me to where the DFU code disables the SD so I can debug and see if it hits that place? I could not find it!

    Thanks!

  • it was a bit misleading of me to say that the bootloader disables the softdevice before branching to the main app. Actually, the bootloader does not enable the softdevice on normal boot (power on reset, etc), only when it enters DFU mode and initialize the BT transport. After DFU complete, the bootloader will perform a system reset to ensure that the application always boots into the same state as it would after a normal boot. 

    To debug the bootloader you can step through the nrf_dfu.c::nrf_dfu_init() and check if nrf_bootloader_app_start() is being called. Then try to disable the softdevice after nrf_dfu_mbr_init_sd(); to see if that helps. Although it shouldn't be necessary as the softdevice should be disabled at this point (Master Boot Record (MBR) and SoftDevice initialization procedure)

    Also, you should remove nrf_drv_clock_uninit() since you're using the WDT, please refer to this thread for more details: https://devzone.nordicsemi.com/f/nordic-q-a/30677/bootloader-doesn-t-load-application-with-watchdog (fixed in SDK 15 bootloader)

    "The unit always seems to be stuck in PC 0x13d6e of SoftDevice."

    The program counter will stay at this address most of the time as this is where the __WFE instruction is being called from the softdevice  to enter System ON mode (sleep). 

  • Thanks Vidar! That are some good points.I fixed my issue with the WDT on the bootloader and I believe that was the main issue-however we are getting the following error if we debug our device without the bootloader in place:

    I have noticed that when I am debugging and restart the device I am getting failures at "nrf_sdh_enable_request();" with error code 0x08. I get this until I do a power cycle. I believe I was getting errors unrelated to this, and when I reset I was getting this issue, which is why I may have confused it with the bootloader. But I tried without the bootloader, got an unrelated error, and after reset kept getting this error!

    To clarify:

    1.) Erased device, loaded SD S132 and Application via nRF GO and J-LINK (note NO bootloader).

    2.) Got an unrelated error (bug in my code, or just reset device with debugger)

    3.) Reset debugger to understand what happened

    4.) After this reset I keep getting "nrf_sdh_enable_request();" errors on the main application until I power cycle.

    This does not happen if I have the bootloader present on step 1.

    The code is the same as the one I states some posts before, but I recopy it here:

    Application main.c

      int main(void)
    {
    int32_t err_code = 0;
        int32_t task_error = 0;
       
        
        nrf_delay_ms(1000); //wait after power up
        
        err_code  = NRF_LOG_INIT(NULL);
        NRF_LOG_DEFAULT_BACKENDS_INIT();
        //nrf_dfu_svci_vector_table_unset();
        NRF_LOG_INFO("Hello!");
        NRF_LOG_FLUSH();
        SEGGER_RTT_WriteString(0, "RTT initialized\n");
         
         BLE_init(); //Chrashes inside here
         ...
         }

    Inside BLE_Init

    int32_t BLE_init(void)
    {
        bool erase_bonds;
        uint32_t err_code;
    
        // Initialize
        ble_stack_init(); //Crashes inside here
        err_code = app_timer_init();
        //...
        }

    Thanks!

  • The bootloader must be present when you initialize the DFU service because it sets up the SVCI interface to the bootloader. This might explain the error in step 2 . However, I don't think it's related to the  invalid state errror from nrf_sdh_enable_request(). I'd suggest to step through the nrf_sdh_enable_request function and see if NRF_ERROR_INVALID_STATE is returned because m_nrf_sdh_enabled is 'true', or if the error gets returned from sd_softdevice_enable(). 

Related