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?

Parents
  • 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.

Reply
  • 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.

Children
No Data
Related