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

Increase hvn_tx_queue_size to maximize throughput

I posted on the forum regarding the same project here https://devzone.nordicsemi.com/f/nordic-q-a/34022/optimizing-throughput-with-multiple-central-links-and-1-peripheral-link.

I wan't to stream with about 25kb/s as a minimum. Iv'e calcuated that if using 100ms conn interval I would need to set NRF_SDH_BLE_GAP_EVENT_LENGTH = 25ms. This would give me approximately 52 packets of 100bytes guaranteed per conn interval. I'm streaming data using notifications as a peripheral to a central device. I'm thinking that I would like to increase the TX buffer (hvn_tx_queue_size ) to increase the throughput. But if I increase it to above 11 i get NRF_ERROR_NO_MEM when running nrf_sdh_ble_enable(). This is fine, I check what RAM settings I should use and try, but I still get same error.

I also initiate with 19 central links so I eat alot of RAM. If I change to 1 central link I can go up to hvn_tx_queue_size = 17.

Is there a max value for hvn_tx_queue_size? Or is there a max value for softDevice RAM allocation? Does it matter what hvn_tx_queue_size is set to if I push data really fast? Do I need a big TX buffer to be able to send as many as 52 packets in 1 connection interval?

That was alot of questions, but I feel a bit confused to why I can't enable the sd with these settings.

Here is the code in ble_stack_init()

static 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.
    ram_start = 0;
    err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
    APP_ERROR_CHECK(err_code);

    ble_cfg_t ble_cfg;
    memset(&ble_cfg, 0, sizeof ble_cfg);
    ble_cfg.conn_cfg.conn_cfg_tag = APP_BLE_CONN_CFG_TAG;
    ble_cfg.conn_cfg.params.gatts_conn_cfg.hvn_tx_queue_size = 17;
    err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTS, &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,

    But if I increase it to above 11 i get NRF_ERROR_NO_MEM when running nrf_sdh_ble_enable(). This is fine, I check what RAM settings I should use and try, but I still get same error.

    This sounds strange. I was not able to reproduce this issue. If nrf_log is enabled, the RAM requirements for the SoftDevice will be printed over either RTT or UART(depending on nrf_log backend) e.g.

    <warning> nrf_sdh_ble: Insufficient RAM allocated for the SoftDevice.
    <warning> nrf_sdh_ble: Change the RAM start location from 0x20004368 to 0x20004F78.

    Then you need to adjust the RAM start in the IDE/toolchain you are using.

    What IDE/toolchain are you using? Where are you setting this number?

    Is there a max value for hvn_tx_queue_size?

    No, it should only be limited by RAM, but by setting it very big you will run out of RAM for your application.

    Do I need a big TX buffer to be able to send as many as 52 packets in 1 connection interval?

    Not necessarily. In the ble_app_att_mtu_throughput example we don't set the hvn_tx_queue_size in the application, but we still achieve maximum throughput. Note that both sides of the link need to support this number of packets per interval. Most smartphones only support maybe 6-9 packets per interval.

    Does it matter what hvn_tx_queue_size is set to if I push data really fast?

    Yes, if you exceed the event length/resources that is set aside for the link, and want to queue more data that should be send the next connection interval, you might want to increase this number. Notice the definition of the hvn_tx_queue_size, “Minimum guaranteed number of Handle Value Notifications that can be queued for transmission.”

  • Ok, so I ran into a similar problem again. I want to set NRF_SDH_BLE_GATT_MAX_MTU_SIZE to 247. It is currently set to 100. When I set it to 247 i get this error ouput on RTT 

    <warning> nrf_sdh_ble: Insufficient RAM allocated for the SoftDevice.
    <warning> nrf_sdh_ble: Change the RAM start location from 0x20010DF8 to 0x2001EE58.
    <warning> nrf_sdh_ble: Maximum RAM size for application is 0x211A8.
    <error> nrf_sdh_ble: sd_ble_enable() returned NRF_ERROR_NO_MEM.
    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at ../src/ble_core.c:435
    PC at: 0x00026E85
    <error> app: End of error report
    

    I then change to those settings in my linker script and build and flash. I then get this error output

    error> nrf_sdh_ble: sd_ble_enable() returned NRF_ERROR_NO_MEM.
    <error> app: ERROR 4 [NRF_ERROR_NO_MEM] at ../src/ble_core.c:435
    PC at: 0x00026E85
    <error> app: End of error report
    

    Basically the same as before but no suggestion to change RAM settings. How can this be?

  • Interesting. If you set hvn_tx_queue_size back to 1, does the same thing happen?

  • No when I decrease hvn_tx_queue_size  or remove rows 14 - 19 it's possible to enable sd again.

  • Hi

    Alexander said:
    Basically the same as before but no suggestion to change RAM settings. How can this be?

    The SoftDevice does not support dynamic RAM sizes over 64 kB. 

    For S140 V6.0.0, the base minium requirement is at 5.54 kB, so if you configure the SoftDevice to use more RAM than 5.54 kB + 64 kB, then this is not supported, and the sd_ble_enable() function will then return NRF_ERROR_NO_MEM.

    EDIT: We will look more into this limit internally, and see if we can increase it for the next SoftDevice release.

    Best regards,

    Sigurd

Related