Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Build and Run with SEGGER Embedded Studio (SES) v6.20a on nRF5 SDK 17.1.0 and S140 7.2.0 on nRF52840

Hi DevZone,

I have recently updated:

  • nRF5 SDK to 17.1.0 from 15.3.0
  • S140 to 7.2.0 from 6.1.1
  • SES to v6.20a from 4.16

The SoftDevice now fails to initialize when using the "Build and Run" option with SES.

The code initializes without issue if I:

  • Use Programmer v2.3.3 from nRF Connect for Desktop v3.10.0
  • If I Power Cycle the hardware after each flash of the .hex files
  • If I "Build and Debug" with SES

Is this a known issue, and could it potentially be a timing issue?

Code that fails:

void ble_stack_init(void)
{
    ret_code_t err_code;

    err_code = nrf_sdh_enable_request();
    APP_ERROR_CHECK(err_code);

    // Configure the BLE stack using the default settings.
    // Fetch the start address of the application RAM.
    uint32_t ram_start = 0;
    err_code = nrf_sdh_ble_default_cfg_set(BLE_CONN_CFG_TAG, &ram_start);
    APP_ERROR_CHECK(err_code);

    // Enable BLE stack.
    err_code = nrf_sdh_ble_enable(&ram_start);
    APP_ERROR_CHECK(err_code);

//    // NO OBSERVERS AT THIS POINT 
//    // Register a handler for BLE events.
//    NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
}

Specifically the call to nrf_sdh_enable_request() returns with error code NRF_ERROR_INVALID_STATE (0x00000008).

This should mean that the SoftDevice is already initialized when reading the documentation. However, preceding the nrf_sdh_enable_request() call with a nrf_sdh_is_enabled()

tells me that it is not.

Comparing with example projects:

I have compared to the example projects given in SDK 17.1.0, and the initialization code for the BLE stack seems unchanged between versions 17.1.0 and 15.3.0. 

Also, I have tried building and running the peripheral example from SDK 17.1.0 "usbd_ble_uart_freertos" both on our hardware and an nRF52840-DK, which fails with the same error code.

So, even with code directly from the SDK and on multiple hardware the issue is the same.

Thanks in advance.

Br. Casper

  • Hi Edvin,

    I looks like the SDK function nrf_sdh_ble_default_cfg_set(), which I am calling, calls sd_ble_cfg_set() 5 times.

    EDIT: (5 times, because (NRF_SDH_BLE_GATT_MAX_MTU_SIZE != 23) condition is not met).

    ret_code_t nrf_sdh_ble_default_cfg_set(uint8_t conn_cfg_tag, uint32_t * p_ram_start)
    {
        uint32_t ret_code;
    
        ret_code = nrf_sdh_ble_app_ram_start_get(p_ram_start);
        if (ret_code != NRF_SUCCESS)
        {
            return ret_code;
        }
    
    #if defined (S112) || defined(S312)
        STATIC_ASSERT(NRF_SDH_BLE_CENTRAL_LINK_COUNT == 0, "When using s112, NRF_SDH_BLE_CENTRAL_LINK_COUNT must be 0.");
    #endif
    
        // Overwrite some of the default settings of the BLE stack.
        // If any of the calls to sd_ble_cfg_set() fail, log the error but carry on so that
        // wrong RAM settings can be caught by nrf_sdh_ble_enable() and a meaningful error
        // message will be printed to the user suggesting the correct value.
        ble_cfg_t ble_cfg;
    
    #if (NRF_SDH_BLE_TOTAL_LINK_COUNT != 0)
        // Configure the connection count.
        memset(&ble_cfg, 0, sizeof(ble_cfg));
        ble_cfg.conn_cfg.conn_cfg_tag                     = conn_cfg_tag;
        ble_cfg.conn_cfg.params.gap_conn_cfg.conn_count   = NRF_SDH_BLE_TOTAL_LINK_COUNT;
        ble_cfg.conn_cfg.params.gap_conn_cfg.event_length = NRF_SDH_BLE_GAP_EVENT_LENGTH;
    
        ret_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_cfg, *p_ram_start);
        if (ret_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_CONN_CFG_GAP.",
                          nrf_strerror_get(ret_code));
        }
    
        // Configure the connection roles.
        memset(&ble_cfg, 0, sizeof(ble_cfg));
    #if !defined (S122)
        ble_cfg.gap_cfg.role_count_cfg.periph_role_count  = NRF_SDH_BLE_PERIPHERAL_LINK_COUNT;
    #endif // !defined (S122)
    #if !defined (S112) && !defined(S312) && !defined(S113)
        ble_cfg.gap_cfg.role_count_cfg.central_role_count = NRF_SDH_BLE_CENTRAL_LINK_COUNT;
        ble_cfg.gap_cfg.role_count_cfg.central_sec_count  = MIN(NRF_SDH_BLE_CENTRAL_LINK_COUNT,
                                                                BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT);
    #endif // !defined (S112) && !defined(S312) && !defined(S113)
    
        ret_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_cfg, *p_ram_start);
        if (ret_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_GAP_CFG_ROLE_COUNT.",
                          nrf_strerror_get(ret_code));
        }
    
        // Configure the maximum ATT MTU.
    #if (NRF_SDH_BLE_GATT_MAX_MTU_SIZE != 23)
        memset(&ble_cfg, 0x00, sizeof(ble_cfg));
        ble_cfg.conn_cfg.conn_cfg_tag                 = conn_cfg_tag;
        ble_cfg.conn_cfg.params.gatt_conn_cfg.att_mtu = NRF_SDH_BLE_GATT_MAX_MTU_SIZE;
    
        ret_code = sd_ble_cfg_set(BLE_CONN_CFG_GATT, &ble_cfg, *p_ram_start);
        if (ret_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_CONN_CFG_GATT.",
                          nrf_strerror_get(ret_code));
        }
    #endif  // NRF_SDH_BLE_GATT_MAX_MTU_SIZE != 23
    #endif  // NRF_SDH_BLE_TOTAL_LINK_COUNT != 0
    
        // Configure number of custom UUIDS.
        memset(&ble_cfg, 0, sizeof(ble_cfg));
        ble_cfg.common_cfg.vs_uuid_cfg.vs_uuid_count = NRF_SDH_BLE_VS_UUID_COUNT;
    
        ret_code = sd_ble_cfg_set(BLE_COMMON_CFG_VS_UUID, &ble_cfg, *p_ram_start);
        if (ret_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_COMMON_CFG_VS_UUID.",
                          nrf_strerror_get(ret_code));
        }
    
        // Configure the GATTS attribute table.
        memset(&ble_cfg, 0x00, sizeof(ble_cfg));
        ble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE;
    
        ret_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_cfg, *p_ram_start);
        if (ret_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_GATTS_CFG_ATTR_TAB_SIZE.",
                          nrf_strerror_get(ret_code));
        }
    
        // Configure Service Changed characteristic.
        memset(&ble_cfg, 0x00, sizeof(ble_cfg));
        ble_cfg.gatts_cfg.service_changed.service_changed = NRF_SDH_BLE_SERVICE_CHANGED;
    
        ret_code = sd_ble_cfg_set(BLE_GATTS_CFG_SERVICE_CHANGED, &ble_cfg, *p_ram_start);
        if (ret_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_GATTS_CFG_SERVICE_CHANGED.",
                          nrf_strerror_get(ret_code));
        }
    
        return NRF_SUCCESS;
    }

    I am only calling ble_stack_init() a single time, followed by nrf_sdh_freertos_init()

    I will grab a DK again and see if I can get the same output ASAP.

    Br. Casper

  • I see. But still, it looks like this is being called after the ble stack is already enabled (at which point, it is too late to change any configurations.

    Is there any way for me to reproduce this? Can you zip your project folder and upload it here?

    BR,
    Edvin

  • Hi Edvin,

    I was able to get a hold of a DK and reproduce the exact same nrf_log output.

    I can send you the project, but then the support has to be changed to private, or receive your direct e-mail. Is that something we can do?

    Br. Casper

  • Update:

    I found this thread which enabled me to build the usbd_ble_uart_freertos_pca10056_s140 SDK example from SDK 17.1.0 by changing line 100 in retarget.c.

    Then I tried the following on an nRF52840-DK:

    1. I removed all features from the SDK example that are not used in our own project and then I was able to start s140 without doing power cycles, using the debugger or any of the other methods.
    2. Then I removed all features and initialization in the main() function except nrf_log and s140 from our own project and used the exact same sequence of function calls as in the SDK example. But the problem still exists.

    Could this mean that the difference might lie in defines in the sdk_config.h header file?

    I am running with the same sdk_config.h as before the change from SDK 15.3.0 to 17.1.0.

    Are any changes needed to that file to make things work as intended when updating the SDK version?

    I am currently investigating the differences between the files.

    Br. Casper

  • Casper Kronborg Pedersen said:
    Could this mean that the difference might lie in defines in the sdk_config.h header file?

    It could be, but my main suspicion, and why I asked about the NRF_LOG_WARNING lines is that when you change the softdevice, it will typically require some other memory settings than what it did in the old SDK. I will change this ticket to private now.

    Casper Kronborg Pedersen said:

    Are any changes needed to that file to make things work as intended when updating the SDK version?

    You should see the migration guide for the SDK versions between 15.3.0 and 17.1.0.

    If you took the project file from the old SDK, then you need to make sure that you upload the new SoftDevice from the new SDK, and you probably need to change flash start address, flash size, ram start address and ram size to match your new SoftDevice.

    For Flash, just see what flash start address and size the other examples in the SDK that uses the same softdevice uses, while for RAM, you need to monitor the log, or debug and set breakpoints at those points to see if it wants you to change the RAM settings. The reason I can't just tell you what to set is that it depends on the application you are running, the number of services and characteristics, the connection parameters that you intend to use, the MTU size, the number of supported simultaneous connections and so on.

    Best regards,

    Edvin

Related