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

Trying to Integrate DFU and now encountering bootloops due to sd_softdevice_enable()

I've been going off of the Buttonless DFU example to integrate DFU functionality into an existing project on a custom board. While I seem to have added the necessary includes and code to compile without errors, my board bootloops when it executes the code. After stepping through the code in debug mode in Eclipse, it appears that the hard fault occurs at the sd_softdevice_enable_request(), in particular when it makes the SVCALL to sd_softdevice_enable(). I'm unable to see what the actual signal returns to induce the failure.

I modified my linker script to match the memory layout of the buttonless DFU example. I also added relevant DFU configuration code to sdk_config.h, and then integrated the appropriate methods for initializing DFU from the example (app_shutdown_handler, ble_dfu_evt_handler, pm_evt_handler, peer_manager_init, delete_bonds, advertising_start) as well as necessary additions to services_init() and ble_init().

The curious thing is that all of these additions occur after the call to sd_softdevice_enable_request(). This makes me suspect that the problem has to do with changes to sdk_config.h, or changes to my Makefile. The biggest changes to sdk_config.h appear to be changing PEER_MANAGER_ENABLED from 0 to 1, PM_CENTRAL_ENABLED from 1 to 0, NRF_SDH_BLE_GAP_EVENT_LENGTH 7 to 3, NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247 to 23, NRF_SDH_BLE_SERVICE_CHANGED 0 to 1.

For the Makefile, the memory layout was altered from

MEMORY
{
  FLASH (rx) : ORIGIN = 0x23000, LENGTH = 0x5D000
  RAM (rwx) :  ORIGIN = 0x20002A68, LENGTH = 0xD598
  
}

to

MEMORY
{
  FLASH (rx) : ORIGIN = 0x23000, LENGTH = 0x55000
  RAM (rwx) :  ORIGIN = 0x20002180, LENGTH = 0xde80
  
}

with an additional section:

  .svc_data :
  {
    PROVIDE(__start_svc_data = .);
    KEEP(*(.svc_data))
    PROVIDE(__stop_svc_data = .);
  } > FLASH

I can include any additional files or sections of code. I realize this isn't very much to go off of, but I'm scratching my head over this, seeing as the bootloop is occurring at a point in the code in which things have not been altered prior to attempting to integrate the DFU code.

EDIT: there is one other detail I forgot to mention that may be a major factor here: In order to resolve an Implicit Declaration error within my build, I included "nrf_sdm.h" within the file initializing my BLE stack. This wasn't included in the example code, perhaps its resulting in improper initialization of the soft device.

Parents
  • Hi Mason,

    I apologize for the late reply. 

    I realize that I forgot to ask which SDK version you were using?Judging by the values in the linker script it could look like its SDK v14.x.0? If the device is resetting then it is likely that its one of the APP_ERROR_CHECK(err_code) calls that are asserting. Could you turn of any code optimization in Eclipse, compile the application , start a debug session and set a breakpoint in app_error_handler_bare() in app_error.c and see if you enter the error handler? If you do please examine the call stack to see where the assert originated from. 

    Bjørn

     

Reply
  • Hi Mason,

    I apologize for the late reply. 

    I realize that I forgot to ask which SDK version you were using?Judging by the values in the linker script it could look like its SDK v14.x.0? If the device is resetting then it is likely that its one of the APP_ERROR_CHECK(err_code) calls that are asserting. Could you turn of any code optimization in Eclipse, compile the application , start a debug session and set a breakpoint in app_error_handler_bare() in app_error.c and see if you enter the error handler? If you do please examine the call stack to see where the assert originated from. 

    Bjørn

     

Children
  • If its the sd_softdevice_enable() call returns an error code other than NRF_SUCCESS, then please provide the error code here. 

  • I'm on SDK 14.2

    I set the optimization flags to be -O0 and -g3 when building, set a breakpoint in app_error_handler_bare(), and ran a debug session. The breakpoint does not get triggered.

    When I step through the app, the furthest I can get is Line 310 in nrf_sdm.h:

    SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));

    After which things seem to blow up, and I error out with the following:

    No source available for "<signal handler called>() at 0xfffffff9" 

    Via the disassembly log:

    fffffff9:   Unable to retrieve disassembly data from backend.

    Perhaps I am missing something, but I don't see what's getting returned by sd_softdevice_enable(). In my interpretation, it seems that things blow up right before something gets returned.

    The disassembly at 0x90c is the following:

  • I reckon that you have flashed the SoftDevice to the nRF52832. What LF clock configuration( nrf_clock_lf_cfg_t p_clock_lf_cfg) are you passing to the sd_softdevice_enable call? Does your custom board have the external 32kHz crystal(LFXO) on it or not? 

  • The nrf_clock_lf_cfg_t configuration is coming from nrf_sdh.c which is defined as the following (Line 217):

        nrf_clock_lf_cfg_t const clock_lf_cfg =
        {
            .source        = NRF_SDH_CLOCK_LF_SRC,
            .rc_ctiv       = NRF_SDH_CLOCK_LF_RC_CTIV,
            .rc_temp_ctiv  = NRF_SDH_CLOCK_LF_RC_TEMP_CTIV,
        #ifdef S140
            .xtal_accuracy = NRF_SDH_CLOCK_LF_XTAL_ACCURACY
        #else
            .accuracy      = NRF_SDH_CLOCK_LF_XTAL_ACCURACY
        #endif
        };

    which evaluates to:

        nrf_clock_lf_cfg_t const clock_lf_cfg =
        {
            .source        = 1,
            .rc_ctiv       = 0,
            .rc_temp_ctiv  = 0,
        #ifdef S140
            .xtal_accuracy = 7
        #else
            .accuracy      = 7
        #endif
        };
    

    We do have a 32.768kHz external crystal in place.

  • Do you see any change in the behaviour if you switch to the internal RC, i.e. 

    #define NRF_CLOCK_LFCLKSRC      {.source        = NRF_CLOCK_LF_SRC_RC,            \
                                     .rc_ctiv       = 16,                                \
                                     .rc_temp_ctiv  = 2,                                \
                                     .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM}

Related