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

Buttonless DFU Debugging Problem

I'm trying to add buttonless DFU to the SDK's template application. 

Here is my setup: 

  • Soft Device 6.1.0
  • Secure Bootloader
  • Modified Template App (Added buttonless DFU)

I am able to successfully OTA upload my package .zip to the board, but the application does not run and there is no advertising.
The bootloader is there because holding button 4 and doing a reset on the dev-kit puts it into DFU.

Trying to debug the code, I can not run a debug session through Segger Embedded Studio when the bootloader is present. 
With just the APP + SD, I can step through and get to the point in services_init where ble_dfu_buttonless_async_svci_init returns: No bootloader was found


Adding a debug post build script for the bootloader settings:

C:\Python27\Scripts\nrfutil.exe settings generate --family NRF52840 --application $(ProjectDir)\Output\$(Configuration)\Exe\$(ProjectName).hex  --application-version 1 --bootloader-version 1 --bl-settings-version 1 settings.hex
With this added, flashing the SD, and Bootloader, and trying to debug through SES, the code just tries to run with no advertising without giving me the option to step through the code.
I've tried adding the SD, Bootloader settings, and Bootloader as Additional Load files in the debug build to no success.

Section Placement Macros:
FLASH_PH_START=0x0
FLASH_PH_SIZE=0x100000
RAM_PH_START=0x20000000
RAM_PH_SIZE=0x40000
FLASH_START=0x26000
FLASH_SIZE=0xd2000
RAM_START=0x20002210
RAM_SIZE=0x3dde0

The same results are seen for my experiments with trying to debug the SDK's buttonless DFU app.
Any help would be appreciated,
Jeff

Parents
  • Hi Jeff,

    I encountered the same problem here. That is, checksum of app image did not match with the one stored in the generated bl settings page and therefore became stuck in DFU mode. Further debugging revealed that the there was a slight difference if I uploaded the .hex file instead of the .elf file in the build directory:

    Not sure if this is expected behavior or if it is a bug in binutils (tested with SES v.3.50). In any case, I worked around this be changing the debugger settings in SES to upload the .hex file instead. Screenshots of my configuration:

    (Post build command :  nrfutil settings generate --family NRF52840 --application $(OutDir)/$(ProjectName).hex --application-version 1 --bootloader-version 1 --bl-settings-version 1 $(OutDir)/settings.hex)

     

     

     

     

     

  • I now am able to program + debug the boot for the buttonless dfu, and modified template app on the development kit. However now I am getting the same or similar issue when I flash one of those working examples to my custom board.

    I modified the boot to not turn the DK LED pins and boot button because of my CUSTOM_BOARD macro, but perhaps I am missing another step. The program again loads right into the boot even though the example is working on the DK.

    Any insight would be appreciated.  

  • Does your custom board have an external LF crystal? Reason I ask is that all SDK bluetooth examples are configured to use the optional LF crystal. If not you need to enable the internal RC oscillator in sdk_config.h (both app and bootloader project):

     

    ......
    
    //==========================================================
    
    // <h> Clock - SoftDevice clock configuration
    
    //==========================================================
    // <o> NRF_SDH_CLOCK_LF_SRC  - SoftDevice clock source.
     
    // <0=> NRF_CLOCK_LF_SRC_RC 
    // <1=> NRF_CLOCK_LF_SRC_XTAL 
    // <2=> NRF_CLOCK_LF_SRC_SYNTH 
    
    #ifndef NRF_SDH_CLOCK_LF_SRC
    #define NRF_SDH_CLOCK_LF_SRC 0
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_RC_CTIV - SoftDevice calibration timer interval. 
    #ifndef NRF_SDH_CLOCK_LF_RC_CTIV
    #define NRF_SDH_CLOCK_LF_RC_CTIV 16
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_RC_TEMP_CTIV - SoftDevice calibration timer interval under constant temperature. 
    // <i> How often (in number of calibration intervals) the RC oscillator shall be calibrated
    // <i>  if the temperature has not changed.
    
    #ifndef NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
    #define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 2
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_ACCURACY  - External clock accuracy used in the LL to compute timing.
     
    // <0=> NRF_CLOCK_LF_ACCURACY_250_PPM 
    // <1=> NRF_CLOCK_LF_ACCURACY_500_PPM 
    // <2=> NRF_CLOCK_LF_ACCURACY_150_PPM 
    // <3=> NRF_CLOCK_LF_ACCURACY_100_PPM 
    // <4=> NRF_CLOCK_LF_ACCURACY_75_PPM 
    // <5=> NRF_CLOCK_LF_ACCURACY_50_PPM 
    // <6=> NRF_CLOCK_LF_ACCURACY_30_PPM 
    // <7=> NRF_CLOCK_LF_ACCURACY_20_PPM 
    // <8=> NRF_CLOCK_LF_ACCURACY_10_PPM 
    // <9=> NRF_CLOCK_LF_ACCURACY_5_PPM 
    // <10=> NRF_CLOCK_LF_ACCURACY_2_PPM 
    // <11=> NRF_CLOCK_LF_ACCURACY_1_PPM 
    
    #ifndef NRF_SDH_CLOCK_LF_ACCURACY
    #define NRF_SDH_CLOCK_LF_ACCURACY 1
    #endif

     

  • Vidar, 

    This was a good thought, however my custom board has an LF crystal.
    I did try to run it using the internal RC as suggested with no favorable results. (Stays in Boot)

    I will be continuing debugging this issue over the next couple of days. If you can think of any other reasons this would happen, please let me know. 


    Thanks,
    Jeff

Reply Children
  • Jeff,

    thanks for confirming. Maybe it could be the bootloader button pin then. The bootloader will enter DFU mode if the NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN is pulled low on startup?

    Vidar

  • Vidar,

    Holding down the button on power-up fixed the issue.
    This is strange to me, as the button is pulled low on contact. (See schematic)
    Perhaps I need to activate an internal pull-up inside the boot?



    Thanks for your continued support!
    Jeff

  • Jeff,

    Happy to help:) Yes, you need to enable pull-up on the pin, see BUTTON_PULL define in you BOARD header. 

    Update: guess I responded too quickly. Based on the schematic, I don't think it make sense that it works when you hold the button on power-up.

    Here are the lines of code that determines if the bootloader should enter DFU mode (nrf_bootloader.c::dfu_enter_check):

    static bool dfu_enter_check(void)
    {
    if (!nrf_dfu_app_is_valid(crc_on_valid_app_required()))
    {
    NRF_LOG_DEBUG("DFU mode because app is not valid.");
    return true;
    }

    if (NRF_BL_DFU_ENTER_METHOD_BUTTON &&
    (nrf_gpio_pin_read(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN) == 0)) // Active low
    {
    NRF_LOG_DEBUG("DFU mode requested via button.");
    return true;
    }

    if (NRF_BL_DFU_ENTER_METHOD_PINRESET &&
    (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk))
    {
    NRF_LOG_DEBUG("DFU mode requested via pin-reset.");
    return true;
    }

    if (NRF_BL_DFU_ENTER_METHOD_GPREGRET &&
    (nrf_power_gpregret_get() & BOOTLOADER_DFU_START))
    {
    NRF_LOG_DEBUG("DFU mode requested via GPREGRET.");
    return true;
    }

    if (NRF_BL_DFU_ENTER_METHOD_BUTTONLESS &&
    (s_dfu_settings.enter_buttonless_dfu == 1))
    {
    NRF_LOG_DEBUG("DFU mode requested via bootloader settings.");
    return true;
    }

    return false;
    }

    And the bootloader button initialization (nrf_bootloader.c::dfu_enter_button_init):

    nrf_gpio_cfg_sense_input(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN,
    BUTTON_PULL,
    NRF_GPIO_PIN_SENSE_LOW); 

     

      

Related