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

RAM requirements per central link?

Hello,

I have an application that is meant to be used mainly as a peripheral. I'm now exploring options to expand functionality via 3rd-party accessories. For this, I need to use the central role.

My question is how much RAM should an extra concurrent central link require? As far as I can see now, testing simply by adding extra links at compile time, each extra link needs 3792 bytes of RAM.

I'm wondering if this is like the absolute minimum RAM requirement or what can I do to reduce it otherwise. My peripheral role is fairly complex (10 services and around 70 characteristics). I don't know if some of this complexity is carried over to the central role, or if each central link is completely independent of each other. In the case where my peripheral application is affecting the RAM requirements of future central links, what can I do to isolate them?

I would like to support up to 8 concurrent accessories. Their implementation in my device would be very simple, most likely a single service and characteristic per accessory. 

I am using an NRF52832 with SDK 15.0. Allocating almost 24 KB of RAM to support 8 central links will leave my application without memory. I know I can reduce the number of concurrent links to 3 or so, but I want to know if it's possible to reduce the requirements for a single link.

  • HI Andy, 

    I did a quick test with the ble_app_multilink_central example in SDK v15.0.0 where I set the NRF_SDH_BLE_TOTAL_LINK_COUNT and NRF_SDH_BLE_CENTRAL_LINK_COUNT to 1  and then added more centrals one by one. 

    I got the following app_ram_start address from sd_ble_enable

    Central Link Count           Application RAM Start Address

           1                                           0x200021F8

           2                                           0x20002758

           3                                           0x2000CB8

          4                                           0x20003218

    Each additional central increased the RAM start address by 0x560 bytes, i.e. 1376 bytes. Are you the default configuration, i.e. calling  nrf_sdh_ble_default_cfg_set() prior to nrf_sdh_ble_enable() or have you modified it?

    Best regards

    Bjørn 

  • Hi Bjorn,

    Good to know that the RAM requirements can be lower!

    My initialization method looks like this:

    void ble_stack_init(void) {
    	ret_code_t err_code;
    
    	// Initialize the SoftDevice handler module.
    	err_code = nrf_sdh_enable_request();
    	APP_ERROR_CHECK(err_code);
    
    	// Fetch the start address of the application RAM.
    	uint32_t ram_start = 0;
    	err_code = nrf_sdh_ble_app_ram_start_get(&ram_start);
    	APP_ERROR_CHECK(err_code);
    
    	// Overwrite some of the default configurations for the BLE stack.
    	ble_cfg_t ble_cfg;
    
    	memset(&ble_cfg, 0, sizeof(ble_cfg));
    	ble_cfg.common_cfg.vs_uuid_cfg.vs_uuid_count = CUSTOM_UUID_COUNT;
    
    	err_code = sd_ble_cfg_set(BLE_COMMON_CFG_VS_UUID, &ble_cfg, ram_start);
    	APP_ERROR_CHECK(err_code);
    
    	memset(&ble_cfg, 0, sizeof(ble_cfg));
    	// TODO: change this value if you get the NRF_ERROR_NO_MEM
    	// If you change the size, you need to change the RAM settings in the linker file
    	ble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT + BLE_GATTS_ATTR_TAB_SIZE_MIN + 0x1100;
    	err_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_cfg, ram_start);
    	APP_ERROR_CHECK(err_code);
    
    	// Configure the maximum number of connections.
    	memset(&ble_cfg, 0, sizeof(ble_cfg));
    	ble_cfg.gap_cfg.role_count_cfg.periph_role_count  = NRF_SDH_BLE_PERIPHERAL_LINK_COUNT;
    	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  = NRF_SDH_BLE_CENTRAL_LINK_COUNT;
    	err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_cfg, ram_start);
    	APP_ERROR_CHECK(err_code);
    
    	// Configure the maximum ATT MTU.
    	memset(&ble_cfg, 0x00, sizeof(ble_cfg));
    	ble_cfg.conn_cfg.params.gatt_conn_cfg.att_mtu = NRF_SDH_BLE_GATT_MAX_MTU_SIZE;
    	ble_cfg.conn_cfg.conn_cfg_tag                 = APP_BLE_CONN_CFG_TAG;
    	err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATT, &ble_cfg, ram_start);
    	APP_ERROR_CHECK(err_code);
    
    	memset(&ble_cfg, 0, sizeof(ble_cfg));
    	ble_cfg.conn_cfg.params.gap_conn_cfg.conn_count     = NRF_BLE_LINK_COUNT;
    	ble_cfg.conn_cfg.params.gap_conn_cfg.event_length   = NRF_SDH_BLE_GAP_EVENT_LENGTH;
    	ble_cfg.conn_cfg.conn_cfg_tag                       = APP_BLE_CONN_CFG_TAG;
    	err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_cfg, ram_start);
    	APP_ERROR_CHECK(err_code);
    
    	// Enable BLE stack.
    	err_code = nrf_sdh_ble_enable(&ram_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);
    }

  • Hi Andy, 

    parameters like ATT MTU size and GATT Table size will affect the RAM usage of each additional role. I have used the default values in the ble_app_multilink_central, i.e. NRF_SDH_BLE_GATT_MAX_MTU_SIZE = 23 and NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE = 1408. 

    I see that you're increasing the GATT table size with 0x1100 compared to the default 1408( if you have not changed it). Make sure that you do not set this higher that you need strictly need to. 

    Best regards

    Bjørn

  • I increased the ATTR TAB SIZE because I need more RAM allocated to the SoftDevice for it to handle the 70 characteristics. If I understand what you're saying, each additional role will be created with enough RAM to handle 70 characteristics as well?

    Is there any way to isolate this? Did I maybe misunderstand the ATTR TAB SIZE attribute and I need to give the RAM for my characteristics elsewhere?

  • HI Andy, 

    it appears that I was mistaken, the Attribute table size does not increase the RAM required for additional connections, its the ATT MTU Size, Write Command Queue and HVN Queue that increase the RAM usage for each additional connection. 

    What is your ATT MTU size? If I set it to 247( the maximum size our SDs allow) then I get a similar RAM increase per connection as you have observed, i.e. 0x1238 per connection added. 

    Best regards

    Bjørn

Related