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.

  • I am setting it to 247. Is it possible somehow to have an MTU of 23 for the central roles? I need a high throughput for my peripheral, but my accessories (central links) have a very low priority which I can handle with a small MTU and long connection intervals.

  • Yes, you can create two different SoftDevice configurations, one for the peripheral role and for the central role. 

    You use sd_ble_cfg_set to set the configuration and the ble_cfg.conn_cfg.conn_cfg_tag field to determine which configuration number that is being set. So for configuration number 1, you can set the ATT MTU to 247 and the peripheral role count to 1. For the seconds configuration, number 2, you can set the ATT  MTU to 23 and the central role count to 8. 

    When you connect to the peripherals using the central role you pass the configuration number in the sd_ble_gap_connect call, i.e. 

    sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params, uint8_t conn_cfg_tag));

  • That's great! Thanks for your support as always :) I'll implement that and report back when I get some results. I'll mark the question as answered then.

  • Happy to help! Let me know if you run into any issues. 

  • Hi Bjorn,

    So I implemented what you mentioned and it seems to be working nicely :) I could reduce the RAM requirements for each additional central link to 1628 bytes.

    However, I ran into issues when connecting to another peripheral using the central role. These issues are specific to the nrf_ble_gatt module. I run into errors because the module is trying to use a larger MTU and a longer data length than what I have allocated memory for.

    The first issue I have is that the module tries to set an MTU of 247 for my central connections. This is because the module initializes the desired MTU to the MAX MTU SIZE definition in sdk_config.h. This is an easy fix because I can just call nrf_ble_gatt_att_mtu_central_set and override the setting.

    The second issue I have is that the module also tries to set the data length to 251. There aren't separate peripheral/central data lengths. So if I call nrf_ble_gatt_data_length_set to set it to 23 for my central links, this value would be set also for future peripheral connections. I think there should be separate settings just like for the MTU. Consider this a feature request :)

    Anyway, do you have any suggestions on how to tackle this issue?

Related