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

SDK13 NRF_ERROR_NO_MEM at sd_ble_gatts_characteristic_add()

Hello, when starting a new project I took the nice Heart-Rate-Example which works fine at my PCA10040. Then I started to add services and characteristics by copying and adapting the HRS - I know that I will have to declare them as vendor specific services and characteristics - this is not already done. One new service with 11 characteristics works fine, but adding a second will lead to a NRF_ERROR_NO_MEM as return value at the sd_ble_gatts_characteristic_add() function and then a Reset is executed. In one post in this forum I saw that adding

memset(&ble_cfg, 0, sizeof(ble_cfg));
ble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_MIN;
err_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_cfg, ram_start);
APP_ERROR_CHECK(err_code);

could help, but in my project this is not the case. I tried already various RAM-settings in the linker configuration file, but all without success. What can I do next?

  • In the softdevice_enable_get_default_config(), the vs_uuid_count is set to 1. If you want to use more than 1 vendor specific you need to increase this. So, after you call softdevice_enable_get_default_config() in ble_stack_init(), you change the vs_uuid_count of the param.

  • Hello Hung Bui, thanks for your information. Only when searching (in the whole project) I can't find a function softdevice_enable_get_default_config()... Actually my new services have UUIDs starting with 0x2Bxx; but they are not already defined as vendor specific. So the stack must assume that these are new (official) services and characteristics. Can that play a role?

  • Hi Mat,

    Could be different name in different Softdevice version. You need to point met to the SDK and softdevice you used.

    Seems like you exceeding the attributable size. Ihave you tried to increase attr_tab_size ? What happen if you set it to BLE_GATTS_ATTR_TAB_SIZE_DEFAULT (1408) ? or more than that ?

    Note that most of the cases you don't need 11 characteristics. It can be easily grouped into one characteristic and use 1 extra byte as the data ID.

  • Hi Hung Bui, my ble_stack_init() looks now like this:

    static void ble_stack_init(void)
    {
        ret_code_t err_code;
    
        nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;
    
        // Initialize the SoftDevice handler module.
        SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);
    
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = softdevice_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;
    
        // Configure the number of custom UUIDS.
        memset(&ble_cfg, 0, sizeof(ble_cfg));
        ble_cfg.common_cfg.vs_uuid_cfg.vs_uuid_count = 0;
        err_code = sd_ble_cfg_set(BLE_COMMON_CFG_VS_UUID, &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  = BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT;
        ble_cfg.gap_cfg.role_count_cfg.central_role_count = 0;
        ble_cfg.gap_cfg.role_count_cfg.central_sec_count  = 0;
        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.conn_cfg_tag                 = CONN_CFG_TAG;
        ble_cfg.conn_cfg.params.gatt_conn_cfg.att_mtu = NRF_BLE_GATT_MAX_MTU_SIZE;
        err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATT, &ble_cfg, ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Configure the maximum event length.
        memset(&ble_cfg, 0x00, sizeof(ble_cfg));
        ble_cfg.conn_cfg.conn_cfg_tag                     = CONN_CFG_TAG;
        ble_cfg.conn_cfg.params.gap_conn_cfg.event_length = 320;
        ble_cfg.conn_cfg.params.gap_conn_cfg.conn_count   = BLE_GAP_CONN_COUNT_DEFAULT;
        err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_cfg, ram_start);
        APP_ERROR_CHECK(err_code);
    
    #ifndef BEACON_TEST
        // aus Beacon Example
        memset(&ble_cfg, 0, sizeof(ble_cfg));
    //    ble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_MIN;
        ble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT;
        err_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_cfg, ram_start);
        APP_ERROR_CHECK(err_code);
    #endif
    
        // Enable BLE stack.
        err_code = softdevice_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Register with the SoftDevice handler module for BLE events.
        err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
        APP_ERROR_CHECK(err_code);
    
        // Register with the SoftDevice handler module for BLE events.
        err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
        APP_ERROR_CHECK(err_code);
    }
    

    The constant BLE_GATTS_ATTR_TAB_SIZE_MIN has the value 23 and BLE_GATTS_ATTR_TAB_SIZE_DEFAULT is defined with 1408.

    Nothing changes by changing the attribute value; it works well with a services_init() with the following services:

    DTHAD (my own, but not already defined with a vendor-specific UUID (0x2B30) and 11 characteristics (starting from 0x2B31...) Heart rate service HRS Battery service BAS Device Information Service DIS

    When I add another service DTHL (from my own, UUID 0x2B50 with some characteristics starting at 0x2B51..., no vendor-specific UUIDs) directly after the DTHAD service the last service in this list - in this case the DIS service - I get error code 4 at ble_dis_init()...

    When I take away the DTHL service everything becomes fine...

    Now I increased the value for BLE_GATTS_ATTR_TAB_SIZE_DEFAULT to 2408 and now with 4 self-created services it works!

    Can you tell me to which value I can increase this constant?

    Thanks in advance,

    Matthias

  • Hi Matthias, Next time , please edit you question and add your code in, not as an Answer. I don't think there would be any issue increasing the size of the attribute table as you did (to 2408), but don't modify BLE_GATTS_ATTR_TAB_SIZE_DEFAULT , just change ble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = 2048 for example.

    The only draw back is you have less RAM for the application.

    Again, I don't really see the point why you need 11 characteristics (and then 2 same service with total 22 characteristics). This will make the service discovery procedure take a lot of time, causing delay when you connecting and start data exchanging.

Related