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

Difference observed between __data_start__ and the value calculated with nrf_sdh_ble_enable()

Hi guys

I am working on a NRF52832 device. My SDK is 15.2. I am on S132.

To initialiser the Softdevice, I use the following function :

/**@brief Function for initializing the BLE stack.
 *
 * @details Initializes the SoftDevice and the BLE event interrupt.
 */
void ble_stack_init(void)
{
    extern uint8_t __data_start__;
    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 app_ram_base = 0;

    err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &app_ram_base);
    APP_ERROR_CHECK(err_code);

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

    // Check if we do memory allocation correctly.
    if (err_code == NRF_SUCCESS)
    {
        // Verify that value provided in linked script (LD file) matches the SD calculations.
        if (app_ram_base == (uint32_t) &__data_start__)
        {
            //NRF_LOG_INFO("Soft Device enabled, __data_start__ is set correctly.");
            printf("Soft Device enabled, __data_start__ is set correctly.\n");
        }
        else
        {
            //NRF_LOG_INFO("Soft Device enabled, __data_start__ is set incorrectly (should be = 0x%08X instead of 0x%08X).", app_ram_base, (uint32_t) &__data_start__);
            printf("Soft Device enabled, __data_start__ is set incorrectly (should be = 0x%08X instead of 0x%08X).\n", app_ram_base, (uint32_t) &__data_start__);
#if (!SECURITY_MODE)
            APP_ERROR_CHECK(NRF_ERROR_FORBIDDEN); //AKR for test
#endif
        }
    }
    else if (err_code == NRF_ERROR_NO_MEM)
    {
        // Not enough memory for the Soft Device (value provided is too low).
        //NRF_LOG_INFO("Soft Device failed to enabled, __data_start__ is set incorrectly (should be = 0x%08X instead of 0x%08X).", app_ram_base, (uint32_t) &__data_start__);
    }
    APP_ERROR_CHECK(err_code);

    // Register a handler for BLE events.
    NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
}

You can see that we added a condition, after nrf_sdh_ble_enable() function, in the case where the err_code == NRF_SUCCESS

Here we check if the the value provided in linked script, __data_start__, is the same as the value returned by the nrf_sdh_ble_enable() function, app_ram_base,  so the SD calculations.

When i don't use the Security Layer, so the Peer manager, the error code from nrf_sdh_ble_enable() is NRF_SUCCESS, and __data_start__ and app_ram_base are the same.

When i implement the Peer manager and all the modules needed, error code from nrf_sdh_ble_enable() is NRF_SUCCESS, but __data_start__ and app_ram_base are not the same.

I have commented in this case the following APP_ERROR_CHECK(NRF_ERROR_FORBIDDEN), and we have done many tests and all seems to work anyway, but it worries me.

Do you know why in this case __data_start__ and app_ram_base are different ? What are the consequences ?

Is there a way to correct that ?

I should mention that I tried to correct this problem by changing the RAM size with RAM_START and RAM_SIZE, but It didn't change anything.

Thanks !

Parents
  • Hello,

    The "__data_start__" symbol is generated by the linker and reflects the actual start address (usually the same as the RAM ORIGIN address in your linker script), while "app_ram_base" is the minimum address required by the Softdevice.

    The Softdevice will get enabled as long as __data_start__ (APP_RAM_BASE) is either equal to or higher than the app_ram_base address returned by the Softdevice, but ideally, you want to keep __data_start__ and app_ram_base the same to prevent an empty memory gap  between the Softdevice and Application region in RAM:

    SoftDevice memory usage

    I should mention that I tried to correct this problem by changing the RAM size with RAM_START and RAM_SIZE, but It didn't change anything.

     Are you using Segger Embedded studio or the GCC makefiles to build the project. Reason I'm asking is that our Segger projects don't use the __data_start__ symbol like in the Makefile projects do. And the makefile projects don't use RAM_START and RAM_SIZE to define the RAM layout like Segger embedded studio.

    Best regards,

    Vidar

  • Hi Vidar,

    I am using Segger Embeddded Studio to build the project. Previously when I have added some custom services and characteristics I have modified few times RAM_START and RAM_SIZE, and also the attribute table in sdk_config and all was Ok.

    Thanks for your answer, it helps me to understand more about my problem, but I think that you haven't answered to my questions.

    If you need more information, don't hesitate to ask me !

Reply
  • Hi Vidar,

    I am using Segger Embeddded Studio to build the project. Previously when I have added some custom services and characteristics I have modified few times RAM_START and RAM_SIZE, and also the attribute table in sdk_config and all was Ok.

    Thanks for your answer, it helps me to understand more about my problem, but I think that you haven't answered to my questions.

    If you need more information, don't hesitate to ask me !

Children
  • Hi,

    It's not clear to me why you have the "__data_start__" linker symbol when you use SES, I would have exepected it to be "__app_ram_start__". Maybe you are not using the flash_placment.xml file that our SDK examples use? In any case, the app should run fine as long as the __data_start__ (or __app_ram_start__) address is equal or higher than the "app_ram_base" returned by the SD.

Related